whole_func_string: function StringReplaceGlobalRegExpWithFunction(subject, regexp, replace) {
    var resultArray = reusableReplaceArray;
    if (resultArray) {
      reusableReplaceArray = null;
    } else {
      // Inside a nested replace (replace called from the replacement function
      // of another replace) or we have failed to set the reusable array
      // back due to an exception in a replacement function. Create a new
      // array to use in the future, or until the original is written back.
      resultArray = new InternalArray(16);
    }
    var res = %RegExpExecMultiple(regexp,
                                  subject,
                                  RegExpLastMatchInfo,
                                  resultArray);
    regexp.lastIndex = 0;
    if (IS_NULL(res)) {
      // No matches at all.
      reusableReplaceArray = resultArray;
      return subject;
    }
    var len = res.length;
    if (NUMBER_OF_CAPTURES(RegExpLastMatchInfo) == 2) {
      // If the number of captures is two then there are no explicit captures in
      // the regexp, just the implicit capture that captures the whole match.  In
      // this case we can simplify quite a bit and end up with something faster.
      // The builder will consist of some integers that indicate slices of the
      // input string and some replacements that were returned from the replace
      // function.
      var match_start = 0;
      for (var i = 0; i < len; i++) {
        var elem = res[i];
        if (%_IsSmi(elem)) {
          // Integers represent slices of the original string.
          if (elem > 0) {
            match_start = (elem >> 11) + (elem & 0x7ff);
          } else {
            match_start = res[++i] - elem;
          }
        } else {
          var func_result = replace(elem, match_start, subject);
          // Overwrite the i'th element in the results with the string we got
          // back from the callback function.
          res[i] = TO_STRING(func_result);
          match_start += elem.length;
        }
      }
    } else {
      for (var i = 0; i < len; i++) {
        var elem = res[i];
        if (!%_IsSmi(elem)) {
          // elem must be an Array.
          // Use the apply argument as backing for global RegExp properties.
          var func_result = %reflect_apply(replace, UNDEFINED, elem);
          // Overwrite the i'th element in the results with the string we got
          // back from the callback function.
          res[i] = TO_STRING(func_result);
        }
      }
    }
    var result = %StringBuilderConcat(res, len, subject);
    resultArray.length = 0;
    reusableReplaceArray = resultArray;
    return result;
  }
func_code_string: function StringReplaceGlobalRegExpWithFunction(subject, regexp, replace) {
    var resultArray = reusableReplaceArray;
    if (resultArray) {
      reusableReplaceArray = null;
    } else {
      // Inside a nested replace (replace called from the replacement function
      // of another replace) or we have failed to set the reusable array
      // back due to an exception in a replacement function. Create a new
      // array to use in the future, or until the original is written back.
      resultArray = new InternalArray(16);
    }
    var res = %RegExpExecMultiple(regexp,
                                  subject,
                                  RegExpLastMatchInfo,
                                  resultArray);
    regexp.lastIndex = 0;
    if (IS_NULL(res)) {
      // No matches at all.
      reusableReplaceArray = resultArray;
      return subject;
    }
    var len = res.length;
    if (NUMBER_OF_CAPTURES(RegExpLastMatchInfo) == 2) {
      // If the number of captures is two then there are no explicit captures in
      // the regexp, just the implicit capture that captures the whole match.  In
      // this case we can simplify quite a bit and end up with something faster.
      // The builder will consist of some integers that indicate slices of the
      // input string and some replacements that were returned from the replace
      // function.
      var match_start = 0;
      for (var i = 0; i < len; i++) {
        var elem = res[i];
        if (%_IsSmi(elem)) {
          // Integers represent slices of the original string.
          if (elem > 0) {
            match_start = (elem >> 11) + (elem & 0x7ff);
          } else {
            match_start = res[++i] - elem;
          }
        } else {
          var func_result = replace(elem, match_start, subject);
          // Overwrite the i'th element in the results with the string we got
          // back from the callback function.
          res[i] = TO_STRING(func_result);
          match_start += elem.length;
        }
      }
    } else {
      for (var i = 0; i < len; i++) {
        var elem = res[i];
        if (!%_IsSmi(elem)) {
          // elem must be an Array.
          // Use the apply argument as backing for global RegExp properties.
          var func_result = %reflect_apply(replace, UNDEFINED, elem);
          // Overwrite the i'th element in the results with the string we got
          // back from the callback function.
          res[i] = TO_STRING(func_result);
        }
      }
    }
    var result = %StringBuilderConcat(res, len, subject);
    resultArray.length = 0;
    reusableReplaceArray = resultArray;
    return result;
  }
func_documentation_string: Helper function for replacing regular expressions with the result of a function application in String.prototype.replace.