diff options
Diffstat (limited to 'chromium/v8/src/regexp/regexp-macro-assembler.cc')
-rw-r--r-- | chromium/v8/src/regexp/regexp-macro-assembler.cc | 75 |
1 files changed, 54 insertions, 21 deletions
diff --git a/chromium/v8/src/regexp/regexp-macro-assembler.cc b/chromium/v8/src/regexp/regexp-macro-assembler.cc index 68fa16db611..96fb53d2a04 100644 --- a/chromium/v8/src/regexp/regexp-macro-assembler.cc +++ b/chromium/v8/src/regexp/regexp-macro-assembler.cc @@ -85,6 +85,20 @@ void RegExpMacroAssembler::CheckPosition(int cp_offset, LoadCurrentCharacter(cp_offset, on_outside_input, true); } +void RegExpMacroAssembler::LoadCurrentCharacter(int cp_offset, + Label* on_end_of_input, + bool check_bounds, + int characters, + int eats_at_least) { + // By default, eats_at_least = characters. + if (eats_at_least == kUseCharactersValue) { + eats_at_least = characters; + } + + LoadCurrentCharacterImpl(cp_offset, on_end_of_input, check_bounds, characters, + eats_at_least); +} + bool RegExpMacroAssembler::CheckSpecialCharacterClass(uc16 type, Label* on_no_match) { return false; @@ -129,32 +143,46 @@ const byte* NativeRegExpMacroAssembler::StringCharacterPosition( } } +// This method may only be called after an interrupt. int NativeRegExpMacroAssembler::CheckStackGuardState( - Isolate* isolate, int start_index, bool is_direct_call, + Isolate* isolate, int start_index, RegExp::CallOrigin call_origin, Address* return_address, Code re_code, Address* subject, const byte** input_start, const byte** input_end) { DisallowHeapAllocation no_gc; DCHECK(re_code.raw_instruction_start() <= *return_address); DCHECK(*return_address <= re_code.raw_instruction_end()); - int return_value = 0; - // Prepare for possible GC. - HandleScope handles(isolate); - Handle<Code> code_handle(re_code, isolate); - Handle<String> subject_handle(String::cast(Object(*subject)), isolate); - bool is_one_byte = String::IsOneByteRepresentationUnderneath(*subject_handle); - StackLimitCheck check(isolate); bool js_has_overflowed = check.JsHasOverflowed(); - if (is_direct_call) { + if (call_origin == RegExp::CallOrigin::kFromJs) { // Direct calls from JavaScript can be interrupted in two ways: // 1. A real stack overflow, in which case we let the caller throw the // exception. // 2. The stack guard was used to interrupt execution for another purpose, // forcing the call through the runtime system. - return_value = js_has_overflowed ? EXCEPTION : RETRY; - } else if (js_has_overflowed) { + + // Bug(v8:9540) Investigate why this method is called from JS although no + // stackoverflow or interrupt is pending on ARM64. We return 0 in this case + // to continue execution normally. + if (js_has_overflowed) { + return EXCEPTION; + } else if (check.InterruptRequested()) { + return RETRY; + } else { + return 0; + } + } + DCHECK(call_origin == RegExp::CallOrigin::kFromRuntime); + + // Prepare for possible GC. + HandleScope handles(isolate); + Handle<Code> code_handle(re_code, isolate); + Handle<String> subject_handle(String::cast(Object(*subject)), isolate); + bool is_one_byte = String::IsOneByteRepresentationUnderneath(*subject_handle); + int return_value = 0; + + if (js_has_overflowed) { AllowHeapAllocation yes_gc; isolate->StackOverflow(); return_value = EXCEPTION; @@ -191,7 +219,7 @@ int NativeRegExpMacroAssembler::CheckStackGuardState( } // Returns a {Result} sentinel, or the number of successful matches. -int NativeRegExpMacroAssembler::Match(Handle<Code> regexp_code, +int NativeRegExpMacroAssembler::Match(Handle<JSRegExp> regexp, Handle<String> subject, int* offsets_vector, int offsets_vector_length, @@ -234,31 +262,36 @@ int NativeRegExpMacroAssembler::Match(Handle<Code> regexp_code, StringCharacterPosition(subject_ptr, start_offset + slice_offset, no_gc); int byte_length = char_length << char_size_shift; const byte* input_end = input_start + byte_length; - return Execute(*regexp_code, *subject, start_offset, input_start, input_end, - offsets_vector, offsets_vector_length, isolate); + return Execute(*subject, start_offset, input_start, input_end, offsets_vector, + offsets_vector_length, isolate, *regexp); } // Returns a {Result} sentinel, or the number of successful matches. +// TODO(pthier): The JSRegExp object is passed to native irregexp code to match +// the signature of the interpreter. We should get rid of JS objects passed to +// internal methods. int NativeRegExpMacroAssembler::Execute( - Code code, String input, // This needs to be the unpacked (sliced, cons) string. int start_offset, const byte* input_start, const byte* input_end, - int* output, int output_size, Isolate* isolate) { + int* output, int output_size, Isolate* isolate, JSRegExp regexp) { // Ensure that the minimum stack has been allocated. RegExpStackScope stack_scope(isolate); Address stack_base = stack_scope.stack()->stack_base(); - int direct_call = 0; + bool is_one_byte = String::IsOneByteRepresentationUnderneath(input); + Code code = Code::cast(regexp.Code(is_one_byte)); + RegExp::CallOrigin call_origin = RegExp::CallOrigin::kFromRuntime; using RegexpMatcherSig = int( Address input_string, int start_offset, // NOLINT(readability/casting) const byte* input_start, const byte* input_end, int* output, - int output_size, Address stack_base, int direct_call, Isolate* isolate); + int output_size, Address stack_base, int call_origin, Isolate* isolate, + Address regexp); auto fn = GeneratedCode<RegexpMatcherSig>::FromCode(code); - int result = - fn.CallIrregexp(input.ptr(), start_offset, input_start, input_end, output, - output_size, stack_base, direct_call, isolate); + int result = fn.CallIrregexp(input.ptr(), start_offset, input_start, + input_end, output, output_size, stack_base, + call_origin, isolate, regexp.ptr()); DCHECK(result >= RETRY); if (result == EXCEPTION && !isolate->has_pending_exception()) { |