Index: src/x64/code-stubs-x64.cc |
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc |
index 3a1edf4c5e848df960b974bf7df26e70122ad131..fc080f4c4cc2fc63abbf122d7d4f4e23b903892d 100644 |
--- a/src/x64/code-stubs-x64.cc |
+++ b/src/x64/code-stubs-x64.cc |
@@ -350,6 +350,85 @@ |
__ ret(0); |
} |
+void RegExpExecStub::Generate(MacroAssembler* masm) { |
+#ifdef V8_INTERPRETED_REGEXP |
+ // This case is handled prior to the RegExpExecStub call. |
+ __ Abort(kUnexpectedRegExpExecCall); |
+#else // V8_INTERPRETED_REGEXP |
+ // Isolates: note we add an additional parameter here (isolate pointer). |
+ static const int kRegExpExecuteArguments = 9; |
+ int argument_slots_on_stack = |
+ masm->ArgumentStackSlotsForCFunctionCall(kRegExpExecuteArguments); |
+ __ EnterApiExitFrame(argument_slots_on_stack); |
+ |
+ // Argument 9: Pass current isolate address. |
+ __ LoadAddress(kScratchRegister, |
+ ExternalReference::isolate_address(isolate())); |
+ __ movq(Operand(rsp, (argument_slots_on_stack - 1) * kRegisterSize), |
+ kScratchRegister); |
+ |
+ // Argument 8: Indicate that this is a direct call from JavaScript. |
+ __ movq(Operand(rsp, (argument_slots_on_stack - 2) * kRegisterSize), |
+ Immediate(1)); |
+ |
+ // Argument 7: Start (high end) of backtracking stack memory area. |
+ ExternalReference address_of_regexp_stack_memory_address = |
+ ExternalReference::address_of_regexp_stack_memory_address(isolate()); |
+ ExternalReference address_of_regexp_stack_memory_size = |
+ ExternalReference::address_of_regexp_stack_memory_size(isolate()); |
+ __ Move(kScratchRegister, address_of_regexp_stack_memory_address); |
+ __ movp(r12, Operand(kScratchRegister, 0)); |
+ __ Move(kScratchRegister, address_of_regexp_stack_memory_size); |
+ __ addp(r12, Operand(kScratchRegister, 0)); |
+ __ movq(Operand(rsp, (argument_slots_on_stack - 3) * kRegisterSize), r12); |
+ |
+ // Argument 6: Set the number of capture registers to zero to force global |
+ // regexps to behave as non-global. This does not affect non-global regexps. |
+ // Argument 6 is passed in r9 on Linux and on the stack on Windows. |
+#ifdef _WIN64 |
+ __ movq(Operand(rsp, (argument_slots_on_stack - 4) * kRegisterSize), |
+ Immediate(0)); |
+#else |
+ __ Set(r9, 0); |
+#endif |
+ |
+ // Argument 5: static offsets vector buffer. |
+ // Argument 5 passed in r8 on Linux and on the stack on Windows. |
+#ifdef _WIN64 |
+ __ LoadAddress( |
+ r12, ExternalReference::address_of_static_offsets_vector(isolate())); |
+ __ movq(Operand(rsp, (argument_slots_on_stack - 5) * kRegisterSize), r12); |
+#else // _WIN64 |
+ __ LoadAddress( |
+ r8, ExternalReference::address_of_static_offsets_vector(isolate())); |
+#endif |
+ |
+ // Argument 2: Previous index. |
+ // TODO(jgruber): Ideally, LastIndexRegister would already equal arg_reg_2, |
+ // but that makes register allocation fail. |
+ __ movp(arg_reg_2, RegExpExecDescriptor::LastIndexRegister()); |
+ |
+ // Argument 4: End of string data |
+ // Argument 3: Start of string data |
+ CHECK(arg_reg_4.is(RegExpExecDescriptor::StringEndRegister())); |
+ CHECK(arg_reg_3.is(RegExpExecDescriptor::StringStartRegister())); |
+ |
+ // Argument 1: Original subject string. |
+ CHECK(arg_reg_1.is(RegExpExecDescriptor::StringRegister())); |
+ |
+ __ addp(RegExpExecDescriptor::CodeRegister(), |
+ Immediate(Code::kHeaderSize - kHeapObjectTag)); |
+ __ call(RegExpExecDescriptor::CodeRegister()); |
+ |
+ __ LeaveApiExitFrame(true); |
+ |
+ // TODO(jgruber): Don't tag return value once this is supported by stubs. |
+ __ Integer32ToSmi(rax, rax); |
+ __ ret(0 * kPointerSize); |
+#endif // V8_INTERPRETED_REGEXP |
+} |
+ |
+ |
static int NegativeComparisonResult(Condition cc) { |
DCHECK(cc != equal); |
DCHECK((cc == less) || (cc == less_equal) |