Change by Anders Carlsson.
Reviewed by me.
- fixed <http://bugzilla.opendarwin.org/show_bug.cgi?id=3294>
String.prototype.replace() fails with function as second param
* kjs/string_object.cpp: (replace): Added code to handle functions.
* tests/mozilla/expected.html: Updated since ecma_3/RegExp/regress-209067.js is fixed now.
* tests/mozilla/run-mozilla-tests: Fix a minor coding style issue that leads to a warning each
time we run the tests.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@9462 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JavaScriptCore/kjs/string_object.cpp b/JavaScriptCore/kjs/string_object.cpp
index 3bbff1d..3eaac0b 100644
--- a/JavaScriptCore/kjs/string_object.cpp
+++ b/JavaScriptCore/kjs/string_object.cpp
@@ -264,6 +264,14 @@
static Value replace(ExecState *exec, const UString &source, const Value &pattern, const Value &replacement)
{
+ ObjectImp *replacementFunction = 0;
+ UString replacementString;
+
+ if (replacement.type() == ObjectType && replacement.toObject(exec).implementsCall())
+ replacementFunction = replacement.toObject(exec).imp();
+ else
+ replacementString = replacement.toString(exec);
+
if (pattern.type() == ObjectType && pattern.toObject(exec).inherits(&RegExpImp::info)) {
RegExpImp* imp = static_cast<RegExpImp *>( pattern.toObject(exec).imp() );
RegExp *reg = imp->regExp();
@@ -271,8 +279,6 @@
RegExpObjectImp* regExpObj = static_cast<RegExpObjectImp*>(exec->lexicalInterpreter()->builtinRegExp().imp());
- UString replacementString = replacement.toString(exec);
-
int matchIndex = 0;
int lastIndex = 0;
int startPosition = 0;
@@ -295,6 +301,26 @@
pushSourceRange(sourceRanges, sourceRangeCount, sourceRangeCapacity, UString::Range(lastIndex, matchIndex - lastIndex));
+ if (replacementFunction) {
+ int completeMatchStart = (*ovector)[0];
+ List args;
+
+ args.append(Value(matchString));
+
+ for (unsigned i = 0; i < reg->subPatterns(); i++) {
+ int matchStart = (*ovector)[(i + 1) * 2];
+ int matchLen = (*ovector)[(i + 1) * 2 + 1] - matchStart;
+
+ args.append(Value(source.substr(matchStart, matchLen)));
+ }
+
+ args.append(Value(completeMatchStart));
+ args.append(Value(source));
+
+ replacementString = replacementFunction->call(exec, exec->dynamicInterpreter()->globalObject(),
+ args).toString(exec);
+ }
+
UString substitutedReplacement = substituteBackreferences(replacementString, source, ovector, reg);
pushReplacement(replacements, replacementCount, replacementCapacity, substitutedReplacement);
@@ -327,7 +353,19 @@
// Do the replacement
if (matchPos == -1)
return String(source);
- return String(source.substr(0, matchPos) + replacement.toString(exec) + source.substr(matchPos + matchLen));
+
+ if (replacementFunction) {
+ List args;
+
+ args.append(Value(source.substr(matchPos, matchLen)));
+ args.append(Value(matchPos));
+ args.append(Value(source));
+
+ replacementString = replacementFunction->call(exec, exec->dynamicInterpreter()->globalObject(),
+ args).toString(exec);
+ }
+
+ return String(source.substr(0, matchPos) + replacementString + source.substr(matchPos + matchLen));
}
// ECMA 15.5.4.2 - 15.5.4.20