Split out from the #107 review (comment on src/HotSwap/HotSwap.php:190).
HotSwap::prepare() currently compiles the donor class entry via an eval()-based unpublish/eval/republish shuffle. The maintainer's concern: eval() executes arbitrary code and is an unsafe mechanism for a hot-swap API. Replace it with a compile path that does not run user code as a side effect of preparing a swap:
- Parse the source with the existing
Compiler::parseString() → engine AST.
- Compile that AST to a
zend_op_array / class entry directly (investigate zend_compile_string/zend_ast-driven compilation without entering the VM), producing the donor class entry in a scratch/unpublished table.
- Keep the existing dtor-disabled donor lifecycle (donor destroyed after apply/discard) and the atomic stage-commit-rollback around it.
Acceptance: the donor is materialized without executing top-level statements from the source; a source whose body has side effects (e.g. a top-level echo/function call outside the class) does not run them during prepare(); existing HotSwap delta tests still pass. Until this lands, HotSwap::prepare() documents the eval-based compile as an interim mechanism.
Deferred from #107 so the encapsulation review round there can merge independently.
Split out from the #107 review (comment on
src/HotSwap/HotSwap.php:190).HotSwap::prepare()currently compiles the donor class entry via aneval()-based unpublish/eval/republish shuffle. The maintainer's concern:eval()executes arbitrary code and is an unsafe mechanism for a hot-swap API. Replace it with a compile path that does not run user code as a side effect of preparing a swap:Compiler::parseString()→ engine AST.zend_op_array/ class entry directly (investigatezend_compile_string/zend_ast-driven compilation without entering the VM), producing the donor class entry in a scratch/unpublished table.Acceptance: the donor is materialized without executing top-level statements from the source; a source whose body has side effects (e.g. a top-level
echo/function call outside the class) does not run them duringprepare(); existingHotSwapdelta tests still pass. Until this lands,HotSwap::prepare()documents the eval-based compile as an interim mechanism.Deferred from #107 so the encapsulation review round there can merge independently.