./js print("fa".replace(/f/g, .unshift)); for (var i = 0; [i] != undefined; ++i) print(uneval([i])); Prints 3a "f" 0 "fa" Seems like the first line causes .unshift to be called with |this| not the global, but instead Object.prototype?? If I replace .unshift with a user-defined function, its |this| is the global...
Igor explains in bug 452913 comment 9: > string.replace(regex, f) will use the parent of f as its "this" to call the > function f. In SpiderMonkey Array's natives have Array.prototype as their > parent. The latter is not specified in EcmaScript and implementations are > free to do what ever suits them since.
I'm nominating this early on for blocking1.9.2, this is common in jsfunfuzz by producing false-positive hangs involving .replace and .unshift behaviour. Reducing hangs take much longer than crashes or assertions so when I painfully reduce a hang testcase only to find it's this bug, it's much time wasted.
With a current js shell, I get "TypeError: can't convert undefined to object" when I try the testcase in comment 0 now.
Bug 514570 changed behavior to not pass the parent but rather to pass |undefined| as this, which -- while not as explicitly specified by ES5 as I would desire -- is the right thing to pass. And when that flows into a builtin function, it causes a TypeError to be thrown. These are the right semantics; if fuzzers still have problems with this, they're going to have to cope.