X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fprogram%2Fsymbol_table.c;h=3e5843225ab9b180a873febe446dc74e0d1b2050;hb=3eb0baeecfed7a2de2b323e1b5d90e2b14dfc803;hp=6a5d686897425896f7214af74d66d1864e14d043;hpb=a01e0afd9fc0d647081c6903baa1a7ba505c4b05;p=mesa.git diff --git a/src/mesa/program/symbol_table.c b/src/mesa/program/symbol_table.c index 6a5d6868974..3e5843225ab 100644 --- a/src/mesa/program/symbol_table.c +++ b/src/mesa/program/symbol_table.c @@ -23,7 +23,7 @@ #include "main/imports.h" #include "symbol_table.h" -#include "hash_table.h" +#include "../../util/hash_table.h" struct symbol { /** @@ -58,7 +58,9 @@ struct symbol { */ int name_space; - + /** Scope depth where this symbol was defined. */ + unsigned depth; + /** * Arbitrary user supplied data. */ @@ -73,7 +75,7 @@ struct symbol_header { struct symbol_header *next; /** Symbol name. */ - const char *name; + char *name; /** Linked list of symbols with the same name. */ struct symbol *symbols; @@ -104,31 +106,16 @@ struct _mesa_symbol_table { /** List of all symbol headers in the table. */ struct symbol_header *hdr; -}; - - -struct _mesa_symbol_table_iterator { - /** - * Name space of symbols returned by this iterator. - */ - int name_space; - - /** - * Currently iterated symbol - * - * The next call to \c _mesa_symbol_table_iterator_get will return this - * value. It will also update this value to the value that should be - * returned by the next call. - */ - struct symbol *curr; + /** Current scope depth. */ + unsigned depth; }; static void check_symbol_table(struct _mesa_symbol_table *table) { -#if 1 +#if !defined(NDEBUG) struct scope_level *scope; for (scope = table->current_scope; scope != NULL; scope = scope->next) { @@ -147,7 +134,9 @@ check_symbol_table(struct _mesa_symbol_table *table) } } } -#endif +#else + (void) table; +#endif /* !defined(NDEBUG) */ } void @@ -157,6 +146,7 @@ _mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table) struct symbol *sym = scope->symbols; table->current_scope = scope->next; + table->depth--; free(scope); @@ -182,82 +172,52 @@ _mesa_symbol_table_push_scope(struct _mesa_symbol_table *table) { struct scope_level *const scope = calloc(1, sizeof(*scope)); + if (scope == NULL) { + _mesa_error_no_memory(__func__); + return; + } + scope->next = table->current_scope; table->current_scope = scope; + table->depth++; } static struct symbol_header * find_symbol(struct _mesa_symbol_table *table, const char *name) { - return (struct symbol_header *) hash_table_find(table->ht, name); + struct hash_entry *entry = _mesa_hash_table_search(table->ht, name); + return entry ? (struct symbol_header *) entry->data : NULL; } -struct _mesa_symbol_table_iterator * -_mesa_symbol_table_iterator_ctor(struct _mesa_symbol_table *table, - int name_space, const char *name) +/** + * Determine the scope "distance" of a symbol from the current scope + * + * \return + * A non-negative number for the number of scopes between the current scope + * and the scope where a symbol was defined. A value of zero means the current + * scope. A negative number if the symbol does not exist. + */ +int +_mesa_symbol_table_symbol_scope(struct _mesa_symbol_table *table, + int name_space, const char *name) { - struct _mesa_symbol_table_iterator *iter = calloc(1, sizeof(*iter)); struct symbol_header *const hdr = find_symbol(table, name); - - iter->name_space = name_space; + struct symbol *sym; if (hdr != NULL) { - struct symbol *sym; - - for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) { - assert(sym->hdr == hdr); - - if ((name_space == -1) || (sym->name_space == name_space)) { - iter->curr = sym; - break; - } - } - } - - return iter; -} - - -void -_mesa_symbol_table_iterator_dtor(struct _mesa_symbol_table_iterator *iter) -{ - free(iter); -} - - -void * -_mesa_symbol_table_iterator_get(struct _mesa_symbol_table_iterator *iter) -{ - return (iter->curr == NULL) ? NULL : iter->curr->data; -} - - -int -_mesa_symbol_table_iterator_next(struct _mesa_symbol_table_iterator *iter) -{ - struct symbol_header *hdr; - - if (iter->curr == NULL) { - return 0; - } - - hdr = iter->curr->hdr; - iter->curr = iter->curr->next_with_same_name; - - while (iter->curr != NULL) { - assert(iter->curr->hdr == hdr); - - if ((iter->name_space == -1) - || (iter->curr->name_space == iter->name_space)) { - return 1; - } - - iter->curr = iter->curr->next_with_same_name; + for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) { + assert(sym->hdr == hdr); + + if ((name_space == -1) || (sym->name_space == name_space)) { + assert(sym->depth <= table->depth); + return sym->depth - table->depth; + } + } } - return 0; + return -1; } @@ -299,22 +259,50 @@ _mesa_symbol_table_add_symbol(struct _mesa_symbol_table *table, check_symbol_table(table); if (hdr == NULL) { - hdr = calloc(1, sizeof(*hdr)); - hdr->name = name; - - hash_table_insert(table->ht, hdr, name); - hdr->next = table->hdr; - table->hdr = hdr; + hdr = calloc(1, sizeof(*hdr)); + if (hdr == NULL) { + _mesa_error_no_memory(__func__); + return -1; + } + + hdr->name = strdup(name); + if (hdr->name == NULL) { + free(hdr); + _mesa_error_no_memory(__func__); + return -1; + } + + _mesa_hash_table_insert(table->ht, hdr->name, hdr); + hdr->next = table->hdr; + table->hdr = hdr; } check_symbol_table(table); + /* If the symbol already exists in this namespace at this scope, it cannot + * be added to the table. + */ + for (sym = hdr->symbols + ; (sym != NULL) && (sym->name_space != name_space) + ; sym = sym->next_with_same_name) { + /* empty */ + } + + if (sym && (sym->depth == table->depth)) + return -1; + sym = calloc(1, sizeof(*sym)); + if (sym == NULL) { + _mesa_error_no_memory(__func__); + return -1; + } + sym->next_with_same_name = hdr->symbols; sym->next_with_same_scope = table->current_scope->symbols; sym->hdr = hdr; sym->name_space = name_space; sym->data = declaration; + sym->depth = table->depth; assert(sym->hdr == hdr); @@ -326,14 +314,99 @@ _mesa_symbol_table_add_symbol(struct _mesa_symbol_table *table, } +int +_mesa_symbol_table_add_global_symbol(struct _mesa_symbol_table *table, + int name_space, const char *name, + void *declaration) +{ + struct symbol_header *hdr; + struct symbol *sym; + struct symbol *curr; + struct scope_level *top_scope; + + check_symbol_table(table); + + hdr = find_symbol(table, name); + + check_symbol_table(table); + + if (hdr == NULL) { + hdr = calloc(1, sizeof(*hdr)); + if (hdr == NULL) { + _mesa_error_no_memory(__func__); + return -1; + } + + hdr->name = strdup(name); + + _mesa_hash_table_insert(table->ht, hdr->name, hdr); + hdr->next = table->hdr; + table->hdr = hdr; + } + + check_symbol_table(table); + + /* If the symbol already exists in this namespace at this scope, it cannot + * be added to the table. + */ + for (sym = hdr->symbols + ; (sym != NULL) && (sym->name_space != name_space) + ; sym = sym->next_with_same_name) { + /* empty */ + } + + if (sym && sym->depth == 0) + return -1; + + /* Find the top-level scope */ + for (top_scope = table->current_scope + ; top_scope->next != NULL + ; top_scope = top_scope->next) { + /* empty */ + } + + sym = calloc(1, sizeof(*sym)); + if (sym == NULL) { + _mesa_error_no_memory(__func__); + return -1; + } + + sym->next_with_same_scope = top_scope->symbols; + sym->hdr = hdr; + sym->name_space = name_space; + sym->data = declaration; + + assert(sym->hdr == hdr); + + /* Since next_with_same_name is ordered by scope, we need to append the + * new symbol to the _end_ of the list. + */ + if (hdr->symbols == NULL) { + hdr->symbols = sym; + } else { + for (curr = hdr->symbols + ; curr->next_with_same_name != NULL + ; curr = curr->next_with_same_name) { + /* empty */ + } + curr->next_with_same_name = sym; + } + top_scope->symbols = sym; + + check_symbol_table(table); + return 0; +} + + + struct _mesa_symbol_table * _mesa_symbol_table_ctor(void) { struct _mesa_symbol_table *table = calloc(1, sizeof(*table)); if (table != NULL) { - table->ht = hash_table_ctor(32, hash_table_string_hash, - hash_table_string_compare); + table->ht = _mesa_hash_table_create(NULL, _mesa_key_hash_string, + _mesa_key_string_equal); _mesa_symbol_table_push_scope(table); } @@ -354,9 +427,10 @@ _mesa_symbol_table_dtor(struct _mesa_symbol_table *table) for (hdr = table->hdr; hdr != NULL; hdr = next) { next = hdr->next; + free(hdr->name); free(hdr); } - hash_table_dtor(table->ht); + _mesa_hash_table_destroy(table->ht, NULL); free(table); }