emit.c (1700B)
1 /* emit_wasm: Wasm module/object emitter. 2 * 3 * For v1 the wasm CGTarget builds a WasmModule incrementally and attaches it 4 * to the ObjBuilder under OBJ_EXT_WASM. emit_wasm flushes that module via 5 * the existing wasm_encode writer. When no module is attached (e.g. an 6 * ObjBuilder produced by an .o reader or an empty TU), an empty module 7 * header is written so downstream tools see a syntactically valid file. */ 8 9 #include "core/core.h" 10 #include "obj/obj.h" 11 #include "obj/wasm/wasm.h" 12 #include "wasm/wasm.h" 13 14 KitStatus kit_obj_builder_wasm_add_custom(KitObjBuilder* b, KitSlice name, 15 KitSlice data) { 16 ObjBuilder* ob = (ObjBuilder*)b; 17 Compiler* c = obj_compiler(ob); 18 WasmModule* m = (WasmModule*)obj_ext_get(ob, OBJ_EXT_WASM); 19 WasmCustom* cs; 20 if (!m || !c) return KIT_NOT_FOUND; 21 cs = wasm_add_custom(c, m); 22 if (!cs) return KIT_NOMEM; 23 cs->name = wasm_strdup(m->heap, name.s, (size_t)name.len); 24 if (!cs->name) return KIT_NOMEM; 25 if (data.len) { 26 cs->data = (uint8_t*)m->heap->alloc(m->heap, (size_t)data.len, 1); 27 if (!cs->data) return KIT_NOMEM; 28 memcpy(cs->data, data.s, (size_t)data.len); 29 cs->len = (uint32_t)data.len; 30 } 31 return KIT_OK; 32 } 33 34 void emit_wasm(Compiler* c, ObjBuilder* o, Writer* w) { 35 WasmModule* m = (WasmModule*)obj_ext_get(o, OBJ_EXT_WASM); 36 if (m) { 37 wasm_encode(c, m, w); 38 return; 39 } 40 /* Empty module: magic + version. wasm_encode emits the same header even 41 * for an empty WasmModule, but we avoid allocating one just to drop it. */ 42 static const uint8_t magic[] = {0x00, 0x61, 0x73, 0x6d, 43 0x01, 0x00, 0x00, 0x00}; 44 w->write(w, magic, sizeof magic); 45 }