#include "map_header_bridge.h" #include "factorio_map_header.h" #include struct w2c_map__host { w2c_factorio__map__header *module; unsigned reads; }; u32 w2c_map__host_read_or_throw(struct w2c_map__host *env, u64 source, u64 destination, u64 size) { wasm_rt_memory_t *memory = w2c_factorio__map__header_memory(env->module); if (memory->size < 24 || source > memory->size - 24 || size > memory->size || destination > memory->size - size) return 2; uint64_t reader[3]; memcpy(reader, memory->data + source, sizeof(reader)); uint64_t data = reader[0], length = reader[1], cursor = reader[2]; 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_map_header_parse(const uint8_t *payload, size_t length, FactorioMapVersion version, FactorioMapHeader *out) { if (!payload || !out) return 2; if (!wasm_rt_is_initialized()) wasm_rt_init(); w2c_factorio__map__header module; struct w2c_map__host env = {.module = &module}; wasm2c_factorio__map__header_instantiate(&module, &env); uint8_t *memory = w2c_factorio__map__header_memory(&module)->data; uint64_t registers[32] = {0}; registers[0] = 2048; registers[1] = 512; registers[31] = 65280; uint64_t reader[5] = {4096, length < 24 ? length : 24, 0, (uint64_t)version.major << 48 | (uint64_t)version.minor << 32 | (uint64_t)version.patch << 16 | version.build, version.flag}; memcpy(memory, registers, sizeof(registers)); memcpy(memory + 512, reader, sizeof(reader)); memcpy(memory + 4096, payload, (size_t)reader[1]); int result = (int)w2c_factorio__map__header_run(&module, 0, 1000); if (!result) { FactorioMapHeader parsed = {.version = version}; memcpy(parsed.tick_fields, memory + 2064, sizeof(parsed.tick_fields)); *out = parsed; } wasm2c_factorio__map__header_free(&module); return result; }