code: function StringReplace(search, replace) {
    CHECK_OBJECT_COERCIBLE(this, "String.prototype.replace");
  
    // Decision tree for dispatch
    // .. regexp search (in src/js/regexp.js, RegExpReplace)
    // .... string replace
    // ...... non-global search
    // ........ empty string replace
    // ........ non-empty string replace (with $-expansion)
    // ...... global search
    // ........ no need to circumvent last match info override
    // ........ need to circument last match info override
    // .... function replace
    // ...... global search
    // ...... non-global search
    // .. string search
    // .... special case that replaces with one single character
    // ...... function replace
    // ...... string replace (with $-expansion)
  
    if (!IS_NULL_OR_UNDEFINED(search)) {
      var replacer = search[replaceSymbol];
      if (!IS_UNDEFINED(replacer)) {
        return %_Call(replacer, search, this, replace);
      }
    }
  
    var subject = TO_STRING(this);
  
    search = TO_STRING(search);
  
    if (search.length == 1 &&
        subject.length > 0xFF &&
        IS_STRING(replace) &&
        %StringIndexOf(replace, '$', 0) < 0) {
      // Searching by traversing a cons string tree and replace with cons of
      // slices works only when the replaced string is a single character, being
      // replaced by a simple string and only pays off for long strings.
      return %StringReplaceOneCharWithString(subject, search, replace);
    }
    var start = %StringIndexOf(subject, search, 0);
    if (start < 0) return subject;
    var end = start + search.length;
  
    var result = %_SubString(subject, 0, start);
  
    // Compute the string to replace with.
    if (IS_CALLABLE(replace)) {
      result += replace(search, start, subject);
    } else {
      reusableMatchInfo[CAPTURE0] = start;
      reusableMatchInfo[CAPTURE1] = end;
      result = ExpandReplacement(TO_STRING(replace),
                                 subject,
                                 reusableMatchInfo,
                                 result);
    }
  
    return result + %_SubString(subject, end, subject.length);
  }
docs: ES6, section 21.1.3.14