Skip to content

Conversation

@khaledalam
Copy link

@khaledalam khaledalam commented Dec 26, 2025

Inspired by Zig's "defer", it schedules a block to run when the current function exits (return, exception, or natural end), executed in LIFO order, aimed at safer cleanup without repetitive try/finally scaffolding.

  • Add T_DEFER token and ZEND_AST_DEFER AST node
  • Compile defer blocks by emitting a skip JMP + trailing JMP back
  • Add DEFER_PUSH/DEFER_RUN VM handlers using per-call defer_stack
  • Run defers before explicit/implicit returns (LIFO)
  • Add initial PHPT tests (basic/LIFO/early return/vars); exception unwind not yet supported

- Add T_DEFER token and ZEND_AST_DEFER AST node
- Compile defer blocks by emitting a skip JMP + trailing JMP back
- Add DEFER_PUSH/DEFER_RUN VM handlers using per-call defer_stack
- Run defers before explicit/implicit returns (LIFO)
- Add initial PHPT tests (basic/LIFO/early return/vars); exception unwind not yet supported
@iluuu1994
Copy link
Member

iluuu1994 commented Dec 26, 2025

Hi @khaledalam. I'm skeptical of this approach.

It effectively mirrors FAST_CALL/FAST_RETURN, which is already quite complex, and causes issues for the optimizer. Deferring until return is very problematic for loops, which with finally would trigger at the end of the current iteration. This will scheule a huge number of defers for long-running functions. Furthermore, any referenced variable in the defer might have long changed to something else by the time the defer is executed.

FWIU Zig executes defer at the end of the current scope. PHP doesn't have true scopes, which would make that somewhat unprecedented. But deferring until return is a no-go, IMO. Zig also doesn't need to think about exceptions, as those aren't a thing there.

Also note there are two recent, competing RFCs that are similar.

https://wiki.php.net/rfc/optin_block_scoping
https://wiki.php.net/rfc/context-managers

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants