Backed out changeset f23a61067cef (bug 887016)

This commit is contained in:
Tooru Fujisawa 2016-03-28 06:49:54 +09:00
parent 1a7246417a
commit 0be2d6fd80
16 changed files with 54 additions and 288 deletions

View File

@ -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;

View File

@ -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) {

View File

@ -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.

View File

@ -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;
}

View File

@ -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)

View File

@ -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;
}

View File

@ -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 */

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -4,7 +4,6 @@
var names = [
"iterator",
"match",
"search",
"species",
"toPrimitive",
"unscopables"

View File

@ -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") \

View File

@ -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,

View File

@ -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),

View File

@ -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'] =