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