Backed out changeset f23a61067cef (bug 887016)
authorTooru Fujisawa <arai_a@mac.com>
Mon, 28 Mar 2016 06:49:54 +0900
changeset 290651 0fd465ec1e2c279f7ae3d9c4243c1d6c2f597c43
parent 290650 185994606889363e10d446e0fb8835fab9fa19f2
child 290652 248bb4773adfc0c076922468f938f8567076b528
push id19656
push usergwagner@mozilla.com
push dateMon, 04 Apr 2016 13:43:23 +0000
treeherderb2g-inbound@e99061fde28a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs887016
milestone48.0a1
backs outf23a61067cefec53fd72dc00383092f72fe707cb
Backed out changeset f23a61067cef (bug 887016)
js/src/builtin/RegExp.cpp
js/src/builtin/RegExp.js
js/src/builtin/String.js
js/src/jit/Lowering.cpp
js/src/jsapi.h
js/src/jsstr.cpp
js/src/jsstr.h
js/src/tests/ecma_6/RegExp/search-this.js
js/src/tests/ecma_6/RegExp/search-trace.js
js/src/tests/ecma_6/RegExp/search.js
js/src/tests/ecma_6/String/search.js
js/src/tests/ecma_6/Symbol/well-known.js
js/src/vm/CommonPropertyNames.h
js/src/vm/GlobalObject.cpp
js/src/vm/SelfHosting.cpp
js/xpconnect/tests/chrome/test_xrayToJS.xul
--- a/js/src/builtin/RegExp.cpp
+++ b/js/src/builtin/RegExp.cpp
@@ -640,17 +640,16 @@ const JSFunctionSpec js::regexp_methods[
 #if JS_HAS_TOSOURCE
     JS_SELF_HOSTED_FN(js_toSource_str, "RegExpToString", 0, 0),
 #endif
     JS_SELF_HOSTED_FN(js_toString_str, "RegExpToString", 0, 0),
     JS_FN("compile",        regexp_compile,     2,0),
     JS_SELF_HOSTED_FN("exec", "RegExp_prototype_Exec", 1,0),
     JS_SELF_HOSTED_FN("test", "RegExpTest" ,    1,0),
     JS_SELF_HOSTED_SYM_FN(match, "RegExpMatch", 1,0),
-    JS_SELF_HOSTED_SYM_FN(search, "RegExpSearch", 1,0),
     JS_FS_END
 };
 
 #define STATIC_PAREN_GETTER_CODE(parenNum)                                      \
     if (!res->createParen(cx, parenNum, args.rval()))                           \
         return false;                                                           \
     if (args.rval().isUndefined())                                              \
         args.rval().setString(cx->runtime()->emptyString);                      \
@@ -1081,22 +1080,24 @@ js::RegExpPrototypeOptimizableRaw(JSCont
     bool has = false;
     if (!HasOwnDataPropertyPure(cx, proto, SYMBOL_TO_JSID(cx->wellKnownSymbols().match), &has))
         return false;
     if (!has) {
         *result = false;
         return true;
     }
 
+    /*
     if (!HasOwnDataPropertyPure(cx, proto, SYMBOL_TO_JSID(cx->wellKnownSymbols().search), &has))
         return false;
     if (!has) {
         *result = false;
         return true;
     }
+    */
 
     if (!HasOwnDataPropertyPure(cx, proto, NameToId(cx->names().exec), &has))
         return false;
     if (!has) {
         *result = false;
         return true;
     }
 
--- a/js/src/builtin/RegExp.js
+++ b/js/src/builtin/RegExp.js
@@ -142,48 +142,16 @@ function RegExpMatch(string) {
             rx.lastIndex = fullUnicode ? AdvanceStringIndex(S, lastIndex) : lastIndex + 1;
         }
 
         // Step 6.e.iii.5.
         n++;
     }
 }
 
