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