Revert of Implement flag and source getters on RegExp.prototype. (patchset #3 id:50001 of https://codereview.chromium.org/1419823010/ )

Reason for revert:
[Sheriff] Changes layout tests. Please rebase upstream first. E.g.:
http://build.chromium.org/p/client.v8.fyi/builders/V8-Blink%20Linux%2064/builds/2686

Original issue's description:
> Implement flag and source getters on RegExp.prototype.
>
> R=littledan@chromium.org
> BUG=v8:3715, v8:4528
> LOG=Y
>
> Committed: https://crrev.com/60e8877e161fe6175e19fafce2d6ed1c3999cdb1
> Cr-Commit-Position: refs/heads/master@{#31753}

TBR=littledan@chromium.org,jochen@chromium.org,ulan@chromium.org,yangguo@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=v8:3715, v8:4528

Review URL: https://codereview.chromium.org/1427733005

Cr-Commit-Position: refs/heads/master@{#31758}
This commit is contained in:
machenbach 2015-11-03 09:27:56 -08:00 committed by Commit bot
parent 6eb5dae536
commit 16e25179ec
20 changed files with 175 additions and 222 deletions

View File

@ -4001,9 +4001,7 @@ class V8_EXPORT RegExp : public Object {
kNone = 0, kNone = 0,
kGlobal = 1, kGlobal = 1,
kIgnoreCase = 2, kIgnoreCase = 2,
kMultiline = 4, kMultiline = 4
kSticky = 8,
kUnicode = 16
}; };
/** /**

View File

@ -6147,8 +6147,6 @@ REGEXP_FLAG_ASSERT_EQ(kNone, NONE);
REGEXP_FLAG_ASSERT_EQ(kGlobal, GLOBAL); REGEXP_FLAG_ASSERT_EQ(kGlobal, GLOBAL);
REGEXP_FLAG_ASSERT_EQ(kIgnoreCase, IGNORE_CASE); REGEXP_FLAG_ASSERT_EQ(kIgnoreCase, IGNORE_CASE);
REGEXP_FLAG_ASSERT_EQ(kMultiline, MULTILINE); REGEXP_FLAG_ASSERT_EQ(kMultiline, MULTILINE);
REGEXP_FLAG_ASSERT_EQ(kSticky, STICKY);
REGEXP_FLAG_ASSERT_EQ(kUnicode, UNICODE_ESCAPES);
#undef REGEXP_FLAG_ASSERT_EQ #undef REGEXP_FLAG_ASSERT_EQ
v8::RegExp::Flags v8::RegExp::GetFlags() const { v8::RegExp::Flags v8::RegExp::GetFlags() const {

View File

@ -1228,16 +1228,31 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
Map::EnsureDescriptorSlack(initial_map, 5); Map::EnsureDescriptorSlack(initial_map, 5);
{ {
// ES6 21.2.3.2.1 // ECMA-262, section 15.10.7.1.
DataDescriptor field(factory->regexp_source_symbol(), DataDescriptor field(factory->source_string(),
JSRegExp::kSourceFieldIndex, final, JSRegExp::kSourceFieldIndex, final,
Representation::Tagged()); Representation::Tagged());
initial_map->AppendDescriptor(&field); initial_map->AppendDescriptor(&field);
} }
{ {
DataDescriptor field(factory->regexp_flags_symbol(), // ECMA-262, section 15.10.7.2.
JSRegExp::kFlagsFieldIndex, final, DataDescriptor field(factory->global_string(),
Representation::Smi()); JSRegExp::kGlobalFieldIndex, final,
Representation::Tagged());
initial_map->AppendDescriptor(&field);
}
{
// ECMA-262, section 15.10.7.3.
DataDescriptor field(factory->ignore_case_string(),
JSRegExp::kIgnoreCaseFieldIndex, final,
Representation::Tagged());
initial_map->AppendDescriptor(&field);
}
{
// ECMA-262, section 15.10.7.4.
DataDescriptor field(factory->multiline_string(),
JSRegExp::kMultilineFieldIndex, final,
Representation::Tagged());
initial_map->AppendDescriptor(&field); initial_map->AppendDescriptor(&field);
} }
{ {

View File

@ -249,6 +249,7 @@ namespace internal {
V(Generator_string, "Generator") \ V(Generator_string, "Generator") \
V(get_string, "get") \ V(get_string, "get") \
V(global_string, "global") \ V(global_string, "global") \
V(ignore_case_string, "ignoreCase") \
V(illegal_access_string, "illegal access") \ V(illegal_access_string, "illegal access") \
V(illegal_argument_string, "illegal argument") \ V(illegal_argument_string, "illegal argument") \
V(index_string, "index") \ V(index_string, "index") \
@ -267,6 +268,7 @@ namespace internal {
V(Map_string, "Map") \ V(Map_string, "Map") \
V(minus_infinity_string, "-Infinity") \ V(minus_infinity_string, "-Infinity") \
V(minus_zero_string, "-0") \ V(minus_zero_string, "-0") \
V(multiline_string, "multiline") \
V(name_string, "name") \ V(name_string, "name") \
V(nan_string, "NaN") \ V(nan_string, "NaN") \
V(next_string, "next") \ V(next_string, "next") \
@ -286,6 +288,7 @@ namespace internal {
V(source_string, "source") \ V(source_string, "source") \
V(source_url_string, "source_url") \ V(source_url_string, "source_url") \
V(stack_string, "stack") \ V(stack_string, "stack") \
V(sticky_string, "sticky") \
V(strict_compare_ic_string, "===") \ V(strict_compare_ic_string, "===") \
V(string_string, "string") \ V(string_string, "string") \
V(String_string, "String") \ V(String_string, "String") \
@ -302,6 +305,7 @@ namespace internal {
V(uint8x16_string, "uint8x16") \ V(uint8x16_string, "uint8x16") \
V(Uint8x16_string, "Uint8x16") \ V(Uint8x16_string, "Uint8x16") \
V(undefined_string, "undefined") \ V(undefined_string, "undefined") \
V(unicode_string, "unicode") \
V(valueOf_string, "valueOf") \ V(valueOf_string, "valueOf") \
V(value_string, "value") \ V(value_string, "value") \
V(WeakMap_string, "WeakMap") \ V(WeakMap_string, "WeakMap") \
@ -345,8 +349,6 @@ namespace internal {
V(promise_raw_symbol) \ V(promise_raw_symbol) \
V(promise_status_symbol) \ V(promise_status_symbol) \
V(promise_value_symbol) \ V(promise_value_symbol) \
V(regexp_flags_symbol) \
V(regexp_source_symbol) \
V(sealed_symbol) \ V(sealed_symbol) \
V(stack_trace_symbol) \ V(stack_trace_symbol) \
V(string_iterator_iterated_string_symbol) \ V(string_iterator_iterated_string_symbol) \
@ -355,6 +357,7 @@ namespace internal {
#define PUBLIC_SYMBOL_LIST(V) \ #define PUBLIC_SYMBOL_LIST(V) \
V(has_instance_symbol, Symbol.hasInstance) \ V(has_instance_symbol, Symbol.hasInstance) \
V(is_regexp_symbol, Symbol.isRegExp) \
V(iterator_symbol, Symbol.iterator) \ V(iterator_symbol, Symbol.iterator) \
V(match_symbol, Symbol.match) \ V(match_symbol, Symbol.match) \
V(replace_symbol, Symbol.replace) \ V(replace_symbol, Symbol.replace) \

View File

@ -11,7 +11,6 @@
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Imports // Imports
var GetRegExpFlagGetter = utils.ImportNow("GetRegExpFlagGetter");
var GlobalRegExp = global.RegExp; var GlobalRegExp = global.RegExp;
var MakeTypeError; var MakeTypeError;
@ -25,8 +24,7 @@ utils.Import(function(from) {
// + https://bugs.ecmascript.org/show_bug.cgi?id=3423 // + https://bugs.ecmascript.org/show_bug.cgi?id=3423
function RegExpGetFlags() { function RegExpGetFlags() {
if (!IS_SPEC_OBJECT(this)) { if (!IS_SPEC_OBJECT(this)) {
throw MakeTypeError( throw MakeTypeError(kFlagsGetterNonObject, TO_STRING(this));
kRegExpNonObject, "RegExp.prototype.flags", TO_STRING(this));
} }
var result = ''; var result = '';
if (this.global) result += 'g'; if (this.global) result += 'g';
@ -41,11 +39,4 @@ function RegExpGetFlags() {
RegExpGetFlags, null, DONT_ENUM); RegExpGetFlags, null, DONT_ENUM);
%SetNativeFlag(RegExpGetFlags); %SetNativeFlag(RegExpGetFlags);
%DefineGetterPropertyUnchecked(GlobalRegExp.prototype, "sticky",
GetRegExpFlagGetter("RegExp.prototype.sticky", REGEXP_STICKY_MASK),
DONT_ENUM);
%DefineGetterPropertyUnchecked(GlobalRegExp.prototype, "unicode",
GetRegExpFlagGetter("RegExp.prototype.unicode", REGEXP_UNICODE_MASK),
DONT_ENUM);
}) })

View File

@ -178,20 +178,6 @@ python macro CHAR_CODE(str) = ord(str[1]);
define REGEXP_NUMBER_OF_CAPTURES = 0; define REGEXP_NUMBER_OF_CAPTURES = 0;
define REGEXP_FIRST_CAPTURE = 3; define REGEXP_FIRST_CAPTURE = 3;
# Constants and macros for internal slot access.
define REGEXP_GLOBAL_MASK = 1;
define REGEXP_IGNORE_CASE_MASK = 2;
define REGEXP_MULTILINE_MASK = 4;
define REGEXP_STICKY_MASK = 8;
define REGEXP_UNICODE_MASK = 16;
macro REGEXP_GLOBAL(regexp) = (regexp[regExpFlagsSymbol] & REGEXP_GLOBAL_MASK);
macro REGEXP_IGNORE_CASE(regexp) = (regexp[regExpFlagsSymbol] & REGEXP_IGNORE_CASE_MASK);
macro REGEXP_MULTILINE(regexp) = (regexp[regExpFlagsSymbol] & REGEXP_MULTILINE_MASK);
macro REGEXP_STICKY(regexp) = (regexp[regExpFlagsSymbol] & REGEXP_STICKY_MASK);
macro REGEXP_UNICODE(regexp) = (regexp[regExpFlagsSymbol] & REGEXP_UNICODE_MASK);
macro REGEXP_SOURCE(regexp) = (regexp[regExpSourceSymbol]);
# We can't put macros in macros so we use constants here. # We can't put macros in macros so we use constants here.
# REGEXP_NUMBER_OF_CAPTURES # REGEXP_NUMBER_OF_CAPTURES
macro NUMBER_OF_CAPTURES(array) = ((array)[0]); macro NUMBER_OF_CAPTURES(array) = ((array)[0]);

View File

@ -175,7 +175,6 @@ function PostNatives(utils) {
"FunctionSourceString", "FunctionSourceString",
"GetIterator", "GetIterator",
"GetMethod", "GetMethod",
"GetRegExpFlagGetter",
"InnerArrayEvery", "InnerArrayEvery",
"InnerArrayFilter", "InnerArrayFilter",
"InnerArrayForEach", "InnerArrayForEach",

View File

@ -16,8 +16,6 @@ var GlobalObject = global.Object;
var GlobalRegExp = global.RegExp; var GlobalRegExp = global.RegExp;
var InternalPackedArray = utils.InternalPackedArray; var InternalPackedArray = utils.InternalPackedArray;
var MakeTypeError; var MakeTypeError;
var regExpFlagsSymbol = utils.ImportNow("regexp_flags_symbol");
var regExpSourceSymbol = utils.ImportNow("regexp_source_symbol");
utils.ImportFromExperimental(function(from) { utils.ImportFromExperimental(function(from) {
FLAG_harmony_regexps = from.FLAG_harmony_regexps; FLAG_harmony_regexps = from.FLAG_harmony_regexps;
@ -53,14 +51,14 @@ function DoConstructRegExp(object, pattern, flags) {
// RegExp : Called as constructor; see ECMA-262, section 15.10.4. // RegExp : Called as constructor; see ECMA-262, section 15.10.4.
if (IS_REGEXP(pattern)) { if (IS_REGEXP(pattern)) {
if (!IS_UNDEFINED(flags)) throw MakeTypeError(kRegExpFlags); if (!IS_UNDEFINED(flags)) throw MakeTypeError(kRegExpFlags);
flags = (REGEXP_GLOBAL(pattern) ? 'g' : '') flags = (pattern.global ? 'g' : '')
+ (REGEXP_IGNORE_CASE(pattern) ? 'i' : '') + (pattern.ignoreCase ? 'i' : '')
+ (REGEXP_MULTILINE(pattern) ? 'm' : ''); + (pattern.multiline ? 'm' : '');
if (FLAG_harmony_unicode_regexps) if (FLAG_harmony_unicode_regexps)
flags += (REGEXP_UNICODE(pattern) ? 'u' : ''); flags += (pattern.unicode ? 'u' : '');
if (FLAG_harmony_regexps) if (FLAG_harmony_regexps)
flags += (REGEXP_STICKY(pattern) ? 'y' : ''); flags += (pattern.sticky ? 'y' : '');
pattern = REGEXP_SOURCE(pattern); pattern = pattern.source;
} }
pattern = IS_UNDEFINED(pattern) ? '' : TO_STRING(pattern); pattern = IS_UNDEFINED(pattern) ? '' : TO_STRING(pattern);
@ -167,8 +165,7 @@ function RegExpExecJS(string) {
// algorithm, step 4) even if the value is discarded for non-global RegExps. // algorithm, step 4) even if the value is discarded for non-global RegExps.
var i = TO_LENGTH_OR_INTEGER(lastIndex); var i = TO_LENGTH_OR_INTEGER(lastIndex);
var updateLastIndex = REGEXP_GLOBAL(this) || var updateLastIndex = this.global || (FLAG_harmony_regexps && this.sticky);
(FLAG_harmony_regexps && REGEXP_STICKY(this));
if (updateLastIndex) { if (updateLastIndex) {
if (i < 0 || i > string.length) { if (i < 0 || i > string.length) {
this.lastIndex = 0; this.lastIndex = 0;
@ -215,7 +212,7 @@ function RegExpTest(string) {
// algorithm, step 4) even if the value is discarded for non-global RegExps. // algorithm, step 4) even if the value is discarded for non-global RegExps.
var i = TO_LENGTH_OR_INTEGER(lastIndex); var i = TO_LENGTH_OR_INTEGER(lastIndex);
if (REGEXP_GLOBAL(this) || (FLAG_harmony_regexps && REGEXP_STICKY(this))) { if (this.global || (FLAG_harmony_regexps && this.sticky)) {
if (i < 0 || i > string.length) { if (i < 0 || i > string.length) {
this.lastIndex = 0; this.lastIndex = 0;
return false; return false;
@ -234,11 +231,10 @@ function RegExpTest(string) {
// checks whether this.source starts with '.*' and that the third char is // checks whether this.source starts with '.*' and that the third char is
// not a '?'. But see https://code.google.com/p/v8/issues/detail?id=3560 // not a '?'. But see https://code.google.com/p/v8/issues/detail?id=3560
var regexp = this; var regexp = this;
var source = REGEXP_SOURCE(regexp); if (regexp.source.length >= 3 &&
if (regexp.length >= 3 && %_StringCharCodeAt(regexp.source, 0) == 46 && // '.'
%_StringCharCodeAt(regexp, 0) == 46 && // '.' %_StringCharCodeAt(regexp.source, 1) == 42 && // '*'
%_StringCharCodeAt(regexp, 1) == 42 && // '*' %_StringCharCodeAt(regexp.source, 2) != 63) { // '?'
%_StringCharCodeAt(regexp, 2) != 63) { // '?'
regexp = TrimRegExp(regexp); regexp = TrimRegExp(regexp);
} }
// matchIndices is either null or the RegExpLastMatchInfo array. // matchIndices is either null or the RegExpLastMatchInfo array.
@ -255,10 +251,9 @@ function TrimRegExp(regexp) {
if (!%_ObjectEquals(regexp_key, regexp)) { if (!%_ObjectEquals(regexp_key, regexp)) {
regexp_key = regexp; regexp_key = regexp;
regexp_val = regexp_val =
new GlobalRegExp( new GlobalRegExp(%_SubString(regexp.source, 2, regexp.source.length),
%_SubString(REGEXP_SOURCE(regexp), 2, REGEXP_SOURCE(regexp).length), (regexp.ignoreCase ? regexp.multiline ? "im" : "i"
(REGEXP_IGNORE_CASE(regexp) ? REGEXP_MULTILINE(regexp) ? "im" : "i" : regexp.multiline ? "m" : ""));
: REGEXP_MULTILINE(regexp) ? "m" : ""));
} }
return regexp_val; return regexp_val;
} }
@ -269,12 +264,12 @@ function RegExpToString() {
throw MakeTypeError(kIncompatibleMethodReceiver, throw MakeTypeError(kIncompatibleMethodReceiver,
'RegExp.prototype.toString', this); 'RegExp.prototype.toString', this);
} }
var result = '/' + REGEXP_SOURCE(this) + '/'; var result = '/' + this.source + '/';
if (REGEXP_GLOBAL(this)) result += 'g'; if (this.global) result += 'g';
if (REGEXP_IGNORE_CASE(this)) result += 'i'; if (this.ignoreCase) result += 'i';
if (REGEXP_MULTILINE(this)) result += 'm'; if (this.multiline) result += 'm';
if (FLAG_harmony_unicode_regexps && REGEXP_UNICODE(this)) result += 'u'; if (FLAG_harmony_unicode_regexps && this.unicode) result += 'u';
if (FLAG_harmony_regexps && REGEXP_STICKY(this)) result += 'y'; if (FLAG_harmony_regexps && this.sticky) result += 'y';
return result; return result;
} }
@ -339,40 +334,6 @@ function RegExpMakeCaptureGetter(n) {
}; };
} }
// ES6 21.2.5.4, 21.2.5.5, 21.2.5.7, 21.2.5.12, 21.2.5.15.
function GetRegExpFlagGetter(name, mask) {
var getter = function() {
if (!IS_SPEC_OBJECT(this)) {
throw MakeTypeError(kRegExpNonObject, name, TO_STRING(this));
}
var flags = this[regExpFlagsSymbol];
if (IS_UNDEFINED(flags)) {
throw MakeTypeError(kRegExpNonRegExp, TO_STRING(this));
}
return !!(flags & mask);
};
%FunctionSetName(getter, name);
%SetNativeFlag(getter);
return getter;
}
// ES6 21.2.5.10.
function RegExpGetSource() {
if (!IS_SPEC_OBJECT(this)) {
throw MakeTypeError(kRegExpNonObject, "RegExp.prototype.source",
TO_STRING(this));
}
var source = this[regExpSourceSymbol];
if (IS_UNDEFINED(source)) {
throw MakeTypeError(kRegExpNonRegExp, TO_STRING(this));
}
return source;
}
%SetNativeFlag(RegExpGetSource);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
%FunctionSetInstanceClassName(GlobalRegExp, 'RegExp'); %FunctionSetInstanceClassName(GlobalRegExp, 'RegExp');
@ -388,18 +349,6 @@ utils.InstallFunctions(GlobalRegExp.prototype, DONT_ENUM, [
"compile", RegExpCompileJS "compile", RegExpCompileJS
]); ]);
%DefineGetterPropertyUnchecked(GlobalRegExp.prototype, "global",
GetRegExpFlagGetter("RegExp.prototype.global", REGEXP_GLOBAL_MASK),
DONT_ENUM);
%DefineGetterPropertyUnchecked(GlobalRegExp.prototype, "ignoreCase",
GetRegExpFlagGetter("RegExp.prototype.ignoreCase", REGEXP_IGNORE_CASE_MASK),
DONT_ENUM);
%DefineGetterPropertyUnchecked(GlobalRegExp.prototype, "multiline",
GetRegExpFlagGetter("RegExp.prototype.multiline", REGEXP_MULTILINE_MASK),
DONT_ENUM);
%DefineGetterPropertyUnchecked(GlobalRegExp.prototype, "source",
RegExpGetSource, DONT_ENUM);
// The length of compile is 1 in SpiderMonkey. // The length of compile is 1 in SpiderMonkey.
%FunctionSetLength(GlobalRegExp.prototype.compile, 1); %FunctionSetLength(GlobalRegExp.prototype.compile, 1);
@ -473,7 +422,6 @@ for (var i = 1; i < 10; ++i) {
// Exports // Exports
utils.Export(function(to) { utils.Export(function(to) {
to.GetRegExpFlagGetter = GetRegExpFlagGetter;
to.RegExpExec = DoRegExpExec; to.RegExpExec = DoRegExpExec;
to.RegExpExecNoTests = RegExpExecNoTests; to.RegExpExecNoTests = RegExpExecNoTests;
to.RegExpLastMatchInfo = RegExpLastMatchInfo; to.RegExpLastMatchInfo = RegExpLastMatchInfo;

View File

@ -19,7 +19,6 @@ var MakeRangeError;
var MakeTypeError; var MakeTypeError;
var RegExpExec; var RegExpExec;
var RegExpExecNoTests; var RegExpExecNoTests;
var regExpFlagsSymbol = utils.ImportNow("regexp_flags_symbol");
var RegExpLastMatchInfo; var RegExpLastMatchInfo;
utils.Import(function(from) { utils.Import(function(from) {
@ -156,7 +155,7 @@ function StringMatchJS(regexp) {
var subject = TO_STRING(this); var subject = TO_STRING(this);
if (IS_REGEXP(regexp)) { if (IS_REGEXP(regexp)) {
if (!REGEXP_GLOBAL(regexp)) return RegExpExecNoTests(regexp, subject, 0); if (!regexp.global) return RegExpExecNoTests(regexp, subject, 0);
var result = %StringMatch(subject, regexp, RegExpLastMatchInfo); var result = %StringMatch(subject, regexp, RegExpLastMatchInfo);
regexp.lastIndex = 0; regexp.lastIndex = 0;
return result; return result;
@ -226,7 +225,7 @@ function StringReplace(search, replace) {
if (!IS_CALLABLE(replace)) { if (!IS_CALLABLE(replace)) {
replace = TO_STRING(replace); replace = TO_STRING(replace);
if (!REGEXP_GLOBAL(search)) { if (!search.global) {
// Non-global regexp search, string replace. // Non-global regexp search, string replace.
var match = RegExpExec(search, subject, 0); var match = RegExpExec(search, subject, 0);
if (match == null) { if (match == null) {
@ -248,7 +247,7 @@ function StringReplace(search, replace) {
subject, search, replace, RegExpLastMatchInfo); subject, search, replace, RegExpLastMatchInfo);
} }
if (REGEXP_GLOBAL(search)) { if (search.global) {
// Global regexp search, function replace. // Global regexp search, function replace.
return StringReplaceGlobalRegExpWithFunction(subject, search, replace); return StringReplaceGlobalRegExpWithFunction(subject, search, replace);
} }

View File

@ -16,6 +16,7 @@ var GlobalSymbol = global.Symbol;
var hasInstanceSymbol = utils.ImportNow("has_instance_symbol"); var hasInstanceSymbol = utils.ImportNow("has_instance_symbol");
var isConcatSpreadableSymbol = var isConcatSpreadableSymbol =
utils.ImportNow("is_concat_spreadable_symbol"); utils.ImportNow("is_concat_spreadable_symbol");
var isRegExpSymbol = utils.ImportNow("is_regexp_symbol");
var iteratorSymbol = utils.ImportNow("iterator_symbol"); var iteratorSymbol = utils.ImportNow("iterator_symbol");
var MakeTypeError; var MakeTypeError;
var ObjectGetOwnPropertyKeys; var ObjectGetOwnPropertyKeys;
@ -93,6 +94,7 @@ utils.InstallConstants(GlobalSymbol, [
// TODO(rossberg): expose when implemented. // TODO(rossberg): expose when implemented.
// "hasInstance", hasInstanceSymbol, // "hasInstance", hasInstanceSymbol,
// "isConcatSpreadable", isConcatSpreadableSymbol, // "isConcatSpreadable", isConcatSpreadableSymbol,
// "isRegExp", isRegExpSymbol,
"iterator", iteratorSymbol, "iterator", iteratorSymbol,
// TODO(yangguo): expose when implemented. // TODO(yangguo): expose when implemented.
// "match", matchSymbol, // "match", matchSymbol,

View File

@ -116,6 +116,8 @@ class CallSite {
"Class extends value % is not a function or null") \ "Class extends value % is not a function or null") \
T(FirstArgumentNotRegExp, \ T(FirstArgumentNotRegExp, \
"First argument to % must not be a regular expression") \ "First argument to % must not be a regular expression") \
T(FlagsGetterNonObject, \
"RegExp.prototype.flags getter called on non-object %") \
T(FunctionBind, "Bind must be called on a function") \ T(FunctionBind, "Bind must be called on a function") \
T(GeneratorRunning, "Generator is already running") \ T(GeneratorRunning, "Generator is already running") \
T(IllegalInvocation, "Illegal invocation") \ T(IllegalInvocation, "Illegal invocation") \
@ -200,8 +202,6 @@ class CallSite {
T(ReduceNoInitial, "Reduce of empty array with no initial value") \ T(ReduceNoInitial, "Reduce of empty array with no initial value") \
T(RegExpFlags, \ T(RegExpFlags, \
"Cannot supply flags when constructing one RegExp from another") \ "Cannot supply flags when constructing one RegExp from another") \
T(RegExpNonObject, "% getter called on non-object %") \
T(RegExpNonRegExp, "% is not an RegExp object") \
T(ReinitializeIntl, "Trying to re-initialize % object.") \ T(ReinitializeIntl, "Trying to re-initialize % object.") \
T(ResolvedOptionsCalledOnNonObject, \ T(ResolvedOptionsCalledOnNonObject, \
"resolvedOptions method called on a non-object or on a object that is " \ "resolvedOptions method called on a non-object or on a object that is " \

View File

@ -7785,9 +7785,11 @@ class JSRegExp: public JSObject {
// In-object fields. // In-object fields.
static const int kSourceFieldIndex = 0; static const int kSourceFieldIndex = 0;
static const int kFlagsFieldIndex = 1; static const int kGlobalFieldIndex = 1;
static const int kLastIndexFieldIndex = 2; static const int kIgnoreCaseFieldIndex = 2;
static const int kInObjectFieldCount = 3; static const int kMultilineFieldIndex = 3;
static const int kLastIndexFieldIndex = 4;
static const int kInObjectFieldCount = 5;
// The uninitialized value for a regexp code object. // The uninitialized value for a regexp code object.
static const int kUninitializedValue = -1; static const int kUninitializedValue = -1;

View File

@ -924,14 +924,26 @@ RUNTIME_FUNCTION(Runtime_RegExpInitializeAndCompile) {
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, escaped_source, ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, escaped_source,
EscapeRegExpSource(isolate, source)); EscapeRegExpSource(isolate, source));
Handle<Object> global = factory->ToBoolean(flags.is_global());
Handle<Object> ignore_case = factory->ToBoolean(flags.is_ignore_case());
Handle<Object> multiline = factory->ToBoolean(flags.is_multiline());
Handle<Object> sticky = factory->ToBoolean(flags.is_sticky());
Handle<Object> unicode = factory->ToBoolean(flags.is_unicode());
Map* map = regexp->map(); Map* map = regexp->map();
Object* constructor = map->GetConstructor(); Object* constructor = map->GetConstructor();
if (constructor->IsJSFunction() && if (!FLAG_harmony_regexps && !FLAG_harmony_unicode_regexps &&
constructor->IsJSFunction() &&
JSFunction::cast(constructor)->initial_map() == map) { JSFunction::cast(constructor)->initial_map() == map) {
// If we still have the original map, set in-object properties directly. // If we still have the original map, set in-object properties directly.
regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, *escaped_source); regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, *escaped_source);
regexp->InObjectPropertyAtPut(JSRegExp::kFlagsFieldIndex, // Both true and false are immovable immortal objects so no need for write
Smi::FromInt(flags.value()), // barrier.
regexp->InObjectPropertyAtPut(JSRegExp::kGlobalFieldIndex, *global,
SKIP_WRITE_BARRIER);
regexp->InObjectPropertyAtPut(JSRegExp::kIgnoreCaseFieldIndex, *ignore_case,
SKIP_WRITE_BARRIER);
regexp->InObjectPropertyAtPut(JSRegExp::kMultilineFieldIndex, *multiline,
SKIP_WRITE_BARRIER); SKIP_WRITE_BARRIER);
regexp->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex, regexp->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex,
Smi::FromInt(0), SKIP_WRITE_BARRIER); Smi::FromInt(0), SKIP_WRITE_BARRIER);
@ -946,13 +958,22 @@ RUNTIME_FUNCTION(Runtime_RegExpInitializeAndCompile) {
PropertyAttributes writable = PropertyAttributes writable =
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
Handle<Object> zero(Smi::FromInt(0), isolate); Handle<Object> zero(Smi::FromInt(0), isolate);
JSObject::SetOwnPropertyIgnoreAttributes(regexp, factory->source_string(),
escaped_source, final).Check();
JSObject::SetOwnPropertyIgnoreAttributes(regexp, factory->global_string(),
global, final).Check();
JSObject::SetOwnPropertyIgnoreAttributes( JSObject::SetOwnPropertyIgnoreAttributes(
regexp, factory->regexp_source_symbol(), escaped_source, final) regexp, factory->ignore_case_string(), ignore_case, final).Check();
.Check();
JSObject::SetOwnPropertyIgnoreAttributes( JSObject::SetOwnPropertyIgnoreAttributes(
regexp, factory->regexp_flags_symbol(), regexp, factory->multiline_string(), multiline, final).Check();
Handle<Smi>(Smi::FromInt(flags.value()), isolate), final) if (FLAG_harmony_regexps) {
.Check(); JSObject::SetOwnPropertyIgnoreAttributes(regexp, factory->sticky_string(),
sticky, final).Check();
}
if (FLAG_harmony_unicode_regexps) {
JSObject::SetOwnPropertyIgnoreAttributes(
regexp, factory->unicode_string(), unicode, final).Check();
}
JSObject::SetOwnPropertyIgnoreAttributes( JSObject::SetOwnPropertyIgnoreAttributes(
regexp, factory->last_index_string(), zero, writable).Check(); regexp, factory->last_index_string(), zero, writable).Check();
} }

View File

@ -1,49 +0,0 @@
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-regexps --harmony-unicode-regexps
var r1 = /abc/gi;
assertEquals("abc", r1.source);
assertTrue(r1.global);
assertTrue(r1.ignoreCase);
assertFalse(r1.multiline);
assertFalse(r1.sticky);
assertFalse(r1.unicode);
// Internal slot of prototype is not read.
var r2 = { __proto__: r1 };
assertThrows(function() { r2.source; }, TypeError);
assertThrows(function() { r2.global; }, TypeError);
assertThrows(function() { r2.ignoreCase; }, TypeError);
assertThrows(function() { r2.multiline; }, TypeError);
assertThrows(function() { r2.sticky; }, TypeError);
assertThrows(function() { r2.unicode; }, TypeError);
var r3 = /I/;
var string = "iIiIi";
var expected = "iXiIi";
assertFalse(r3.global);
assertFalse(r3.ignoreCase);
assertEquals("", r3.flags);
assertEquals(expected, string.replace(r3, "X"));
var get_count = 0;
Object.defineProperty(r3, "global", {
get: function() { get_count++; return true; }
});
Object.defineProperty(r3, "ignoreCase", {
get: function() { get_count++; return true; }
});
assertTrue(r3.global);
assertEquals(1, get_count);
assertTrue(r3.ignoreCase);
assertEquals(2, get_count);
// Overridden flag getters affects the flags getter.
assertEquals("gi", r3.flags);
assertEquals(4, get_count);
// Overridden flag getters do not affect the internal flags.
assertEquals(expected, string.replace(r3, "X"));
assertEquals(4, get_count);

View File

@ -25,17 +25,19 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-debug-as debug --harmony-regexps --harmony-unicode-regexps // Flags: --expose-debug-as debug --harmony-unicode-regexps
// Test the mirror object for regular expression values // Test the mirror object for regular expression values
var dont_enum = debug.PropertyAttribute.DontEnum; var all_attributes = debug.PropertyAttribute.ReadOnly |
var dont_delete = debug.PropertyAttribute.DontDelete; debug.PropertyAttribute.DontEnum |
var expected_prototype_attributes = { debug.PropertyAttribute.DontDelete;
'source': dont_enum, var expected_attributes = {
'global': dont_enum, 'source': all_attributes,
'ignoreCase': dont_enum, 'global': all_attributes,
'multiline': dont_enum, 'ignoreCase': all_attributes,
'unicode' : dont_enum, 'multiline': all_attributes,
'unicode' : all_attributes,
'lastIndex': debug.PropertyAttribute.DontEnum | debug.PropertyAttribute.DontDelete
}; };
function MirrorRefCache(json_refs) { function MirrorRefCache(json_refs) {
@ -68,12 +70,9 @@ function testRegExpMirror(r) {
assertTrue(mirror.isRegExp()); assertTrue(mirror.isRegExp());
assertEquals('regexp', mirror.type()); assertEquals('regexp', mirror.type());
assertFalse(mirror.isPrimitive()); assertFalse(mirror.isPrimitive());
assertEquals(dont_enum | dont_delete, for (var p in expected_attributes) {
mirror.property('lastIndex').attributes()); assertEquals(expected_attributes[p],
var proto_mirror = mirror.protoObject(); mirror.property(p).attributes(),
for (var p in expected_prototype_attributes) {
assertEquals(expected_prototype_attributes[p],
proto_mirror.property(p).attributes(),
p + ' attributes'); p + ' attributes');
} }
@ -84,12 +83,24 @@ function testRegExpMirror(r) {
var fromJSON = eval('(' + json + ')'); var fromJSON = eval('(' + json + ')');
assertEquals('regexp', fromJSON.type); assertEquals('regexp', fromJSON.type);
assertEquals('RegExp', fromJSON.className); assertEquals('RegExp', fromJSON.className);
assertEquals('lastIndex', fromJSON.properties[0].name); for (var p in expected_attributes) {
assertEquals(dont_enum | dont_delete, fromJSON.properties[0].attributes); for (var i = 0; i < fromJSON.properties.length; i++) {
assertEquals(mirror.property('lastIndex').propertyType(), if (fromJSON.properties[i].name == p) {
fromJSON.properties[0].propertyType); assertEquals(expected_attributes[p],
assertEquals(mirror.property('lastIndex').value().value(), fromJSON.properties[i].attributes,
refs.lookup(fromJSON.properties[0].ref).value); 'Unexpected value for ' + p + ' attributes');
assertEquals(mirror.property(p).propertyType(),
fromJSON.properties[i].propertyType,
'Unexpected value for ' + p + ' propertyType');
assertEquals(mirror.property(p).value().handle(),
fromJSON.properties[i].ref,
'Unexpected handle for ' + p);
assertEquals(mirror.property(p).value().value(),
refs.lookup(fromJSON.properties[i].ref).value,
'Unexpected value for ' + p);
}
}
}
} }

View File

@ -605,29 +605,23 @@ assertEquals(["ts", "li"], log);
// Check that properties of RegExp have the correct permissions. // Check that properties of RegExp have the correct permissions.
var re = /x/g; var re = /x/g;
var desc = Object.getOwnPropertyDescriptor(re.__proto__, "global"); var desc = Object.getOwnPropertyDescriptor(re, "global");
assertInstanceof(desc.get, Function); assertEquals(true, desc.value);
assertEquals(true, desc.configurable); assertEquals(false, desc.configurable);
assertEquals(false, desc.enumerable); assertEquals(false, desc.enumerable);
assertEquals(false, desc.writable);
desc = Object.getOwnPropertyDescriptor(re.__proto__, "multiline");
assertInstanceof(desc.get, Function);
assertEquals(true, desc.configurable);
assertEquals(false, desc.enumerable);
desc = Object.getOwnPropertyDescriptor(re.__proto__, "ignoreCase");
assertInstanceof(desc.get, Function);
assertEquals(true, desc.configurable);
assertEquals(false, desc.enumerable);
desc = Object.getOwnPropertyDescriptor(re, "global");
assertEquals(undefined, desc);
desc = Object.getOwnPropertyDescriptor(re, "multiline"); desc = Object.getOwnPropertyDescriptor(re, "multiline");
assertEquals(undefined, desc); assertEquals(false, desc.value);
assertEquals(false, desc.configurable);
assertEquals(false, desc.enumerable);
assertEquals(false, desc.writable);
desc = Object.getOwnPropertyDescriptor(re, "ignoreCase"); desc = Object.getOwnPropertyDescriptor(re, "ignoreCase");
assertEquals(undefined, desc); assertEquals(false, desc.value);
assertEquals(false, desc.configurable);
assertEquals(false, desc.enumerable);
assertEquals(false, desc.writable);
desc = Object.getOwnPropertyDescriptor(re, "lastIndex"); desc = Object.getOwnPropertyDescriptor(re, "lastIndex");
assertEquals(0, desc.value); assertEquals(0, desc.value);

View File

@ -3,8 +3,8 @@
// found in the LICENSE file. // found in the LICENSE file.
__proto__ = /foo/gi; __proto__ = /foo/gi;
assertThrows(function() { source }); assertEquals("foo", source);
assertThrows(function() { global }); assertTrue(global);
assertThrows(function() { ignoreCase }); assertTrue(ignoreCase);
assertThrows(function() { multiline }); assertFalse(multiline);
assertEquals(0, lastIndex); assertEquals(0, lastIndex);

View File

@ -144,6 +144,24 @@
'built-ins/WeakMap/iterator-items-are-not-object-close-iterator': [FAIL], 'built-ins/WeakMap/iterator-items-are-not-object-close-iterator': [FAIL],
'built-ins/WeakSet/iterator-close-after-add-failure': [FAIL], 'built-ins/WeakSet/iterator-close-after-add-failure': [FAIL],
# https://code.google.com/p/v8/issues/detail?id=3715
'built-ins/Object/getOwnPropertyDescriptor/15.2.3.3-4-212': [FAIL],
'built-ins/Object/getOwnPropertyDescriptor/15.2.3.3-4-213': [FAIL],
'built-ins/Object/getOwnPropertyDescriptor/15.2.3.3-4-214': [FAIL],
'built-ins/Object/getOwnPropertyDescriptor/15.2.3.3-4-215': [FAIL],
'built-ins/RegExp/prototype/global/15.10.7.2-1': [FAIL],
'built-ins/RegExp/prototype/global/15.10.7.2-2': [FAIL],
'built-ins/RegExp/prototype/global/S15.10.7.2_A9': [FAIL],
'built-ins/RegExp/prototype/ignoreCase/15.10.7.3-1': [FAIL],
'built-ins/RegExp/prototype/ignoreCase/15.10.7.3-2': [FAIL],
'built-ins/RegExp/prototype/ignoreCase/S15.10.7.3_A9': [FAIL],
'built-ins/RegExp/prototype/multiline/15.10.7.4-1': [FAIL],
'built-ins/RegExp/prototype/multiline/15.10.7.4-2': [FAIL],
'built-ins/RegExp/prototype/multiline/S15.10.7.4_A9': [FAIL],
'built-ins/RegExp/prototype/source/15.10.7.1-1': [FAIL],
'built-ins/RegExp/prototype/source/15.10.7.1-2': [FAIL],
'built-ins/RegExp/prototype/source/S15.10.7.1_A9': [FAIL],
# https://code.google.com/p/v8/issues/detail?id=4243 # https://code.google.com/p/v8/issues/detail?id=4243
'built-ins/Promise/race/S25.4.4.3_A3.1_T2': [FAIL], 'built-ins/Promise/race/S25.4.4.3_A3.1_T2': [FAIL],
'built-ins/Promise/reject/S25.4.4.4_A3.1_T1': [FAIL], 'built-ins/Promise/reject/S25.4.4.4_A3.1_T1': [FAIL],
@ -163,6 +181,16 @@
'built-ins/RegExp/from-regexp-like-get-ctor-err': [FAIL], 'built-ins/RegExp/from-regexp-like-get-ctor-err': [FAIL],
'built-ins/RegExp/call_with_regexp_not_same_constructor': [FAIL], 'built-ins/RegExp/call_with_regexp_not_same_constructor': [FAIL],
# https://code.google.com/p/v8/issues/detail?id=4528
'built-ins/RegExp/prototype/source/S15.10.7.1_A8': [FAIL],
'built-ins/RegExp/prototype/source/S15.10.7.1_A10': [FAIL],
'built-ins/RegExp/prototype/global/S15.10.7.2_A8': [FAIL],
'built-ins/RegExp/prototype/global/S15.10.7.2_A10': [FAIL],
'built-ins/RegExp/prototype/ignoreCase/S15.10.7.3_A8': [FAIL],
'built-ins/RegExp/prototype/ignoreCase/S15.10.7.3_A10': [FAIL],
'built-ins/RegExp/prototype/multiline/S15.10.7.4_A8': [FAIL],
'built-ins/RegExp/prototype/multiline/S15.10.7.4_A10': [FAIL],
# https://code.google.com/p/v8/issues/detail?id=4006 # https://code.google.com/p/v8/issues/detail?id=4006
'built-ins/String/prototype/S15.5.4_A1': [FAIL], 'built-ins/String/prototype/S15.5.4_A1': [FAIL],
'built-ins/String/prototype/S15.5.4_A2': [FAIL], 'built-ins/String/prototype/S15.5.4_A2': [FAIL],
@ -352,7 +380,11 @@
'built-ins/RegExp/prototype/test/u-captured-value': [FAIL], 'built-ins/RegExp/prototype/test/u-captured-value': [FAIL],
'built-ins/RegExp/prototype/test/u-lastindex-adv': [FAIL], 'built-ins/RegExp/prototype/test/u-lastindex-adv': [FAIL],
'built-ins/RegExp/prototype/test/u-lastindex-value': [FAIL], 'built-ins/RegExp/prototype/test/u-lastindex-value': [FAIL],
'built-ins/RegExp/prototype/unicode/length': [FAIL],
'built-ins/RegExp/prototype/unicode/name': [FAIL], 'built-ins/RegExp/prototype/unicode/name': [FAIL],
'built-ins/RegExp/prototype/unicode/prop-desc': [FAIL],
'built-ins/RegExp/prototype/unicode/this-invald-obj': [FAIL],
'built-ins/RegExp/prototype/unicode/this-non-obj': [FAIL],
'built-ins/RegExp/prototype/unicode/this-regexp': [FAIL], 'built-ins/RegExp/prototype/unicode/this-regexp': [FAIL],
'built-ins/RegExp/unicode_identity_escape': [FAIL], 'built-ins/RegExp/unicode_identity_escape': [FAIL],
'language/literals/regexp/u-unicode-esc': [FAIL], 'language/literals/regexp/u-unicode-esc': [FAIL],
@ -363,6 +395,9 @@
# https://code.google.com/p/v8/issues/detail?id=4342 # https://code.google.com/p/v8/issues/detail?id=4342
'built-ins/RegExp/prototype/exec/get-sticky-coerce': [FAIL], 'built-ins/RegExp/prototype/exec/get-sticky-coerce': [FAIL],
'built-ins/RegExp/prototype/exec/get-sticky-err': [FAIL], 'built-ins/RegExp/prototype/exec/get-sticky-err': [FAIL],
'built-ins/RegExp/prototype/sticky/prop-desc': [FAIL],
'built-ins/RegExp/prototype/sticky/this-invalid-obj': [FAIL],
'built-ins/RegExp/prototype/sticky/this-non-obj': [FAIL],
'built-ins/RegExp/prototype/test/get-sticky-coerce': [FAIL], 'built-ins/RegExp/prototype/test/get-sticky-coerce': [FAIL],
'built-ins/RegExp/prototype/test/get-sticky-err': [FAIL], 'built-ins/RegExp/prototype/test/get-sticky-err': [FAIL],
'built-ins/RegExp/valid-flags-y': [FAIL], 'built-ins/RegExp/valid-flags-y': [FAIL],
@ -406,6 +441,7 @@
# https://code.google.com/p/v8/issues/detail?id=4346 # https://code.google.com/p/v8/issues/detail?id=4346
'built-ins/RegExp/prototype/flags/name': [FAIL], 'built-ins/RegExp/prototype/flags/name': [FAIL],
'built-ins/RegExp/prototype/flags/y-attr-err': [FAIL],
'built-ins/RegExp/prototype/flags/u': [FAIL], 'built-ins/RegExp/prototype/flags/u': [FAIL],
# https://code.google.com/p/v8/issues/detail?id=4347 # https://code.google.com/p/v8/issues/detail?id=4347

View File

@ -28,7 +28,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
PASS RegExp('/').source is "\\/" PASS RegExp('/').source is "\\/"
PASS RegExp('').source is "(?:)" PASS RegExp('').source is "(?:)"
FAIL RegExp.prototype.source should be (?:). Threw exception TypeError: Method RegExp.prototype.toString called on incompatible receiver [object Object] FAIL RegExp.prototype.source should be (?:) (of type string). Was undefined (of type undefined).
PASS RegExp('/').toString() is "/\\//" PASS RegExp('/').toString() is "/\\//"
PASS RegExp('').toString() is "/(?:)/" PASS RegExp('').toString() is "/(?:)/"
FAIL RegExp.prototype.toString() should be /(?:)/. Threw exception TypeError: Method RegExp.prototype.toString called on incompatible receiver [object Object] FAIL RegExp.prototype.toString() should be /(?:)/. Threw exception TypeError: Method RegExp.prototype.toString called on incompatible receiver [object Object]
@ -58,4 +58,3 @@ PASS successfullyParsed is true
TEST COMPLETE TEST COMPLETE

View File

@ -348,8 +348,8 @@ def BuildFilterChain(macro_filename, message_template_file):
if macro_filename: if macro_filename:
(consts, macros) = ReadMacros(ReadFile(macro_filename)) (consts, macros) = ReadMacros(ReadFile(macro_filename))
filter_chain.append(lambda l: ExpandMacros(l, macros))
filter_chain.append(lambda l: ExpandConstants(l, consts)) filter_chain.append(lambda l: ExpandConstants(l, consts))
filter_chain.append(lambda l: ExpandMacros(l, macros))
if message_template_file: if message_template_file:
message_templates = ReadMessageTemplates(ReadFile(message_template_file)) message_templates = ReadMessageTemplates(ReadFile(message_template_file))