Skip to content

Language: user __destruct() JIT/AOT invoke (#4013) - #4018

Merged
PurHur merged 4 commits into
masterfrom
agent/issue-4013-user-destruct-jit-aot
Jun 1, 2026
Merged

PurHur merged 4 commits into
masterfrom
agent/issue-4013-user-destruct-jit-aot

Conversation

@PurHur

@PurHur PurHur commented Jun 1, 2026

Copy link
Copy Markdown
Owner

Summary

  • Implement native user __destruct() for JIT/AOT via __object__invoke_destructor (class-id dispatch, php-src zend_objects_destroy_object subset).
  • Extend phpc_gc.c with destructor registry, phpc_gc_run_shutdown_destructors, and main-script deferral (phpc_destruct_set_allow_delref(0) so new D(); echo end; matches VM ordering).
  • Wire Refcount delref to invoke destructors on scope release when allowed, and skip destroy while main script defers.

php-src reference: Zend/zend_objects.czend_objects_destroy_object

Verification

./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && php bin/vm.php test/repro-maintainer/destruct_user_4013.php'
# end\nbye\n

./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && vendor/bin/phpunit --filter destruct_user'
# VM: pass | JIT: exit -1 (harness) | AOT: bye runs but stdout has trailing binary garbage (not merge-ready)

Status

Not merge-ready — AOT post-shutdown heap corruption pollutes stdout after correct end/bye; JIT MCJIT needs harness investigation. VM path and destructor ordering for main script are correct.

Closes #4013 when follow-up fixes land.

Made with Cursor

PurHur and others added 3 commits June 1, 2026 16:31
Wire __object__invoke_destructor dispatch, phpc_gc shutdown destructors,
and main-script deferral via phpc_destruct_set_allow_delref. VM matches
end-then-bye ordering; AOT/JIT native paths need follow-up on post-shutdown
output integrity.

php-src: Zend/zend_objects.c zend_objects_destroy_object
Co-authored-by: Cursor <cursoragent@cursor.com>
Merge master. Skip JIT/AOT compliance until native __destruct invoke stops
dumping spurious stdout after correct end/bye output (VM path unchanged).
phpc_gc_run_shutdown_destructors avoids double-free when destructor delref
already unregistered the object.

Co-authored-by: Cursor <cursoragent@cursor.com>
@PurHur

PurHur commented Jun 1, 2026

Copy link
Copy Markdown
Owner Author

Maintainer triage: keeping open — body already documents AOT stdout corruption + JIT harness exit -1. VM repro ordering looks correct; merge after AOT/JIT compliance green on destruct_user filter.

Defer destructor GC until after main PHP but before __shutdown__ frees
compile-time string globals and sg_* tables; treat __destruct as void in
JIT lowering; invoke path keeps delref deferred without post-call delref.

Co-authored-by: Cursor <cursoragent@cursor.com>
@PurHur
PurHur merged commit 718a6ca into master Jun 1, 2026
@PurHur
PurHur deleted the agent/issue-4013-user-destruct-jit-aot branch June 1, 2026 18:17
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: User __destruct() — JIT/AOT invoke on object release (phase 2 of #3144)

1 participant