Skip to content

Language: builtin Exception/Error/Throwable VM classes (#195) - #3215

Merged
PurHur merged 9 commits into
masterfrom
agent/issue-195-exception-classes
May 31, 2026
Merged

PurHur merged 9 commits into
masterfrom
agent/issue-195-exception-classes

Conversation

@PurHur

@PurHur PurHur commented May 29, 2026

Copy link
Copy Markdown
Owner

Summary

Rebased on master (May 2026): builtin Throwable / Exception / Error hierarchy is already registered via #3371. This PR closes the remaining #195 gap — catch-variable use after merge resume.

  • Set inheritUndefinedLocals on the try/catch merge block so enterMatchingCatchHandler can build the post-catch resume frame without Could not resolve argument when the catch body uses $e->getMessage() (etc.).

php-src reference

  • Zend/zend_exceptions.c — catch frame setup + merge/finally resume control flow

Verification

./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && php bin/vm.php -r '"'"'try { throw new Exception("x"); } catch (Exception $e) { echo $e->getMessage(); }'"'"''
# x

./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && vendor/bin/phpunit --filter ExceptionBuiltin test/unit/ExceptionBuiltinTest.php'
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && vendor/bin/phpunit --filter exception_throw test/compliance/VMTest.php'
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && vendor/bin/phpunit --filter TryCatchCompliance test/unit/TryCatchComplianceTest.php'

All green on rebased branch.

Closes #195

@PurHur

PurHur commented May 30, 2026

Copy link
Copy Markdown
Owner Author

Worker lane A (continuation): Rebased onto latest master and re-verified.

Verification (May 2026)

./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && php bin/vm.php -r '"'"'try { throw new Exception("x"); } catch (Exception $e) { echo $e->getMessage(); }'"'"''
# x

./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && vendor/bin/phpunit test/unit/ExceptionBuiltinTest.php test/compliance/VMTest.php --filter exception'
# OK (7 tests)

Master without this patch still fails with Could not resolve argument on the catch repro.

@PurHur

PurHur commented May 31, 2026

Copy link
Copy Markdown
Owner Author

Update (cursor-agent-lane-a)

Added Zend getLine() parity for rethrow and deferred throw paths:

  • TYPE_NEW arg3 — record creation-site line on Throwable before __construct
  • stampThrowLine — skip when line already set (rethrow preserves original)
  • resolveCatchVarSlot — register catch var on catch-body block so throw $e works in nested try without a prior read

New compliance: exception_throw_rethrow.phpt, exception_throw_deferred.phpt, exception_throw_code.phpt

Verification

PHP_COMPILER_CI_SINGLE_CONTAINER=0 ./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && vendor/bin/phpunit test/unit/ExceptionBuiltinTest.php test/unit/TryCatchComplianceTest.php test/compliance/VMTest.php --filter exception_throw'
# OK (24 tests)

php-src: Zend/zend_exceptions.c

PurHur added a commit that referenced this pull request May 31, 2026
Add ExceptionBuiltinTest subprocess coverage matching compliance PHPTs;
Runtime-only unit tests pass on master while stdin VM CLI still fails
with merge resume frame setup until #3215 lands.

php-src: Zend/zend_exceptions.c (catch frame + merge resume)
Co-authored-by: Cursor <cursoragent@cursor.com>
PurHur and others added 9 commits May 31, 2026 09:43
Set inheritUndefinedLocals on the try/catch merge block so enterMatchingCatchHandler
can build the merge resume frame without "Could not resolve argument" when dispatching
from TYPE_THROW into a catch handler.

php-src: Zend/zend_exceptions.c (catch frame + finally/merge resume)
Co-authored-by: Cursor <cursoragent@cursor.com>
Record php-cfg startLine on TYPE_THROW arg2 and update the exception
object at throw time so getLine() matches Zend for caught throws.

php-src: Zend/zend_exceptions.c (zend_exception_set_previous)
Co-authored-by: Cursor <cursoragent@cursor.com>
Guards throw-site line stamping (TYPE_THROW arg2) and file path on
caught Exception objects per Zend zend_exceptions.c parity.

Co-authored-by: Cursor <cursoragent@cursor.com>
…195)

Record new-expression startLine on TYPE_NEW for Throwable objects and only
stamp TYPE_THROW line when still unset (Zend zend_exceptions.c parity).
Register catch variables on catch-body blocks so throw $e works without a
prior read in nested try handlers.

php-src: Zend/zend_exceptions.c
Co-authored-by: Cursor <cursoragent@cursor.com>
Add ExceptionBuiltinTest subprocess coverage matching compliance PHPTs;
Runtime-only unit tests pass on master while stdin VM CLI still fails
with merge resume frame setup until #3215 lands.

php-src: Zend/zend_exceptions.c (catch frame + merge resume)
Co-authored-by: Cursor <cursoragent@cursor.com>
Add compliance PHPT and unit test for merge-block resume when the catch
body contains an inner try/catch before using the caught exception.

Co-authored-by: Cursor <cursoragent@cursor.com>
…lly block (#195)

When a catch body references \$e, php-cfg merge lowering incorrectly registers
\$e as a finally-block inherited arg. Finally runs before catch on throw, so
getFrame failed with "Could not resolve argument". Mark the finally CFG block
inheritUndefinedLocals so catch locals are not required during finally dispatch.

Adds compliance PHPT and unit test for try/catch/finally with getMessage().

php-src: Zend/zend_exceptions.c — finally-before-catch unwind order
Co-authored-by: Cursor <cursoragent@cursor.com>
On matching catch, run the catch body before finally (php-src zend_exceptions.c).
Unmatched throws still run finally before propagating. Fixes PHPT/unit expectations.

Co-authored-by: Cursor <cursoragent@cursor.com>
Update testFinallyRunsBeforeCatchOnThrow expectation to match Zend
zend_exceptions.c order (catch body before finally on matched throw).

Co-authored-by: Cursor <cursoragent@cursor.com>
@PurHur
PurHur force-pushed the agent/issue-195-exception-classes branch from 7fd1971 to b372531 Compare May 31, 2026 09:43
@PurHur
PurHur merged commit 3c7a885 into master May 31, 2026
@PurHur
PurHur deleted the agent/issue-195-exception-classes branch May 31, 2026 09:43
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.

Language: throw expressions and Exception object propagation

1 participant