Skip to content

Zend: user opcode DISPATCH runs on a stale frame in the TAILCALL VM. - #24109

Closed
devnexen wants to merge 3 commits into
php:PHP-8.6from
devnexen:gh24081
Closed

devnexen wants to merge 3 commits into
php:PHP-8.6from
devnexen:gh24081

Conversation

@devnexen

@devnexen devnexen commented Oct 3, 2026

Copy link
Copy Markdown
Member

Fix #24081

ZEND_VM_DISPATCH() ran the CALL variant of the handler and returned its next opline to execute_ex(), whose execute_data still pointed at the entry frame. It now tail calls the TAILCALL variant of the handler.

Fix php#24081

ZEND_VM_DISPATCH() ran the CALL variant of the handler and returned its
next opline to execute_ex(), whose execute_data still pointed at the
entry frame. It now tail calls the TAILCALL variant of the handler.

@arnaud-lb arnaud-lb left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me!

@arnaud-lb

Copy link
Copy Markdown
Member

NB: This should target 8.5

@devnexen devnexen closed this in 2cf7ad0 Oct 9, 2026
@LamentXU123

Copy link
Copy Markdown
Member

@devnexen

devnexen commented Oct 10, 2026 •

Copy link
Copy Markdown
Member Author

I think can be fixed with zend_test.observer.show_output=1 (just because I remember someone fixed case like this that way not so long ago). will push a PR soon-ish

@devnexen
devnexen deleted the gh24081 branch October 10, 2026 08:12
lisachenko pushed a commit to lisachenko/z-engine that referenced this pull request Oct 10, 2026
#280)

php/php-src#24109 (merged into PHP-8.6 as 2cf7ad0) makes the generated
ZEND_USER_OPCODE_SPEC_TAILCALL_HANDLER resume the DISPATCH result inside
the tail-call chain instead of returning it to execute_ex()'s stale
frame, so OpCode::setHandler() no longer needs to refuse on
VM_KIND_TAILCALL. Remove the guard, its exception factory, the issue-280
probe ladder and the dispatch-only diagnose workflow; keep Core::vmKind()
as plain engine introspection, and keep the every-leg hook coverage the
guard test introduced as OpCodeHookLifecycleTest (the gap that let #280
ship unnoticed was that all other hook tests are internal-group only).
Docs now record the bug as fixed upstream rather than as a live caveat.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U4cKi87mVQ896uSrw592fG
lisachenko pushed a commit to lisachenko/zdebug that referenced this pull request Oct 10, 2026
… fixed

php-src fixed the user-opcode dispatch under the tail-call VM
(lisachenko/z-engine#280, resolved by php/php-src#24109 merged into
PHP-8.6), and current 8.6 nightlies run engine hooks cleanly on Apple
Silicon, so the experimental escape hatch comes off: the arm64 + 8.6 leg
fails the workflow like every other leg again. Docs record the bug as
fixed instead of as a platform exception.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U4cKi87mVQ896uSrw592fG
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] User opcode handlers resume execution against a stale frame under ZEND_VM_KIND_TAILCALL

3 participants