#include "version_bridge.h" #include "version_host.h" #include static uint64_t read64(const void *p) { uint64_t value; memcpy(&value, p, sizeof(value)); return value; } u32 w2c_env_read_or_throw(struct w2c_env *env, u64 source, u64 destination, u64 size) { wasm_rt_memory_t *memory = w2c_factorio__version_memory(env->module); if (memory->size < 24 || source > memory->size - 24 || size > memory->size || destination > memory->size - size) return 2; uint64_t data = read64(memory->data + source); uint64_t length = read64(memory->data + source + 8); uint64_t cursor = read64(memory->data + source + 16); if (data > memory->size || length > memory->size - data) return 2; if (cursor > length || size > length - cursor) return 1; memmove(memory->data + destination, memory->data + data + cursor, (size_t)size); cursor += size; memcpy(memory->data + source + 16, &cursor, sizeof(cursor)); ++env->reads; return 0; } int factorio_version_parse(const uint8_t *bytes, size_t length, FactorioMapVersion *out) { if (!bytes || !out) return 2; if (!wasm_rt_is_initialized()) wasm_rt_init(); w2c_factorio__version module; struct w2c_env env = {.module = &module}; wasm2c_factorio__version_instantiate(&module, &env); uint8_t *memory = w2c_factorio__version_memory(&module)->data; uint64_t registers[32] = {0}; registers[0] = 2048; /* guest output object */ registers[1] = 512; /* opaque stream adapter */ registers[31] = 65280; uint64_t reader[3] = {4096, length < 9 ? length : 9, 0}; memcpy(memory, registers, sizeof(registers)); memcpy(memory + 512, reader, sizeof(reader)); memcpy(memory + 4096, bytes, (size_t)reader[1]); int result = (int)w2c_factorio__version_run(&module, 0); if (!result) { uint64_t packed = read64(memory + 2048); *out = (FactorioMapVersion){.major = (uint16_t)(packed >> 48), .minor = (uint16_t)(packed >> 32), .patch = (uint16_t)(packed >> 16), .build = (uint16_t)packed, .flag = memory[2056]}; } wasm2c_factorio__version_free(&module); return result; }