mirror of
https://github.com/odin-lang/Odin.git
synced 2026-09-02 02:03:35 +00:00
mnemonic_builders.odin bakes `global_index + 1` into Instruction.enc_hint so the encoder can skip the O(forms) match scan. The index is GLOBAL, so any edit to the encoding table that inserts or removes a form shifts every index after it and leaves the builders naming another instruction's encoding -- and nothing noticed: the encoder took the form, emitted its bytes and returned success. It has happened twice.6e17e7a2dleft 2130 of 3671 builders wrong;36af73834regenerated both halves and cleared it;baae2636b(adding `in`/`out`) re-broke 37;9ae9a9bf9shifted an early mnemonic and broke 3393 of 3802 -- including CALL, whose r/m64 builder then encoded 0F 8A (JPE) instead of FF /2, turning every indirect call into a conditional jump. The symptom was a segfault in a JIT'd program, arbitrarily far from the cause. Regenerated: 3820 of 3820 builders now correct. Three guards so it cannot return silently: - the encoder checks, under ODIN_DEBUG, that the hinted form lies inside its own mnemonic's ENCODE_RUNS entry. Release keeps the byte-for-byte fast path; this is a regeneration-time mistake and only has to be caught once by anyone running tests. - the generator stamps BUILDER_TABLE_FINGERPRINT, an FNV-1a hash of every ENCODE_RUNS (start, count), into the file it emits. - run_builder_generation_test recomputes it from the loaded tables and fails with the command to regenerate. Known-failing at this commit: four SAL/SHL cases, a separate defect in the alias table, fixed in the commit that follows. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Riok9vMpkLmo78wsVKJHhz