Skip to content

VM: fix run-stack push for nested return <call>() (#1885) - #1910

Merged
PurHur merged 1 commit into
masterfrom
fix/1885-run-stack-push
May 25, 2026
Merged

PurHur merged 1 commit into
masterfrom
fix/1885-run-stack-push

Conversation

@PurHur

@PurHur PurHur commented May 25, 2026

Copy link
Copy Markdown
Owner

Summary

PR #1897 landed compiler slot reuse for return <call>(), but nested returns still produced empty output because Context::push() used a broken chained assignment:

$this->runStack = $this->runStack->prev = new RunStackEntry($frame);

That attached the new entry as main.prev instead of the stack top, so the caller frame was lost after the first nested call and late_static_binding.phpt stayed empty.

This PR fixes push() to chain entries correctly, stops clearing returnVar on TYPE_RETURN_VOID when it may alias the caller slot, and resolves indirect values on TYPE_RETURN.

Test plan

  • NestedReturnVmTest (nested return f(), void inner call + return, late static return static::tag())
  • VMTest late_static_binding compliance PHPT
  • Docker php-compiler:22.04-dev (no GHA)

Follow-up to merged #1897; completes #1885 on master.

Made with Cursor

Context::push() used a chained assignment that wired the new entry as
main.prev instead of the stack top, so nested calls lost the caller
frame and returns never resumed main (empty PHPT output).

Also stop nulling returnVar on TYPE_RETURN_VOID when it aliases the
caller's result slot, and resolve indirect values on TYPE_RETURN.

Compiler slot-reuse from #1885 remains; late_static_binding.phpt passes.

Co-authored-by: Cursor <cursoragent@cursor.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.

1 participant