#include "factorio_rng.h" #include #include #include extern uint32_t factorio_rng_original(uint32_t state[3]); extern void factorio_rng_seed_original(uint32_t state[3], uint32_t seed); static uint32_t next_case(uint32_t *seed) { *seed ^= *seed << 13; *seed ^= *seed >> 17; *seed ^= *seed << 5; return *seed; } // Returns zero only after comparing outputs AND mutated state with original // ARM64 instruction words. No generated code is mapped executable at runtime. int factorio_rng_verify(void) { const uint32_t edges[] = {0, 1, 2, 7, 8, 15, 16, 127, 128, 0x7fffffff, 0x80000000, 0xffffffff}; const uint32_t offsets[] = {0, 1, 15, 1024, 65524}; uint32_t random = 0x375adc91; uint64_t calls = 0; w2c_factorio__rng instance; wasm_rt_init(); wasm2c_factorio__rng_instantiate(&instance); wasm_rt_memory_t *memory = w2c_factorio__rng_memory(&instance); for (uint32_t example = 0; example < 6848; ++example) { uint32_t state[3]; if (example < 1728) { state[0] = edges[example % 12]; state[1] = edges[(example / 12) % 12]; state[2] = edges[example / 144]; } else if (example < 5824) { for (int i = 0; i < 3; ++i) state[i] = next_case(&random); } uint32_t offset = offsets[example % 5]; memset(memory->data, 0xa5, 65536); if (example >= 5824) { uint32_t seed = example < 6336 ? example - 5824 : next_case(&random); factorio_rng_seed_original(state, seed); w2c_factorio__rng_seed(&instance, offset, seed); if (memcmp(memory->data + offset, state, 12)) { fprintf(stderr, "Constructor mismatch at seed %u\n", seed); wasm2c_factorio__rng_free(&instance); wasm_rt_free(); return 3; } } else { memcpy(memory->data + offset, state, 12); } for (int step = 0; step < 128; ++step) { uint32_t expected = factorio_rng_original(state); uint32_t actual = w2c_factorio__rng_get_int(&instance, offset); ++calls; if (actual != expected || memcmp(memory->data + offset, state, 12)) { fprintf(stderr, "Mismatch: case %u step %d, expected %08x actual %08x\n", example, step, expected, actual); wasm2c_factorio__rng_free(&instance); wasm_rt_free(); return 1; } } // Catch writes outside the 12-byte state, including unaligned addresses. for (uint32_t i = 0; i < 65536; ++i) { if ((i < offset || i >= offset + 12) && memory->data[i] != 0xa5) { fprintf(stderr, "Out-of-state write: case %u offset %u\n", example, i); wasm2c_factorio__rng_free(&instance); wasm_rt_free(); return 2; } } } wasm2c_factorio__rng_free(&instance); wasm_rt_free(); printf("PASS: %llu RNG calls and 1024 constructor calls, 6848 starting states, five memory alignments; outputs, state and guards match\n", (unsigned long long)calls); return 0; } #ifndef FACTORIO_RNG_NO_MAIN int main(void) { return factorio_rng_verify(); } #endif