Skip to content

wasm/jit backend fixes, blackhole and frame-state repairs, and 3.14 interpreter surface parity - #890

Merged
youknowone merged 108 commits into
mainfrom
wasm-jit
Aug 1, 2026
Merged

wasm/jit backend fixes, blackhole and frame-state repairs, and 3.14 interpreter surface parity#890
youknowone merged 108 commits into
mainfrom
wasm-jit

Conversation

@youknowone

@youknowone youknowone commented Jul 30, 2026

Copy link
Copy Markdown
Owner

74 commits, rebased onto main (8c878513ef, #878).

jit / blackhole / frame state

  • Blackhole: drop the abort frame-state rollback that replayed executed effects; seed the miframe from every register and resume past a frame-forcing residual that ran user bytecode; end the deadframe root scope before the forward run.
  • Walk declines: a jitcode register read that finds an unwritten slot, a code object past the jitcode label-id ceiling, the LOAD_GLOBAL cell fold when the namespace operand is null.
  • Frames: force and write back the frame's locals for locals()/vars(); force the frame before f_locals reads its fastlocals; defer the escape-flush undo restore to the walk-end epilogue; exempt the FOR_ITER loop-variable store from the in-flight body-effect guard.
  • Roots and barriers: root the deadframe exit values across handle_fail and blackhole resume; size the typed-array tids from the block they describe and barrier the blackhole ref stores; write-barrier the flat-pycall callee locals array; re-gray black stack roots before the major cycle freezes survivors.
  • Cross-loop close is attempted once per recording walk instead of on every crossing of the same header (reached_loop_header answers a cancelled close with cancel_count += 1 and, with max_unroll_loops at its default 0, SwitchToBlackhole(ABORT_BAD_LOOP), so upstream re-attempts at most once per tracing pass).
  • pypyjit.set_param; wide binop immediates materialize through the scratch register; GUARD_NOT_INVALIDATED's branch routes through the long-branch pattern; setarrayitem_vable_r for the BUILD_LIST push.

wasm backend

  • Intern trace reference constants into a per-loop GcTable; root the deadframe exit-value copies; register the collect_full GC hook and the user-del action; give the launcher a stderr channel, an exit status and the script path; raise MAX_STACK_SIZE off wasm32 and clamp the length to the OS stack.

interpreter surface (3.14)

  • Builtin call convention: bind arguments through the clinic two-branch arity check; word arity, keyword and receiver/module errors by the C calling convention.
  • Descriptors: bind a method_descriptor to a builtin_function_or_method; __rpow__'s third (modulus) argument; publish __objclass__/__name__ as member descriptors; type's own docstring; type.__prepare__; object.__subclasshook__ as a classmethod; exception __str__/__repr__ descriptors, slot deletion and SystemExit init.
  • Iteration: separate iterator types for str/bytes/bytearray/memoryview and for array; name the class, not the instance layout, in iteration errors.
  • Errors and messages: structured renderer for uncaught exceptions with repeated-frame collapse; one ZeroDivisionError message for every zero divisor; source length in "too many values to unpack" only for an exact tuple or list; MRO blocked-base and store-miss wording; add_note argument-clinic wording.
  • Sorting: port rpython/rlib/listsort.py TimSort, sort through the list strategy and reinstall the items in one bulk init.
  • Also: recursion budget spent per frame activation; independent locals() snapshot for optimized frames; dir() resolves its frame the way locals() does; _abc_register structural-match marker; _imp.init_frozen; posix chown/lchown, pathconf_names, bytes-path directory names; _operator registration; bytes.translate(table, /, delete); str.islower/isupper skip uncased letters; TabError on mixed tabs and spaces; math/descroperation numeric-tower parity.

verification (macOS)

  • pyre/check.py --backend dynasm,wasm on this tip, after re-extracting LLBC for pyre-object / pyre-interpreter / pyre-module / pyre-jit:
    • wasm 341/341 passed.
    • dynasm 343 passed, 1 failed: synth/const_arg_call_resume trips the perf gate. Its exec is stable at 0.19s across runs and rebases while the ratio floats 37.8x / 38.8x / 39.0x / 44.8x — the movement is entirely in the pypy denominator, which the harness rounds to 0.005–0.01s. A/B of the base and branch pyre-dynasm binaries earlier in this work measured the same user time, so this is the denominator-collapse class, not a behaviour change.
    • synth/str_search_index_bounds — red before this rebase and resolved now that main advanced; the MergePoint vable-identity fix is in the new base.
  • pyre/extra_tests/run.py --dynasm-only — 235/241. The six failures are pre-existing: three deliberate declines (builtin_list, builtin_tuple, builtin_slice), pickle_pypy_module (fails on CPython 3.14 too), and two open epics (stdlib_sys frame→function link, stdlib_sqlite _sqlite3 port).
  • cargo test -p pyre-interpreter --features dynasm --lib 430 passed; cargo test -p pyre-jit-trace --lib 300 passed; cargo fmt --all --check clean.

Known gap in the history: commit 728db88e17 does not compile standalone — getindex_repeat is still private in typedef.rs at that point while descroperation.rs already calls it through baseobjspace; the next commit moves and promotes it. The tip is fine; only git bisect is affected.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added Python 3.14-compatible iterator identities and expanded built-in API behavior.
    • Added improved WebAssembly script-path handling, stderr capture, and exit-code reporting.
    • Added support for additional filesystem, sorting, exception, and stream operations.
  • Bug Fixes

    • Improved garbage-collection safety during JIT and WebAssembly execution.
    • Corrected recursion tracking, sequence operations, argument validation, and exception formatting.
    • Prevented failures from unreachable branches and oversized generated code.
  • Tests

    • Expanded coverage for built-ins, iterators, descriptors, WebAssembly execution, and JIT edge cases.

Loading
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