Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(178)

Unified Diff: src/runtime/runtime-regexp.cc

Issue 719403005: One instead of two runtime calls when initializing regexp. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: addressed comments Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/runtime/runtime.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/runtime/runtime-regexp.cc
diff --git a/src/runtime/runtime-regexp.cc b/src/runtime/runtime-regexp.cc
index 982ef6669932d29d532a7217d7d648cbbd94397a..e46d9b91765d30b7a4beaf4785f43d515dae0146 100644
--- a/src/runtime/runtime-regexp.cc
+++ b/src/runtime/runtime-regexp.cc
@@ -759,19 +759,6 @@ RUNTIME_FUNCTION(Runtime_StringSplit) {
}
-RUNTIME_FUNCTION(Runtime_RegExpCompile) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 3);
- CONVERT_ARG_HANDLE_CHECKED(JSRegExp, re, 0);
- CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
- CONVERT_ARG_HANDLE_CHECKED(String, flags, 2);
- Handle<Object> result;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
- RegExpImpl::Compile(re, pattern, flags));
- return *result;
-}
-
-
RUNTIME_FUNCTION(Runtime_RegExpExecRT) {
HandleScope scope(isolate);
DCHECK(args.length() == 4);
@@ -813,26 +800,65 @@ RUNTIME_FUNCTION(Runtime_RegExpConstructResult) {
}
-RUNTIME_FUNCTION(Runtime_RegExpInitializeObject) {
+static JSRegExp::Flags RegExpFlagsFromString(Handle<String> flags,
+ bool* success) {
+ uint32_t value = JSRegExp::NONE;
+ int length = flags->length();
+ // A longer flags string cannot be valid.
+ if (length > 4) return JSRegExp::Flags(0);
+ for (int i = 0; i < length; i++) {
+ uint32_t flag = JSRegExp::NONE;
+ switch (flags->Get(i)) {
+ case 'g':
+ flag = JSRegExp::GLOBAL;
+ break;
+ case 'i':
+ flag = JSRegExp::IGNORE_CASE;
+ break;
+ case 'm':
+ flag = JSRegExp::MULTILINE;
+ break;
+ case 'y':
+ if (!FLAG_harmony_regexps) return JSRegExp::Flags(0);
+ flag = JSRegExp::STICKY;
+ break;
+ default:
+ return JSRegExp::Flags(0);
+ }
+ // Duplicate flag.
+ if (value & flag) return JSRegExp::Flags(0);
+ value |= flag;
+ }
+ *success = true;
+ return JSRegExp::Flags(value);
+}
+
+
+RUNTIME_FUNCTION(Runtime_RegExpInitializeAndCompile) {
HandleScope scope(isolate);
- DCHECK(args.length() == 6);
+ DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
+ CONVERT_ARG_HANDLE_CHECKED(String, flags_string, 2);
+ Factory* factory = isolate->factory();
// If source is the empty string we set it to "(?:)" instead as
// suggested by ECMA-262, 5th, section 15.10.4.1.
- if (source->length() == 0) source = isolate->factory()->query_colon_string();
-
- CONVERT_ARG_HANDLE_CHECKED(Object, global, 2);
- if (!global->IsTrue()) global = isolate->factory()->false_value();
-
- CONVERT_ARG_HANDLE_CHECKED(Object, ignoreCase, 3);
- if (!ignoreCase->IsTrue()) ignoreCase = isolate->factory()->false_value();
-
- CONVERT_ARG_HANDLE_CHECKED(Object, multiline, 4);
- if (!multiline->IsTrue()) multiline = isolate->factory()->false_value();
+ if (source->length() == 0) source = factory->query_colon_string();
+
+ bool success = false;
+ JSRegExp::Flags flags = RegExpFlagsFromString(flags_string, &success);
+ if (!success) {
+ Handle<FixedArray> element = factory->NewFixedArray(1);
+ element->set(0, *flags_string);
+ Handle<JSArray> args = factory->NewJSArrayWithElements(element);
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate, NewSyntaxError("invalid_regexp_flags", args));
+ }
- CONVERT_ARG_HANDLE_CHECKED(Object, sticky, 5);
- if (!sticky->IsTrue()) sticky = isolate->factory()->false_value();
+ 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());
Map* map = regexp->map();
Object* constructor = map->constructor();
@@ -844,41 +870,43 @@ RUNTIME_FUNCTION(Runtime_RegExpInitializeObject) {
// barrier.
regexp->InObjectPropertyAtPut(JSRegExp::kGlobalFieldIndex, *global,
SKIP_WRITE_BARRIER);
- regexp->InObjectPropertyAtPut(JSRegExp::kIgnoreCaseFieldIndex, *ignoreCase,
+ regexp->InObjectPropertyAtPut(JSRegExp::kIgnoreCaseFieldIndex, *ignore_case,
SKIP_WRITE_BARRIER);
regexp->InObjectPropertyAtPut(JSRegExp::kMultilineFieldIndex, *multiline,
SKIP_WRITE_BARRIER);
regexp->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex,
Smi::FromInt(0), SKIP_WRITE_BARRIER);
- return *regexp;
+ } else {
+ // Map has changed, so use generic, but slower, method. We also end here if
+ // 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 =
+ static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE);
+ PropertyAttributes writable =
+ static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
+ Handle<Object> zero(Smi::FromInt(0), isolate);
+ JSObject::SetOwnPropertyIgnoreAttributes(regexp, factory->source_string(),
+ source, final).Check();
+ JSObject::SetOwnPropertyIgnoreAttributes(regexp, factory->global_string(),
+ global, final).Check();
+ JSObject::SetOwnPropertyIgnoreAttributes(
+ regexp, factory->ignore_case_string(), ignore_case, final).Check();
+ JSObject::SetOwnPropertyIgnoreAttributes(
+ regexp, factory->multiline_string(), multiline, final).Check();
+ if (FLAG_harmony_regexps) {
+ JSObject::SetOwnPropertyIgnoreAttributes(regexp, factory->sticky_string(),
+ sticky, final).Check();
+ }
+ JSObject::SetOwnPropertyIgnoreAttributes(
+ regexp, factory->last_index_string(), zero, writable).Check();
}
- // Map has changed, so use generic, but slower, method. We also end here if
- // 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 =
- static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE);
- PropertyAttributes writable =
- static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
- Handle<Object> zero(Smi::FromInt(0), isolate);
- Factory* factory = isolate->factory();
- JSObject::SetOwnPropertyIgnoreAttributes(regexp, factory->source_string(),
- source, final).Check();
- JSObject::SetOwnPropertyIgnoreAttributes(regexp, factory->global_string(),
- global, final).Check();
- JSObject::SetOwnPropertyIgnoreAttributes(
- regexp, factory->ignore_case_string(), ignoreCase, final).Check();
- JSObject::SetOwnPropertyIgnoreAttributes(regexp, factory->multiline_string(),
- multiline, final).Check();
- if (FLAG_harmony_regexps) {
- JSObject::SetOwnPropertyIgnoreAttributes(regexp, factory->sticky_string(),
- sticky, final).Check();
- }
- JSObject::SetOwnPropertyIgnoreAttributes(regexp, factory->last_index_string(),
- zero, writable).Check();
- return *regexp;
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result, RegExpImpl::Compile(regexp, source, flags));
+ return *result;
}
« no previous file with comments | « src/runtime/runtime.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698