kit

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

module.c (18265B)


      1 #include "wasm/wasm.h"
      2 
      3 KitSrcLoc wasm_loc(uint32_t line, uint32_t col) {
      4   KitSrcLoc loc;
      5   loc.file_id = 0;
      6   loc.line = line;
      7   loc.col = col;
      8   return loc;
      9 }
     10 
     11 void wasm_error(KitCompiler* c, KitSrcLoc loc, const char* fmt, ...) {
     12   va_list ap;
     13   va_start(ap, fmt);
     14   kit_frontend_vfatal(c, loc, fmt, ap);
     15 }
     16 
     17 void* wasm_realloc(KitHeap* h, void* p, size_t old_n, size_t new_n) {
     18   return h->realloc(h, p, old_n ? old_n : 1u, new_n ? new_n : 1u,
     19                     _Alignof(max_align_t));
     20 }
     21 
     22 char* wasm_strdup(KitHeap* h, const char* s, size_t len) {
     23   char* out;
     24   if (!h || !s) return NULL;
     25   out = (char*)h->alloc(h, len + 1u, 1);
     26   if (!out) return NULL;
     27   memcpy(out, s, len);
     28   out[len] = '\0';
     29   return out;
     30 }
     31 
     32 void wasm_free_str(KitHeap* h, char** s) {
     33   if (!h || !s || !*s) return;
     34   h->free(h, *s, strlen(*s) + 1u);
     35   *s = NULL;
     36 }
     37 
     38 void wasm_module_init(WasmModule* m, KitHeap* heap) {
     39   memset(m, 0, sizeof *m);
     40   m->heap = heap;
     41   m->features = WASM_FEATURE_THREADS | WASM_FEATURE_TYPED_FUNC_REFS |
     42                 WASM_FEATURE_TAIL_CALLS | WASM_FEATURE_MULTI_MEMORY |
     43                 WASM_FEATURE_MEMORY64 | WASM_FEATURE_BULK_MEMORY |
     44                 WASM_FEATURE_NONTRAPPING_FTOI;
     45 }
     46 
     47 void wasm_module_free(WasmModule* m) {
     48   uint32_t i;
     49   if (!m || !m->heap) return;
     50   for (i = 0; i < m->ntypes; ++i) {
     51     WasmFuncType* t = &m->types[i];
     52     wasm_free_str(m->heap, &t->name);
     53     if (t->params)
     54       m->heap->free(m->heap, t->params, sizeof(*t->params) * t->cap_params);
     55     if (t->results)
     56       m->heap->free(m->heap, t->results, sizeof(*t->results) * t->cap_results);
     57   }
     58   if (m->types)
     59     m->heap->free(m->heap, m->types, sizeof(*m->types) * m->cap_types);
     60   for (i = 0; i < m->nfuncs; ++i) {
     61     WasmFunc* f = &m->funcs[i];
     62     wasm_free_str(m->heap, &f->name);
     63     wasm_free_str(m->heap, &f->import_module);
     64     wasm_free_str(m->heap, &f->import_name);
     65     wasm_free_str(m->heap, &f->export_name);
     66     if (f->local_names) {
     67       for (uint32_t j = 0; j < f->cap_local_names; ++j)
     68         wasm_free_str(m->heap, &f->local_names[j]);
     69       m->heap->free(m->heap, f->local_names,
     70                     sizeof(*f->local_names) * f->cap_local_names);
     71     }
     72     if (f->params)
     73       m->heap->free(m->heap, f->params, sizeof(*f->params) * f->cap_params);
     74     if (f->results)
     75       m->heap->free(m->heap, f->results, sizeof(*f->results) * f->cap_results);
     76     if (f->locals)
     77       m->heap->free(m->heap, f->locals, sizeof(*f->locals) * f->cap_locals);
     78     if (f->insns) {
     79       for (uint32_t j = 0; j < f->ninsns; ++j)
     80         if (f->insns[j].targets)
     81           m->heap->free(m->heap, f->insns[j].targets,
     82                         sizeof(uint32_t) * f->insns[j].ntargets);
     83       m->heap->free(m->heap, f->insns, sizeof(*f->insns) * f->cap_insns);
     84     }
     85   }
     86   if (m->funcs)
     87     m->heap->free(m->heap, m->funcs, sizeof(*m->funcs) * m->cap_funcs);
     88   for (i = 0; i < m->nmemories; ++i) {
     89     wasm_free_str(m->heap, &m->memories[i].name);
     90     wasm_free_str(m->heap, &m->memories[i].import_module);
     91     wasm_free_str(m->heap, &m->memories[i].import_name);
     92     wasm_free_str(m->heap, &m->memories[i].export_name);
     93   }
     94   if (m->memories)
     95     m->heap->free(m->heap, m->memories, sizeof(*m->memories) * m->cap_memories);
     96   for (i = 0; i < m->ndata; ++i) {
     97     wasm_free_str(m->heap, &m->data[i].name);
     98     if (m->data[i].bytes)
     99       m->heap->free(m->heap, m->data[i].bytes, (size_t)m->data[i].nbytes);
    100   }
    101   if (m->data) m->heap->free(m->heap, m->data, sizeof(*m->data) * m->cap_data);
    102   for (i = 0; i < m->nelems; ++i) {
    103     wasm_free_str(m->heap, &m->elems[i].name);
    104     if (m->elems[i].funcs)
    105       m->heap->free(m->heap, m->elems[i].funcs,
    106                     sizeof(*m->elems[i].funcs) * m->elems[i].cap_funcs);
    107   }
    108   for (i = 0; i < m->ntables; ++i) {
    109     wasm_free_str(m->heap, &m->tables[i].name);
    110     wasm_free_str(m->heap, &m->tables[i].import_module);
    111     wasm_free_str(m->heap, &m->tables[i].import_name);
    112     wasm_free_str(m->heap, &m->tables[i].export_name);
    113   }
    114   if (m->tables)
    115     m->heap->free(m->heap, m->tables, sizeof(*m->tables) * m->cap_tables);
    116   for (i = 0; i < m->nglobals; ++i) {
    117     wasm_free_str(m->heap, &m->globals[i].name);
    118     wasm_free_str(m->heap, &m->globals[i].import_module);
    119     wasm_free_str(m->heap, &m->globals[i].import_name);
    120     wasm_free_str(m->heap, &m->globals[i].export_name);
    121   }
    122   if (m->globals)
    123     m->heap->free(m->heap, m->globals, sizeof(*m->globals) * m->cap_globals);
    124   if (m->elems)
    125     m->heap->free(m->heap, m->elems, sizeof(*m->elems) * m->cap_elems);
    126   if (m->exports)
    127     m->heap->free(m->heap, m->exports, sizeof(*m->exports) * m->cap_exports);
    128   for (i = 0; i < m->ncustoms; ++i) {
    129     wasm_free_str(m->heap, &m->customs[i].name);
    130     if (m->customs[i].data)
    131       m->heap->free(m->heap, m->customs[i].data, m->customs[i].len);
    132   }
    133   if (m->customs)
    134     m->heap->free(m->heap, m->customs, sizeof(*m->customs) * m->cap_customs);
    135   memset(m, 0, sizeof *m);
    136 }
    137 
    138 WasmMemory* wasm_add_memory(KitCompiler* c, WasmModule* m) {
    139   WasmMemory* mem;
    140   if (m->nmemories == m->cap_memories) {
    141     uint32_t new_cap = m->cap_memories ? m->cap_memories * 2u : 2u;
    142     void* p = wasm_realloc(m->heap, m->memories,
    143                            sizeof(*m->memories) * m->cap_memories,
    144                            sizeof(*m->memories) * new_cap);
    145     if (!p) wasm_error(c, wasm_loc(0, 0), "wasm: out of memory");
    146     m->memories = (WasmMemory*)p;
    147     memset(m->memories + m->cap_memories, 0,
    148            sizeof(*m->memories) * (new_cap - m->cap_memories));
    149     m->cap_memories = new_cap;
    150   }
    151   mem = &m->memories[m->nmemories++];
    152   memset(mem, 0, sizeof *mem);
    153   return mem;
    154 }
    155 
    156 WasmFunc* wasm_add_func(KitCompiler* c, WasmModule* m) {
    157   WasmFunc* f;
    158   if (m->nfuncs == m->cap_funcs) {
    159     uint32_t new_cap = m->cap_funcs ? m->cap_funcs * 2u : 4u;
    160     void* p = wasm_realloc(m->heap, m->funcs, sizeof(*m->funcs) * m->cap_funcs,
    161                            sizeof(*m->funcs) * new_cap);
    162     if (!p) wasm_error(c, wasm_loc(0, 0), "wasm: out of memory");
    163     m->funcs = (WasmFunc*)p;
    164     memset(m->funcs + m->cap_funcs, 0,
    165            sizeof(*m->funcs) * (new_cap - m->cap_funcs));
    166     m->cap_funcs = new_cap;
    167   }
    168   f = &m->funcs[m->nfuncs++];
    169   memset(f, 0, sizeof *f);
    170   return f;
    171 }
    172 
    173 WasmFuncType* wasm_add_type(KitCompiler* c, WasmModule* m) {
    174   WasmFuncType* t;
    175   if (m->ntypes == m->cap_types) {
    176     uint32_t new_cap = m->cap_types ? m->cap_types * 2u : 8u;
    177     void* p = wasm_realloc(m->heap, m->types, sizeof(*m->types) * m->cap_types,
    178                            sizeof(*m->types) * new_cap);
    179     if (!p) wasm_error(c, wasm_loc(0, 0), "wasm: out of memory");
    180     m->types = (WasmFuncType*)p;
    181     memset(m->types + m->cap_types, 0,
    182            sizeof(*m->types) * (new_cap - m->cap_types));
    183     m->cap_types = new_cap;
    184   }
    185   t = &m->types[m->ntypes++];
    186   memset(t, 0, sizeof *t);
    187   return t;
    188 }
    189 
    190 static void wasm_grow_valtypes(KitCompiler* c, WasmModule* m, WasmValType** arr,
    191                                uint32_t* cap, uint32_t want) {
    192   uint32_t new_cap;
    193   void* p;
    194   if (want <= *cap) return;
    195   new_cap = *cap ? *cap : 4u;
    196   while (new_cap < want) new_cap *= 2u;
    197   p = wasm_realloc(m->heap, *arr, sizeof(WasmValType) * (*cap),
    198                    sizeof(WasmValType) * new_cap);
    199   if (!p) wasm_error(c, wasm_loc(0, 0), "wasm: out of memory");
    200   *arr = (WasmValType*)p;
    201   *cap = new_cap;
    202 }
    203 
    204 uint32_t wasm_func_push_param(KitCompiler* c, WasmModule* m, WasmFunc* f,
    205                               WasmValType vt) {
    206   wasm_grow_valtypes(c, m, &f->params, &f->cap_params, f->nparams + 1u);
    207   f->params[f->nparams] = vt;
    208   return f->nparams++;
    209 }
    210 
    211 uint32_t wasm_func_push_local(KitCompiler* c, WasmModule* m, WasmFunc* f,
    212                               WasmValType vt) {
    213   wasm_grow_valtypes(c, m, &f->locals, &f->cap_locals, f->nlocals + 1u);
    214   f->locals[f->nlocals] = vt;
    215   return f->nparams + f->nlocals++;
    216 }
    217 
    218 void wasm_func_set_params(KitCompiler* c, WasmModule* m, WasmFunc* f,
    219                           const WasmValType* src, uint32_t n) {
    220   wasm_grow_valtypes(c, m, &f->params, &f->cap_params, n);
    221   if (n) memcpy(f->params, src, sizeof(WasmValType) * n);
    222   f->nparams = n;
    223 }
    224 
    225 uint32_t wasm_func_push_result(KitCompiler* c, WasmModule* m, WasmFunc* f,
    226                                WasmValType vt) {
    227   wasm_grow_valtypes(c, m, &f->results, &f->cap_results, f->nresults + 1u);
    228   f->results[f->nresults] = vt;
    229   return f->nresults++;
    230 }
    231 
    232 void wasm_func_set_results(KitCompiler* c, WasmModule* m, WasmFunc* f,
    233                            const WasmValType* src, uint32_t n) {
    234   wasm_grow_valtypes(c, m, &f->results, &f->cap_results, n);
    235   if (n) memcpy(f->results, src, sizeof(WasmValType) * n);
    236   f->nresults = n;
    237 }
    238 
    239 void wasm_func_set_local_name(KitCompiler* c, WasmModule* m, WasmFunc* f,
    240                               uint32_t idx, const char* name, size_t len) {
    241   if (idx >= f->cap_local_names) {
    242     uint32_t new_cap = f->cap_local_names ? f->cap_local_names * 2u : 8u;
    243     void* p;
    244     while (new_cap <= idx) new_cap *= 2u;
    245     p = wasm_realloc(m->heap, f->local_names,
    246                      sizeof(char*) * f->cap_local_names,
    247                      sizeof(char*) * new_cap);
    248     if (!p) wasm_error(c, wasm_loc(0, 0), "wasm: out of memory");
    249     f->local_names = (char**)p;
    250     memset(f->local_names + f->cap_local_names, 0,
    251            sizeof(char*) * (new_cap - f->cap_local_names));
    252     f->cap_local_names = new_cap;
    253   }
    254   wasm_free_str(m->heap, &f->local_names[idx]);
    255   f->local_names[idx] = wasm_strdup(m->heap, name, len);
    256   if (!f->local_names[idx])
    257     wasm_error(c, wasm_loc(0, 0), "wasm: out of memory");
    258 }
    259 
    260 uint32_t wasm_type_push_param(KitCompiler* c, WasmModule* m, WasmFuncType* t,
    261                               WasmValType vt) {
    262   wasm_grow_valtypes(c, m, &t->params, &t->cap_params, t->nparams + 1u);
    263   t->params[t->nparams] = vt;
    264   return t->nparams++;
    265 }
    266 
    267 uint32_t wasm_type_push_result(KitCompiler* c, WasmModule* m, WasmFuncType* t,
    268                                WasmValType vt) {
    269   wasm_grow_valtypes(c, m, &t->results, &t->cap_results, t->nresults + 1u);
    270   t->results[t->nresults] = vt;
    271   return t->nresults++;
    272 }
    273 
    274 uint32_t wasm_intern_func_type(KitCompiler* c, WasmModule* m,
    275                                const WasmFunc* f) {
    276   uint32_t i;
    277   for (i = 0; i < m->ntypes; ++i) {
    278     WasmFuncType* t = &m->types[i];
    279     if (t->nparams == f->nparams && t->nresults == f->nresults &&
    280         (t->nparams == 0 || memcmp(t->params, f->params,
    281                                    sizeof(t->params[0]) * t->nparams) == 0) &&
    282         (t->nresults == 0 ||
    283          memcmp(t->results, f->results,
    284                 sizeof(t->results[0]) * t->nresults) == 0))
    285       return i;
    286   }
    287   {
    288     WasmFuncType* t = wasm_add_type(c, m);
    289     wasm_grow_valtypes(c, m, &t->params, &t->cap_params, f->nparams);
    290     t->nparams = f->nparams;
    291     if (f->nparams)
    292       memcpy(t->params, f->params, sizeof(t->params[0]) * f->nparams);
    293     wasm_grow_valtypes(c, m, &t->results, &t->cap_results, f->nresults);
    294     t->nresults = f->nresults;
    295     if (f->nresults)
    296       memcpy(t->results, f->results, sizeof(t->results[0]) * f->nresults);
    297     return m->ntypes - 1u;
    298   }
    299 }
    300 
    301 WasmTable* wasm_add_table(KitCompiler* c, WasmModule* m) {
    302   WasmTable* t;
    303   if (m->ntables == m->cap_tables) {
    304     uint32_t new_cap = m->cap_tables ? m->cap_tables * 2u : 2u;
    305     void* p =
    306         wasm_realloc(m->heap, m->tables, sizeof(*m->tables) * m->cap_tables,
    307                      sizeof(*m->tables) * new_cap);
    308     if (!p) wasm_error(c, wasm_loc(0, 0), "wasm: out of memory");
    309     m->tables = (WasmTable*)p;
    310     memset(m->tables + m->cap_tables, 0,
    311            sizeof(*m->tables) * (new_cap - m->cap_tables));
    312     m->cap_tables = new_cap;
    313   }
    314   t = &m->tables[m->ntables++];
    315   memset(t, 0, sizeof *t);
    316   return t;
    317 }
    318 
    319 WasmGlobal* wasm_add_global(KitCompiler* c, WasmModule* m) {
    320   WasmGlobal* g;
    321   if (m->nglobals == m->cap_globals) {
    322     uint32_t new_cap = m->cap_globals ? m->cap_globals * 2u : 4u;
    323     void* p =
    324         wasm_realloc(m->heap, m->globals, sizeof(*m->globals) * m->cap_globals,
    325                      sizeof(*m->globals) * new_cap);
    326     if (!p) wasm_error(c, wasm_loc(0, 0), "wasm: out of memory");
    327     m->globals = (WasmGlobal*)p;
    328     memset(m->globals + m->cap_globals, 0,
    329            sizeof(*m->globals) * (new_cap - m->cap_globals));
    330     m->cap_globals = new_cap;
    331   }
    332   g = &m->globals[m->nglobals++];
    333   memset(g, 0, sizeof *g);
    334   return g;
    335 }
    336 
    337 WasmElemSegment* wasm_add_elem(KitCompiler* c, WasmModule* m) {
    338   WasmElemSegment* e;
    339   if (m->nelems == m->cap_elems) {
    340     uint32_t new_cap = m->cap_elems ? m->cap_elems * 2u : 4u;
    341     void* p = wasm_realloc(m->heap, m->elems, sizeof(*m->elems) * m->cap_elems,
    342                            sizeof(*m->elems) * new_cap);
    343     if (!p) wasm_error(c, wasm_loc(0, 0), "wasm: out of memory");
    344     m->elems = (WasmElemSegment*)p;
    345     memset(m->elems + m->cap_elems, 0,
    346            sizeof(*m->elems) * (new_cap - m->cap_elems));
    347     m->cap_elems = new_cap;
    348   }
    349   e = &m->elems[m->nelems++];
    350   memset(e, 0, sizeof *e);
    351   return e;
    352 }
    353 
    354 WasmDataSegment* wasm_add_data(KitCompiler* c, WasmModule* m) {
    355   WasmDataSegment* d;
    356   if (m->ndata == m->cap_data) {
    357     uint32_t new_cap = m->cap_data ? m->cap_data * 2u : 4u;
    358     void* p = wasm_realloc(m->heap, m->data, sizeof(*m->data) * m->cap_data,
    359                            sizeof(*m->data) * new_cap);
    360     if (!p) wasm_error(c, wasm_loc(0, 0), "wasm: out of memory");
    361     m->data = (WasmDataSegment*)p;
    362     memset(m->data + m->cap_data, 0,
    363            sizeof(*m->data) * (new_cap - m->cap_data));
    364     m->cap_data = new_cap;
    365   }
    366   d = &m->data[m->ndata++];
    367   memset(d, 0, sizeof *d);
    368   return d;
    369 }
    370 
    371 void wasm_data_set_bytes(KitCompiler* c, WasmModule* m, WasmDataSegment* d,
    372                          const uint8_t* src, uint64_t n) {
    373   void* p;
    374   if (n > SIZE_MAX)
    375     wasm_error(c, wasm_loc(0, 0), "wasm: data segment too large");
    376   if (d->bytes && d->nbytes)
    377     m->heap->free(m->heap, d->bytes, (size_t)d->nbytes);
    378   d->bytes = NULL;
    379   d->nbytes = 0;
    380   if (!n) return;
    381   p = m->heap->alloc(m->heap, (size_t)n, 1);
    382   if (!p) wasm_error(c, wasm_loc(0, 0), "wasm: out of memory");
    383   if (src)
    384     memcpy(p, src, (size_t)n);
    385   else
    386     memset(p, 0, (size_t)n);
    387   d->bytes = (uint8_t*)p;
    388   d->nbytes = n;
    389 }
    390 
    391 void wasm_elem_push_func(KitCompiler* c, WasmModule* m, WasmElemSegment* e,
    392                          uint32_t funcidx) {
    393   if (e->nfuncs == e->cap_funcs) {
    394     uint32_t new_cap = e->cap_funcs ? e->cap_funcs * 2u : 8u;
    395     void* p = wasm_realloc(m->heap, e->funcs, sizeof(*e->funcs) * e->cap_funcs,
    396                            sizeof(*e->funcs) * new_cap);
    397     if (!p) wasm_error(c, wasm_loc(0, 0), "wasm: out of memory");
    398     e->funcs = (uint32_t*)p;
    399     e->cap_funcs = new_cap;
    400   }
    401   e->funcs[e->nfuncs++] = funcidx;
    402 }
    403 
    404 WasmExport* wasm_add_export(KitCompiler* c, WasmModule* m) {
    405   WasmExport* e;
    406   if (m->nexports == m->cap_exports) {
    407     uint32_t new_cap = m->cap_exports ? m->cap_exports * 2u : 8u;
    408     void* p =
    409         wasm_realloc(m->heap, m->exports, sizeof(*m->exports) * m->cap_exports,
    410                      sizeof(*m->exports) * new_cap);
    411     if (!p) wasm_error(c, wasm_loc(0, 0), "wasm: out of memory");
    412     m->exports = (WasmExport*)p;
    413     memset(m->exports + m->cap_exports, 0,
    414            sizeof(*m->exports) * (new_cap - m->cap_exports));
    415     m->cap_exports = new_cap;
    416   }
    417   e = &m->exports[m->nexports++];
    418   memset(e, 0, sizeof *e);
    419   return e;
    420 }
    421 
    422 WasmCustom* wasm_add_custom(KitCompiler* c, WasmModule* m) {
    423   WasmCustom* cs;
    424   if (m->ncustoms == m->cap_customs) {
    425     uint32_t new_cap = m->cap_customs ? m->cap_customs * 2u : 4u;
    426     void* p =
    427         wasm_realloc(m->heap, m->customs, sizeof(*m->customs) * m->cap_customs,
    428                      sizeof(*m->customs) * new_cap);
    429     if (!p) wasm_error(c, wasm_loc(0, 0), "wasm: out of memory");
    430     m->customs = (WasmCustom*)p;
    431     memset(m->customs + m->cap_customs, 0,
    432            sizeof(*m->customs) * (new_cap - m->cap_customs));
    433     m->cap_customs = new_cap;
    434   }
    435   cs = &m->customs[m->ncustoms++];
    436   memset(cs, 0, sizeof *cs);
    437   return cs;
    438 }
    439 
    440 void wasm_func_add_insn(KitCompiler* c, WasmModule* m, WasmFunc* f,
    441                         WasmInsnKind kind, int64_t imm) {
    442   if (f->ninsns == f->cap_insns) {
    443     uint32_t new_cap = f->cap_insns ? f->cap_insns * 2u : 16u;
    444     void* p = wasm_realloc(m->heap, f->insns, sizeof(*f->insns) * f->cap_insns,
    445                            sizeof(*f->insns) * new_cap);
    446     if (!p) wasm_error(c, wasm_loc(0, 0), "wasm: out of memory");
    447     f->insns = (WasmInsn*)p;
    448     f->cap_insns = new_cap;
    449   }
    450   f->insns[f->ninsns].loc = m ? m->current_loc : wasm_loc(0, 0);
    451   f->insns[f->ninsns].kind = (uint8_t)kind;
    452   f->insns[f->ninsns].type = 0;
    453   f->insns[f->ninsns].imm = imm;
    454   f->insns[f->ninsns].fp = 0.0;
    455   f->insns[f->ninsns].align = 0;
    456   f->insns[f->ninsns].memidx = 0;
    457   f->insns[f->ninsns].offset64 = imm < 0 ? 0 : (uint64_t)imm;
    458   f->insns[f->ninsns].aux_idx = 0;
    459   f->insns[f->ninsns].ntargets = 0;
    460   f->insns[f->ninsns].targets = NULL;
    461   f->ninsns++;
    462 }
    463 
    464 void wasm_func_add_mem_insn(KitCompiler* c, WasmModule* m, WasmFunc* f,
    465                             WasmInsnKind kind, uint32_t align, uint64_t offset,
    466                             uint32_t memidx) {
    467   wasm_func_add_insn(c, m, f, kind,
    468                      offset > INT64_MAX ? INT64_MAX : (int64_t)offset);
    469   f->insns[f->ninsns - 1u].align = align;
    470   f->insns[f->ninsns - 1u].offset64 = offset;
    471   f->insns[f->ninsns - 1u].memidx = memidx;
    472 }
    473 
    474 void wasm_func_add_fp_insn(KitCompiler* c, WasmModule* m, WasmFunc* f,
    475                            WasmInsnKind kind, double value) {
    476   wasm_func_add_insn(c, m, f, kind, 0);
    477   f->insns[f->ninsns - 1u].fp = value;
    478 }
    479 
    480 void wasm_insn_set_targets(KitCompiler* c, WasmModule* m, WasmInsn* in,
    481                            const uint32_t* targets, uint32_t ntargets) {
    482   if (in->targets)
    483     m->heap->free(m->heap, in->targets, sizeof(uint32_t) * in->ntargets);
    484   in->targets = NULL;
    485   in->ntargets = ntargets;
    486   if (!ntargets) return;
    487   in->targets = (uint32_t*)m->heap->alloc(m->heap, sizeof(uint32_t) * ntargets,
    488                                           _Alignof(uint32_t));
    489   if (!in->targets)
    490     wasm_error(c, wasm_loc(0, 0), "wasm: out of memory for br_table targets");
    491   if (targets) memcpy(in->targets, targets, sizeof(uint32_t) * ntargets);
    492 }