for (let i = 0; i < 3000; ++i) { let r = /abcd/; regexLastIndex = {}; regexLastIndex.toString = function () { print(i) return "1"; }; r.lastIndex = regexLastIndex; "test".replace(r, "cons") } With the above script as input to JSC, run JSC with the following parameters: ./jsc test.js --useConcurrentJIT=0 This bug is similar to 191731, but they are different. The above js scripts should print 0-2999, but jsc only prints 0-2209. In DFGBytecodeParser, replace is inlined into StringReplace node. In DFGStrengthReduction, StringReplace is converted to Identity. So after DFG, lastIndex is no longer read and updated. Therefore, regexLastIndex.toString is no longer invoked.
Modified to run in the browser console. ``` for (let i = 0; i < 3000; ++i) { let r = /abcd/; regexLastIndex = {}; regexLastIndex.toString = function () { console.log(i) return "1"; }; r.lastIndex = regexLastIndex; "test".replace(r, "cons") } ``` Safari result is random Both Firefox and Chrome print until 2999. Tested on macOS 13.0 --- Safari Technology Preview 155 18615.1.7.1 Firefox Nightly 107.0a1 10722.10.4 Google Chrome Canary 108.0.5355.0 5355.0
<rdar://problem/101122567>
Pull request: https://github.com/WebKit/WebKit/pull/24959
Committed 275255@main (3790f1e3cc0a): <https://commits.webkit.org/275255@main> Reviewed commits have been landed. Closing PR #24959 and removing active labels.