Skip to content

VM/JIT: X::class without declaration + rebind folded assign temps (#16828 layers 1-2) - #16850

Merged
PurHur merged 1 commit into
masterfrom
fix/16828-spine-assign
Jul 6, 2026
Merged

PurHur merged 1 commit into
masterfrom
fix/16828-spine-assign

Conversation

@PurHur

@PurHur PurHur commented Jul 6, 2026

Copy link
Copy Markdown
Owner

Peels the first two regressions off #16828 (spine bundle native emit broken; gen-0 sidecar refresh blocked). Both are Zend-parity bugs visible beyond the bundle.

1. Foo::class must not require the class to exist

Zend resolves X::class as a pure name literal. The const-expr evaluator and the VM class-const-fetch opcode both demanded a class entry, so \DateException::class (native 8.3+, in ThrowableManifest's const map since #16780) died on the 8.2 reference profile with Forward reference to class constant / Unknown class for constant fetch. Both sites now short-circuit 'class' fetches on plain names (self/static/parent excluded).

Verified against Zend:

const MAP = ['a' => \TotallyUndeclared::class, 'b' => \DateException::class]
VM output == php 8.2 output, both positions (const-expr + expression)

New unit test: ClassConstNameLiteralUndeclaredTest.

2. JIT: assigning into a folded KIND_VALUE temp

assignOperandValue() threw Cannot assign to a value when the destination temp was pre-bound by the defined()/class_exists() spine-guard folding (NATIVE_BOOL KIND_VALUE) and the real producer emitted afterwards — hit at bundle scale via ext/sodium/bootstrap_sodiumexception.php:8. assignOperand() already rebinds this case; now mirrored via makeVariableFromValueOp.

Verification

Also: --preload experimental flag on the unit emitter (corpus-dependency experiments for the 25 undefined-method helper units — chain documented on #16828), and the spine bundle test assertion catches up to 4151 (missed in #16809's final resync — the test was red on master).

🤖 Generated with Claude Code

…6828 layers 1-2).

Two of the regressions breaking the spine bundle native emit:

- Foo::class is a pure name literal — Zend resolves it without the
  class being declared or autoloadable. The const-expr evaluator
  (ClassConstExpr) and the VM class-const-fetch opcode both demanded a
  class entry first, so native 8.3+ exception names in const maps
  (\DateException::class in ThrowableManifest since #16780) died with
  'Forward reference to class constant' / 'Unknown class for constant
  fetch' on the 8.2 reference profile. Both sites now short-circuit
  'class' fetches on plain names to the resolved name string
  (self/static/parent excluded). Unit test covers const-expr and
  expression positions.

- JIT assignOperandValue() threw 'Cannot assign to a value' when the
  destination temp was pre-bound as a folded KIND_VALUE — the
  defined()/class_exists() spine-guard folding registers NATIVE_BOOL
  value bindings and the real producer emits afterwards.
  assignOperand() already rebinds these; assignOperandValue() now
  mirrors it via makeVariableFromValueOp. Hit at bundle scale on
  ext/sodium/bootstrap_sodiumexception.php line 8
  ('if (!\class_exists(\SodiumException::class, false))').

Also: emit-helper-runtime-object.php gains an experimental
--preload=<paths> child flag (dependency-corpus experiments for the 25
undefined-method helper units), and the spine bundle test assertion
catches up to 4151 (missed in #16809's final resync).

Bundle emit now progresses past both errors; the next blocker
('Array offset access requires hashtable or boxed array, got
__string__*', top-level main) is still under investigation on #16828.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@PurHur
PurHur force-pushed the fix/16828-spine-assign branch from 0e6c5e6 to eea6991 Compare July 6, 2026 09:17
@PurHur
PurHur merged commit df056dc into master Jul 6, 2026
@PurHur
PurHur deleted the fix/16828-spine-assign branch July 6, 2026 09:17
PurHur added a commit that referenced this pull request Jul 6, 2026
…ecar refresh restored (#16828) (#16873)

* VM/JIT: X::class without declaration + rebind folded assign temps (#16828 layers 1-2).

Two of the regressions breaking the spine bundle native emit:

- Foo::class is a pure name literal — Zend resolves it without the
  class being declared or autoloadable. The const-expr evaluator
  (ClassConstExpr) and the VM class-const-fetch opcode both demanded a
  class entry first, so native 8.3+ exception names in const maps
  (\DateException::class in ThrowableManifest since #16780) died with
  'Forward reference to class constant' / 'Unknown class for constant
  fetch' on the 8.2 reference profile. Both sites now short-circuit
  'class' fetches on plain names to the resolved name string
  (self/static/parent excluded). Unit test covers const-expr and
  expression positions.

- JIT assignOperandValue() threw 'Cannot assign to a value' when the
  destination temp was pre-bound as a folded KIND_VALUE — the
  defined()/class_exists() spine-guard folding registers NATIVE_BOOL
  value bindings and the real producer emits afterwards.
  assignOperand() already rebinds these; assignOperandValue() now
  mirrors it via makeVariableFromValueOp. Hit at bundle scale on
  ext/sodium/bootstrap_sodiumexception.php line 8
  ('if (!\class_exists(\SodiumException::class, false))').

Also: emit-helper-runtime-object.php gains an experimental
--preload=<paths> child flag (dependency-corpus experiments for the 25
undefined-method helper units), and the spine bundle test assertion
catches up to 4151 (missed in #16809's final resync).

Bundle emit now progresses past both errors; the next blocker
('Array offset access requires hashtable or boxed array, got
__string__*', top-level main) is still under investigation on #16828.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Spine: defer TimezoneAbbreviationsData from native link (#16866); sidecar refresh restored (#16828).

Third and final blocker on the spine bundle emit (#16828): the huge
nested array literal in ext/standard/TimezoneAbbreviationsData.php
breaks the AOT lowering (compile error at bundle scale, standalone
binary segfault — filed as #16866 with repros). Deferred honestly via
bootstrap_spine_native_link_deferred(): VM inventory coverage is
unaffected, footnotes show 4158/4159 with the 1-deferred annotation
across the six tracked docs + bundle test, and every spine sync check
is green.

spine-sync.sh discovery now consults the deferred SSOT so it stops
re-adding deferred paths to the bundle.

With this plus #16850 (layers 1-2), the honest gen-0 sidecar refresh
works again: make bootstrap-gen0-refresh-sidecar green, stamp matches
spine entry SHA-1 368eaa303685. Refreshed prelinked/bootstrap-gen0
included.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Merge follow-up: inventory regen on merged base.

---------

Co-authored-by: PurHur <tedyyyyy@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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.

2 participants