Skip to content

Language: isolate generator try/catch across yield (#22869)#22878

Merged
PurHur merged 1 commit into
masterfrom
agent/issue-22869-generator-getreturn
Jul 24, 2026
Merged

Language: isolate generator try/catch across yield (#22869)#22878
PurHur merged 1 commit into
masterfrom
agent/issue-22869-generator-getreturn

Conversation

@PurHur

@PurHur PurHur commented Jul 24, 2026

Copy link
Copy Markdown
Owner

Summary

  • Isolate activeTryHandlerFrames / tryMergeBlockIds across generator suspend/resume so a suspended generator try/catch cannot absorb caller uncaught exceptions (silent exit 0).
  • After generator try/finally with no catch, bubble via GeneratorUncaughtThrow instead of raiseUncaughtException while still inside advance (keeps foreach caller catch working).
  • Compliance PHPT + repro for uncaught Generator::getReturn() after throw→yield-in-catch.

Closes #22869

php-src reference

  • Zend/zend_generators.czend_generator_get_return / throw→catch yield suspension

PHP implementation

  • lib/VM.phpadvanceGeneratorIteration try-handler isolation; resumeCatchAfterFinally generator/fiber bubble
  • lib/VM/GeneratorState.phpsuspendedTryHandlerFrames / suspendedTryMergeBlockIds

Test plan

  • Issue repro: php bin/vm.php test/repro/issue_22869_generator_getreturn_uncaught.php → fatal + exit 255
  • ./script/phpunit.sh --filter GeneratorVMTest → OK (33)
  • ./script/ci-fast.sh (AOT smoke slow under host load; not required for this VM-only path)

Verification

$ php bin/vm.php test/repro/issue_22869_generator_getreturn_uncaught.php; echo exit=$?
A
1
B
2
C
PHP Fatal error:  Uncaught Exception: Cannot get return value of a generator that hasn't returned ...
exit=255

$ ./script/phpunit.sh --filter GeneratorVMTest
OK (33 tests, 36 assertions)

Trust probe (this run)

Made with Cursor

…urn fatals (#22869)

Suspended generator try handlers were left in activeTryHandlerFrames and swallowed
caller exceptions (silent exit 0). Save/restore try state per generator resume and
bubble finally-then-uncaught throws via GeneratorUncaughtThrow.

Co-authored-by: Cursor <cursoragent@cursor.com>
@PurHur
PurHur merged commit 8b4ed9f into master Jul 24, 2026
1 check failed
@PurHur
PurHur deleted the agent/issue-22869-generator-getreturn branch July 24, 2026 13:22
@PurHur
PurHur restored the agent/issue-22869-generator-getreturn branch July 24, 2026 13:22
PurHur added a commit that referenced this pull request Jul 24, 2026
Post-#22873 merge #22878 moved live lowering_source_fingerprint to
d65fbcf5… while the committed stamp stayed at 0859c4ca…, redding
north-star5-verify-fast step 4f-m and user_release_ready. Restamp only;
honest verified-fresh remains on #22642/#22717.

Co-authored-by: PurHur <PurHur@users.noreply.github.com>
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.

Regression: Generator::getReturn() while still valid — uncaught Exception exits 0 silently (re-#13027, Zend/zend_generators.c)

1 participant