Index: src/builtins/builtins-regexp-gen.cc |
diff --git a/src/builtins/builtins-regexp-gen.cc b/src/builtins/builtins-regexp-gen.cc |
index d1fb9e82f193276867951be555e5d52635a59507..f1169c0b94cc66e8c09adb633c7748e83858fc9b 100644 |
--- a/src/builtins/builtins-regexp-gen.cc |
+++ b/src/builtins/builtins-regexp-gen.cc |
@@ -231,11 +231,11 @@ |
var_string_end->Bind(IntPtrAdd(string_data, to_offset)); |
} |
-Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context, |
- Node* const regexp, |
- Node* const string, |
- Node* const last_index, |
- Node* const match_info) { |
+Node* RegExpBuiltinsAssembler::IrregexpExec(Node* const context, |
+ Node* const regexp, |
+ Node* const string, |
+ Node* const last_index, |
+ Node* const match_info) { |
// Just jump directly to runtime if native RegExp is not selected at compile |
// time or if regexp entry in generated code is turned off runtime switch or |
// at compilation. |
@@ -260,14 +260,12 @@ |
Label out(this), runtime(this, Label::kDeferred); |
// External constants. |
- Node* const isolate_address = |
- ExternalConstant(ExternalReference::isolate_address(isolate())); |
- Node* const regexp_stack_memory_address_address = ExternalConstant( |
- ExternalReference::address_of_regexp_stack_memory_address(isolate())); |
Node* const regexp_stack_memory_size_address = ExternalConstant( |
ExternalReference::address_of_regexp_stack_memory_size(isolate())); |
Node* const static_offsets_vector_address = ExternalConstant( |
ExternalReference::address_of_static_offsets_vector(isolate())); |
+ Node* const pending_exception_address = ExternalConstant( |
+ ExternalReference(Isolate::kPendingExceptionAddress, isolate())); |
// Ensure that a RegExp stack is allocated. |
{ |
@@ -363,85 +361,22 @@ |
{ |
IncrementCounter(isolate()->counters()->regexp_entry_native(), 1); |
- // Set up args for the final call into generated Irregexp code. |
- |
- MachineType type_int32 = MachineType::Int32(); |
- MachineType type_tagged = MachineType::AnyTagged(); |
- MachineType type_ptr = MachineType::Pointer(); |
- |
- // Result: A NativeRegExpMacroAssembler::Result return code. |
- MachineType retval_type = type_int32; |
- |
- // Argument 0: Original subject string. |
- MachineType arg0_type = type_tagged; |
- Node* const arg0 = string; |
- |
- // Argument 1: Previous index. |
- MachineType arg1_type = type_int32; |
- Node* const arg1 = TruncateWordToWord32(int_last_index); |
- |
- // Argument 2: Start of string data. |
- MachineType arg2_type = type_ptr; |
- Node* const arg2 = var_string_start.value(); |
- |
- // Argument 3: End of string data. |
- MachineType arg3_type = type_ptr; |
- Node* const arg3 = var_string_end.value(); |
- |
- // Argument 4: static offsets vector buffer. |
- MachineType arg4_type = type_ptr; |
- Node* const arg4 = static_offsets_vector_address; |
- |
- // Argument 5: Set the number of capture registers to zero to force global |
- // regexps to behave as non-global. This does not affect non-global |
- // regexps. |
- MachineType arg5_type = type_int32; |
- Node* const arg5 = Int32Constant(0); |
- |
- // Argument 6: Start (high end) of backtracking stack memory area. |
- Node* const stack_start = |
- Load(MachineType::Pointer(), regexp_stack_memory_address_address); |
- Node* const stack_size = |
- Load(MachineType::IntPtr(), regexp_stack_memory_size_address); |
- Node* const stack_end = IntPtrAdd(stack_start, stack_size); |
- |
- MachineType arg6_type = type_ptr; |
- Node* const arg6 = stack_end; |
- |
- // Argument 7: Indicate that this is a direct call from JavaScript. |
- MachineType arg7_type = type_int32; |
- Node* const arg7 = Int32Constant(1); |
- |
- // Argument 8: Pass current isolate address. |
- MachineType arg8_type = type_ptr; |
- Node* const arg8 = isolate_address; |
- |
- Node* const code_entry = |
- IntPtrAdd(BitcastTaggedToWord(code), |
- IntPtrConstant(Code::kHeaderSize - kHeapObjectTag)); |
- |
- Node* const result = CallCFunction9( |
- retval_type, arg0_type, arg1_type, arg2_type, arg3_type, arg4_type, |
- arg5_type, arg6_type, arg7_type, arg8_type, code_entry, arg0, arg1, |
- arg2, arg3, arg4, arg5, arg6, arg7, arg8); |
+ Callable exec_callable = CodeFactory::RegExpExec(isolate()); |
+ Node* const result = CallStub( |
+ exec_callable, context, string, TruncateWordToWord32(int_last_index), |
+ var_string_start.value(), var_string_end.value(), code); |
// Check the result. |
- // We expect exactly one result since we force the called regexp to behave |
- // as non-global. |
- Node* const int_result = ChangeInt32ToIntPtr(result); |
- GotoIf(IntPtrEqual(int_result, |
- IntPtrConstant(NativeRegExpMacroAssembler::SUCCESS)), |
- &if_success); |
- GotoIf(IntPtrEqual(int_result, |
- IntPtrConstant(NativeRegExpMacroAssembler::FAILURE)), |
+ // We expect exactly one result since the stub forces the called regexp to |
+ // behave as non-global. |
+ GotoIf(SmiEqual(result, SmiConstant(1)), &if_success); |
+ GotoIf(SmiEqual(result, SmiConstant(NativeRegExpMacroAssembler::FAILURE)), |
&if_failure); |
- GotoIf(IntPtrEqual(int_result, |
- IntPtrConstant(NativeRegExpMacroAssembler::EXCEPTION)), |
+ GotoIf(SmiEqual(result, SmiConstant(NativeRegExpMacroAssembler::EXCEPTION)), |
&if_exception); |
- CSA_ASSERT(this, |
- IntPtrEqual(int_result, |
- IntPtrConstant(NativeRegExpMacroAssembler::RETRY))); |
+ CSA_ASSERT( |
+ this, SmiEqual(result, SmiConstant(NativeRegExpMacroAssembler::RETRY))); |
Goto(&runtime); |
} |
@@ -505,14 +440,21 @@ |
BIND(&if_exception); |
{ |
-// A stack overflow was detected in RegExp code. |
-#ifdef DEBUG |
- Node* const pending_exception_address = ExternalConstant( |
- ExternalReference(Isolate::kPendingExceptionAddress, isolate())); |
- CSA_ASSERT(this, IsTheHole(Load(MachineType::AnyTagged(), |
- pending_exception_address))); |
-#endif // DEBUG |
+ Node* const pending_exception = |
+ Load(MachineType::AnyTagged(), pending_exception_address); |
+ |
+ // If there is no pending exception, a |
+ // stack overflow (on the backtrack stack) was detected in RegExp code. |
+ |
+ Label stack_overflow(this), rethrow(this); |
+ Branch(IsTheHole(pending_exception), &stack_overflow, &rethrow); |
+ |
+ BIND(&stack_overflow); |
CallRuntime(Runtime::kThrowStackOverflow, context); |
+ Unreachable(); |
+ |
+ BIND(&rethrow); |
+ CallRuntime(Runtime::kRegExpExecReThrow, context); |
Unreachable(); |
} |
@@ -629,8 +571,8 @@ |
native_context, Context::REGEXP_LAST_MATCH_INFO_INDEX); |
// Call the exec stub. |
- match_indices = RegExpExecInternal(context, regexp, string, |
- var_lastindex.value(), last_match_info); |
+ match_indices = IrregexpExec(context, regexp, string, var_lastindex.value(), |
+ last_match_info); |
var_result.Bind(match_indices); |
// {match_indices} is either null or the RegExpMatchInfo array. |
@@ -2162,8 +2104,8 @@ |
Node* const last_match_info = LoadContextElement( |
native_context, Context::REGEXP_LAST_MATCH_INFO_INDEX); |
- Node* const match_indices = RegExpExecInternal(context, regexp, string, |
- smi_zero, last_match_info); |
+ Node* const match_indices = |
+ IrregexpExec(context, regexp, string, smi_zero, last_match_info); |
Label return_singleton_array(this); |
Branch(WordEqual(match_indices, null), &return_singleton_array, |
@@ -2224,8 +2166,8 @@ |
Node* const last_match_info = LoadContextElement( |
native_context, Context::REGEXP_LAST_MATCH_INFO_INDEX); |
- Node* const match_indices = RegExpExecInternal( |
- context, regexp, string, next_search_from, last_match_info); |
+ Node* const match_indices = IrregexpExec(context, regexp, string, |
+ next_search_from, last_match_info); |
// We're done if no match was found. |
{ |
@@ -2906,8 +2848,8 @@ |
Node* const internal_match_info = LoadContextElement( |
native_context, Context::REGEXP_INTERNAL_MATCH_INFO_INDEX); |
- Node* const match_indices = RegExpExecInternal(context, regexp, string, |
- smi_zero, internal_match_info); |
+ Node* const match_indices = |
+ IrregexpExec(context, regexp, string, smi_zero, internal_match_info); |
Label if_matched(this), if_didnotmatch(this); |
Branch(WordEqual(match_indices, null), &if_didnotmatch, &if_matched); |