#include "target_bridge.h" #include "target_host.h" #include u32 w2c_target__host_allocate(struct w2c_target__host *env, u32 context) { wasm_rt_memory_t *memory=w2c_factorio__target_memory(env->module); if (memory->size<256 || context>memory->size-256 || env->heap.memory!=memory->data || env->heap.memory_size!=memory->size) return 2; uint64_t size,address; memcpy(&size,memory->data+context,8); int status=factorio_guest_heap_allocate(&env->heap,size,&address); if (status) return status==1 ? 5 : 2; memcpy(memory->data+context,&address,8); return 0; } u32 w2c_target__host_unsupported_delete(struct w2c_target__host *env,u64 a,u64 b,u64 c) { (void)env;(void)a;(void)b;(void)c;return 6; } u32 w2c_target__host_unsupported_length(struct w2c_target__host *env,u64 a,u64 b,u64 c) { return w2c_target__host_unsupported_delete(env,a,b,c); } u32 w2c_target__host_unsupported_array_length(struct w2c_target__host *env,u64 a,u64 b,u64 c) { return w2c_target__host_unsupported_delete(env,a,b,c); } static uint64_t get(const uint8_t *memory,size_t offset) { uint64_t value;memcpy(&value,memory+offset,8);return value; } int factorio_target_probe(FactorioTargetProbe *out) { if (!out) return 2; if (!wasm_rt_is_initialized()) wasm_rt_init(); w2c_factorio__target module; struct w2c_target__host env={.module=&module}; wasm2c_factorio__target_instantiate(&module,&env); wasm_rt_memory_t *ram=w2c_factorio__target_memory(&module); uint8_t *memory=ram->data; memset(memory,0xa5,(size_t)ram->size); int status=factorio_guest_heap_init(&env.heap,memory,ram->size,131072,196608); uint64_t registers[32]={0}; registers[0]=4096;registers[31]=ram->size-256; memcpy(memory,registers,sizeof(registers)); if (!status) status=(int)w2c_factorio__target_run(&module,0,10000); if (!status) { /* Fixed allocation trace is part of this pinned constructor's contract. * No dereference occurs until those offsets have been checked. */ uint64_t block=131072,targets=131104,vector=133152,last=133168; if (env.heap.allocations!=4 || env.heap.cursor!=last+8 || get(memory,0)!=4096 || memory[4096]!=0 || memory[4096+0x88]!=0 || get(memory,4104)!=vector || get(memory,4112)!=vector+8 || get(memory,4120)!=vector+8 || get(memory,4128)!=64 || get(memory,4136)!=0 || get(memory,4144)!=0 || get(memory,4096+0x38)!=last || get(memory,4096+0x40)!=last+8 || get(memory,4096+0x48)!=last+8 || get(memory,last)!=0 || get(memory,vector)!=block || get(memory,block)!=targets || get(memory,block+8)!=targets+2048 || get(memory,block+16)!=targets+2048) status=7; for (unsigned i=0;!status && i<64;++i) { if (get(memory,targets+i*32)!=65536+0xda8 || get(memory,targets+i*32+8) || get(memory,targets+i*32+16) || get(memory,targets+i*32+24)) status=7; } for (unsigned i=0x50;!status && i<0x81;++i) if (memory[4096+i]) status=7; if (!status) *out=(FactorioTargetProbe){4,64,64,env.heap.cursor-env.heap.begin}; } wasm2c_factorio__target_free(&module); return status; }