-// ES 2016 draft Mar 25, 2016 21.2.5.9.
-function RegExpSearch(string) {
-    // Step 1.
-    var rx = this;
-
-    // Step 2.
-    if (!IsObject(rx))
-        ThrowTypeError(JSMSG_NOT_NONNULL_OBJECT, rx === null ? "null" : typeof rx);
-
-    // Step 3.
-    var S = ToString(string);
-
-    // Step 4.
-    var previousLastIndex = rx.lastIndex;
-
-    // Step 5.
-    rx.lastIndex = 0;
-
-    // Step 6.
-    var result = RegExpExec(rx, S, false);
-
-    // Step 7.
-    rx.lastIndex = previousLastIndex;
-
-    // Step 8.
-    if (result === null)
-        return -1;
-
-    // Step 9.
-    return result.index;
-}
-
 // ES6 21.2.5.2.
 // NOTE: This is not RegExpExec (21.2.5.2.1).
 function RegExp_prototype_Exec(string) {
     // Steps 1-3.
     var R = this;
     if (!IsObject(R) || !IsRegExpObject(R))
         return callFunction(CallRegExpMethodIfWrapped, R, string, "RegExp_prototype_Exec");
 
--- a/js/src/builtin/String.js
+++ b/js/src/builtin/String.js
@@ -66,79 +66,16 @@ function String_match(regexp) {
 }
 
 function String_generic_match(thisValue, regexp) {
     if (thisValue === undefined)
         ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.match');
     return callFunction(String_match, thisValue, regexp);
 }
 
-function StringProtoHasNoSearch() {
-    var ObjectProto = GetBuiltinPrototype("Object");
-    var StringProto = GetBuiltinPrototype("String");
-    if (!ObjectHasPrototype(StringProto, ObjectProto))
-        return false;
-    return !(std_search in StringProto);
-}
-
-function IsStringSearchOptimizable() {
-    var RegExpProto = GetBuiltinPrototype("RegExp");
-    // If RegExpPrototypeOptimizable succeeds, `exec` and `@@search` are
-    // guaranteed to be data properties.
-    return RegExpPrototypeOptimizable(RegExpProto) &&
-           RegExpProto.exec === RegExp_prototype_Exec &&
-           RegExpProto[std_search] === RegExpSearch;
-}
-
-// ES 2016 draft Mar 25, 2016 21.1.3.15.
-function String_search(regexp) {
-    // Step 1.
-    RequireObjectCoercible(this);
-
-    // Step 2.
-    var isPatternString = (typeof regexp === "string");
-    if (!(isPatternString && StringProtoHasNoSearch()) && regexp !== undefined && regexp !== null) {
-        // Step 2.a.
-        var searcher = regexp[std_search];
-
-        // Step 2.b.
-        if (searcher !== undefined)
-            return callContentFunction(searcher, regexp, this);
-    }
-
-    // Step 3.
-    var string = ToString(this);
-
-    // FIXME: Non-standard flags argument (bug 1108382).
-    var flags = undefined;
-    if (arguments.length > 1) {
-        if (IsMatchFlagsArgumentEnabled())
-            flags = arguments[1];
-        WarnOnceAboutFlagsArgument();
-    } else {
-        if (isPatternString && IsStringSearchOptimizable()) {
-            var flatResult = FlatStringSearch(string, regexp);
-            if (flatResult !== -2)
-                return flatResult;
-        }
-    }
-
-    // Step 4.
-    var rx = RegExpCreate(regexp, flags);
-
-    // Step 5.
-    return callContentFunction(GetMethod(rx, std_search), rx, string);
-}
-
-function String_generic_search(thisValue, regexp) {
-    if (thisValue === undefined)
-        ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.search');
-    return callFunction(String_search, thisValue, regexp);
-}
-
 /* ES6 Draft Oct 14, 2014 21.1.3.19 */
 function String_substring(start, end) {
     // Steps 1-3.
     RequireObjectCoercible(this);
     var str = ToString(this);
 
     // Step 4.
     var len = str.length;
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -2184,17 +2184,18 @@ MustCloneRegExpForCall(MCall* call, uint
     // this is a native call that does not let the regex escape.
 
     JSFunction* target = call->getSingleTarget();
     if (!target || !target->isNative())
         return true;
 
     if (useIndex == MCall::IndexOfArgument(0) &&
         (target->native() == str_split ||
-         target->native() == str_replace))
+         target->native() == str_replace ||
+         target->native() == str_search))
     {
         return false;
     }
 
     return true;
 }
 
 
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -4861,17 +4861,16 @@ GetSymbolFor(JSContext* cx, HandleString
  */
 JS_PUBLIC_API(JSString*)
 GetSymbolDescription(HandleSymbol symbol);
 
 /* Well-known symbols. */
 #define JS_FOR_EACH_WELL_KNOWN_SYMBOL(macro) \
     macro(iterator) \
     macro(match) \
-    macro(search) \
     macro(species) \
     macro(toPrimitive) \
     macro(unscopables)
 
 enum class SymbolCode : uint32_t {
     // There is one SymbolCode for each well-known symbol.
 #define JS_DEFINE_SYMBOL_ENUM(name) name,
     JS_FOR_EACH_WELL_KNOWN_SYMBOL(JS_DEFINE_SYMBOL_ENUM)  // SymbolCode::iterator, etc.
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -2290,16 +2290,61 @@ AdvanceStringIndex(HandleLinearString in
     /* Step 10. */
     if (!unicode::IsTrailSurrogate(second))
         return index + 1;
 
     /* Step 11. */
     return index + 2;
 }
 
+bool
+js::str_search(JSContext* cx, unsigned argc, Value* vp)
+{
+    CallArgs args = CallArgsFromVp(argc, vp);
+    RootedString str(cx, ThisToStringForStringProto(cx, args));
+    if (!str)
+        return false;
+
+    StringRegExpGuard g(cx);
+    if (!g.init(cx, args, true))
+        return false;
+    if (const FlatMatch* fm = g.tryFlatMatch(cx, str, 1, args.length())) {
+        args.rval().setInt32(fm->match());
+        return true;
+    }
+
+    if (cx->isExceptionPending())  /* from tryFlatMatch */
+        return false;
+
+    if (!g.normalizeRegExp(cx, false, 1, args))
+        return false;
+
+    RootedLinearString linearStr(cx, str->ensureLinear(cx));
+    if (!linearStr)
+        return false;
+
+    RegExpStatics* res = cx->global()->getRegExpStatics(cx);
+    if (!res)
+        return false;
+
+    /* Per ECMAv5 15.5.4.12 (5) The last index property is ignored and left unchanged. */
+    ScopedMatchPairs matches(&cx->tempLifoAlloc());
+    RegExpShared& re = g.regExp();
+    bool sticky = re.sticky();
+    RegExpRunStatus status = re.execute(cx, linearStr, 0, sticky, &matches, nullptr);
+    if (status == RegExpRunStatus_Error)
+        return false;
+
+    if (status == RegExpRunStatus_Success)
+        res->updateLazily(cx, linearStr, &re, 0, sticky);
+
+    args.rval().setInt32(status == RegExpRunStatus_Success_NotFound ? -1 : matches[0].start);
+    return true;
+}
+
 // Utility for building a rope (lazy concatenation) of strings.
 class RopeBuilder {
     JSContext* cx;
     RootedString res;
 
     RopeBuilder(const RopeBuilder& other) = delete;
     void operator=(const RopeBuilder& other) = delete;
 
@@ -3943,17 +3988,17 @@ static const JSFunctionSpec string_metho
 #endif
     JS_SELF_HOSTED_FN("repeat", "String_repeat",      1,0),
 #if EXPOSE_INTL_API
     JS_FN("normalize",         str_normalize,         0,JSFUN_GENERIC_NATIVE),
 #endif
 
     /* Perl-ish methods (search is actually Python-esque). */
     JS_SELF_HOSTED_FN("match", "String_match",        1,0),
-    JS_SELF_HOSTED_FN("search", "String_search",      1,0),
+    JS_FN("search",            str_search,            1,JSFUN_GENERIC_NATIVE),
     JS_INLINABLE_FN("replace", str_replace,           2,JSFUN_GENERIC_NATIVE, StringReplace),
     JS_INLINABLE_FN("split",   str_split,             2,JSFUN_GENERIC_NATIVE, StringSplit),
     JS_SELF_HOSTED_FN("substr", "String_substr",      2,0),
 
     /* Python-esque sequence methods. */
     JS_FN("concat",            str_concat,            1,JSFUN_GENERIC_NATIVE),
     JS_SELF_HOSTED_FN("slice", "String_slice",        2,0),
 
@@ -4098,17 +4143,16 @@ static const JSFunctionSpec string_stati
 
     JS_SELF_HOSTED_FN("fromCodePoint",   "String_static_fromCodePoint", 1,0),
     JS_SELF_HOSTED_FN("raw",             "String_static_raw",           2,JSFUN_HAS_REST),
     JS_SELF_HOSTED_FN("substring",       "String_static_substring",     3,0),
     JS_SELF_HOSTED_FN("substr",          "String_static_substr",        3,0),
     JS_SELF_HOSTED_FN("slice",           "String_static_slice",         3,0),
 
     JS_SELF_HOSTED_FN("match",           "String_generic_match",        2,0),
-    JS_SELF_HOSTED_FN("search",          "String_generic_search",       2,0),
 
     // This must be at the end because of bug 853075: functions listed after
     // self-hosted methods aren't available in self-hosted code.
 #if EXPOSE_INTL_API
     JS_SELF_HOSTED_FN("localeCompare",   "String_static_localeCompare", 2,0),
 #endif
     JS_FS_END
 };
@@ -5255,39 +5299,8 @@ js::FlatStringMatch(JSContext* cx, unsig
 
     if (!isFlat) {
         args.rval().setUndefined();
         return true;
     }
 
     return BuildFlatMatchArray(cx, str, pattern, match, args.rval());
 }
-
-bool
-js::FlatStringSearch(JSContext* cx, unsigned argc, Value* vp)
-{
-    CallArgs args = CallArgsFromVp(argc, vp);
-    MOZ_ASSERT(args.length() == 2);
-    MOZ_ASSERT(args[0].isString());
-    MOZ_ASSERT(args[1].isString());
-#ifdef DEBUG
-    bool isOptimizable = false;
-    if (!CallIsStringOptimizable(cx, "IsStringSearchOptimizable", &isOptimizable))
-        return false;
-    MOZ_ASSERT(isOptimizable);
-#endif
-
-    RootedString str(cx,args[0].toString());
-    RootedString pattern(cx, args[1].toString());
-
-    bool isFlat = false;
-    int32_t match = 0;
-    if (!FlatStringMatchHelper(cx, str, pattern, &isFlat, &match))
-        return false;
-
-    if (!isFlat) {
-        args.rval().setInt32(-2);
-        return true;
-    }
-
-    args.rval().setInt32(match);
-    return true;
-}
--- a/js/src/jsstr.h
+++ b/js/src/jsstr.h
@@ -426,16 +426,19 @@ FileEscapedString(FILE* fp, const char* 
 {
     Fprinter out(fp);
     bool res = EscapedStringPrinter(out, chars, length, quote);
     out.finish();
     return res;
 }
 
 bool
+str_search(JSContext* cx, unsigned argc, Value* vp);
+
+bool
 str_split(JSContext* cx, unsigned argc, Value* vp);
 
 JSObject*
 str_split_string(JSContext* cx, HandleObjectGroup group, HandleString str, HandleString sep);
 
 JSString *
 str_flat_replace_string(JSContext *cx, HandleString string, HandleString pattern,
                         HandleString replacement);
@@ -445,14 +448,11 @@ str_replace_string_raw(JSContext* cx, Ha
                        HandleString replacement);
 
 extern bool
 StringConstructor(JSContext* cx, unsigned argc, Value* vp);
 
 extern bool
 FlatStringMatch(JSContext* cx, unsigned argc, Value* vp);
 
-extern bool
-FlatStringSearch(JSContext* cx, unsigned argc, Value* vp);
-
 } /* namespace js */
 
 #endif /* jsstr_h */
deleted file mode 100644
--- a/js/src/tests/ecma_6/RegExp/search-this.js
+++ /dev/null
@@ -1,12 +0,0 @@
-var BUGNUMBER = 887016;
-var summary = "RegExp.prototype[@@search] should check this value.";
-
-print(BUGNUMBER + ": " + summary);
-
-for (var v of [null, 1, true, undefined, "", Symbol.iterator]) {
-  assertThrowsInstanceOf(() => RegExp.prototype[Symbol.search].call(v),
-                         TypeError);
-}
-
-if (typeof reportCompare === "function")
-    reportCompare(true, true);
deleted file mode 100644
--- a/js/src/tests/ecma_6/RegExp/search-trace.js
+++ /dev/null
@@ -1,76 +0,0 @@
-var BUGNUMBER = 887016;
-var summary = "Trace RegExp.prototype[@@search] behavior.";
-
-print(BUGNUMBER + ": " + summary);
-
-var n;
-var log;
-var target;
-
-var execResult;
-var lastIndexResult;
-var lastIndexExpected;
-
-function P(index) {
-  return new Proxy({ index }, {
-    get(that, name) {
-      log += "get:result[" + name + "],";
-      return that[name];
-    }
-  });
-}
-
-var myRegExp = {
-  get lastIndex() {
-    log += "get:lastIndex,";
-    return lastIndexResult[n];
-  },
-  set lastIndex(v) {
-    log += "set:lastIndex,";
-    assertEq(v, lastIndexExpected[n]);
-  },
-  get exec() {
-    log += "get:exec,";
-    return function(S) {
-      log += "call:exec,";
-      assertEq(S, target);
-      return execResult[n++];
-    };
-  },
-};
-
-function reset() {
-  n = 0;
-  log = "";
-  target = "abcAbcABC";
-}
-
-// Trace hit.
-reset();
-execResult        = [     P(16) ];
-lastIndexResult   = [ 10, ,     ];
-lastIndexExpected = [ 0,  10    ];
-var ret = RegExp.prototype[Symbol.search].call(myRegExp, target);
-assertEq(ret, 16);
-assertEq(log,
-         "get:lastIndex," +
-         "set:lastIndex," +
-         "get:exec,call:exec," +
-         "set:lastIndex," +
-         "get:result[index],");
-
-// Trace not hit.
-reset();
-execResult        = [     null ];
-lastIndexResult   = [ 10, ,    ];
-lastIndexExpected = [ 0,  10   ];
-ret = RegExp.prototype[Symbol.search].call(myRegExp, target);
-assertEq(ret, -1);
-assertEq(log,
-         "get:lastIndex," +
-         "set:lastIndex," +
-         "get:exec,call:exec," +
-         "set:lastIndex,");
-
-if (typeof reportCompare === "function")
-    reportCompare(true, true);
deleted file mode 100644
--- a/js/src/tests/ecma_6/RegExp/search.js
+++ /dev/null
@@ -1,26 +0,0 @@
-var BUGNUMBER = 887016;
-var summary = "Implement RegExp.prototype[@@search].";
-
-print(BUGNUMBER + ": " + summary);
-
-assertEq(RegExp.prototype[Symbol.search].name, "[Symbol.search]");
-assertEq(RegExp.prototype[Symbol.search].length, 1);
-var desc = Object.getOwnPropertyDescriptor(RegExp.prototype, Symbol.search);
-assertEq(desc.configurable, true);
-assertEq(desc.enumerable, false);
-assertEq(desc.writable, true);
-
-var re = /B/;
-var v = re[Symbol.search]("abcAbcABC");
-assertEq(v, 7);
-
-re = /B/i;
-v = re[Symbol.search]("abcAbcABCD");
-assertEq(v, 1);
-
-re = /d/;
-v = re[Symbol.search]("abcAbcABCD");
-assertEq(v, -1);
-
-if (typeof reportCompare === "function")
-    reportCompare(true, true);
deleted file mode 100644
--- a/js/src/tests/ecma_6/String/search.js
+++ /dev/null
@@ -1,27 +0,0 @@
-var BUGNUMBER = 887016;
-var summary = "Call RegExp.prototype[@@search] from String.prototype.search.";
-
-print(BUGNUMBER + ": " + summary);
-
-var called = 0;
-var myRegExp = {
-  [Symbol.search](S) {
-    assertEq(S, "abcAbcABC");
-    called++;
-    return 42;
-  }
-};
-assertEq("abcAbcABC".search(myRegExp), 42);
-assertEq(called, 1);
-
-called = 0;
-RegExp.prototype[Symbol.search] = function(S) {
-  assertEq(S, "abcAbcABC");
-  called++;
-  return 43;
-};
-assertEq("abcAbcABC".search("abc"), 43);
-assertEq(called, 1);
-
-if (typeof reportCompare === "function")
-    reportCompare(true, true);
--- a/js/src/tests/ecma_6/Symbol/well-known.js
+++ b/js/src/tests/ecma_6/Symbol/well-known.js
@@ -1,15 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/licenses/publicdomain/ */
 
 var names = [
     "iterator",
     "match",
-    "search",
     "species",
     "toPrimitive",
     "unscopables"
 ];
 
 for (var name of names) {
     // Well-known symbols exist.
     assertEq(typeof Symbol[name], "symbol");
--- a/js/src/vm/CommonPropertyNames.h
+++ b/js/src/vm/CommonPropertyNames.h
@@ -303,25 +303,23 @@
     macro(number, number, "number") \
     macro(boolean, boolean, "boolean") \
     macro(null, null, "null") \
     macro(symbol, symbol, "symbol") \
     /* Well-known atom names must be continuous and ordered, matching \
      * enum JS::SymbolCode in jsapi.h. */ \
     macro(iterator, iterator, "iterator") \
     macro(match, match, "match") \
-    macro(search, search, "search") \
     macro(species, species, "species") \
     macro(toPrimitive, toPrimitive, "toPrimitive") \
     macro(unscopables, unscopables, "unscopables") \
     /* Same goes for the descriptions of the well-known symbols. */ \
     macro(Symbol_hasInstance, Symbol_hasInstance, "Symbol.hasInstance") \
     macro(Symbol_isConcatSpreadable, Symbol_isConcatSpreadable, "Symbol.isConcatSpreadable") \
     macro(Symbol_iterator, Symbol_iterator, "Symbol.iterator") \
     macro(Symbol_match,    Symbol_match,    "Symbol.match") \
-    macro(Symbol_search,   Symbol_search,   "Symbol.search") \
     macro(Symbol_species,  Symbol_species,  "Symbol.species") \
     macro(Symbol_toPrimitive, Symbol_toPrimitive, "Symbol.toPrimitive") \
     macro(Symbol_unscopables, Symbol_unscopables, "Symbol.unscopables") \
     /* Function names for properties named by symbols. */ \
     macro(Symbol_iterator_fun, Symbol_iterator_fun, "[Symbol.iterator]") \
 
 #endif /* vm_CommonPropertyNames_h */
--- a/js/src/vm/GlobalObject.cpp
+++ b/js/src/vm/GlobalObject.cpp
@@ -456,24 +456,16 @@ GlobalObject::initSelfHostingBuiltins(JS
     RootedValue std_match(cx);
     std_match.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::match));
     if (!JS_DefineProperty(cx, global, "std_match", std_match,
                            JSPROP_PERMANENT | JSPROP_READONLY))
     {
         return false;
     }
 
-    RootedValue std_search(cx);
-    std_search.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::search));
-    if (!JS_DefineProperty(cx, global, "std_search", std_search,
-                           JSPROP_PERMANENT | JSPROP_READONLY))
-    {
-        return false;
-    }
-
     RootedValue std_species(cx);
     std_species.setSymbol(cx->wellKnownSymbols().get(JS::SymbolCode::species));
     if (!JS_DefineProperty(cx, global, "std_species", std_species,
                            JSPROP_PERMANENT | JSPROP_READONLY))
     {
         return false;
     }
 
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -2416,17 +2416,16 @@ static const JSFunctionSpec intrinsic_fu
                     RegExpTester),
     JS_FN("RegExpCreate", intrinsic_RegExpCreate, 2,0),
     JS_INLINABLE_FN("RegExpPrototypeOptimizable", RegExpPrototypeOptimizable, 1,0,
                     RegExpPrototypeOptimizable),
     JS_INLINABLE_FN("RegExpInstanceOptimizable", RegExpInstanceOptimizable, 1,0,
                     RegExpInstanceOptimizable),
 
     JS_FN("FlatStringMatch", FlatStringMatch, 2,0),
