Skip to content

fix(core): release owning call-result/argument temporaries when a call throws - #428

Closed
Guikingone wants to merge 1 commit into
illegalstudio:mainfrom
Guikingone:fix/399-call-result-temp-leaks-on-throw
Closed

fix(core): release owning call-result/argument temporaries when a call throws#428
Guikingone wants to merge 1 commit into
illegalstudio:mainfrom
Guikingone:fix/399-call-result-temp-leaks-on-throw

Conversation

@Guikingone

Copy link
Copy Markdown
Contributor

When a chained method call like $t->make()->boom() throws, the intermediate owning temporary from make() was leaked because longjmp bypassed the straight-line release code. This adds a runtime pending- cleanup stack (TLS global array) that records owning temporaries before a potentially-throwing call. If the call throws, __rt_throw_current drains the stack via __rt_eh_drain (calling __rt_decref_any on each entry) before longjmp. On the normal path, eh_pop removes the entry after the call returns.

New EIR ops: EhPush (1 operand) and EhPop (0 operands). New runtime helpers: __rt_eh_push, __rt_eh_pop, __rt_eh_drain (AArch64 + x86_64).
New globals: _eh_cleanup_stack (2048 bytes), _eh_cleanup_top (8 bytes).

Fixes #399

When a chained method call like $t->make()->boom() throws, the
intermediate owning temporary from make() was leaked because longjmp
bypassed the straight-line release code. This adds a runtime pending-
cleanup stack (TLS global array) that records owning temporaries
before a potentially-throwing call. If the call throws, __rt_throw_current
drains the stack via __rt_eh_drain (calling __rt_decref_any on each
entry) before longjmp. On the normal path, eh_pop removes the entry
after the call returns.

New EIR ops: EhPush (1 operand) and EhPop (0 operands).
New runtime helpers: __rt_eh_push, __rt_eh_pop, __rt_eh_drain
(AArch64 + x86_64).
New globals: _eh_cleanup_stack (2048 bytes), _eh_cleanup_top (8 bytes).

Fixes illegalstudio#399
@Guikingone
Guikingone force-pushed the fix/399-call-result-temp-leaks-on-throw branch from a5162c0 to e61819b Compare July 2, 2026 16:18
@github-actions github-actions Bot added area:codegen Touches target-aware assembly or backend lowering. area:eir Touches EIR definitions, lowering, validation, or passes. area:runtime Touches runtime helpers, GC, ownership, or bridge runtimes. size:s Small pull request. type:fix Corrects broken or incompatible behavior. labels Jul 13, 2026
@nahime0

nahime0 commented Aug 29, 2026

Copy link
Copy Markdown
Member

Closing this draft. Do not close #399.

The leak is still real on main. This patch is not the fix: the cleanup stack is process-global (not TLS), would not survive fiber switch, already failed Linux PIE link, and the codegen paths it edits no longer exist.

Please do not rebase e61819bb. Salvage is the three destructor tests and the problem statement. A real fix belongs on current main, registered into the existing activation / fiber story, not a second global stack. #775 stays separate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:codegen Touches target-aware assembly or backend lowering. area:eir Touches EIR definitions, lowering, validation, or passes. area:runtime Touches runtime helpers, GC, ownership, or bridge runtimes. size:s Small pull request. type:fix Corrects broken or incompatible behavior.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Owning call-result/argument temporary leaks when the call throws

2 participants