Skip to content

AOT: fix request_parse_body compile/link (#5965)#17316

Open
PurHur wants to merge 5 commits into
masterfrom
agent/issue-5965-request-parse-body-aot
Open

AOT: fix request_parse_body compile/link (#5965)#17316
PurHur wants to merge 5 commits into
masterfrom
agent/issue-5965-request-parse-body-aot

Conversation

@PurHur

@PurHur PurHur commented Jul 7, 2026

Copy link
Copy Markdown
Owner

Summary

Continued #5965 — AOT standalone putenv() compile+execute fixed; request_parse_body() AOT execute still blocked.

Root fixes (commit 6fff073):

  • BasicBlockHelper::restoreInsertBlock(null) — standalone init no longer TypeErrors (Stdlib: request_parse_body() — PHP 8.4 HTTP body parser without superglobals (ext/standard/http.c) #5965)
  • StringGetenv::implement preserves insert block after bridge emit — fixes "Current basic block has no parent function" on AOT compile
  • JitEnv::putenv routes standalone through GetenvJitHelper::putenv via JitNestedHelperCoerce (avoids __compiler_env_register_putenv segfault)
  • RequestParseBodyEngine::overlayGetenv reads JIT putenv overlay + libc environ for CONTENT_TYPE/REQUEST_BODY
  • Defer RequestParseBodyRuntime from ensureMinimalUserStandaloneBodies (lazy link on first call)

php-src ref: ext/standard/http.c (request_parse_body), ext/standard/basic_functions.c (putenv/getenv)

Verification (2026-07-12, Docker)

./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && export PHP_COMPILER_PROFILE=8.4

# VM — green
php bin/vm.php test/repro/issue_5965_aot_index.php
# array ('a' => '1', 'b' => 'two')

# AOT putenv-only — green
php bin/compile.php -o /tmp/pe test/repro/issue_5965_putenv_only.php && /tmp/pe
# ok

vendor/bin/phpunit test/unit/JIT/EnvLocalRuntimeStandaloneTest.php
# OK (2 tests, 9 assertions)

# AOT request_parse_body — still red
php bin/compile.php -o /tmp/rpb test/repro/issue_5965_aot_index.php && /tmp/rpb
# phpc: fatal signal (segfault) after c:main_before_php — exit 139

vendor/bin/phpunit test/aot/AotTest.php --filter request_parse
# FAIL exit 139/134

# AOT putenv.phpt fixture — getenv after putenv returns empty (overlay not visible via __compiler_getenv bridge)
vendor/bin/phpunit test/aot/AotTest.php --filter putenv
# FAIL expected production, got empty string
'

Blockers (next run)

  1. request_parse_body AOT execute — any script calling request_parse_body() segfaults before user output; VM green. Bisect JIT call() return / nested RequestParseBodyJitHelper link.
  2. putenv→getenv AOT — standalone nested putenv does not populate overlay visible to __compiler_getenv; need unified helper path for both or fix register bridge without segfault.

Closes #5965 when AOT fixtures request_parse_body_{urlencoded,multipart}.phpt + putenv.phpt execute green.

- Link __compiler_env_register_putenv via EnvLocalRuntime during standalone putenv JIT
- Route GetenvJitHelper hashtable fills through phpc_native_ht_set_string_key (nested-JIT safe)
- Promote list-unpack assign targets to entry allocas for LLVM dominance (#5965)
- Preserve insert blocks across RequestParseBodyRuntime / EnvLocalRuntime nested emits

Compile + link green for urlencoded/multipart fixtures; AOT runtime still segfaults at
c:main_before_php (follow-up).

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

PurHur commented Jul 8, 2026

Copy link
Copy Markdown
Owner Author

Maintainer triage 2026-07-08: compile/link green per PR body but AOT runtime still segfaults at c:main_before_php — not merge-ready until execute repro passes. Re-run bootstrap not required (stdlib/AOT path only).

@PurHur

PurHur commented Jul 8, 2026

Copy link
Copy Markdown
Owner Author

Maintainer triage 2026-07-08: compile/link green per PR body but runtime segfault remains — hold merge until AOT execute passes issue repro.

PurHur and others added 2 commits July 12, 2026 15:08
- Link EnvLocalRuntime + RequestParseBodyRuntime in user-script standalone init
- Route GetenvJitHelper fill/merge through phpc_native_ht_set_string_key (nested-JIT)
- Split VM overlay merge into EnvLocalJitHelperVm (HashTable::update path)
- Add issue repro scripts for putenv/request_parse_body AOT bisect

Compile+link green; AOT execute still segfaults in __compiler_env_register_putenv.

Co-authored-by: Cursor <cursoragent@cursor.com>
- BasicBlockHelper::restoreInsertBlock accepts null during standalone init
- JitEnv::putenv calls GetenvJitHelper via JitNestedHelperCoerce (fixes AOT segfault)
- RequestParseBodyEngine reads JIT+VM env overlay for CONTENT_TYPE/REQUEST_BODY
- Defer RequestParseBodyRuntime from ensureMinimalUserStandaloneBodies (lazy link)
- StringGetenv: preserve insert block across bridge emit

AOT putenv-only repro green; request_parse_body execute still segfaults on nested
helper call (empty parseIntoNative also crashes) — follow-up bisect needed.

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

PurHur commented Jul 12, 2026

Copy link
Copy Markdown
Owner Author

Continued work (2026-07-12, lane C)

Pushed 6fff07342 — partial progress on AOT execute blocker.

Fixed

  • AOT putenv() — route standalone lowering through JitNestedHelperCoerce::callHelperGetenvJitHelper::putenv (drops broken __compiler_env_register_putenv malloc bridge path)
  • Standalone init compileBasicBlockHelper::restoreInsertBlock(?BasicBlock) + StringGetenv insert-block restore (fixes TypeError during ensureMinimalUserStandaloneBodies)
  • VM env overlay for parserRequestParseBodyEngine::overlayGetenv() checks JIT overlay then VmEnv
  • Lazy link — stop eager RequestParseBodyRuntime::ensureLinked in standalone init (match putenv lazy helper compile)

Verification (Docker)

PHP_COMPILER_CI_SINGLE_CONTAINER=0 ./script/docker-exec.sh -- bash -lc '
source script/php-env.sh && export PHP_COMPILER_PROFILE=8.4
php bin/vm.php test/repro/issue_5965_rpb_only.php
tmpdir=$(mktemp -d)
php bin/compile.php -o "$tmpdir/pe" test/repro/issue_5965_putenv_only.php && "$tmpdir/pe"
vendor/bin/phpunit test/unit/JIT/EnvLocalRuntimeStandaloneTest.php
'
  • VM issue_5965_rpb_only.phpPASS
  • AOT issue_5965_putenv_only.phpPASS (ok, exit 0)
  • EnvLocalRuntimeStandaloneTestPASS

Still red (blocker)

  • AOT request_parse_body()segfault (139) even when RequestParseBodyJitHelper::parseIntoNative body is empty
  • Bisect: skipping __compiler_request_parse_body bridge helper call avoids segfault; any call to parseIntoNative from bridge or builtin crashes
  • Next: align with working GetenvJitHelper pattern (helper compiled in user-script TU, not init TU) + link ParseStrNativeJitHelper when re-enabling lazy compile; investigate nested-helper MCJIT entry / helper-runtime .o link

Not merge-ready until test/fixtures/aot/cases/request_parse_body_{urlencoded,multipart}.phpt execute green.

@PurHur

PurHur commented Jul 13, 2026

Copy link
Copy Markdown
Owner Author

claim: cursor-agent-lane-a — continuing PR #17316 AOT request_parse_body execute fix

- Route user-script AOT through RequestParseBodyNativeJitHelper (avoids
  nested-JIT of RequestParseBodyEngine which segfaults at main_after_init)
- Call parseIntoNative via JitNestedHelperCoerce::callHelper from builtin
  lowering (mirrors putenv fix) instead of __compiler_request_parse_body bridge
- Drop eager EnvLocalRuntime from ensureMinimalUserStandaloneBodies (putenv
  uses GetenvJitHelper overlay path)

AOT putenv-only + VM repro green. request_parse_body() AOT execute still
segfaults (139) before user output — bisect shows crash is not helper body
logic (empty no-op helper also crashes). Next: hand-lowered LLVM path like
ParseStrUserScriptDelimitedJit + MultipartRuntime for user-script AOT.

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

PurHur commented Jul 13, 2026

Copy link
Copy Markdown
Owner Author

Continued work (2026-07-13, lane A) — commit 9020369

Progress

  • AOT putenv() — still green (test/repro/issue_5965_putenv_only.php, EnvLocalRuntimeStandaloneTest)
  • VM request_parse_body() — green (test/repro/issue_5965_rpb_only.php)
  • Added RequestParseBodyNativeJitHelper (thin wrapper: GetenvJitHelper + ParseStrNativeJitHelper + MultipartNativeJitHelper) to avoid nested-JIT of full RequestParseBodyEngine
  • User-script AOT routes through JitNestedHelperCoerce::callHelper from builtin lowering (putenv pattern) instead of __compiler_request_parse_body bridge
  • Removed eager EnvLocalRuntime::ensureLinked from ensureMinimalUserStandaloneBodies (conflicted with GetenvJitHelper putenv path)

Bisect (AOT execute still red)

PHP_COMPILER_CI_SINGLE_CONTAINER=0 ./script/docker-exec.sh -- bash -lc '
source script/php-env.sh && export PHP_COMPILER_PROFILE=8.4
tmpdir=$(mktemp -d)
php bin/compile.php -o "$tmpdir/pe" test/repro/issue_5965_rpb_only.php && "$tmpdir/pe"
'
# phpc: fatal signal (segfault) after c:main_before_php — exit 139
Variant Compile Execute
function_exists("request_parse_body") only OK OK
putenv() only OK OK
request_parse_body() (any helper body, incl. empty no-op) OK SIGSEGV 139
Helper call disabled (alloc pair only) OK SIGABRT 134

Crash occurs before user PHP output (c:main_before_php), not in helper semantics. Nested-JIT of any helper from request_parse_body::call() appears to poison standalone init.

Next step

Hand-lowered user-script LLVM like ParseStrUserScriptDelimitedJit / SuperglobalRefreshUserScriptLlvm — emit getenv + __phpc_parse_str_parse_delimited_pairs / __compiler_multipart_populate_post_body without nested-JIT helper compile during user-script link.

Not merge-ready until test/fixtures/aot/cases/request_parse_body_{urlencoded,multipart}.phpt execute green.

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: request_parse_body() — PHP 8.4 HTTP body parser without superglobals (ext/standard/http.c)

1 participant