-    JS_FN("FlatStringSearch", FlatStringSearch, 2,0),
 
     // See builtin/RegExp.h for descriptions of the regexp_* functions.
     JS_FN("regexp_exec_no_statics", regexp_exec_no_statics, 2,0),
     JS_FN("regexp_test_no_statics", regexp_test_no_statics, 2,0),
     JS_FN("regexp_construct", regexp_construct_self_hosting, 2,0),
 
     JS_FN("IsMatchFlagsArgumentEnabled", IsMatchFlagsArgumentEnabled, 0,0),
     JS_FN("WarnOnceAboutFlagsArgument", WarnOnceAboutFlagsArgument, 0,0),
--- a/js/xpconnect/tests/chrome/test_xrayToJS.xul
+++ b/js/xpconnect/tests/chrome/test_xrayToJS.xul
@@ -222,17 +222,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 
   gPrototypeProperties['Function'] =
     ["constructor", "toSource", "toString", "apply", "call", "bind",
      "isGenerator", "length", "name", "arguments", "caller"];
   gConstructorProperties['Function'] = constructorProps([])
 
   gPrototypeProperties['RegExp'] =
     ["constructor", "toSource", "toString", "compile", "exec", "test",
-     Symbol.match, Symbol.search,
+     Symbol.match,
      "flags", "global", "ignoreCase", "multiline", "source", "sticky", "unicode",
      "lastIndex"];
   gConstructorProperties['RegExp'] =
     constructorProps(["input", "lastMatch", "lastParen",
                       "leftContext", "rightContext", "$1", "$2", "$3", "$4",
                       "$5", "$6", "$7", "$8", "$9", "$_", "$&", "$+",
                       "$`", "$'"])