Revert "RegExp: Add support for the ES6-proposed sticky flag"
Causes a flaky failure on buildbots. Here is the (deterministic) repro step (thanks to Michael Stanton): first go to flag-definitions.h and set this to false. DEFINE_BOOL(enable_sse4_1, false, "enable use of SSE4.1 instructions if available") Run the following and it should fail: tools/run-tests.py --arch=ia32 --mode=release cctest/test-api/Regress2107 R=yangguo@chromium.org BUG= Review URL: https://codereview.chromium.org/580123002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24045 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
8b761b1b1b
commit
cc960f8034
@ -203,7 +203,6 @@ class Genesis BASE_EMBEDDED {
|
|||||||
// New context initialization. Used for creating a context from scratch.
|
// New context initialization. Used for creating a context from scratch.
|
||||||
void InitializeGlobal(Handle<GlobalObject> global_object,
|
void InitializeGlobal(Handle<GlobalObject> global_object,
|
||||||
Handle<JSFunction> empty_function);
|
Handle<JSFunction> empty_function);
|
||||||
void InitializeExperimentalGlobal();
|
|
||||||
// Installs the contents of the native .js files on the global objects.
|
// Installs the contents of the native .js files on the global objects.
|
||||||
// Used for creating a context from scratch.
|
// Used for creating a context from scratch.
|
||||||
void InstallNativeFunctions();
|
void InstallNativeFunctions();
|
||||||
@ -1352,20 +1351,6 @@ void Genesis::InstallTypedArray(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Genesis::InitializeExperimentalGlobal() {
|
|
||||||
// TODO(erikcorry): Move this into Genesis::InitializeGlobal once we no
|
|
||||||
// longer need to live behind a flag.
|
|
||||||
Handle<JSObject> builtins(native_context()->builtins());
|
|
||||||
|
|
||||||
Handle<HeapObject> flag(
|
|
||||||
FLAG_harmony_regexps ? heap()->true_value() : heap()->false_value());
|
|
||||||
PropertyAttributes attributes =
|
|
||||||
static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
|
|
||||||
Runtime::DefineObjectProperty(builtins, factory()->harmony_regexps_string(),
|
|
||||||
flag, attributes).Assert();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Genesis::CompileBuiltin(Isolate* isolate, int index) {
|
bool Genesis::CompileBuiltin(Isolate* isolate, int index) {
|
||||||
Vector<const char> name = Natives::GetScriptName(index);
|
Vector<const char> name = Natives::GetScriptName(index);
|
||||||
Handle<String> source_code =
|
Handle<String> source_code =
|
||||||
@ -2666,7 +2651,6 @@ Genesis::Genesis(Isolate* isolate,
|
|||||||
|
|
||||||
// Install experimental natives.
|
// Install experimental natives.
|
||||||
if (!InstallExperimentalNatives()) return;
|
if (!InstallExperimentalNatives()) return;
|
||||||
InitializeExperimentalGlobal();
|
|
||||||
|
|
||||||
// We can't (de-)serialize typed arrays currently, but we are lucky: The state
|
// We can't (de-)serialize typed arrays currently, but we are lucky: The state
|
||||||
// of the random number generator needs no initialization during snapshot
|
// of the random number generator needs no initialization during snapshot
|
||||||
|
@ -344,7 +344,7 @@ MaybeHandle<SharedFunctionInfo> CompilationCache::LookupEval(
|
|||||||
|
|
||||||
|
|
||||||
MaybeHandle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source,
|
MaybeHandle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source,
|
||||||
JSRegExp::Flags flags) {
|
JSRegExp::Flags flags) {
|
||||||
if (!IsEnabled()) return MaybeHandle<FixedArray>();
|
if (!IsEnabled()) return MaybeHandle<FixedArray>();
|
||||||
|
|
||||||
return reg_exp_.Lookup(source, flags);
|
return reg_exp_.Lookup(source, flags);
|
||||||
|
@ -162,7 +162,6 @@ DEFINE_BOOL(harmony_arrow_functions, false, "enable harmony arrow functions")
|
|||||||
DEFINE_BOOL(harmony_classes, false, "enable harmony classes")
|
DEFINE_BOOL(harmony_classes, false, "enable harmony classes")
|
||||||
DEFINE_BOOL(harmony_object_literals, false,
|
DEFINE_BOOL(harmony_object_literals, false,
|
||||||
"enable harmony object literal extensions")
|
"enable harmony object literal extensions")
|
||||||
DEFINE_BOOL(harmony_regexps, false, "enable regexp-related harmony features")
|
|
||||||
DEFINE_BOOL(harmony, false, "enable all harmony features (except proxies)")
|
DEFINE_BOOL(harmony, false, "enable all harmony features (except proxies)")
|
||||||
|
|
||||||
DEFINE_IMPLICATION(harmony, harmony_scoping)
|
DEFINE_IMPLICATION(harmony, harmony_scoping)
|
||||||
@ -175,7 +174,6 @@ DEFINE_IMPLICATION(harmony, harmony_arrays)
|
|||||||
DEFINE_IMPLICATION(harmony, harmony_arrow_functions)
|
DEFINE_IMPLICATION(harmony, harmony_arrow_functions)
|
||||||
DEFINE_IMPLICATION(harmony, harmony_classes)
|
DEFINE_IMPLICATION(harmony, harmony_classes)
|
||||||
DEFINE_IMPLICATION(harmony, harmony_object_literals)
|
DEFINE_IMPLICATION(harmony, harmony_object_literals)
|
||||||
DEFINE_IMPLICATION(harmony, harmony_regexps)
|
|
||||||
DEFINE_IMPLICATION(harmony_modules, harmony_scoping)
|
DEFINE_IMPLICATION(harmony_modules, harmony_scoping)
|
||||||
DEFINE_IMPLICATION(harmony_classes, harmony_scoping)
|
DEFINE_IMPLICATION(harmony_classes, harmony_scoping)
|
||||||
DEFINE_IMPLICATION(harmony_classes, harmony_object_literals)
|
DEFINE_IMPLICATION(harmony_classes, harmony_object_literals)
|
||||||
|
@ -287,8 +287,6 @@ namespace internal {
|
|||||||
V(global_string, "global") \
|
V(global_string, "global") \
|
||||||
V(ignore_case_string, "ignoreCase") \
|
V(ignore_case_string, "ignoreCase") \
|
||||||
V(multiline_string, "multiline") \
|
V(multiline_string, "multiline") \
|
||||||
V(sticky_string, "sticky") \
|
|
||||||
V(harmony_regexps_string, "harmony_regexps") \
|
|
||||||
V(input_string, "input") \
|
V(input_string, "input") \
|
||||||
V(index_string, "index") \
|
V(index_string, "index") \
|
||||||
V(last_index_string, "lastIndex") \
|
V(last_index_string, "lastIndex") \
|
||||||
|
@ -70,9 +70,6 @@ static JSRegExp::Flags RegExpFlagsFromString(Handle<String> str) {
|
|||||||
case 'm':
|
case 'm':
|
||||||
flags |= JSRegExp::MULTILINE;
|
flags |= JSRegExp::MULTILINE;
|
||||||
break;
|
break;
|
||||||
case 'y':
|
|
||||||
if (FLAG_harmony_regexps) flags |= JSRegExp::STICKY;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return JSRegExp::Flags(flags);
|
return JSRegExp::Flags(flags);
|
||||||
@ -188,14 +185,12 @@ MaybeHandle<Object> RegExpImpl::Compile(Handle<JSRegExp> re,
|
|||||||
|
|
||||||
if (parse_result.simple &&
|
if (parse_result.simple &&
|
||||||
!flags.is_ignore_case() &&
|
!flags.is_ignore_case() &&
|
||||||
!flags.is_sticky() &&
|
|
||||||
!HasFewDifferentCharacters(pattern)) {
|
!HasFewDifferentCharacters(pattern)) {
|
||||||
// Parse-tree is a single atom that is equal to the pattern.
|
// Parse-tree is a single atom that is equal to the pattern.
|
||||||
AtomCompile(re, pattern, flags, pattern);
|
AtomCompile(re, pattern, flags, pattern);
|
||||||
has_been_compiled = true;
|
has_been_compiled = true;
|
||||||
} else if (parse_result.tree->IsAtom() &&
|
} else if (parse_result.tree->IsAtom() &&
|
||||||
!flags.is_ignore_case() &&
|
!flags.is_ignore_case() &&
|
||||||
!flags.is_sticky() &&
|
|
||||||
parse_result.capture_count == 0) {
|
parse_result.capture_count == 0) {
|
||||||
RegExpAtom* atom = parse_result.tree->AsAtom();
|
RegExpAtom* atom = parse_result.tree->AsAtom();
|
||||||
Vector<const uc16> atom_pattern = atom->data();
|
Vector<const uc16> atom_pattern = atom->data();
|
||||||
@ -435,8 +430,7 @@ bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re,
|
|||||||
}
|
}
|
||||||
RegExpEngine::CompilationResult result = RegExpEngine::Compile(
|
RegExpEngine::CompilationResult result = RegExpEngine::Compile(
|
||||||
&compile_data, flags.is_ignore_case(), flags.is_global(),
|
&compile_data, flags.is_ignore_case(), flags.is_global(),
|
||||||
flags.is_multiline(), flags.is_sticky(), pattern, sample_subject,
|
flags.is_multiline(), pattern, sample_subject, is_one_byte, &zone);
|
||||||
is_one_byte, &zone);
|
|
||||||
if (result.error_message != NULL) {
|
if (result.error_message != NULL) {
|
||||||
// Unable to compile regexp.
|
// Unable to compile regexp.
|
||||||
Handle<String> error_message = isolate->factory()->NewStringFromUtf8(
|
Handle<String> error_message = isolate->factory()->NewStringFromUtf8(
|
||||||
@ -6033,8 +6027,8 @@ void DispatchTableConstructor::VisitAction(ActionNode* that) {
|
|||||||
|
|
||||||
RegExpEngine::CompilationResult RegExpEngine::Compile(
|
RegExpEngine::CompilationResult RegExpEngine::Compile(
|
||||||
RegExpCompileData* data, bool ignore_case, bool is_global,
|
RegExpCompileData* data, bool ignore_case, bool is_global,
|
||||||
bool is_multiline, bool is_sticky, Handle<String> pattern,
|
bool is_multiline, Handle<String> pattern, Handle<String> sample_subject,
|
||||||
Handle<String> sample_subject, bool is_one_byte, Zone* zone) {
|
bool is_one_byte, Zone* zone) {
|
||||||
if ((data->capture_count + 1) * 2 - 1 > RegExpMacroAssembler::kMaxRegister) {
|
if ((data->capture_count + 1) * 2 - 1 > RegExpMacroAssembler::kMaxRegister) {
|
||||||
return IrregexpRegExpTooBig(zone->isolate());
|
return IrregexpRegExpTooBig(zone->isolate());
|
||||||
}
|
}
|
||||||
@ -6061,9 +6055,9 @@ RegExpEngine::CompilationResult RegExpEngine::Compile(
|
|||||||
bool is_end_anchored = data->tree->IsAnchoredAtEnd();
|
bool is_end_anchored = data->tree->IsAnchoredAtEnd();
|
||||||
bool is_start_anchored = data->tree->IsAnchoredAtStart();
|
bool is_start_anchored = data->tree->IsAnchoredAtStart();
|
||||||
int max_length = data->tree->max_match();
|
int max_length = data->tree->max_match();
|
||||||
if (!is_start_anchored && !is_sticky) {
|
if (!is_start_anchored) {
|
||||||
// Add a .*? at the beginning, outside the body capture, unless
|
// Add a .*? at the beginning, outside the body capture, unless
|
||||||
// this expression is anchored at the beginning or sticky.
|
// this expression is anchored at the beginning.
|
||||||
RegExpNode* loop_node =
|
RegExpNode* loop_node =
|
||||||
RegExpQuantifier::ToNode(0,
|
RegExpQuantifier::ToNode(0,
|
||||||
RegExpTree::kInfinity,
|
RegExpTree::kInfinity,
|
||||||
|
@ -1661,7 +1661,7 @@ class RegExpEngine: public AllStatic {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static CompilationResult Compile(RegExpCompileData* input, bool ignore_case,
|
static CompilationResult Compile(RegExpCompileData* input, bool ignore_case,
|
||||||
bool global, bool multiline, bool sticky,
|
bool global, bool multiline,
|
||||||
Handle<String> pattern,
|
Handle<String> pattern,
|
||||||
Handle<String> sample_subject,
|
Handle<String> sample_subject,
|
||||||
bool is_one_byte, Zone* zone);
|
bool is_one_byte, Zone* zone);
|
||||||
|
@ -8034,13 +8034,7 @@ class JSRegExp: public JSObject {
|
|||||||
// IRREGEXP: Compiled with Irregexp.
|
// IRREGEXP: Compiled with Irregexp.
|
||||||
// IRREGEXP_NATIVE: Compiled to native code with Irregexp.
|
// IRREGEXP_NATIVE: Compiled to native code with Irregexp.
|
||||||
enum Type { NOT_COMPILED, ATOM, IRREGEXP };
|
enum Type { NOT_COMPILED, ATOM, IRREGEXP };
|
||||||
enum Flag {
|
enum Flag { NONE = 0, GLOBAL = 1, IGNORE_CASE = 2, MULTILINE = 4 };
|
||||||
NONE = 0,
|
|
||||||
GLOBAL = 1,
|
|
||||||
IGNORE_CASE = 2,
|
|
||||||
MULTILINE = 4,
|
|
||||||
STICKY = 8
|
|
||||||
};
|
|
||||||
|
|
||||||
class Flags {
|
class Flags {
|
||||||
public:
|
public:
|
||||||
@ -8048,7 +8042,6 @@ class JSRegExp: public JSObject {
|
|||||||
bool is_global() { return (value_ & GLOBAL) != 0; }
|
bool is_global() { return (value_ & GLOBAL) != 0; }
|
||||||
bool is_ignore_case() { return (value_ & IGNORE_CASE) != 0; }
|
bool is_ignore_case() { return (value_ & IGNORE_CASE) != 0; }
|
||||||
bool is_multiline() { return (value_ & MULTILINE) != 0; }
|
bool is_multiline() { return (value_ & MULTILINE) != 0; }
|
||||||
bool is_sticky() { return (value_ & STICKY) != 0; }
|
|
||||||
uint32_t value() { return value_; }
|
uint32_t value() { return value_; }
|
||||||
private:
|
private:
|
||||||
uint32_t value_;
|
uint32_t value_;
|
||||||
|
@ -22,8 +22,6 @@ function DoConstructRegExp(object, pattern, flags) {
|
|||||||
flags = (pattern.global ? 'g' : '')
|
flags = (pattern.global ? 'g' : '')
|
||||||
+ (pattern.ignoreCase ? 'i' : '')
|
+ (pattern.ignoreCase ? 'i' : '')
|
||||||
+ (pattern.multiline ? 'm' : '');
|
+ (pattern.multiline ? 'm' : '');
|
||||||
if (harmony_regexps)
|
|
||||||
flags += (pattern.sticky ? 'y' : '');
|
|
||||||
pattern = pattern.source;
|
pattern = pattern.source;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,7 +31,6 @@ function DoConstructRegExp(object, pattern, flags) {
|
|||||||
var global = false;
|
var global = false;
|
||||||
var ignoreCase = false;
|
var ignoreCase = false;
|
||||||
var multiline = false;
|
var multiline = false;
|
||||||
var sticky = false;
|
|
||||||
for (var i = 0; i < flags.length; i++) {
|
for (var i = 0; i < flags.length; i++) {
|
||||||
var c = %_CallFunction(flags, i, StringCharAt);
|
var c = %_CallFunction(flags, i, StringCharAt);
|
||||||
switch (c) {
|
switch (c) {
|
||||||
@ -55,18 +52,12 @@ function DoConstructRegExp(object, pattern, flags) {
|
|||||||
}
|
}
|
||||||
multiline = true;
|
multiline = true;
|
||||||
break;
|
break;
|
||||||
case 'y':
|
|
||||||
if (!harmony_regexps || sticky) {
|
|
||||||
throw MakeSyntaxError("invalid_regexp_flags", [flags]);
|
|
||||||
}
|
|
||||||
sticky = true;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
throw MakeSyntaxError("invalid_regexp_flags", [flags]);
|
throw MakeSyntaxError("invalid_regexp_flags", [flags]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
%RegExpInitializeObject(object, pattern, global, ignoreCase, multiline, sticky);
|
%RegExpInitializeObject(object, pattern, global, ignoreCase, multiline);
|
||||||
|
|
||||||
// Call internal function to compile the pattern.
|
// Call internal function to compile the pattern.
|
||||||
%RegExpCompile(object, pattern, flags);
|
%RegExpCompile(object, pattern, flags);
|
||||||
@ -168,8 +159,8 @@ function RegExpExec(string) {
|
|||||||
// algorithm, step 5) even if the value is discarded for non-global RegExps.
|
// algorithm, step 5) even if the value is discarded for non-global RegExps.
|
||||||
var i = TO_INTEGER(lastIndex);
|
var i = TO_INTEGER(lastIndex);
|
||||||
|
|
||||||
var updateLastIndex = this.global || (harmony_regexps && this.sticky);
|
var global = this.global;
|
||||||
if (updateLastIndex) {
|
if (global) {
|
||||||
if (i < 0 || i > string.length) {
|
if (i < 0 || i > string.length) {
|
||||||
this.lastIndex = 0;
|
this.lastIndex = 0;
|
||||||
return null;
|
return null;
|
||||||
@ -188,7 +179,7 @@ function RegExpExec(string) {
|
|||||||
|
|
||||||
// Successful match.
|
// Successful match.
|
||||||
lastMatchInfoOverride = null;
|
lastMatchInfoOverride = null;
|
||||||
if (updateLastIndex) {
|
if (global) {
|
||||||
this.lastIndex = lastMatchInfo[CAPTURE1];
|
this.lastIndex = lastMatchInfo[CAPTURE1];
|
||||||
}
|
}
|
||||||
RETURN_NEW_RESULT_FROM_MATCH_INFO(matchIndices, string);
|
RETURN_NEW_RESULT_FROM_MATCH_INFO(matchIndices, string);
|
||||||
@ -216,7 +207,7 @@ function RegExpTest(string) {
|
|||||||
// algorithm, step 5) even if the value is discarded for non-global RegExps.
|
// algorithm, step 5) even if the value is discarded for non-global RegExps.
|
||||||
var i = TO_INTEGER(lastIndex);
|
var i = TO_INTEGER(lastIndex);
|
||||||
|
|
||||||
if (this.global || (harmony_regexps && this.sticky)) {
|
if (this.global) {
|
||||||
if (i < 0 || i > string.length) {
|
if (i < 0 || i > string.length) {
|
||||||
this.lastIndex = 0;
|
this.lastIndex = 0;
|
||||||
return false;
|
return false;
|
||||||
@ -231,13 +222,12 @@ function RegExpTest(string) {
|
|||||||
this.lastIndex = lastMatchInfo[CAPTURE1];
|
this.lastIndex = lastMatchInfo[CAPTURE1];
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
// Non-global, non-sticky regexp.
|
// Non-global regexp.
|
||||||
// Remove irrelevant preceeding '.*' in a test regexp. The expression
|
// Remove irrelevant preceeding '.*' in a non-global test regexp.
|
||||||
// checks whether this.source starts with '.*' and that the third char is
|
// The expression checks whether this.source starts with '.*' and
|
||||||
// not a '?'. But see https://code.google.com/p/v8/issues/detail?id=3560
|
// that the third char is not a '?'.
|
||||||
var regexp = this;
|
var regexp = this;
|
||||||
if (regexp.source.length >= 3 &&
|
if (%_StringCharCodeAt(regexp.source, 0) == 46 && // '.'
|
||||||
%_StringCharCodeAt(regexp.source, 0) == 46 && // '.'
|
|
||||||
%_StringCharCodeAt(regexp.source, 1) == 42 && // '*'
|
%_StringCharCodeAt(regexp.source, 1) == 42 && // '*'
|
||||||
%_StringCharCodeAt(regexp.source, 2) != 63) { // '?'
|
%_StringCharCodeAt(regexp.source, 2) != 63) { // '?'
|
||||||
regexp = TrimRegExp(regexp);
|
regexp = TrimRegExp(regexp);
|
||||||
@ -274,7 +264,6 @@ function RegExpToString() {
|
|||||||
if (this.global) result += 'g';
|
if (this.global) result += 'g';
|
||||||
if (this.ignoreCase) result += 'i';
|
if (this.ignoreCase) result += 'i';
|
||||||
if (this.multiline) result += 'm';
|
if (this.multiline) result += 'm';
|
||||||
if (harmony_regexps && this.sticky) result += 'y';
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2548,7 +2548,7 @@ RUNTIME_FUNCTION(Runtime_RegExpConstructResult) {
|
|||||||
|
|
||||||
RUNTIME_FUNCTION(Runtime_RegExpInitializeObject) {
|
RUNTIME_FUNCTION(Runtime_RegExpInitializeObject) {
|
||||||
HandleScope scope(isolate);
|
HandleScope scope(isolate);
|
||||||
DCHECK(args.length() == 6);
|
DCHECK(args.length() == 5);
|
||||||
CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
|
CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
|
||||||
CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
|
CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
|
||||||
// If source is the empty string we set it to "(?:)" instead as
|
// If source is the empty string we set it to "(?:)" instead as
|
||||||
@ -2564,13 +2564,9 @@ RUNTIME_FUNCTION(Runtime_RegExpInitializeObject) {
|
|||||||
CONVERT_ARG_HANDLE_CHECKED(Object, multiline, 4);
|
CONVERT_ARG_HANDLE_CHECKED(Object, multiline, 4);
|
||||||
if (!multiline->IsTrue()) multiline = isolate->factory()->false_value();
|
if (!multiline->IsTrue()) multiline = isolate->factory()->false_value();
|
||||||
|
|
||||||
CONVERT_ARG_HANDLE_CHECKED(Object, sticky, 5);
|
|
||||||
if (!sticky->IsTrue()) sticky = isolate->factory()->false_value();
|
|
||||||
|
|
||||||
Map* map = regexp->map();
|
Map* map = regexp->map();
|
||||||
Object* constructor = map->constructor();
|
Object* constructor = map->constructor();
|
||||||
if (!FLAG_harmony_regexps &&
|
if (constructor->IsJSFunction() &&
|
||||||
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, *source);
|
regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, *source);
|
||||||
@ -2587,11 +2583,7 @@ RUNTIME_FUNCTION(Runtime_RegExpInitializeObject) {
|
|||||||
return *regexp;
|
return *regexp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map has changed, so use generic, but slower, method. We also end here if
|
// Map has changed, so use generic, but slower, method.
|
||||||
// the --harmony-regexp flag is set, because the initial map does not have
|
|
||||||
// space for the 'sticky' flag, since it is from the snapshot, but must work
|
|
||||||
// both with and without --harmony-regexp. When sticky comes out from under
|
|
||||||
// the flag, we will be able to use the fast initial map.
|
|
||||||
PropertyAttributes final =
|
PropertyAttributes final =
|
||||||
static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE);
|
static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE);
|
||||||
PropertyAttributes writable =
|
PropertyAttributes writable =
|
||||||
@ -2606,10 +2598,6 @@ RUNTIME_FUNCTION(Runtime_RegExpInitializeObject) {
|
|||||||
regexp, factory->ignore_case_string(), ignoreCase, final).Check();
|
regexp, factory->ignore_case_string(), ignoreCase, final).Check();
|
||||||
JSObject::SetOwnPropertyIgnoreAttributes(
|
JSObject::SetOwnPropertyIgnoreAttributes(
|
||||||
regexp, factory->multiline_string(), multiline, final).Check();
|
regexp, factory->multiline_string(), multiline, final).Check();
|
||||||
if (FLAG_harmony_regexps) {
|
|
||||||
JSObject::SetOwnPropertyIgnoreAttributes(
|
|
||||||
regexp, factory->sticky_string(), sticky, final).Check();
|
|
||||||
}
|
|
||||||
JSObject::SetOwnPropertyIgnoreAttributes(
|
JSObject::SetOwnPropertyIgnoreAttributes(
|
||||||
regexp, factory->last_index_string(), zero, writable).Check();
|
regexp, factory->last_index_string(), zero, writable).Check();
|
||||||
return *regexp;
|
return *regexp;
|
||||||
|
@ -154,7 +154,7 @@ namespace internal {
|
|||||||
/* Regular expressions */ \
|
/* Regular expressions */ \
|
||||||
F(RegExpCompile, 3, 1) \
|
F(RegExpCompile, 3, 1) \
|
||||||
F(RegExpExecMultiple, 4, 1) \
|
F(RegExpExecMultiple, 4, 1) \
|
||||||
F(RegExpInitializeObject, 6, 1) \
|
F(RegExpInitializeObject, 5, 1) \
|
||||||
\
|
\
|
||||||
/* JSON */ \
|
/* JSON */ \
|
||||||
F(ParseJson, 1, 1) \
|
F(ParseJson, 1, 1) \
|
||||||
|
@ -518,7 +518,7 @@ static RegExpNode* Compile(const char* input, bool multiline, bool is_one_byte,
|
|||||||
NewStringFromUtf8(CStrVector(input)).ToHandleChecked();
|
NewStringFromUtf8(CStrVector(input)).ToHandleChecked();
|
||||||
Handle<String> sample_subject =
|
Handle<String> sample_subject =
|
||||||
isolate->factory()->NewStringFromUtf8(CStrVector("")).ToHandleChecked();
|
isolate->factory()->NewStringFromUtf8(CStrVector("")).ToHandleChecked();
|
||||||
RegExpEngine::Compile(&compile_data, false, false, multiline, false, pattern,
|
RegExpEngine::Compile(&compile_data, false, false, multiline, pattern,
|
||||||
sample_subject, is_one_byte, zone);
|
sample_subject, is_one_byte, zone);
|
||||||
return compile_data.node;
|
return compile_data.node;
|
||||||
}
|
}
|
||||||
|
@ -1,132 +0,0 @@
|
|||||||
// Copyright 2014 the V8 project authors. All rights reserved.
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are
|
|
||||||
// met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following
|
|
||||||
// disclaimer in the documentation and/or other materials provided
|
|
||||||
// with the distribution.
|
|
||||||
// * Neither the name of Google Inc. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived
|
|
||||||
// from this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
// Flags: --harmony-regexps
|
|
||||||
|
|
||||||
var re = /foo.bar/;
|
|
||||||
|
|
||||||
assertTrue(!!"foo*bar".match(re));
|
|
||||||
assertTrue(!!"..foo*bar".match(re));
|
|
||||||
|
|
||||||
var plain = /foobar/;
|
|
||||||
|
|
||||||
assertTrue(!!"foobar".match(plain));
|
|
||||||
assertTrue(!!"..foobar".match(plain));
|
|
||||||
|
|
||||||
var sticky = /foo.bar/y;
|
|
||||||
|
|
||||||
assertTrue(!!"foo*bar".match(sticky));
|
|
||||||
assertEquals(0, sticky.lastIndex);
|
|
||||||
assertFalse(!!"..foo*bar".match(sticky));
|
|
||||||
|
|
||||||
var stickyplain = /foobar/y;
|
|
||||||
|
|
||||||
assertTrue(!!"foobar".match(stickyplain));
|
|
||||||
assertEquals(0, stickyplain.lastIndex);
|
|
||||||
assertFalse(!!"..foobar".match(stickyplain));
|
|
||||||
|
|
||||||
var global = /foo.bar/g;
|
|
||||||
|
|
||||||
assertTrue(global.test("foo*bar"));
|
|
||||||
assertFalse(global.test("..foo*bar"));
|
|
||||||
global.lastIndex = 0;
|
|
||||||
assertTrue(global.test("..foo*bar"));
|
|
||||||
|
|
||||||
var plainglobal = /foobar/g;
|
|
||||||
|
|
||||||
assertTrue(plainglobal.test("foobar"));
|
|
||||||
assertFalse(plainglobal.test("foobar"));
|
|
||||||
plainglobal.lastIndex = 0;
|
|
||||||
assertTrue(plainglobal.test("foobar"));
|
|
||||||
|
|
||||||
var stickyglobal = /foo.bar/gy;
|
|
||||||
|
|
||||||
assertTrue(stickyglobal.test("foo*bar"));
|
|
||||||
assertEquals(7, stickyglobal.lastIndex);
|
|
||||||
assertFalse(stickyglobal.test("..foo*bar"));
|
|
||||||
stickyglobal.lastIndex = 0;
|
|
||||||
assertFalse(stickyglobal.test("..foo*bar"));
|
|
||||||
stickyglobal.lastIndex = 2;
|
|
||||||
assertTrue(stickyglobal.test("..foo*bar"));
|
|
||||||
assertEquals(9, stickyglobal.lastIndex);
|
|
||||||
|
|
||||||
var stickyplainglobal = /foobar/yg;
|
|
||||||
assertTrue(stickyplainglobal.sticky);
|
|
||||||
stickyplainglobal.sticky = false;
|
|
||||||
|
|
||||||
assertTrue(stickyplainglobal.test("foobar"));
|
|
||||||
assertEquals(6, stickyplainglobal.lastIndex);
|
|
||||||
assertFalse(stickyplainglobal.test("..foobar"));
|
|
||||||
stickyplainglobal.lastIndex = 0;
|
|
||||||
assertFalse(stickyplainglobal.test("..foobar"));
|
|
||||||
stickyplainglobal.lastIndex = 2;
|
|
||||||
assertTrue(stickyplainglobal.test("..foobar"));
|
|
||||||
assertEquals(8, stickyplainglobal.lastIndex);
|
|
||||||
|
|
||||||
assertEquals("/foo.bar/gy", "" + stickyglobal);
|
|
||||||
assertEquals("/foo.bar/g", "" + global);
|
|
||||||
|
|
||||||
assertTrue(stickyglobal.sticky);
|
|
||||||
stickyglobal.sticky = false;
|
|
||||||
assertTrue(stickyglobal.sticky);
|
|
||||||
|
|
||||||
var stickyglobal2 = new RegExp("foo.bar", "gy");
|
|
||||||
assertTrue(stickyglobal2.test("foo*bar"));
|
|
||||||
assertEquals(7, stickyglobal2.lastIndex);
|
|
||||||
assertFalse(stickyglobal2.test("..foo*bar"));
|
|
||||||
stickyglobal2.lastIndex = 0;
|
|
||||||
assertFalse(stickyglobal2.test("..foo*bar"));
|
|
||||||
stickyglobal2.lastIndex = 2;
|
|
||||||
assertTrue(stickyglobal2.test("..foo*bar"));
|
|
||||||
assertEquals(9, stickyglobal2.lastIndex);
|
|
||||||
|
|
||||||
assertEquals("/foo.bar/gy", "" + stickyglobal2);
|
|
||||||
|
|
||||||
assertTrue(stickyglobal2.sticky);
|
|
||||||
stickyglobal2.sticky = false;
|
|
||||||
assertTrue(stickyglobal2.sticky);
|
|
||||||
|
|
||||||
sticky.lastIndex = -1; // Causes sticky regexp to fail fast
|
|
||||||
assertFalse(sticky.test("..foo.bar"));
|
|
||||||
assertEquals(0, sticky.lastIndex);
|
|
||||||
|
|
||||||
sticky.lastIndex = -1; // Causes sticky regexp to fail fast
|
|
||||||
assertFalse(!!sticky.exec("..foo.bar"));
|
|
||||||
assertEquals(0, sticky.lastIndex);
|
|
||||||
|
|
||||||
// ES6 draft says: Even when the y flag is used with a pattern, ^ always
|
|
||||||
// matches only at the beginning of Input, or (if Multiline is true) at the
|
|
||||||
// beginning of a line.
|
|
||||||
var hat = /^foo/y;
|
|
||||||
hat.lastIndex = 2;
|
|
||||||
assertFalse(hat.test("..foo"));
|
|
||||||
|
|
||||||
var mhat = /^foo/my;
|
|
||||||
mhat.lastIndex = 2;
|
|
||||||
assertFalse(mhat.test("..foo"));
|
|
||||||
mhat.lastIndex = 2;
|
|
||||||
assertTrue(mhat.test(".\nfoo"));
|
|
@ -1,65 +0,0 @@
|
|||||||
// Copyright 2014 the V8 project authors. All rights reserved.
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are
|
|
||||||
// met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following
|
|
||||||
// disclaimer in the documentation and/or other materials provided
|
|
||||||
// with the distribution.
|
|
||||||
// * Neither the name of Google Inc. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived
|
|
||||||
// from this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
// Test that sticky regexp support is not affecting V8 when the
|
|
||||||
// --harmony-regexps flag is not on.
|
|
||||||
|
|
||||||
assertThrows(function() { eval("/foo.bar/y"); }, SyntaxError);
|
|
||||||
assertThrows(function() { eval("/foobar/y"); }, SyntaxError);
|
|
||||||
assertThrows(function() { eval("/foo.bar/gy"); }, SyntaxError);
|
|
||||||
assertThrows(function() { eval("/foobar/gy"); }, SyntaxError);
|
|
||||||
assertThrows(function() { new RegExp("foo.bar", "y"); }, SyntaxError);
|
|
||||||
assertThrows(function() { new RegExp("foobar", "y"); }, SyntaxError);
|
|
||||||
assertThrows(function() { new RegExp("foo.bar", "gy"); }, SyntaxError);
|
|
||||||
assertThrows(function() { new RegExp("foobar", "gy"); }, SyntaxError);
|
|
||||||
|
|
||||||
var re = /foo.bar/;
|
|
||||||
assertEquals("/foo.bar/", "" + re);
|
|
||||||
var plain = /foobar/;
|
|
||||||
assertEquals("/foobar/", "" + plain);
|
|
||||||
|
|
||||||
re.compile("foo.bar");
|
|
||||||
assertEquals(void 0, re.sticky);
|
|
||||||
|
|
||||||
var global = /foo.bar/g;
|
|
||||||
assertEquals("/foo.bar/g", "" + global);
|
|
||||||
var plainglobal = /foobar/g;
|
|
||||||
assertEquals("/foobar/g", "" + plainglobal);
|
|
||||||
|
|
||||||
assertEquals(void 0, re.sticky);
|
|
||||||
re.sticky = true; // Has no effect on the regexp, just sets a property.
|
|
||||||
assertTrue(re.sticky);
|
|
||||||
|
|
||||||
assertTrue(re.test("..foo.bar"));
|
|
||||||
|
|
||||||
re.lastIndex = -1; // Ignored for non-global, non-sticky.
|
|
||||||
assertTrue(re.test("..foo.bar"));
|
|
||||||
assertEquals(-1, re.lastIndex);
|
|
||||||
|
|
||||||
re.lastIndex = -1; // Ignored for non-global, non-sticky.
|
|
||||||
assertTrue(!!re.exec("..foo.bar"));
|
|
||||||
assertEquals(-1, re.lastIndex);
|
|
Loading…
Reference in New Issue
Block a user