Add integer overflow detection to VM and compiler - #21
Merged
Merged
Conversation
INT_ADD/INT_SUB/INT_MUL now return VmError::IntOverflow { pc } when the
exact result falls outside [-2^23, 2^23 - 1]. The constant folder leaves
out-of-range arithmetic unfolded so the VM traps at runtime, and the
emitter rejects integer literals outside the range instead of truncating
them. Documented in VM.md.
Closes #16
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L5Xv4Npfn2U5QBKUqV9Dbu
vbergeron
pushed a commit
that referenced
this pull request
Sep 23, 2026
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 adds proper overflow detection for integer arithmetic in the VM and compiler. Previously, integer operations used wrapping arithmetic, which could silently produce incorrect results. Now,
INT_ADD,INT_SUB, andINT_MULdetect when the exact result falls outside the 24-bit signed range[-2^23, 2^23 - 1]and return aVmError::IntOverflowerror instead.Key Changes
VM (
encore_vm/src/vm.rs): Replace wrapping arithmetic with checked arithmetic forINT_ADD,INT_SUB, andINT_MUL. Operations that overflow the 24-bit range now trap withVmError::IntOverflow { pc }.Value module (
encore_vm/src/value.rs): AddINT_MINandINT_MAXconstants andint_in_range()helper function to define and check the valid 24-bit signed integer range.Error handling (
encore_vm/src/error.rs): AddIntOverflow { pc: u16 }variant toVmErrorenum.Compiler constant folder (
encore_compiler/src/pass/cps_simplify/simpl_03_constant_fold.rs): Updateeval_int_binop()to use checked arithmetic and returnOption<Val>. Expressions that would overflow are left unfolded, allowing the VM to trap at runtime with the same semantics.Code emitter (
encore_compiler/src/pass/asm_emit.rs): Add assertion to reject integer literals outside the valid range at compile time, with a clear error message.Documentation (
VM.md): Update the integer value description to clarify the exact range and overflow behavior.Tests: Add comprehensive test coverage:
test_int_add_at_max,test_int_sub_at_min,test_int_mul_at_min)test_int_add_overflow,test_int_sub_overflow,test_int_mul_overflow,test_int_mul_overflow_i32)Implementation Details
The overflow detection uses Rust's
checked_*methods oni32, which returnOption. For arithmetic operations, we check both that the operation doesn't overflowi32and that the result fits in the 24-bit range. Comparison operations (INT_EQ,INT_LT) are unaffected since they always produce boolean results.The compiler maintains the same contract: the constant folder leaves out-of-range arithmetic unfolded (so it traps at runtime), and the emitter rejects integer literals outside the range at compile time.
https://claude.ai/code/session_01L5Xv4Npfn2U5QBKUqV9Dbu