wasm_imports.c (3218B)
1 /* Wasm import-attribute side table. Stored on the ObjBuilder under 2 * OBJ_EXT_WASM_IMPORTS so the C frontend (lang/c) can populate it from 3 * `__attribute__((import_module/import_name))` at decl_declare time before 4 * the wasm backend exists, and so the backend can read it back from the 5 * single shared ObjBuilder when promoting undefined function symbols to 6 * `(import ...)` declarations. */ 7 8 #include "obj/wasm_imports.h" 9 10 #include <string.h> 11 12 #include "core/core.h" 13 #include "core/heap.h" 14 15 typedef struct WasmImportEntry { 16 Sym name; 17 Sym import_module; 18 Sym import_name; 19 } WasmImportEntry; 20 21 typedef struct WasmImportTable { 22 Heap* heap; 23 WasmImportEntry* entries; 24 u32 count; 25 u32 cap; 26 } WasmImportTable; 27 28 static void wasm_imports_free(Compiler* c, void* p) { 29 (void)c; 30 WasmImportTable* t = (WasmImportTable*)p; 31 if (!t) return; 32 if (t->entries) 33 t->heap->free(t->heap, t->entries, sizeof(*t->entries) * t->cap); 34 t->heap->free(t->heap, t, sizeof(*t)); 35 } 36 37 static WasmImportTable* table_ensure(ObjBuilder* o) { 38 WasmImportTable* t = (WasmImportTable*)obj_ext_get(o, OBJ_EXT_WASM_IMPORTS); 39 if (t) return t; 40 Compiler* c = obj_compiler(o); 41 Heap* h = c->ctx->heap; 42 t = (WasmImportTable*)h->alloc(h, sizeof(*t), _Alignof(WasmImportTable)); 43 if (!t) return NULL; 44 memset(t, 0, sizeof *t); 45 t->heap = h; 46 obj_ext_set(o, OBJ_EXT_WASM_IMPORTS, t, wasm_imports_free); 47 return t; 48 } 49 50 static WasmImportEntry* table_find_mut(WasmImportTable* t, Sym name) { 51 for (u32 i = 0; i < t->count; ++i) { 52 if (t->entries[i].name == name) return &t->entries[i]; 53 } 54 return NULL; 55 } 56 57 static const WasmImportEntry* table_find(const WasmImportTable* t, Sym name) { 58 for (u32 i = 0; i < t->count; ++i) { 59 if (t->entries[i].name == name) return &t->entries[i]; 60 } 61 return NULL; 62 } 63 64 void wasm_imports_set(ObjBuilder* o, Sym name, Sym import_module, 65 Sym import_name) { 66 if (!o || name == 0) return; 67 if (import_module == 0 && import_name == 0) return; 68 WasmImportTable* t = table_ensure(o); 69 if (!t) return; 70 WasmImportEntry* e = table_find_mut(t, name); 71 if (e) { 72 if (import_module) e->import_module = import_module; 73 if (import_name) e->import_name = import_name; 74 return; 75 } 76 if (t->count == t->cap) { 77 u32 nc = t->cap ? t->cap * 2u : 8u; 78 void* p = 79 t->heap->realloc(t->heap, t->entries, sizeof(*t->entries) * t->cap, 80 sizeof(*t->entries) * nc, _Alignof(WasmImportEntry)); 81 if (!p) return; 82 t->entries = (WasmImportEntry*)p; 83 t->cap = nc; 84 } 85 t->entries[t->count].name = name; 86 t->entries[t->count].import_module = import_module; 87 t->entries[t->count].import_name = import_name; 88 t->count++; 89 } 90 91 int wasm_imports_get(const ObjBuilder* o, Sym name, Sym* import_module, 92 Sym* import_name) { 93 if (import_module) *import_module = 0; 94 if (import_name) *import_name = 0; 95 if (!o || name == 0) return 0; 96 WasmImportTable* t = (WasmImportTable*)obj_ext_get(o, OBJ_EXT_WASM_IMPORTS); 97 if (!t) return 0; 98 const WasmImportEntry* e = table_find(t, name); 99 if (!e) return 0; 100 if (import_module) *import_module = e->import_module; 101 if (import_name) *import_name = e->import_name; 102 return 1; 103 }