During review of PR #474 (calls.py decomposition — pure code motion), CodeRabbit identified 10 pre-existing bugs in the WASM call translator code. These were not introduced by the refactor; they existed in vera/wasm/calls.py before the split. Filing them here so they're tracked but don't contaminate the mechanical refactor PR.
Findings
| # |
Severity |
Location (post-refactor) |
Description |
| 1 |
🔴 Critical |
calls_handlers.py _translate_handle_exn |
Catch-arm result type inference only checks when clause.body is ast.Block; expression-bodied handlers leave result_wt = None, omitting the (result ...) annotation in emitted WAT. |
| 2 |
🔴 Critical |
calls_strings.py _translate_string_slice |
Slice bounds narrowed with i32.wrap_i64 before clamping — large positive i64 indices wrap to negative i32 values, then get clamped to 0. Should clamp in i64 first, wrap after. |
| 3 |
🔴 Critical |
calls_strings.py _translate_char_code |
No bounds check on index before i32.load8_u — out-of-range index reads arbitrary memory. |
| 4 |
🟠 Major |
calls_arrays.py _translate_array_slice |
Same i64→i32 narrowing issue as #2 (both start and end indices). |
| 5 |
🟠 Major |
calls_containers.py _map_wasm_tag |
Fallback routes every non-primitive/non-String type to "b" (i32), but Array<T> lowers to i32_pair. Breaks map_insert/map_values for Map<K, Array<T>>. Should reject Array values with a clear error. |
| 6 |
🟠 Major |
calls_encoding.py _translate_url_parse / _translate_url_join |
url_parse discards has_auth and delimiter-presence info, so url_join(url_parse("http:path")) round-trips as http://path. Need to preserve scheme_has_authority, query_delimiter_present, fragment_delimiter_present flags. |
| 7 |
🟠 Major |
calls_encoding.py _translate_base64_decode |
Only counts trailing = into pad but still treats = as value 0 in the main loop. = in non-padding positions should be rejected. |
| 8 |
🟠 Major |
calls_parsing.py _translate_parse_nat / _translate_parse_int |
Space-skip loop runs unconditionally, so embedded spaces are silently accepted: "12 34" parses as 1234, "- 5" parses as -5. Should only skip spaces before the first digit/sign. |
| 9 |
🟠 Major |
calls_strings.py _translate_to_string |
Integer negation of INT64_MIN (-9223372036854775808) overflows (no positive representation fits in i64), producing wrong output. Need INT64_MIN special case or unsigned-magnitude conversion. |
| 10 |
🟠 Major |
calls_strings.py _translate_float_to_string |
Rounded fractional part can equal 1_000_000 (e.g., 1.9999995), dropping the carry and producing 1.0 instead of 2.0. Need carry detection after i64.trunc_f64_s. |
Verification
Each finding references code that was moved by #474 without modification. To confirm pre-existence, compare the cited lines against git show main:vera/wasm/calls.py — the bug patterns match exactly.
Priority
The three Critical findings (1, 2, 3) should be addressed first. 8 (parse_nat/int embedded spaces) is almost certainly user-visible. The others are edge cases but represent real semantic gaps.
Filed from PR #474 review.
During review of PR #474 (calls.py decomposition — pure code motion), CodeRabbit identified 10 pre-existing bugs in the WASM call translator code. These were not introduced by the refactor; they existed in
vera/wasm/calls.pybefore the split. Filing them here so they're tracked but don't contaminate the mechanical refactor PR.Findings
calls_handlers.py_translate_handle_exnclause.bodyisast.Block; expression-bodied handlers leaveresult_wt = None, omitting the(result ...)annotation in emitted WAT.calls_strings.py_translate_string_slicei32.wrap_i64before clamping — large positive i64 indices wrap to negative i32 values, then get clamped to 0. Should clamp in i64 first, wrap after.calls_strings.py_translate_char_codei32.load8_u— out-of-range index reads arbitrary memory.calls_arrays.py_translate_array_slicecalls_containers.py_map_wasm_tag"b"(i32), butArray<T>lowers to i32_pair. Breaksmap_insert/map_valuesforMap<K, Array<T>>. Should reject Array values with a clear error.calls_encoding.py_translate_url_parse/_translate_url_joinurl_parsediscardshas_authand delimiter-presence info, sourl_join(url_parse("http:path"))round-trips ashttp://path. Need to preservescheme_has_authority,query_delimiter_present,fragment_delimiter_presentflags.calls_encoding.py_translate_base64_decode=into pad but still treats=as value 0 in the main loop.=in non-padding positions should be rejected.calls_parsing.py_translate_parse_nat/_translate_parse_int"12 34"parses as 1234,"- 5"parses as -5. Should only skip spaces before the first digit/sign.calls_strings.py_translate_to_stringINT64_MIN(-9223372036854775808) overflows (no positive representation fits in i64), producing wrong output. Need INT64_MIN special case or unsigned-magnitude conversion.calls_strings.py_translate_float_to_string1.0instead of2.0. Need carry detection afteri64.trunc_f64_s.Verification
Each finding references code that was moved by #474 without modification. To confirm pre-existence, compare the cited lines against
git show main:vera/wasm/calls.py— the bug patterns match exactly.Priority
The three Critical findings (1, 2, 3) should be addressed first. 8 (parse_nat/int embedded spaces) is almost certainly user-visible. The others are edge cases but represent real semantic gaps.
Filed from PR #474 review.