| Index: src/x64/codegen-x64.cc
|
| diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc
|
| index 3df547098d6969b75f592130cc021988a205ecea..7e2e6ed2b1d097c86cdd5c7bc481264f4e8e2934 100644
|
| --- a/src/x64/codegen-x64.cc
|
| +++ b/src/x64/codegen-x64.cc
|
| @@ -50,6 +50,9 @@ CodeGenerator::CodeGenerator(int buffer_size,
|
| in_spilled_code_(false) {
|
| }
|
|
|
| +#define __ masm->
|
| +
|
| +
|
| void CodeGenerator::DeclareGlobals(Handle<FixedArray> a) {
|
| UNIMPLEMENTED();
|
| }
|
| @@ -229,10 +232,97 @@ void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) {
|
| masm->int3(); // TODO(X64): UNIMPLEMENTED.
|
| }
|
|
|
| -void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
|
| - masm->int3(); // TODO(X64): UNIMPLEMENTED.
|
| -}
|
| -
|
|
|
| +void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
|
| + Label invoke, exit;
|
| +
|
| + // Setup frame.
|
| + __ push(rbp);
|
| + __ movq(rbp, rsp);
|
| +
|
| + // Save callee-saved registers (X64 calling conventions).
|
| + int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY;
|
| + // Push something that is not an arguments adaptor.
|
| + __ push(Immediate(ArgumentsAdaptorFrame::NON_SENTINEL));
|
| + __ push(Immediate(Smi::FromInt(marker))); // @ function offset
|
| + __ push(r12);
|
| + __ push(r13);
|
| + __ push(r14);
|
| + __ push(r15);
|
| + __ push(rdi);
|
| + __ push(rsi);
|
| + __ push(rbx);
|
| + // TODO(X64): Push XMM6-XMM15 (low 64 bits) as well, or make them
|
| + // callee-save in JS code as well.
|
| +
|
| + // Save copies of the top frame descriptor on the stack.
|
| + ExternalReference c_entry_fp(Top::k_c_entry_fp_address);
|
| + __ load_rax(c_entry_fp);
|
| + __ push(rax);
|
| +
|
| + // Call a faked try-block that does the invoke.
|
| + __ call(&invoke);
|
| +
|
| + // Caught exception: Store result (exception) in the pending
|
| + // exception field in the JSEnv and return a failure sentinel.
|
| + ExternalReference pending_exception(Top::k_pending_exception_address);
|
| + __ store_rax(pending_exception);
|
| + __ movq(rax, Failure::Exception(), RelocInfo::NONE);
|
| + __ jmp(&exit);
|
| +
|
| + // Invoke: Link this frame into the handler chain.
|
| + __ bind(&invoke);
|
| + __ PushTryHandler(IN_JS_ENTRY, JS_ENTRY_HANDLER);
|
| + __ push(rax); // flush TOS
|
| +
|
| + // Clear any pending exceptions.
|
| + __ load_rax(ExternalReference::the_hole_value_location());
|
| + __ store_rax(pending_exception);
|
| +
|
| + // Fake a receiver (NULL).
|
| + __ push(Immediate(0)); // receiver
|
| +
|
| + // Invoke the function by calling through JS entry trampoline
|
| + // builtin and pop the faked function when we return. We load the address
|
| + // from an external reference instead of inlining the call target address
|
| + // directly in the code, because the builtin stubs may not have been
|
| + // generated yet at the time this code is generated.
|
| + if (is_construct) {
|
| + ExternalReference construct_entry(Builtins::JSConstructEntryTrampoline);
|
| + __ load_rax(construct_entry);
|
| + } else {
|
| + ExternalReference entry(Builtins::JSEntryTrampoline);
|
| + __ load_rax(entry);
|
| + }
|
| + __ call(FieldOperand(rax, Code::kHeaderSize));
|
| +
|
| + // Unlink this frame from the handler chain.
|
| + __ movq(kScratchRegister, ExternalReference(Top::k_handler_address));
|
| + __ pop(Operand(kScratchRegister, 0));
|
| + // Pop next_sp.
|
| + __ add(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize));
|
| +
|
| + // Restore the top frame descriptor from the stack.
|
| + __ bind(&exit);
|
| + __ movq(kScratchRegister, ExternalReference(Top::k_c_entry_fp_address));
|
| + __ pop(Operand(kScratchRegister, 0));
|
| +
|
| + // Restore callee-saved registers (X64 conventions).
|
| + __ pop(rbx);
|
| + __ pop(rsi);
|
| + __ pop(rdi);
|
| + __ pop(r15);
|
| + __ pop(r14);
|
| + __ pop(r13);
|
| + __ pop(r12);
|
| + __ add(rsp, Immediate(2 * kPointerSize)); // remove markers
|
| +
|
| + // Restore frame pointer and return.
|
| + __ pop(rbp);
|
| + __ ret(0);
|
| +}
|
| +
|
| +
|
| +#undef __
|
|
|
| } } // namespace v8::internal
|
|
|