◐ Shell
clean mode source ↗

A few README tweaks by nedbat · Pull Request #73 · python/cpython

SonicField added a commit to SonicField/cpython that referenced this pull request

@SonicField

Convert HIRBuilder::emitInlineExceptionMatch — the largest, most
complex method in the original 7-method remaining set (185-line C++
source with inline bytecode dispatch + 5-block + D-1774910012
invariant). Mirrors C++ HIRBuilder::emitInlineExceptionMatch @
builder.cpp:1329 (pre-conversion).

Tier 5 milestone: 70.1%. emitInlineExceptionMatch is the FIRST method
shipping with both encoding-clean AND invariant-preserved validation
per pythia python#73 (chat 14:39:something) gap closure: D-1774910012
falsifier (3 tests, 595734c) landed pre-port and preserved post-port
per testkeeper 8-test gate at chat 15:31:50Z.

W25-defer-aware A1 stub-heavy bytecode-parse design (theologian
chat 14:48:10Z pre-audit): ZERO new bridges. Pre-audit bridge-count
gate per supervisor 14:16:55Z policy (>1 → HALT for Option B
reconsideration); this method passed at 0 ≤ 1.

5 phases per pre-audit:
  P1: getitem CallStatic dispatch (pointer pre-resolved by C++ stub
      via JITRT_DictGetItem vs PyObject_GetItem)
  P2: exc_tc setup with depth-trim + LoadConst exc_type +
      JITRT_MatchAndClearException CallStatic + match_block /
      deopt_block CondBranch
  P3: match_tc setup + Py_None placeholder push (D-1774910012 PA)
      + bytecode dispatch loop (10 cases + default)
  P4: deopt_tc setup with re-push left/right + Snapshot + Deopt
  P5: ok block — RefineType in-place SSA-rename

3 separate PhxTranslationContext objects (PB):
  exc_tc copies from tc.frame
  match_tc copies from EXC_TC.FRAME (depth-trimmed)
  deopt_tc copies from TC.FRAME (original, NOT exc_tc)

Approach: C++ stub iterates info.except_body bytecodes via
BytecodeInstruction.nextInstr() and builds an opcode array with
pre-resolved const_obj (LOAD_CONST/RETURN_CONST) and
jump_target_block (JUMP_BACKWARD*). C body switches on the array.
Sibling C emit functions (hir_builder_emit_swap_c / load_fast_c /
store_fast_c / binary_op_c) called directly with extern decls.

OpcodeArrayEntry struct mirrored on C++ + C side (5 fields per entry:
opcode, oparg, base_offset, const_obj, jump_target_block). C++
static_assert on size sanity check.

D-1774910012 invariant (PA pitfall): Py_None placeholder pushed on
match_tc.frame.stack BEFORE dispatch loop; POP_EXCEPT case pops the
placeholder. Mirrors the inline exception handler deopt fix at
28b4ee1 from 2026-04-01. Failure mode: closure LOAD_DEREF in
except blocks → deopt stack mismatch → exc_info chain corruption
post-threshold (only triggers post-1000 calls). Preserved via the
falsifier in test_phoenix_jit_inline_except_closure.py (push 595734c).

Bytecode dispatch loop opcodes (10 handled + default):
  POP_EXCEPT (pops placeholder per PA), POP_TOP (pops TOS),
  SWAP, LOAD_FAST/_CHECK/_AND_CLEAR (3 cases), LOAD_CONST,
  STORE_FAST, BINARY_OP, RETURN_CONST, RETURN_VALUE,
  JUMP_BACKWARD/_NO_INTERRUPT (2 cases), default → deopt

Pitfalls addressed inline (theologian chat 14:48:10Z 8 pitfalls):
  PA: D-1774910012 Py_None placeholder + POP_EXCEPT pops
  PB: 3-TC frame-copy origins (each from correct source frame)
  PC: handler.depth depth-trim while-loop in P2
  PD: dispatch loop default → deopt (silent path; supervisor
      chat 15:30:08Z (b) JIT_DCHECK addition deferred to follow-up
      commit pending design clarification)
  PE: emitted_terminator semantics replaced by `goto match_loop_done`
      pattern in C
  PF: phx_frame_state_destroy on ALL 3 TCs at function end
  PG: sibling C emit functions take match_tc explicitly
  PH: stub-built opcode array with 5 fields per entry

JITRT_MatchAndClearException pointer passed from C++ stub via void*
(vs C-side direct reference) — avoids C-vs-C++ name mangling at
link time. Same pattern as getitem_fn.

testkeeper iter cycle:
  iter 1: 5 errors (extern decl signature mismatches on sibling
    emit functions + arg counts on LOAD_FAST/STORE_FAST)
  iter 2: 2 errors (binary_op_c PhxTranslationContext* sig +
    BCOffset→int conversion)
  iter 3: 1 link error (JITRT_MatchAndClearException name mangling)
  iter 4: PASS — JIT_BUILD_EXIT=0, full --clean BUILD_EXIT=0,
    8-test gate including D-1774910012 falsifier 8/8 PASS

W26 gate-hardening not triggered (clean build path). ZERO new
bridges held. Per pythia python#74 (chat 15:29:something): PA invariant
validated by falsifier; PB-PH rely on theologian's spec + reviewer
inspection. Mutation test per supervisor chat 15:30:08Z (a) is
gating push 59 PUSH AUTHORIZED — testkeeper to execute before
dual-arch.