Skip to content

Stdlib: split process JIT helpers for AOT exec capture (#10492)#16478

Merged
PurHur merged 3 commits into
masterfrom
agent/stdlib-10492-process-aot-clean
Jul 5, 2026
Merged

Stdlib: split process JIT helpers for AOT exec capture (#10492)#16478
PurHur merged 3 commits into
masterfrom
agent/stdlib-10492-process-aot-clean

Conversation

@PurHur

@PurHur PurHur commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Summary

  • Split ProcessJitHelper into lazy-linked units: ProcessPhpcRunCommandJitHelper (iterateKeyed env), ProcessExecCaptureNativeJitHelper (phpc_native_ht_* + shell_exec capture), keeping shell/escape helpers in a minimal ProcessJitHelper.php.
  • Add phpc_native_ht_set_string_key_long + ParseStrNativeOpsJit::setStringKeyLong for native hashtable status fields.
  • Fix ObOutputJitBridge / ObOutputUserScriptLlvm insert-block restore when ensureLinked() is called nested from JitExec::writeLinesToStdout.

Root cause

AOT compile of any script using shell_exec/exec/passthru/system nested-JITed all of ProcessJitHelper.php, hitting HashTable::iterateKeyed() (object::iteratekeyed) and VM HashTable::add() in stream loops. Master fails at compile with Call to undefined method object::iteratekeyed().

Verification

# VM repro (php-src-strict) — PASS
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && php bin/vm.php test/repro/maintainer_gap_system_passthru_ob.php'
# system_ob_ok=1 / passthru_ob_ok=1

# Unit — PASS
./script/docker-exec.sh -- bash -lc 'vendor/bin/phpunit test/unit/ProcessRuntimeShrinkTest.php test/unit/ExecJitRuntimeShrinkTest.php'

# AOT shell_exec / exec — compile phase PASS (link may need -lcrypto in image)
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && php bin/compile.php -o /tmp/x -r "\$o=[]; exec(\"echo hi\", \$o); echo count(\$o);" && echo compile_ok'
# exit 2 = link only (no LLVM verify failure)

# AOT system_passthru fixture — FAIL (LLVM verify)
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && vendor/bin/phpunit test/aot/AotTest.php --filter system_passthru'
# Module verification: AddrSpaceCast source must be a pointer in JitExec::writeLinesToStdout ob-echo path

Remaining blocker (not merged)

passthru()/system() AOT compile reaches JitExec::writeLinesToStdout but LLVM verify fails (AddrSpaceCast source must be a pointer) when routing captured lines through user-script ob echo (ObOutputUserScriptLlvm). Next: align __phpc_ob_echo_substr arg lowering with EmbedObEchoBridge in user-script AOT mode.

Closes #10492 when system_passthru_ob AOT fixture is green.

Made with Cursor

Split ProcessJitHelper nested-JIT units (phpc_run_command iterateKeyed,
exec capture hashtable build) into lazy-linked helpers with phpc_native_ht_*
for AOT. Fix ObOutput bridge insert-block restore on nested ensureLinked.
shell_exec/exec AOT compile green; passthru+ob LLVM verify remains.

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

PurHur commented Jul 5, 2026

Copy link
Copy Markdown
Owner Author

Maintainer triage 2026-07-05: VM repro + unit tests green per PR body; AOT system_passthru LLVM verify still red — holding merge until ObOutput user-script lowering fixed. Supersedes overlap with #16470 (iterateKeyed split landed here).

@PurHur

PurHur commented Jul 5, 2026

Copy link
Copy Markdown
Owner Author

Maintainer triage 2026-07-05: VM repro + unit tests pass per PR body; merge blocked on AOT AddrSpaceCast verify in JitExec::writeLinesToStdout / ObOutputUserScriptLlvm. Re-run vendor/bin/phpunit test/aot/AotTest.php --filter system_passthru before merge.

PurHur and others added 2 commits July 5, 2026 19:02
)

Route exec stdout through __phpc_ob_append_bytes with correct string structGep
lowering, lazy-link ObOutputExecCaptureJitHelper for user-script AOT (avoids full
ObOutputJitHelper nested JIT / HashTable::popLast), and fix JitExec CFG so stdout
write loops do not terminate proc_ok early.

AOT compile of system_passthru_ob reaches link-only (LLVM verify green); VM repro
unchanged green.

Co-authored-by: Cursor <cursoragent@cursor.com>
Resolve conflicts keeping lazy ObOutputExecCaptureRuntime ob stack and
JitExec CFG/append_bytes lowering from #10492 work.

Co-authored-by: Cursor <cursoragent@cursor.com>
@PurHur PurHur merged commit 11724d5 into master Jul 5, 2026
@PurHur PurHur deleted the agent/stdlib-10492-process-aot-clean branch July 5, 2026 19:03
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.

Stdlib: system()/passthru() bypass active output buffer — ob_get_clean() empty (ext/standard/exec.c)

1 participant