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
AOT: str_replace() prints "Array" instead of the replaced string #23912
str_replace() returns something that stringifies to Array in an AOT binary, instead of the
replaced string. Silent wrong output — runs to completion, exit code 0.
All three arguments are scalars — string $search, string $replace, string $subject — so the
array-returning overload (array $search) is not in play. Zend returns a string here.
Printing Array specifically suggests the result is coming back as a PHP array rather than a
string, i.e. the return value's type is wrong rather than its contents.
Blast radius
Explains two standing AOT differential failures:
c10_builtin.php — str_replace($r['a'],$r['b'],'xy!'), whose first line currently prints empty
e15_str_fns.php — its str_replace("o","0",$s) line
e15 also hits #23913 (str_pad segfault), so it will need both fixed before it passes.
Related but distinct
Several closed issues cover str_replace()argument handling — null coercion (#20173, #19755, #21189), and string $search + array $replace returning the first element (#22827). This is a
different failure: three plain string arguments, wrong return type, AOT only.
Correction: the str_pad segfault referenced above as "#23913" is actually #23911. e15_str_fns.php needs both #23911 and this one fixed before it passes.
At 8893fab the same probe SIGSEGV (rc=139); current master returns empty string (rc=0) — regression changed shape but never matched Zend.
Hypothesis (not yet proven)
HelperRuntimeCache::USER_SCRIPT_INLINE_ONLY_LOGICALS lists StrReplaceJitHelper::replaceArgv, but JitVmHelperLink::runNestedHelperCompile clears PHP_COMPILER_AOT_USER_SCRIPT (#15407), so tryProvide() may bind stale unit.o for replaceArgv during the NestedJIT window (#23912 comment). Partial attempts this run (inline-only guard during NestedJitCompileScope, skipHelperRuntimeCache on bridges, defer Context pre-init) did not fix the repro.
Next step
Confirm whether phpc_str_replace bridge calls NestedJIT-compiled replaceArgv or a stale extern (module verify / symbol trace on user AOT TU).
Activity
PurHur commentedon Jul 27, 2026
Correction: the
str_padsegfault referenced above as "#23913" is actually #23911.e15_str_fns.phpneeds both #23911 and this one fixed before it passes.PurHur commentedon Jul 27, 2026
claim: Lane C implementer — starting this run (after closing #23897 as already-fixed on master)
PurHur commentedon Jul 27, 2026
claim: Lane C implementer — continuing in-flight branch agent/issue-23912-aot-str-replace (verify + merge this run)
PurHur commentedon Jul 27, 2026
claim: Lane C implementer — continuing agent/issue-23912-aot-str-replace (verify + merge this run)
AOT: fix str_replace via NestedJIT walk of original subject (#23912)
AOT: str_replace scalar subject returns replaced string (#23912) (#23940
PurHur commentedon Jul 27, 2026
Merged via #23940
Verification (
./script/docker-exec.sh --bind):test/repro/issue_23912_aot_str_replace.php→hell0 w0rldll/l/empty searchvendor/bin/phpunit --filter StrReplaceRuntimeShrinkTest→ OKFix: NestedJIT helper walks the original subject (no suffix reassign / int tally); scalars route through
StringStrReplace.Stdlib: AOT str_word_count NestedJIT under helper-runtime (#27019) (#…
PurHur commentedon Aug 19, 2026
claim: implementer-worker-lane-b — starting this run (lane overflow: north-star queue closed; aot_str_replace_scalar_subject regressed — empty output)
PurHur commentedon Aug 19, 2026
status: repro still red after investigation this run (lane overflow — north-star queue closed).
Verified on master @ c3cf23f
./script/aot-smoke.sh→ 8/8 green./script/phpunit.sh --filter aot_str_replace_scalar_subject→ FAIL (expectedhell0 w0rld\nhell0 w0rld\n, actual empty stdout)./script/differential-sweep.sh --aot --dir …/c10_builtin.php→ DIFF (zendzw!\nzw, aot~zw— str_replace line missing + max wrong)./script/differential-sweep.sh --aot --dir …/c11_strcmp.php(str_pad/substr) → SIGSEGV on str_pad path isolatedVM/JIT:
StrReplaceRuntimeShrinkTestgreen;php bin/vm.phpprints correct output.AOT isolate
At 8893fab the same probe SIGSEGV (rc=139); current master returns empty string (rc=0) — regression changed shape but never matched Zend.
Hypothesis (not yet proven)
HelperRuntimeCache::USER_SCRIPT_INLINE_ONLY_LOGICALSlistsStrReplaceJitHelper::replaceArgv, butJitVmHelperLink::runNestedHelperCompileclearsPHP_COMPILER_AOT_USER_SCRIPT(#15407), sotryProvide()may bind staleunit.ofor replaceArgv during the NestedJIT window (#23912 comment). Partial attempts this run (inline-only guard duringNestedJitCompileScope,skipHelperRuntimeCacheon bridges, defer Context pre-init) did not fix the repro.Next step
phpc_str_replacebridge calls NestedJIT-compiledreplaceArgvor a stale extern (module verify / symbol trace on user AOT TU).StrPadJitHelper::padArgvto inline-only list (peer AOT: str_pad() segfaults — three-argument literal call is enough #23911) once replaceArgv path is understood — str_pad-only probe SIGSEGV rc=139../script/differential-sweep.sh --aotbatch after fix; regenerate baseline if c10/c11 green.Did not merge — issue repro still fails.
AOT: preg_replace TYPE_VALUE string subject uses invokeString (#35059) (