Skip to content

Add integer overflow detection to VM and compiler - #21

Merged
vbergeron merged 1 commit into
mainfrom
claude/compassionate-noether-617s68
Sep 23, 2026
Merged

vbergeron merged 1 commit into
mainfrom
claude/compassionate-noether-617s68

Conversation

@vbergeron

Copy link
Copy Markdown
Owner

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, and INT_MUL detect when the exact result falls outside the 24-bit signed range [-2^23, 2^23 - 1] and return a VmError::IntOverflow error instead.

Key Changes

  • VM (encore_vm/src/vm.rs): Replace wrapping arithmetic with checked arithmetic for INT_ADD, INT_SUB, and INT_MUL. Operations that overflow the 24-bit range now trap with VmError::IntOverflow { pc }.

  • Value module (encore_vm/src/value.rs): Add INT_MIN and INT_MAX constants and int_in_range() helper function to define and check the valid 24-bit signed integer range.

  • Error handling (encore_vm/src/error.rs): Add IntOverflow { pc: u16 } variant to VmError enum.

  • Compiler constant folder (encore_compiler/src/pass/cps_simplify/simpl_03_constant_fold.rs): Update eval_int_binop() to use checked arithmetic and return Option<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:

    • VM tests for operations at the boundaries (test_int_add_at_max, test_int_sub_at_min, test_int_mul_at_min)
    • VM tests for overflow detection (test_int_add_overflow, test_int_sub_overflow, test_int_mul_overflow, test_int_mul_overflow_i32)
    • Compiler constant folder tests for boundary cases and non-folding of overflowing expressions
    • Emitter tests for literal bounds checking and rejection of out-of-range literals

Implementation Details

The overflow detection uses Rust's checked_* methods on i32, which return Option. For arithmetic operations, we check both that the operation doesn't overflow i32 and 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

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
vbergeron merged commit 1821b72 into main Sep 23, 2026
2 checks passed
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants