Index: src/runtime/runtime-regexp.cc |
diff --git a/src/runtime/runtime-regexp.cc b/src/runtime/runtime-regexp.cc |
index b4cf184c403ae5a67973af5cfa2927d410cde7d4..786852105fba3723762834debf0a0c9978457307 100644 |
--- a/src/runtime/runtime-regexp.cc |
+++ b/src/runtime/runtime-regexp.cc |
@@ -825,145 +825,17 @@ RUNTIME_FUNCTION(Runtime_RegExpConstructResult) { |
} |
-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 > 5) 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 'u': |
- if (!FLAG_harmony_unicode_regexps) return JSRegExp::Flags(0); |
- flag = JSRegExp::UNICODE_ESCAPES; |
- 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); |
-} |
- |
- |
-template <typename Char> |
-inline int CountRequiredEscapes(Handle<String> source) { |
- DisallowHeapAllocation no_gc; |
- int escapes = 0; |
- Vector<const Char> src = source->GetCharVector<Char>(); |
- for (int i = 0; i < src.length(); i++) { |
- if (src[i] == '/' && (i == 0 || src[i - 1] != '\\')) escapes++; |
- } |
- return escapes; |
-} |
- |
- |
-template <typename Char, typename StringType> |
-inline Handle<StringType> WriteEscapedRegExpSource(Handle<String> source, |
- Handle<StringType> result) { |
- DisallowHeapAllocation no_gc; |
- Vector<const Char> src = source->GetCharVector<Char>(); |
- Vector<Char> dst(result->GetChars(), result->length()); |
- int s = 0; |
- int d = 0; |
- while (s < src.length()) { |
- if (src[s] == '/' && (s == 0 || src[s - 1] != '\\')) dst[d++] = '\\'; |
- dst[d++] = src[s++]; |
- } |
- DCHECK_EQ(result->length(), d); |
- return result; |
-} |
- |
- |
-MaybeHandle<String> EscapeRegExpSource(Isolate* isolate, |
- Handle<String> source) { |
- String::Flatten(source); |
- if (source->length() == 0) return isolate->factory()->query_colon_string(); |
- bool one_byte = source->IsOneByteRepresentationUnderneath(); |
- int escapes = one_byte ? CountRequiredEscapes<uint8_t>(source) |
- : CountRequiredEscapes<uc16>(source); |
- if (escapes == 0) return source; |
- int length = source->length() + escapes; |
- if (one_byte) { |
- Handle<SeqOneByteString> result; |
- ASSIGN_RETURN_ON_EXCEPTION(isolate, result, |
- isolate->factory()->NewRawOneByteString(length), |
- String); |
- return WriteEscapedRegExpSource<uint8_t>(source, result); |
- } else { |
- Handle<SeqTwoByteString> result; |
- ASSIGN_RETURN_ON_EXCEPTION(isolate, result, |
- isolate->factory()->NewRawTwoByteString(length), |
- String); |
- return WriteEscapedRegExpSource<uc16>(source, result); |
- } |
-} |
- |
- |
RUNTIME_FUNCTION(Runtime_RegExpInitializeAndCompile) { |
HandleScope scope(isolate); |
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 = factory->query_colon_string(); |
- |
- bool success = false; |
- JSRegExp::Flags flags = RegExpFlagsFromString(flags_string, &success); |
- if (!success) { |
- THROW_NEW_ERROR_RETURN_FAILURE( |
- isolate, |
- NewSyntaxError(MessageTemplate::kInvalidRegExpFlags, flags_string)); |
- } |
- |
- Handle<String> escaped_source; |
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, escaped_source, |
- EscapeRegExpSource(isolate, source)); |
+ CONVERT_ARG_HANDLE_CHECKED(String, flags, 2); |
- regexp->set_source(*escaped_source); |
- regexp->set_flags(Smi::FromInt(flags.value())); |
+ RETURN_FAILURE_ON_EXCEPTION(isolate, |
+ JSRegExp::Initialize(regexp, source, flags)); |
- Map* map = regexp->map(); |
- Object* constructor = map->GetConstructor(); |
- if (constructor->IsJSFunction() && |
- JSFunction::cast(constructor)->initial_map() == map) { |
- // If we still have the original map, set in-object properties directly. |
- regexp->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex, |
- Smi::FromInt(0), SKIP_WRITE_BARRIER); |
- } else { |
- // Map has changed, so use generic, but slower, method. |
- PropertyAttributes writable = |
- static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); |
- JSObject::SetOwnPropertyIgnoreAttributes( |
- regexp, factory->last_index_string(), |
- Handle<Smi>(Smi::FromInt(0), isolate), writable) |
- .Check(); |
- } |
- |
- Handle<Object> result; |
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
- isolate, result, RegExpImpl::Compile(regexp, source, flags)); |
- return *result; |
+ return *regexp; |
} |
@@ -975,12 +847,9 @@ RUNTIME_FUNCTION(Runtime_MaterializeRegExpLiteral) { |
CONVERT_ARG_HANDLE_CHECKED(String, pattern, 2); |
CONVERT_ARG_HANDLE_CHECKED(String, flags, 3); |
- Handle<JSFunction> constructor = isolate->regexp_function(); |
- // Compute the regular expression literal. |
- Handle<Object> regexp; |
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
- isolate, regexp, |
- RegExpImpl::CreateRegExpLiteral(constructor, pattern, flags)); |
+ Handle<JSRegExp> regexp; |
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, regexp, |
+ JSRegExp::New(pattern, flags)); |
literals->set_literal(index, *regexp); |
return *regexp; |
} |