Add division, bitwise, shift ops and support >256 globals - #22
Merged
Merged
Conversation
New integer opcodes, end to end (VM, IntOp, constant folding, emit, disasm, Scheme and Fleche): INT_DIV, INT_MOD (Rocq Nat convention: x / 0 = 0, x mod 0 = x, truncating), INT_SUB_SAT (Nat.sub), INT_LE, INT_AND/OR/XOR, INT_SHL and logical INT_SHR (shift amounts outside 0..24 give 0). The semantics live in encore_vm::int, shared by the VM and the constant folder so they agree bit for bit. Globals: the VM no longer has a fixed [_; 64] table. load() carves one word per global from the top of the heap buffer, and fails with GlobalsOverflow when they do not fit. Program reads globals from its source instead of copying into a fixed array. The asm IR uses u16 global indices, emitted as GLOBAL_W for indices >= 256. The global-name metadata index is now u16. Hard limits are reported instead of wrapping: CompileError for too many globals, code over 64 KB, over-long byte literals, too many captures and too-wide constructors; a parse error past 256 constructor tags. compile_module now returns a Result. Closes #20 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013oP2CQNhSb824xmzwM9kqx
Resolve conflicts with the 24-bit overflow trap. The new integer ops follow the same contract: INT_DIV (INT_MIN / -1), INT_SUB_SAT and INT_SHL (exact a * 2^b) now trap with IntOverflow instead of wrapping, and the constant folder leaves those cases unfolded. INT_MOD, the bitwise ops and INT_SHR cannot overflow and are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013oP2CQNhSb824xmzwM9kqx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR extends the VM and compiler to support:
u16indices instead ofu8Key Changes
New Integer Operations
int::module with 24-bit semantics for all operations (wrapping, saturation, zero-fill shifts)INT_LE,INT_DIV,INT_MOD,INT_SUB_SAT,INT_AND,INT_OR,INT_XOR,INT_SHL,INT_SHRvm_tests.rsandfleche_tests.rscovering edge cases (division by zero, overflow, out-of-range shifts)Global Slots Management
vm.load()instead of fixed 64-slot arrayu8tou16throughout compiler and VMGLOBAL_Wopcode (0x04) for wide (u16) global indices;GLOBAL(0x03) still used for u8 indicesGLOBAL_Wwhen index > 255VmError::GlobalsOverflowwhen globals don't fit in available heap spaceProgramto support unlimited globals viaGlobalsenum (slice or raw bytes)Compiler Limits & Error Handling
CompileErrorenum with variants for limit violations:TooManyGlobals(>65535)CodeTooLarge(>65535 bytes)BytesLiteralTooLong(>255)TooManyCaptures(>125)CtorTooWide(>126 fields)pipeline::compile_module()now returnsResult<Vec<u8>, CompileError>Documentation & Tests
VM.mdandFLECHE.mdwith new opcodes and semanticsSCHEME.mddocumentation for Scheme primitivesMAINconstant and handle.unwrap()on compile resultsImplementation Details
i32with 24-bit masking/sign-extension viaint::wrap()x / 0 = 0,x mod 0 = xu16with0xFFFFreserved for NULL; max heap is 65535 wordshttps://claude.ai/code/session_013oP2CQNhSb824xmzwM9kqx