Skip to content

fpybc traps ARITHMETIC_OVERFLOW on U64 arithmetic whose result is representable #234

Description

@zimri-leisher

pick_binary_op_case lowers +, - and * to the same ADD/SUB/MUL directives for signed and unsigned operands, and the VM's op_add/op_sub/op_mul (FpySequencerDirectives.cpp:728-799) pop both operands as I64 and apply signed overflow checks, so any U64 operand or result at or above 2^63 is misclassified as an overflow. The sequence dies on the flight VM while the wasm backend computes the correct value, even though every result below is representable in U64 and so should not end the program per #59. The fix is either unsigned variants of the three directives (as UDIV/UMOD already exist) or a compiler-side guard for U64 operands; this is the opposite direction from #111, which covers genuine unsigned wraparound going untrapped on both backends.

a: U64 = 9223372036854775807
b: U64 = a + 1                 # fpybc: ARITHMETIC_OVERFLOW;  wasm: 9223372036854775808
a: U64 = 9223372036854775813
b: U64 = a - 10                # fpybc: ARITHMETIC_UNDERFLOW; wasm: 9223372036854775803
a: U64 = 4611686018427387904
b: U64 = a * 3                 # fpybc: ARITHMETIC_OVERFLOW;  wasm: 13835058055282163712

Verified on the real Svc::FpySequencer and Svc::WasmSequencer through the harnesses. The directive stream for the first case is LOADREL; PUSHVAL 1; ADD; STORERELCONSTOFFSET, i.e. nothing tells the VM the operands are unsigned. Conversely a: U64 = 5; b: U64 = a - 10 wraps silently on both backends (the #111 direction).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions