diff options
author | Michaël Zasso <targos@protonmail.com> | 2017-02-14 11:27:26 +0100 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2017-02-22 15:55:42 +0100 |
commit | 7a77daf24344db7942e34c962b0f1ee729ab7af5 (patch) | |
tree | e7cbe7bf4e2f4b802a8f5bc18336c546cd6a0d7f /deps/v8/src/regexp | |
parent | 5f08871ee93ea739148cc49e0f7679e33c70295a (diff) | |
download | android-node-v8-7a77daf24344db7942e34c962b0f1ee729ab7af5.tar.gz android-node-v8-7a77daf24344db7942e34c962b0f1ee729ab7af5.tar.bz2 android-node-v8-7a77daf24344db7942e34c962b0f1ee729ab7af5.zip |
deps: update V8 to 5.6.326.55
PR-URL: https://github.com/nodejs/node/pull/10992
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Diffstat (limited to 'deps/v8/src/regexp')
-rw-r--r-- | deps/v8/src/regexp/OWNERS | 4 | ||||
-rw-r--r-- | deps/v8/src/regexp/jsregexp.cc | 113 | ||||
-rw-r--r-- | deps/v8/src/regexp/jsregexp.h | 55 | ||||
-rw-r--r-- | deps/v8/src/regexp/regexp-macro-assembler-tracer.cc | 6 | ||||
-rw-r--r-- | deps/v8/src/regexp/regexp-parser.cc | 2 | ||||
-rw-r--r-- | deps/v8/src/regexp/regexp-utils.cc | 192 | ||||
-rw-r--r-- | deps/v8/src/regexp/regexp-utils.h | 52 |
7 files changed, 312 insertions, 112 deletions
diff --git a/deps/v8/src/regexp/OWNERS b/deps/v8/src/regexp/OWNERS index d9d588df6c..c493afa8f0 100644 --- a/deps/v8/src/regexp/OWNERS +++ b/deps/v8/src/regexp/OWNERS @@ -1,6 +1,4 @@ set noparent -jochen@chromium.org -marja@chromium.org -ulan@chromium.org +jgruber@chromium.org yangguo@chromium.org diff --git a/deps/v8/src/regexp/jsregexp.cc b/deps/v8/src/regexp/jsregexp.cc index 96a778cfb7..f0abc9a8b3 100644 --- a/deps/v8/src/regexp/jsregexp.cc +++ b/deps/v8/src/regexp/jsregexp.cc @@ -136,16 +136,12 @@ MaybeHandle<Object> RegExpImpl::Compile(Handle<JSRegExp> re, Handle<String> pattern, JSRegExp::Flags flags) { Isolate* isolate = re->GetIsolate(); - Zone zone(isolate->allocator()); + Zone zone(isolate->allocator(), ZONE_NAME); CompilationCache* compilation_cache = isolate->compilation_cache(); MaybeHandle<FixedArray> maybe_cached = compilation_cache->LookupRegExp(pattern, flags); Handle<FixedArray> cached; - bool in_cache = maybe_cached.ToHandle(&cached); - LOG(isolate, RegExpCompileEvent(re, in_cache)); - - Handle<Object> result; - if (in_cache) { + if (maybe_cached.ToHandle(&cached)) { re->set_data(*cached); return re; } @@ -194,7 +190,7 @@ MaybeHandle<Object> RegExpImpl::Compile(Handle<JSRegExp> re, MaybeHandle<Object> RegExpImpl::Exec(Handle<JSRegExp> regexp, Handle<String> subject, int index, - Handle<JSObject> last_match_info) { + Handle<RegExpMatchInfo> last_match_info) { switch (regexp->TypeTag()) { case JSRegExp::ATOM: return AtomExec(regexp, subject, index, last_match_info); @@ -222,17 +218,14 @@ void RegExpImpl::AtomCompile(Handle<JSRegExp> re, match_pattern); } - -static void SetAtomLastCapture(FixedArray* array, - String* subject, - int from, - int to) { - SealHandleScope shs(array->GetIsolate()); - RegExpImpl::SetLastCaptureCount(array, 2); - RegExpImpl::SetLastSubject(array, subject); - RegExpImpl::SetLastInput(array, subject); - RegExpImpl::SetCapture(array, 0, from); - RegExpImpl::SetCapture(array, 1, to); +static void SetAtomLastCapture(Handle<RegExpMatchInfo> last_match_info, + String* subject, int from, int to) { + SealHandleScope shs(last_match_info->GetIsolate()); + last_match_info->SetNumberOfCaptureRegisters(2); + last_match_info->SetLastSubject(subject); + last_match_info->SetLastInput(subject); + last_match_info->SetCapture(0, from); + last_match_info->SetCapture(1, to); } @@ -289,7 +282,7 @@ int RegExpImpl::AtomExecRaw(Handle<JSRegExp> regexp, Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re, Handle<String> subject, int index, - Handle<JSObject> last_match_info) { + Handle<RegExpMatchInfo> last_match_info) { Isolate* isolate = re->GetIsolate(); static const int kNumRegisters = 2; @@ -302,8 +295,8 @@ Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re, Handle<String> subject, DCHECK_EQ(res, RegExpImpl::RE_SUCCESS); SealHandleScope shs(isolate); - FixedArray* array = FixedArray::cast(last_match_info->elements()); - SetAtomLastCapture(array, *subject, output_registers[0], output_registers[1]); + SetAtomLastCapture(last_match_info, *subject, output_registers[0], + output_registers[1]); return last_match_info; } @@ -343,7 +336,7 @@ bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re, bool is_one_byte) { // Compile the RegExp. Isolate* isolate = re->GetIsolate(); - Zone zone(isolate->allocator()); + Zone zone(isolate->allocator(), ZONE_NAME); PostponeInterruptsScope postpone(isolate); // If we had a compilation error the last time this is saved at the // saved code index. @@ -417,7 +410,7 @@ void RegExpImpl::SetIrregexpMaxRegisterCount(FixedArray* re, int value) { void RegExpImpl::SetIrregexpCaptureNameMap(FixedArray* re, Handle<FixedArray> value) { if (value.is_null()) { - re->set(JSRegExp::kIrregexpCaptureNameMapIndex, Smi::FromInt(0)); + re->set(JSRegExp::kIrregexpCaptureNameMapIndex, Smi::kZero); } else { re->set(JSRegExp::kIrregexpCaptureNameMapIndex, *value); } @@ -566,10 +559,9 @@ int RegExpImpl::IrregexpExecRaw(Handle<JSRegExp> regexp, #endif // V8_INTERPRETED_REGEXP } -MaybeHandle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> regexp, - Handle<String> subject, - int previous_index, - Handle<JSObject> last_match_info) { +MaybeHandle<Object> RegExpImpl::IrregexpExec( + Handle<JSRegExp> regexp, Handle<String> subject, int previous_index, + Handle<RegExpMatchInfo> last_match_info) { Isolate* isolate = regexp->GetIsolate(); DCHECK_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP); @@ -613,31 +605,40 @@ MaybeHandle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> regexp, return isolate->factory()->null_value(); } -static void EnsureSize(Handle<JSObject> array, uint32_t minimum_size) { - if (static_cast<uint32_t>(array->elements()->length()) < minimum_size) { - array->GetElementsAccessor()->GrowCapacityAndConvert(array, minimum_size); - } -} +Handle<RegExpMatchInfo> RegExpImpl::SetLastMatchInfo( + Handle<RegExpMatchInfo> last_match_info, Handle<String> subject, + int capture_count, int32_t* match) { + // This is the only place where match infos can grow. If, after executing the + // regexp, RegExpExecStub finds that the match info is too small, it restarts + // execution in RegExpImpl::Exec, which finally grows the match info right + // here. -Handle<JSObject> RegExpImpl::SetLastMatchInfo(Handle<JSObject> last_match_info, - Handle<String> subject, - int capture_count, - int32_t* match) { - DCHECK(last_match_info->HasFastObjectElements()); int capture_register_count = (capture_count + 1) * 2; - EnsureSize(last_match_info, capture_register_count + kLastMatchOverhead); + Handle<RegExpMatchInfo> result = + RegExpMatchInfo::ReserveCaptures(last_match_info, capture_register_count); + result->SetNumberOfCaptureRegisters(capture_register_count); + + if (*result != *last_match_info) { + // The match info has been reallocated, update the corresponding reference + // on the native context. + Isolate* isolate = last_match_info->GetIsolate(); + if (*last_match_info == *isolate->regexp_last_match_info()) { + isolate->native_context()->set_regexp_last_match_info(*result); + } else if (*last_match_info == *isolate->regexp_internal_match_info()) { + isolate->native_context()->set_regexp_internal_match_info(*result); + } + } + DisallowHeapAllocation no_allocation; - FixedArray* array = FixedArray::cast(last_match_info->elements()); if (match != NULL) { for (int i = 0; i < capture_register_count; i += 2) { - SetCapture(array, i, match[i]); - SetCapture(array, i + 1, match[i + 1]); + result->SetCapture(i, match[i]); + result->SetCapture(i + 1, match[i + 1]); } } - SetLastCaptureCount(array, capture_register_count); - SetLastSubject(array, *subject); - SetLastInput(array, *subject); - return last_match_info; + result->SetLastSubject(*subject); + result->SetLastInput(*subject); + return result; } @@ -6781,10 +6782,10 @@ Object* RegExpResultsCache::Lookup(Heap* heap, String* key_string, FixedArray** last_match_cache, ResultsCacheType type) { FixedArray* cache; - if (!key_string->IsInternalizedString()) return Smi::FromInt(0); + if (!key_string->IsInternalizedString()) return Smi::kZero; if (type == STRING_SPLIT_SUBSTRINGS) { DCHECK(key_pattern->IsString()); - if (!key_pattern->IsInternalizedString()) return Smi::FromInt(0); + if (!key_pattern->IsInternalizedString()) return Smi::kZero; cache = heap->string_split_cache(); } else { DCHECK(type == REGEXP_MULTIPLE_INDICES); @@ -6801,7 +6802,7 @@ Object* RegExpResultsCache::Lookup(Heap* heap, String* key_string, ((index + kArrayEntriesPerCacheEntry) & (kRegExpResultsCacheSize - 1)); if (cache->get(index + kStringOffset) != key_string || cache->get(index + kPatternOffset) != key_pattern) { - return Smi::FromInt(0); + return Smi::kZero; } } @@ -6831,7 +6832,7 @@ void RegExpResultsCache::Enter(Isolate* isolate, Handle<String> key_string, uint32_t hash = key_string->Hash(); uint32_t index = ((hash & (kRegExpResultsCacheSize - 1)) & ~(kArrayEntriesPerCacheEntry - 1)); - if (cache->get(index + kStringOffset) == Smi::FromInt(0)) { + if (cache->get(index + kStringOffset) == Smi::kZero) { cache->set(index + kStringOffset, *key_string); cache->set(index + kPatternOffset, *key_pattern); cache->set(index + kArrayOffset, *value_array); @@ -6839,16 +6840,16 @@ void RegExpResultsCache::Enter(Isolate* isolate, Handle<String> key_string, } else { uint32_t index2 = ((index + kArrayEntriesPerCacheEntry) & (kRegExpResultsCacheSize - 1)); - if (cache->get(index2 + kStringOffset) == Smi::FromInt(0)) { + if (cache->get(index2 + kStringOffset) == Smi::kZero) { cache->set(index2 + kStringOffset, *key_string); cache->set(index2 + kPatternOffset, *key_pattern); cache->set(index2 + kArrayOffset, *value_array); cache->set(index2 + kLastMatchOffset, *last_match_cache); } else { - cache->set(index2 + kStringOffset, Smi::FromInt(0)); - cache->set(index2 + kPatternOffset, Smi::FromInt(0)); - cache->set(index2 + kArrayOffset, Smi::FromInt(0)); - cache->set(index2 + kLastMatchOffset, Smi::FromInt(0)); + cache->set(index2 + kStringOffset, Smi::kZero); + cache->set(index2 + kPatternOffset, Smi::kZero); + cache->set(index2 + kArrayOffset, Smi::kZero); + cache->set(index2 + kLastMatchOffset, Smi::kZero); cache->set(index + kStringOffset, *key_string); cache->set(index + kPatternOffset, *key_pattern); cache->set(index + kArrayOffset, *value_array); @@ -6865,13 +6866,13 @@ void RegExpResultsCache::Enter(Isolate* isolate, Handle<String> key_string, } } // Convert backing store to a copy-on-write array. - value_array->set_map_no_write_barrier(*factory->fixed_cow_array_map()); + value_array->set_map_no_write_barrier(isolate->heap()->fixed_cow_array_map()); } void RegExpResultsCache::Clear(FixedArray* cache) { for (int i = 0; i < kRegExpResultsCacheSize; i++) { - cache->set(i, Smi::FromInt(0)); + cache->set(i, Smi::kZero); } } diff --git a/deps/v8/src/regexp/jsregexp.h b/deps/v8/src/regexp/jsregexp.h index 8118889966..b2e84ba4f3 100644 --- a/deps/v8/src/regexp/jsregexp.h +++ b/deps/v8/src/regexp/jsregexp.h @@ -48,7 +48,7 @@ class RegExpImpl { // This function calls the garbage collector if necessary. V8_EXPORT_PRIVATE MUST_USE_RESULT static MaybeHandle<Object> Exec( Handle<JSRegExp> regexp, Handle<String> subject, int index, - Handle<JSObject> lastMatchInfo); + Handle<RegExpMatchInfo> last_match_info); // Prepares a JSRegExp object with Irregexp-specific data. static void IrregexpInitialize(Handle<JSRegExp> re, @@ -71,7 +71,7 @@ class RegExpImpl { static Handle<Object> AtomExec(Handle<JSRegExp> regexp, Handle<String> subject, int index, - Handle<JSObject> lastMatchInfo); + Handle<RegExpMatchInfo> last_match_info); enum IrregexpResult { RE_FAILURE = 0, RE_SUCCESS = 1, RE_EXCEPTION = -1 }; @@ -103,12 +103,12 @@ class RegExpImpl { // Returns an empty handle in case of an exception. MUST_USE_RESULT static MaybeHandle<Object> IrregexpExec( Handle<JSRegExp> regexp, Handle<String> subject, int index, - Handle<JSObject> lastMatchInfo); + Handle<RegExpMatchInfo> last_match_info); // Set last match info. If match is NULL, then setting captures is omitted. - static Handle<JSObject> SetLastMatchInfo(Handle<JSObject> last_match_info, - Handle<String> subject, - int capture_count, int32_t* match); + static Handle<RegExpMatchInfo> SetLastMatchInfo( + Handle<RegExpMatchInfo> last_match_info, Handle<String> subject, + int capture_count, int32_t* match); class GlobalCache { public: @@ -142,49 +142,6 @@ class RegExpImpl { Handle<String> subject_; }; - - // Array index in the lastMatchInfo array. - static const int kLastCaptureCount = 0; - static const int kLastSubject = 1; - static const int kLastInput = 2; - static const int kFirstCapture = 3; - static const int kLastMatchOverhead = 3; - - // Direct offset into the lastMatchInfo array. - static const int kLastCaptureCountOffset = - FixedArray::kHeaderSize + kLastCaptureCount * kPointerSize; - static const int kLastSubjectOffset = - FixedArray::kHeaderSize + kLastSubject * kPointerSize; - static const int kLastInputOffset = - FixedArray::kHeaderSize + kLastInput * kPointerSize; - static const int kFirstCaptureOffset = - FixedArray::kHeaderSize + kFirstCapture * kPointerSize; - - // Used to access the lastMatchInfo array. - static int GetCapture(FixedArray* array, int index) { - return Smi::cast(array->get(index + kFirstCapture))->value(); - } - - static void SetLastCaptureCount(FixedArray* array, int to) { - array->set(kLastCaptureCount, Smi::FromInt(to)); - } - - static void SetLastSubject(FixedArray* array, String* to) { - array->set(kLastSubject, to); - } - - static void SetLastInput(FixedArray* array, String* to) { - array->set(kLastInput, to); - } - - static void SetCapture(FixedArray* array, int index, int to) { - array->set(index + kFirstCapture, Smi::FromInt(to)); - } - - static int GetLastCaptureCount(FixedArray* array) { - return Smi::cast(array->get(kLastCaptureCount))->value(); - } - // For acting on the JSRegExp data FixedArray. static int IrregexpMaxRegisterCount(FixedArray* re); static void SetIrregexpMaxRegisterCount(FixedArray* re, int value); diff --git a/deps/v8/src/regexp/regexp-macro-assembler-tracer.cc b/deps/v8/src/regexp/regexp-macro-assembler-tracer.cc index ec86526033..abdf577209 100644 --- a/deps/v8/src/regexp/regexp-macro-assembler-tracer.cc +++ b/deps/v8/src/regexp/regexp-macro-assembler-tracer.cc @@ -12,9 +12,9 @@ namespace internal { RegExpMacroAssemblerTracer::RegExpMacroAssemblerTracer( Isolate* isolate, RegExpMacroAssembler* assembler) : RegExpMacroAssembler(isolate, assembler->zone()), assembler_(assembler) { - unsigned int type = assembler->Implementation(); - DCHECK(type < 8); - const char* impl_names[] = {"IA32", "ARM", "ARM64", "MIPS", + IrregexpImplementation type = assembler->Implementation(); + DCHECK_LT(type, 9); + const char* impl_names[] = {"IA32", "ARM", "ARM64", "MIPS", "S390", "PPC", "X64", "X87", "Bytecode"}; PrintF("RegExpMacroAssembler%s();\n", impl_names[type]); } diff --git a/deps/v8/src/regexp/regexp-parser.cc b/deps/v8/src/regexp/regexp-parser.cc index dba81ae9a7..fd3123f674 100644 --- a/deps/v8/src/regexp/regexp-parser.cc +++ b/deps/v8/src/regexp/regexp-parser.cc @@ -1607,7 +1607,7 @@ void RegExpBuilder::AddCharacter(uc16 c) { void RegExpBuilder::AddUnicodeCharacter(uc32 c) { - if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) { + if (c > static_cast<uc32>(unibrow::Utf16::kMaxNonSurrogateCharCode)) { DCHECK(unicode()); AddLeadSurrogate(unibrow::Utf16::LeadSurrogate(c)); AddTrailSurrogate(unibrow::Utf16::TrailSurrogate(c)); diff --git a/deps/v8/src/regexp/regexp-utils.cc b/deps/v8/src/regexp/regexp-utils.cc new file mode 100644 index 0000000000..62daf3f1d5 --- /dev/null +++ b/deps/v8/src/regexp/regexp-utils.cc @@ -0,0 +1,192 @@ +// Copyright 2016 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. + +#include "src/regexp/regexp-utils.h" + +#include "src/factory.h" +#include "src/isolate.h" +#include "src/objects-inl.h" +#include "src/regexp/jsregexp.h" + +namespace v8 { +namespace internal { + +Handle<String> RegExpUtils::GenericCaptureGetter( + Isolate* isolate, Handle<RegExpMatchInfo> match_info, int capture, + bool* ok) { + const int index = capture * 2; + if (index >= match_info->NumberOfCaptureRegisters()) { + if (ok != nullptr) *ok = false; + return isolate->factory()->empty_string(); + } + + const int match_start = match_info->Capture(index); + const int match_end = match_info->Capture(index + 1); + if (match_start == -1 || match_end == -1) { + if (ok != nullptr) *ok = false; + return isolate->factory()->empty_string(); + } + + if (ok != nullptr) *ok = true; + Handle<String> last_subject(match_info->LastSubject()); + return isolate->factory()->NewSubString(last_subject, match_start, match_end); +} + +namespace { + +V8_INLINE bool HasInitialRegExpMap(Isolate* isolate, Handle<JSReceiver> recv) { + return recv->map() == isolate->regexp_function()->initial_map(); +} + +} // namespace + +MaybeHandle<Object> RegExpUtils::SetLastIndex(Isolate* isolate, + Handle<JSReceiver> recv, + int value) { + if (HasInitialRegExpMap(isolate, recv)) { + JSRegExp::cast(*recv)->SetLastIndex(value); + return recv; + } else { + return Object::SetProperty(recv, isolate->factory()->lastIndex_string(), + handle(Smi::FromInt(value), isolate), STRICT); + } +} + +MaybeHandle<Object> RegExpUtils::GetLastIndex(Isolate* isolate, + Handle<JSReceiver> recv) { + if (HasInitialRegExpMap(isolate, recv)) { + return handle(JSRegExp::cast(*recv)->LastIndex(), isolate); + } else { + return Object::GetProperty(recv, isolate->factory()->lastIndex_string()); + } +} + +// ES#sec-regexpexec Runtime Semantics: RegExpExec ( R, S ) +// Also takes an optional exec method in case our caller +// has already fetched exec. +MaybeHandle<Object> RegExpUtils::RegExpExec(Isolate* isolate, + Handle<JSReceiver> regexp, + Handle<String> string, + Handle<Object> exec) { + if (exec->IsUndefined(isolate)) { + ASSIGN_RETURN_ON_EXCEPTION( + isolate, exec, + Object::GetProperty(regexp, isolate->factory()->exec_string()), Object); + } + + if (exec->IsCallable()) { + const int argc = 1; + ScopedVector<Handle<Object>> argv(argc); + argv[0] = string; + + Handle<Object> result; + ASSIGN_RETURN_ON_EXCEPTION( + isolate, result, + Execution::Call(isolate, exec, regexp, argc, argv.start()), Object); + + if (!result->IsJSReceiver() && !result->IsNull(isolate)) { + THROW_NEW_ERROR(isolate, + NewTypeError(MessageTemplate::kInvalidRegExpExecResult), + Object); + } + return result; + } + + if (!regexp->IsJSRegExp()) { + THROW_NEW_ERROR(isolate, + NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, + isolate->factory()->NewStringFromAsciiChecked( + "RegExp.prototype.exec"), + regexp), + Object); + } + + { + Handle<JSFunction> regexp_exec = isolate->regexp_exec_function(); + + const int argc = 1; + ScopedVector<Handle<Object>> argv(argc); + argv[0] = string; + + return Execution::Call(isolate, regexp_exec, regexp, argc, argv.start()); + } +} + +Maybe<bool> RegExpUtils::IsRegExp(Isolate* isolate, Handle<Object> object) { + if (!object->IsJSReceiver()) return Just(false); + + Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object); + + if (isolate->regexp_function()->initial_map() == receiver->map()) { + // Fast-path for unmodified JSRegExp instances. + // TODO(ishell): Adapt for new fast-path logic. + return Just(true); + } + + Handle<Object> match; + ASSIGN_RETURN_ON_EXCEPTION_VALUE( + isolate, match, + JSObject::GetProperty(receiver, isolate->factory()->match_symbol()), + Nothing<bool>()); + + if (!match->IsUndefined(isolate)) return Just(match->BooleanValue()); + return Just(object->IsJSRegExp()); +} + +bool RegExpUtils::IsUnmodifiedRegExp(Isolate* isolate, Handle<Object> obj) { + // TODO(ishell): Update this check once map changes for constant field + // tracking are landing. + + if (!obj->IsJSReceiver()) return false; + + JSReceiver* recv = JSReceiver::cast(*obj); + + // Check the receiver's map. + Handle<JSFunction> regexp_function = isolate->regexp_function(); + if (recv->map() != regexp_function->initial_map()) return false; + + // Check the receiver's prototype's map. + Object* proto = recv->map()->prototype(); + if (!proto->IsJSReceiver()) return false; + + Handle<Map> initial_proto_initial_map = isolate->regexp_prototype_map(); + return (JSReceiver::cast(proto)->map() == *initial_proto_initial_map); +} + +int RegExpUtils::AdvanceStringIndex(Isolate* isolate, Handle<String> string, + int index, bool unicode) { + if (unicode && index < string->length()) { + const uint16_t first = string->Get(index); + if (first >= 0xD800 && first <= 0xDBFF && string->length() > index + 1) { + const uint16_t second = string->Get(index + 1); + if (second >= 0xDC00 && second <= 0xDFFF) { + return index + 2; + } + } + } + + return index + 1; +} + +MaybeHandle<Object> RegExpUtils::SetAdvancedStringIndex( + Isolate* isolate, Handle<JSReceiver> regexp, Handle<String> string, + bool unicode) { + Handle<Object> last_index_obj; + ASSIGN_RETURN_ON_EXCEPTION( + isolate, last_index_obj, + Object::GetProperty(regexp, isolate->factory()->lastIndex_string()), + Object); + + ASSIGN_RETURN_ON_EXCEPTION(isolate, last_index_obj, + Object::ToLength(isolate, last_index_obj), Object); + + const int last_index = Handle<Smi>::cast(last_index_obj)->value(); + const int new_last_index = + AdvanceStringIndex(isolate, string, last_index, unicode); + + return SetLastIndex(isolate, regexp, new_last_index); +} + +} // namespace internal +} // namespace v8 diff --git a/deps/v8/src/regexp/regexp-utils.h b/deps/v8/src/regexp/regexp-utils.h new file mode 100644 index 0000000000..eff1ed739c --- /dev/null +++ b/deps/v8/src/regexp/regexp-utils.h @@ -0,0 +1,52 @@ +// Copyright 2016 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. + +#ifndef V8_REGEXP_REGEXP_UTILS_H_ +#define V8_REGEXP_REGEXP_UTILS_H_ + +#include "src/objects.h" + +namespace v8 { +namespace internal { + +// Helper methods for C++ regexp builtins. +class RegExpUtils : public AllStatic { + public: + // Last match info accessors. + static Handle<String> GenericCaptureGetter(Isolate* isolate, + Handle<RegExpMatchInfo> match_info, + int capture, bool* ok = nullptr); + + // Last index (RegExp.lastIndex) accessors. + static MUST_USE_RESULT MaybeHandle<Object> SetLastIndex( + Isolate* isolate, Handle<JSReceiver> regexp, int value); + static MUST_USE_RESULT MaybeHandle<Object> GetLastIndex( + Isolate* isolate, Handle<JSReceiver> recv); + + // ES#sec-regexpexec Runtime Semantics: RegExpExec ( R, S ) + static MUST_USE_RESULT MaybeHandle<Object> RegExpExec( + Isolate* isolate, Handle<JSReceiver> regexp, Handle<String> string, + Handle<Object> exec); + + // ES#sec-isregexp IsRegExp ( argument ) + // Includes checking of the match property. + static Maybe<bool> IsRegExp(Isolate* isolate, Handle<Object> object); + + // Checks whether the given object is an unmodified JSRegExp instance. + // Neither the object's map, nor its prototype's map may be modified. + static bool IsUnmodifiedRegExp(Isolate* isolate, Handle<Object> obj); + + // ES#sec-advancestringindex + // AdvanceStringIndex ( S, index, unicode ) + static int AdvanceStringIndex(Isolate* isolate, Handle<String> string, + int index, bool unicode); + static MUST_USE_RESULT MaybeHandle<Object> SetAdvancedStringIndex( + Isolate* isolate, Handle<JSReceiver> regexp, Handle<String> string, + bool unicode); +}; + +} // namespace internal +} // namespace v8 + +#endif // V8_REGEXP_REGEXP_UTILS_H_ |