mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-26 03:35:33 +00:00
Backed out changeset f23a61067cef (bug 887016)
This commit is contained in:
parent
1a7246417a
commit
0be2d6fd80
@ -645,7 +645,6 @@ const JSFunctionSpec js::regexp_methods[] = {
|
||||
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
|
||||
};
|
||||
|
||||
@ -1086,12 +1085,14 @@ js::RegExpPrototypeOptimizableRaw(JSContext* cx, JSObject* proto, uint8_t* resul
|
||||
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;
|
||||
|
@ -147,38 +147,6 @@ function RegExpMatch(string) {
|
||||
}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
|
@ -71,69 +71,6 @@ function String_generic_match(thisValue, regexp) {
|
||||
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.
|
||||
|
@ -2189,7 +2189,8 @@ MustCloneRegExpForCall(MCall* call, uint32_t useIndex)
|
||||
|
||||
if (useIndex == MCall::IndexOfArgument(0) &&
|
||||
(target->native() == str_split ||
|
||||
target->native() == str_replace))
|
||||
target->native() == str_replace ||
|
||||
target->native() == str_search))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -4866,7 +4866,6 @@ GetSymbolDescription(HandleSymbol symbol);
|
||||
#define JS_FOR_EACH_WELL_KNOWN_SYMBOL(macro) \
|
||||
macro(iterator) \
|
||||
macro(match) \
|
||||
macro(search) \
|
||||
macro(species) \
|
||||
macro(toPrimitive) \
|
||||
macro(unscopables)
|
||||
|
@ -2295,6 +2295,51 @@ AdvanceStringIndex(HandleLinearString input, size_t length, size_t index, bool u
|
||||
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;
|
||||
@ -3948,7 +3993,7 @@ static const JSFunctionSpec string_methods[] = {
|
||||
|
||||
/* 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),
|
||||
@ -4103,7 +4148,6 @@ static const JSFunctionSpec string_static_methods[] = {
|
||||
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.
|
||||
@ -5260,34 +5304,3 @@ js::FlatStringMatch(JSContext* cx, unsigned argc, Value* vp)
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -430,6 +430,9 @@ FileEscapedString(FILE* fp, const char* chars, size_t length, uint32_t quote)
|
||||
return res;
|
||||
}
|
||||
|
||||
bool
|
||||
str_search(JSContext* cx, unsigned argc, Value* vp);
|
||||
|
||||
bool
|
||||
str_split(JSContext* cx, unsigned argc, Value* vp);
|
||||
|
||||
@ -450,9 +453,6 @@ 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 */
|
||||
|
@ -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);
|
@ -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);
|
@ -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);
|
@ -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);
|
@ -4,7 +4,6 @@
|
||||
var names = [
|
||||
"iterator",
|
||||
"match",
|
||||
"search",
|
||||
"species",
|
||||
"toPrimitive",
|
||||
"unscopables"
|
||||
|
@ -308,7 +308,6 @@
|
||||
* 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") \
|
||||
@ -317,7 +316,6 @@
|
||||
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") \
|
||||
|
@ -461,14 +461,6 @@ GlobalObject::initSelfHostingBuiltins(JSContext* cx, Handle<GlobalObject*> globa
|
||||
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,
|
||||
|
@ -2421,7 +2421,6 @@ static const JSFunctionSpec intrinsic_functions[] = {
|
||||
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),
|
||||
|
@ -227,7 +227,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681
|
||||
|
||||
gPrototypeProperties['RegExp'] =
|
||||
["constructor", "toSource", "toString", "compile", "exec", "test",
|
||||
Symbol.match, Symbol.search,
|
||||
Symbol.match,
|
||||
"flags", "global", "ignoreCase", "multiline", "source", "sticky", "unicode",
|
||||
"lastIndex"];
|
||||
gConstructorProperties['RegExp'] =
|
||||
|
Loading…
Reference in New Issue
Block a user