target.c (2116B)
1 /* Wasm backend registration. 2 * 3 * The public CGTarget path records semantic CG into CgIrModule. Finalize 4 * replays that IR into the private WIR/module emitter in emit.c. */ 5 6 #include <string.h> 7 8 #include "cg/ir_recorder.h" 9 10 typedef CGFuncDesc WasmSemFuncDesc; 11 typedef CGCallDesc WasmSemCallDesc; 12 13 #include "arch/wasm/internal.h" 14 15 static void wasm_ir_finalize(void* user, const CgIrModule* module) { 16 WTarget* t = (WTarget*)user; 17 wasm_emit_ir_module(t, module); 18 wasm_finalize((CGTarget*)&t->base); 19 } 20 21 static void wasm_ir_destroy(void* user) { 22 WTarget* t = (WTarget*)user; 23 if (t) wasm_destroy((CGTarget*)&t->base); 24 } 25 26 static int wasm_ir_local_static_data_begin(void* user, 27 const CGLocalStaticDataDesc* desc) { 28 (void)user; 29 (void)desc; 30 return 0; /* opt out: CG falls back to TU-wide data emission. */ 31 } 32 33 static const char* wasm_ir_data_label_addr_unsupported_msg(void* user) { 34 (void)user; 35 return "wasm target: &&label addresses in static-data initializers are " 36 "not yet supported"; 37 } 38 39 static const char* wasm_ir_tail_call_unrealizable_reason( 40 void* user, const WasmSemFuncDesc* caller, const WasmSemCallDesc* call) { 41 WTarget* t = (WTarget*)user; 42 const ABIFuncInfo* abi; 43 (void)caller; 44 if (!t || !call || !call->fn_type) return NULL; 45 abi = abi_cg_func_info(t->c->abi, call->fn_type); 46 if (abi && abi->variadic) 47 return "wasm cannot tail-call a variadic function (its vararg buffer " 48 "lives in the frame a sibling call tears down)"; 49 return NULL; 50 } 51 52 CgTarget* wasm_cgtarget_new(Compiler* c, ObjBuilder* o, MCEmitter* mc) { 53 WTarget* emitter = wasm_emit_target_new(c, o, mc); 54 CgIrRecorderConfig cfg; 55 if (!emitter) return NULL; 56 memset(&cfg, 0, sizeof cfg); 57 cfg.finalize = wasm_ir_finalize; 58 cfg.destroy = wasm_ir_destroy; 59 cfg.local_static_data_begin = wasm_ir_local_static_data_begin; 60 cfg.data_label_addr_unsupported_msg = wasm_ir_data_label_addr_unsupported_msg; 61 cfg.tail_call_unrealizable_reason = wasm_ir_tail_call_unrealizable_reason; 62 cfg.user = emitter; 63 return cg_ir_recorder_new(c, o, &cfg); 64 }