Skip to content

Fix: An ArrayParam function that can run user code stays interpreted (#203) - #205

Merged
b-re-w merged 1 commit into
developfrom
feat/tp-arrayparam-closed
Oct 17, 2026
Merged

b-re-w merged 1 commit into
developfrom
feat/tp-arrayparam-closed

Conversation

@b-re-w

@b-re-w b-re-w commented Oct 17, 2026

Copy link
Copy Markdown
Member

Closes #203

Defect fixed: a function holding a list copy-in that also ran user code compiled, and diverged from CPython. On develop, f(xs, cb) (cb() sets xs[0] = 100.0, then return xs[0]) returned 1.0 compiled against 100.0 interpreted. A store followed by a callback was also overwritten by write-back.

Fix: a new verifier rule, verify/array-open. A function with an ArrayParam must be closed: no GetAttr, CallObject, Truth, CompareObj, ObjToFloat or OBJ BinOp. It also may not use FieldGet or New, whose slow paths run user code after a class change. The rule applies over the whole call tree (fixpoint). Such a function stays interpreted with a reason.

Tests added:

  • verifier: CallObject, GetAttr, Truth, an open callee, and the closed case still accepted;
  • end to end: test_array_function_with_a_callback_matches_cpython.

Red before the fix: 5 failed, 1 passed; the passing one is the accepted closed case.

Tests corrected: these encoded the defect and now use closed array functions or non-array functions:

  • test_len_bound_is_zero_to_two_to_the_62;
  • test_the_same_open_node_without_entry_globals_is_accepted;
  • the scale and ip base functions;
  • one fuzz mutation that assumed scale had an ArrayParam;
  • fill in test_cgen_class_changes.py. It was an array function whose slot read ran a property installed after init, which is exactly this defect. It now returns the entry global instead, so the scenario still checks the snapshot against the property.

Documentation corrected: the ArrayParam contract in ir.py (the verifier, not the front end, enforces it), and the SPEC N-9 table row.

Verification (local):

  • Full TypedPython suite: 962 passed, 3 skipped.
  • Mutation: disabling the rule makes the end-to-end test fail.
  • The five benchmarks compile exactly the same functions as on develop.

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.

1 participant