#include "version_bridge.h" #include "version_host.h" #include #include #include typedef struct { uint8_t bytes[9]; size_t cursor; unsigned reads; } NativeReader; extern void *factorio_version_original(void *out, NativeReader *reader); void native_version_read(NativeReader *reader, void *out, size_t length) { assert(length == (reader->reads == 4 ? 1 : 2)); assert(reader->cursor + length <= 9); memcpy(out, reader->bytes + reader->cursor, length); reader->cursor += length; ++reader->reads; } static uint32_t random_word(uint32_t *state) { *state ^= *state << 13; *state ^= *state >> 17; *state ^= *state << 5; return *state; } int main(void) { 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; uint32_t seed = 0xc46b21f3; for (unsigned example = 0; example < 20000; ++example) { NativeReader reader = {0}; for (int i = 0; i < 9; ++i) reader.bytes[i] = (uint8_t)random_word(&seed); if (example < 2) memset(reader.bytes, example ? 0xff : 0, 9); uint8_t expected[16]; memset(expected, 0xa5, sizeof(expected)); assert(factorio_version_original(expected, &reader) == expected); assert(reader.cursor == 9 && reader.reads == 5); memset(memory, 0xa5, 65536); uint64_t registers[32]; for (int i = 0; i < 32; ++i) registers[i] = random_word(&seed); registers[0] = 2048; registers[1] = 512; registers[31] = 65280; uint64_t stream[] = {4096, 9, 0}; memcpy(memory, registers, sizeof(registers)); memcpy(memory + 512, stream, sizeof(stream)); memcpy(memory + 4096, reader.bytes, 9); env.reads = 0; assert(w2c_factorio__version_run(&module, 0) == 0); assert(env.reads == 5); assert(memcmp(memory + 2048, expected, sizeof(expected)) == 0); uint64_t after[32]; memcpy(after, memory, sizeof(after)); assert(after[0] == 2048 && after[31] == registers[31]); for (int i = 19; i <= 30; ++i) assert(after[i] == registers[i]); for (int i = 256; i < 65536; ++i) { if ((i >= 512 && i < 536) || (i >= 2048 && i < 2057) || (i >= 4096 && i < 4105) || (i >= 65200 && i < 65280)) continue; assert(memory[i] == 0xa5); } } uint8_t sample[9] = {2, 0, 0, 0, 77, 0, 0, 0, 0}; FactorioMapVersion output; assert(factorio_version_parse(sample, sizeof(sample), &output) == 0); assert(output.major == 2 && output.minor == 0 && output.patch == 77 && output.build == 0 && output.flag == 0); for (size_t length = 0; length < 9; ++length) { memset(&output, 0xa5, sizeof(output)); FactorioMapVersion before = output; assert(factorio_version_parse(sample, length, &output) == 1); assert(memcmp(&output, &before, sizeof(output)) == 0); } wasm2c_factorio__version_free(&module); wasm_rt_free(); puts("PASS: 20000 original ARM64 constructor comparisons, five-read protocol, preserved registers, memory guards, and short-header errors"); return 0; }