summaryrefslogtreecommitdiff
path: root/src/wasm-ast.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm-ast.c')
-rw-r--r--src/wasm-ast.c171
1 files changed, 7 insertions, 164 deletions
diff --git a/src/wasm-ast.c b/src/wasm-ast.c
index a6c4fe8a..780f595f 100644
--- a/src/wasm-ast.c
+++ b/src/wasm-ast.c
@@ -21,158 +21,15 @@
#include "wasm-allocator.h"
-#define INITIAL_HASH_CAPACITY 8
-
-static size_t hash_name(const WasmStringSlice* name) {
- // FNV-1a hash
- const uint32_t fnv_prime = 0x01000193;
- const uint8_t* bp = (const uint8_t*)name->start;
- const uint8_t* be = bp + name->length;
- uint32_t hval = 0x811c9dc5;
- while (bp < be) {
- hval ^= (uint32_t)*bp++;
- hval *= fnv_prime;
- }
- return hval;
-}
-
-static WasmBindingHashEntry* hash_main_entry(const WasmBindingHash* hash,
- const WasmStringSlice* name) {
- return &hash->entries.data[hash_name(name) % hash->entries.capacity];
-}
-
-WasmBool wasm_hash_entry_is_free(const WasmBindingHashEntry* entry) {
- return !entry->binding.name.start;
-}
-
-static WasmBindingHashEntry* hash_new_entry(WasmBindingHash* hash,
- const WasmStringSlice* name) {
- WasmBindingHashEntry* entry = hash_main_entry(hash, name);
- if (!wasm_hash_entry_is_free(entry)) {
- assert(hash->free_head);
- WasmBindingHashEntry* free_entry = hash->free_head;
- hash->free_head = free_entry->next;
- if (free_entry->next)
- free_entry->next->prev = NULL;
-
- /* our main position is already claimed. Check to see if the entry in that
- * position is in its main position */
- WasmBindingHashEntry* other_entry =
- hash_main_entry(hash, &entry->binding.name);
- if (other_entry == entry) {
- /* yes, so add this new entry to the chain, even if it is already there */
- /* add as the second entry in the chain */
- free_entry->next = entry->next;
- entry->next = free_entry;
- entry = free_entry;
- } else {
- /* no, move the entry to the free entry */
- assert(!wasm_hash_entry_is_free(other_entry));
- while (other_entry->next != entry)
- other_entry = other_entry->next;
-
- other_entry->next = free_entry;
- *free_entry = *entry;
- entry->next = NULL;
- }
- } else {
- /* remove from the free list */
- if (entry->next)
- entry->next->prev = entry->prev;
- if (entry->prev)
- entry->prev->next = entry->next;
- else
- hash->free_head = entry->next;
- entry->next = NULL;
- }
-
- WASM_ZERO_MEMORY(entry->binding);
- entry->binding.name = *name;
- entry->prev = NULL;
- /* entry->next is set above */
- return entry;
-}
-
-static void hash_resize(WasmAllocator* allocator,
- WasmBindingHash* hash,
- size_t desired_capacity) {
- WasmBindingHash new_hash;
- WASM_ZERO_MEMORY(new_hash);
- /* TODO(binji): better plural */
- wasm_reserve_binding_hash_entrys(allocator, &new_hash.entries,
- desired_capacity);
-
- /* update the free list */
- size_t i;
- for (i = 0; i < new_hash.entries.capacity; ++i) {
- WasmBindingHashEntry* entry = &new_hash.entries.data[i];
- if (new_hash.free_head)
- new_hash.free_head->prev = entry;
-
- WASM_ZERO_MEMORY(entry->binding.name);
- entry->next = new_hash.free_head;
- new_hash.free_head = entry;
- }
- new_hash.free_head->prev = NULL;
-
- /* copy from the old hash to the new hash */
- for (i = 0; i < hash->entries.capacity; ++i) {
- WasmBindingHashEntry* old_entry = &hash->entries.data[i];
- if (wasm_hash_entry_is_free(old_entry))
- continue;
-
- WasmStringSlice* name = &old_entry->binding.name;
- WasmBindingHashEntry* new_entry = hash_new_entry(&new_hash, name);
- new_entry->binding = old_entry->binding;
- }
-
- /* we are sharing the WasmStringSlices, so we only need to destroy the old
- * binding vector */
- wasm_destroy_binding_hash_entry_vector(allocator, &hash->entries);
- *hash = new_hash;
-}
-
-WasmBinding* wasm_insert_binding(WasmAllocator* allocator,
- WasmBindingHash* hash,
- const WasmStringSlice* name) {
- if (hash->entries.size == 0)
- hash_resize(allocator, hash, INITIAL_HASH_CAPACITY);
-
- if (!hash->free_head) {
- /* no more free space, allocate more */
- hash_resize(allocator, hash, hash->entries.capacity * 2);
- }
-
- WasmBindingHashEntry* entry = hash_new_entry(hash, name);
- assert(entry);
- hash->entries.size++;
- return &entry->binding;
-}
-
-static int find_binding_index_by_name(const WasmBindingHash* hash,
- const WasmStringSlice* name) {
- if (hash->entries.capacity == 0)
- return -1;
-
- WasmBindingHashEntry* entry = hash_main_entry(hash, name);
- do {
- if (wasm_string_slices_are_equal(&entry->binding.name, name))
- return entry->binding.index;
-
- entry = entry->next;
- } while (entry && !wasm_hash_entry_is_free(entry));
- return -1;
-}
-
int wasm_get_index_from_var(const WasmBindingHash* hash, const WasmVar* var) {
if (var->type == WASM_VAR_TYPE_NAME)
- return find_binding_index_by_name(hash, &var->name);
+ return wasm_find_binding_index_by_name(hash, &var->name);
return (int)var->index;
}
WasmExportPtr wasm_get_export_by_name(const WasmModule* module,
const WasmStringSlice* name) {
- int index = find_binding_index_by_name(&module->export_bindings, name);
+ int index = wasm_find_binding_index_by_name(&module->export_bindings, name);
if (index == -1)
return NULL;
return module->exports.data[index];
@@ -203,11 +60,12 @@ int wasm_get_local_index_by_var(const WasmFunc* func, const WasmVar* var) {
if (var->type == WASM_VAR_TYPE_INDEX)
return (int)var->index;
- int result = find_binding_index_by_name(&func->param_bindings, &var->name);
+ int result =
+ wasm_find_binding_index_by_name(&func->param_bindings, &var->name);
if (result != -1)
return result;
- result = find_binding_index_by_name(&func->local_bindings, &var->name);
+ result = wasm_find_binding_index_by_name(&func->local_bindings, &var->name);
if (result == -1)
return result;
@@ -393,21 +251,6 @@ WasmExpr* wasm_new_empty_expr(struct WasmAllocator* allocator,
return result;
}
-static void destroy_binding_hash_entry(WasmAllocator* allocator,
- WasmBindingHashEntry* entry) {
- wasm_destroy_string_slice(allocator, &entry->binding.name);
-}
-
-static void destroy_binding_hash(WasmAllocator* allocator,
- WasmBindingHash* hash) {
- /* Can't use WASM_DESTROY_VECTOR_AND_ELEMENTS, because it loops over size, not
- * capacity. */
- size_t i;
- for (i = 0; i < hash->entries.capacity; ++i)
- destroy_binding_hash_entry(allocator, &hash->entries.data[i]);
- wasm_destroy_binding_hash_entry_vector(allocator, &hash->entries);
-}
-
void wasm_destroy_var(WasmAllocator* allocator, WasmVar* var) {
if (var->type == WASM_VAR_TYPE_NAME)
wasm_destroy_string_slice(allocator, &var->name);
@@ -513,8 +356,8 @@ void wasm_destroy_func(WasmAllocator* allocator, WasmFunc* func) {
wasm_destroy_string_slice(allocator, &func->name);
wasm_destroy_func_declaration(allocator, &func->decl);
wasm_destroy_type_vector(allocator, &func->local_types);
- destroy_binding_hash(allocator, &func->param_bindings);
- destroy_binding_hash(allocator, &func->local_bindings);
+ wasm_destroy_binding_hash(allocator, &func->param_bindings);
+ wasm_destroy_binding_hash(allocator, &func->local_bindings);
wasm_destroy_expr_list(allocator, func->first_expr);
}