You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Regression: strlen() on non-constant operand silently terminates AOT binaries — exit 0, output truncated; VM/JIT fine (root cause of #15624) #15632
Any non-constant-foldedstrlen() call terminates an AOT binary at the call site: process exits 0, all output after the call is lost, no error. VM and MCJIT execute the same script correctly, so the LLVM lowering is fine in-process — the failure is specific to the AOT link (suspect: a runtime helper symbol binding to a no-op/exit stub in the prelinked objects instead of the real implementation; MCJIT instead resolves against the host process, masking it).
echo strlen("abc") works (constant-folded). substr, is_string, count on variables work.
Blast radius: every AOT web example that touches request parsing (lib/Web/MultipartParser.php is strlen-heavy) — direct root cause of #15624 (006-FileUploadWeb empty state). Regression window: 2026-06-02 (6ca795e72, honest AOT benchmark timings) → master.
Root cause:JitStrlen::lowerLengthFromValueBox() returned from PHP after emitting the non-strict null-deprecation branch, leaving strlen_value_ok as an empty ret void. Any non-null boxed operand (including {main} script globals like $x in the repro) took that branch and silently ended the function — exit 0, no output after strlen($var).
Fix: Continue LLVM emission into the string-length path after the null branch; merge null-coercion (deprecation + length 0) via phi.
Verified: VM + AOT repro test/repro/issue_15632_strlen_aot.php prints 3 / after; AotRegressionFixtureCatalogTest + strlen_script_global.phpt; ci-fast.sh green.
Master is still broken after #15641 (verified at 8250d4076, 2026-07-03):
$x = "abc"; echo strlen($x), "\n"; echo "after\n";
# phpc build + run → no output, exit 0 (unchanged symptom)
#15641 merged the null path via phi but kept the early return in the non-strict objectBlock branch of lowerLengthFromValueBox. For any non-strict compile the PHP method returns during objectBlock emission, so coerceBlock — the plain-string runtime path — and mergeBlock are never populated: same dangling-block failure, one block later. Two further defects: mergeBlock is appended unconditionally but never terminated in strict mode (new dangling block on strict scripts), and the phi incomings use the block labels ($nullLenBlock, $coerceBlock) rather than the builder's actual end blocks — wrong if emitNullStringDeprecation/JitStringArg::lower emit internal branches.
PR #15640 (opened before #15641 landed) fixes all paths — null/object/plain merge via phi with getInsertBlock() incomings, merge block only in non-strict mode; verified plain/null/strict/JIT/examples-000 + Strlen-filter regression-neutral. Rebasing it onto master now.
Activity
PurHur commentedon Jul 3, 2026
claim: lane-c-worker — starting this run
Fix AOT strlen() on boxed script globals after null-deprecation branch (
PurHur commentedon Jul 3, 2026
Merged via #15641.
Root cause:
JitStrlen::lowerLengthFromValueBox()returned from PHP after emitting the non-strict null-deprecation branch, leavingstrlen_value_okas an emptyret void. Any non-null boxed operand (including{main}script globals like$xin the repro) took that branch and silently ended the function — exit 0, no output afterstrlen($var).Fix: Continue LLVM emission into the string-length path after the null branch; merge null-coercion (deprecation + length 0) via phi.
Verified: VM + AOT repro
test/repro/issue_15632_strlen_aot.phpprints3/after;AotRegressionFixtureCatalogTest+strlen_script_global.phpt;ci-fast.shgreen.PurHur commentedon Jul 3, 2026
Master is still broken after #15641 (verified at
8250d4076, 2026-07-03):#15641 merged the null path via phi but kept the early
returnin the non-strict objectBlock branch oflowerLengthFromValueBox. For any non-strict compile the PHP method returns during objectBlock emission, socoerceBlock— the plain-string runtime path — andmergeBlockare never populated: same dangling-block failure, one block later. Two further defects:mergeBlockis appended unconditionally but never terminated in strict mode (new dangling block on strict scripts), and the phi incomings use the block labels ($nullLenBlock,$coerceBlock) rather than the builder's actual end blocks — wrong ifemitNullStringDeprecation/JitStringArg::loweremit internal branches.PR #15640 (opened before #15641 landed) fixes all paths — null/object/plain merge via phi with
getInsertBlock()incomings, merge block only in non-strict mode; verified plain/null/strict/JIT/examples-000 + Strlen-filter regression-neutral. Rebasing it onto master now.Fix strlen() value-box lowering: dangling okBlock/coerceBlock silentl…
Fix strlen() value-box lowering: dangling okBlock/coerceBlock silentl…
Tooling: modernize script/bench.php — Zend 8.x runtimes, VM column, h…
Gates: AOT build+execute+VM-differential smoke in the fast gate (#16010…