/external/mesa3d/src/mesa/program/symbol_table.c

https://gitlab.com/brian0218/rk3188_r-box_android4.2.2_sdk · C · 488 lines · 276 code · 116 blank · 96 comment · 80 complexity · cea98835c05cdce374773fc171063ad4 MD5 · raw file

  1. /*
  2. * Copyright © 2008 Intel Corporation
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice (including the next
  12. * paragraph) shall be included in all copies or substantial portions of the
  13. * Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  18. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  21. * DEALINGS IN THE SOFTWARE.
  22. */
  23. #include "main/imports.h"
  24. #include "symbol_table.h"
  25. #include "hash_table.h"
  26. struct symbol {
  27. /**
  28. * Link to the next symbol in the table with the same name
  29. *
  30. * The linked list of symbols with the same name is ordered by scope
  31. * from inner-most to outer-most.
  32. */
  33. struct symbol *next_with_same_name;
  34. /**
  35. * Link to the next symbol in the table with the same scope
  36. *
  37. * The linked list of symbols with the same scope is unordered. Symbols
  38. * in this list my have unique names.
  39. */
  40. struct symbol *next_with_same_scope;
  41. /**
  42. * Header information for the list of symbols with the same name.
  43. */
  44. struct symbol_header *hdr;
  45. /**
  46. * Name space of the symbol
  47. *
  48. * Name space are arbitrary user assigned integers. No two symbols can
  49. * exist in the same name space at the same scope level.
  50. */
  51. int name_space;
  52. /** Scope depth where this symbol was defined. */
  53. unsigned depth;
  54. /**
  55. * Arbitrary user supplied data.
  56. */
  57. void *data;
  58. };
  59. /**
  60. */
  61. struct symbol_header {
  62. /** Linkage in list of all headers in a given symbol table. */
  63. struct symbol_header *next;
  64. /** Symbol name. */
  65. char *name;
  66. /** Linked list of symbols with the same name. */
  67. struct symbol *symbols;
  68. };
  69. /**
  70. * Element of the scope stack.
  71. */
  72. struct scope_level {
  73. /** Link to next (inner) scope level. */
  74. struct scope_level *next;
  75. /** Linked list of symbols with the same scope. */
  76. struct symbol *symbols;
  77. };
  78. /**
  79. *
  80. */
  81. struct _mesa_symbol_table {
  82. /** Hash table containing all symbols in the symbol table. */
  83. struct hash_table *ht;
  84. /** Top of scope stack. */
  85. struct scope_level *current_scope;
  86. /** List of all symbol headers in the table. */
  87. struct symbol_header *hdr;
  88. /** Current scope depth. */
  89. unsigned depth;
  90. };
  91. struct _mesa_symbol_table_iterator {
  92. /**
  93. * Name space of symbols returned by this iterator.
  94. */
  95. int name_space;
  96. /**
  97. * Currently iterated symbol
  98. *
  99. * The next call to \c _mesa_symbol_table_iterator_get will return this
  100. * value. It will also update this value to the value that should be
  101. * returned by the next call.
  102. */
  103. struct symbol *curr;
  104. };
  105. static void
  106. check_symbol_table(struct _mesa_symbol_table *table)
  107. {
  108. #if 1
  109. struct scope_level *scope;
  110. for (scope = table->current_scope; scope != NULL; scope = scope->next) {
  111. struct symbol *sym;
  112. for (sym = scope->symbols
  113. ; sym != NULL
  114. ; sym = sym->next_with_same_name) {
  115. const struct symbol_header *const hdr = sym->hdr;
  116. struct symbol *sym2;
  117. for (sym2 = hdr->symbols
  118. ; sym2 != NULL
  119. ; sym2 = sym2->next_with_same_name) {
  120. assert(sym2->hdr == hdr);
  121. }
  122. }
  123. }
  124. #endif
  125. }
  126. void
  127. _mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table)
  128. {
  129. struct scope_level *const scope = table->current_scope;
  130. struct symbol *sym = scope->symbols;
  131. table->current_scope = scope->next;
  132. table->depth--;
  133. free(scope);
  134. while (sym != NULL) {
  135. struct symbol *const next = sym->next_with_same_scope;
  136. struct symbol_header *const hdr = sym->hdr;
  137. assert(hdr->symbols == sym);
  138. hdr->symbols = sym->next_with_same_name;
  139. free(sym);
  140. sym = next;
  141. }
  142. check_symbol_table(table);
  143. }
  144. void
  145. _mesa_symbol_table_push_scope(struct _mesa_symbol_table *table)
  146. {
  147. struct scope_level *const scope = calloc(1, sizeof(*scope));
  148. scope->next = table->current_scope;
  149. table->current_scope = scope;
  150. table->depth++;
  151. }
  152. static struct symbol_header *
  153. find_symbol(struct _mesa_symbol_table *table, const char *name)
  154. {
  155. return (struct symbol_header *) hash_table_find(table->ht, name);
  156. }
  157. struct _mesa_symbol_table_iterator *
  158. _mesa_symbol_table_iterator_ctor(struct _mesa_symbol_table *table,
  159. int name_space, const char *name)
  160. {
  161. struct _mesa_symbol_table_iterator *iter = calloc(1, sizeof(*iter));
  162. struct symbol_header *const hdr = find_symbol(table, name);
  163. iter->name_space = name_space;
  164. if (hdr != NULL) {
  165. struct symbol *sym;
  166. for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
  167. assert(sym->hdr == hdr);
  168. if ((name_space == -1) || (sym->name_space == name_space)) {
  169. iter->curr = sym;
  170. break;
  171. }
  172. }
  173. }
  174. return iter;
  175. }
  176. void
  177. _mesa_symbol_table_iterator_dtor(struct _mesa_symbol_table_iterator *iter)
  178. {
  179. free(iter);
  180. }
  181. void *
  182. _mesa_symbol_table_iterator_get(struct _mesa_symbol_table_iterator *iter)
  183. {
  184. return (iter->curr == NULL) ? NULL : iter->curr->data;
  185. }
  186. int
  187. _mesa_symbol_table_iterator_next(struct _mesa_symbol_table_iterator *iter)
  188. {
  189. struct symbol_header *hdr;
  190. if (iter->curr == NULL) {
  191. return 0;
  192. }
  193. hdr = iter->curr->hdr;
  194. iter->curr = iter->curr->next_with_same_name;
  195. while (iter->curr != NULL) {
  196. assert(iter->curr->hdr == hdr);
  197. if ((iter->name_space == -1)
  198. || (iter->curr->name_space == iter->name_space)) {
  199. return 1;
  200. }
  201. iter->curr = iter->curr->next_with_same_name;
  202. }
  203. return 0;
  204. }
  205. /**
  206. * Determine the scope "distance" of a symbol from the current scope
  207. *
  208. * \return
  209. * A non-negative number for the number of scopes between the current scope
  210. * and the scope where a symbol was defined. A value of zero means the current
  211. * scope. A negative number if the symbol does not exist.
  212. */
  213. int
  214. _mesa_symbol_table_symbol_scope(struct _mesa_symbol_table *table,
  215. int name_space, const char *name)
  216. {
  217. struct symbol_header *const hdr = find_symbol(table, name);
  218. struct symbol *sym;
  219. if (hdr != NULL) {
  220. for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
  221. assert(sym->hdr == hdr);
  222. if ((name_space == -1) || (sym->name_space == name_space)) {
  223. assert(sym->depth <= table->depth);
  224. return sym->depth - table->depth;
  225. }
  226. }
  227. }
  228. return -1;
  229. }
  230. void *
  231. _mesa_symbol_table_find_symbol(struct _mesa_symbol_table *table,
  232. int name_space, const char *name)
  233. {
  234. struct symbol_header *const hdr = find_symbol(table, name);
  235. if (hdr != NULL) {
  236. struct symbol *sym;
  237. for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
  238. assert(sym->hdr == hdr);
  239. if ((name_space == -1) || (sym->name_space == name_space)) {
  240. return sym->data;
  241. }
  242. }
  243. }
  244. return NULL;
  245. }
  246. int
  247. _mesa_symbol_table_add_symbol(struct _mesa_symbol_table *table,
  248. int name_space, const char *name,
  249. void *declaration)
  250. {
  251. struct symbol_header *hdr;
  252. struct symbol *sym;
  253. check_symbol_table(table);
  254. hdr = find_symbol(table, name);
  255. check_symbol_table(table);
  256. if (hdr == NULL) {
  257. hdr = calloc(1, sizeof(*hdr));
  258. hdr->name = strdup(name);
  259. hash_table_insert(table->ht, hdr, hdr->name);
  260. hdr->next = table->hdr;
  261. table->hdr = hdr;
  262. }
  263. check_symbol_table(table);
  264. /* If the symbol already exists in this namespace at this scope, it cannot
  265. * be added to the table.
  266. */
  267. for (sym = hdr->symbols
  268. ; (sym != NULL) && (sym->name_space != name_space)
  269. ; sym = sym->next_with_same_name) {
  270. /* empty */
  271. }
  272. if (sym && (sym->depth == table->depth))
  273. return -1;
  274. sym = calloc(1, sizeof(*sym));
  275. sym->next_with_same_name = hdr->symbols;
  276. sym->next_with_same_scope = table->current_scope->symbols;
  277. sym->hdr = hdr;
  278. sym->name_space = name_space;
  279. sym->data = declaration;
  280. sym->depth = table->depth;
  281. assert(sym->hdr == hdr);
  282. hdr->symbols = sym;
  283. table->current_scope->symbols = sym;
  284. check_symbol_table(table);
  285. return 0;
  286. }
  287. int
  288. _mesa_symbol_table_add_global_symbol(struct _mesa_symbol_table *table,
  289. int name_space, const char *name,
  290. void *declaration)
  291. {
  292. struct symbol_header *hdr;
  293. struct symbol *sym;
  294. struct symbol *curr;
  295. struct scope_level *top_scope;
  296. check_symbol_table(table);
  297. hdr = find_symbol(table, name);
  298. check_symbol_table(table);
  299. if (hdr == NULL) {
  300. hdr = calloc(1, sizeof(*hdr));
  301. hdr->name = strdup(name);
  302. hash_table_insert(table->ht, hdr, hdr->name);
  303. hdr->next = table->hdr;
  304. table->hdr = hdr;
  305. }
  306. check_symbol_table(table);
  307. /* If the symbol already exists in this namespace at this scope, it cannot
  308. * be added to the table.
  309. */
  310. for (sym = hdr->symbols
  311. ; (sym != NULL) && (sym->name_space != name_space)
  312. ; sym = sym->next_with_same_name) {
  313. /* empty */
  314. }
  315. if (sym && sym->depth == 0)
  316. return -1;
  317. /* Find the top-level scope */
  318. for (top_scope = table->current_scope
  319. ; top_scope->next != NULL
  320. ; top_scope = top_scope->next) {
  321. /* empty */
  322. }
  323. sym = calloc(1, sizeof(*sym));
  324. sym->next_with_same_scope = top_scope->symbols;
  325. sym->hdr = hdr;
  326. sym->name_space = name_space;
  327. sym->data = declaration;
  328. assert(sym->hdr == hdr);
  329. /* Since next_with_same_name is ordered by scope, we need to append the
  330. * new symbol to the _end_ of the list.
  331. */
  332. if (hdr->symbols == NULL) {
  333. hdr->symbols = sym;
  334. } else {
  335. for (curr = hdr->symbols
  336. ; curr->next_with_same_name != NULL
  337. ; curr = curr->next_with_same_name) {
  338. /* empty */
  339. }
  340. curr->next_with_same_name = sym;
  341. }
  342. top_scope->symbols = sym;
  343. check_symbol_table(table);
  344. return 0;
  345. }
  346. struct _mesa_symbol_table *
  347. _mesa_symbol_table_ctor(void)
  348. {
  349. struct _mesa_symbol_table *table = calloc(1, sizeof(*table));
  350. if (table != NULL) {
  351. table->ht = hash_table_ctor(32, hash_table_string_hash,
  352. hash_table_string_compare);
  353. _mesa_symbol_table_push_scope(table);
  354. }
  355. return table;
  356. }
  357. void
  358. _mesa_symbol_table_dtor(struct _mesa_symbol_table *table)
  359. {
  360. struct symbol_header *hdr;
  361. struct symbol_header *next;
  362. while (table->current_scope != NULL) {
  363. _mesa_symbol_table_pop_scope(table);
  364. }
  365. for (hdr = table->hdr; hdr != NULL; hdr = next) {
  366. next = hdr->next;
  367. free(hdr->name);
  368. free(hdr);
  369. }
  370. hash_table_dtor(table->ht);
  371. free(table);
  372. }