kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

wasm_imports.c (3224B)


      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 "arch/wasm/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 }