Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Side by Side Diff: src/x64/code-stubs-x64.cc

Issue 847913005: move HandleApiCall builtin to assembly (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: cleanup Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/runtime/runtime-api.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_X64 7 #if V8_TARGET_ARCH_X64
8 8
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 5007 matching lines...) Expand 10 before | Expand all | Expand 10 after
5018 // The name handler is counted as an argument. 5018 // The name handler is counted as an argument.
5019 StackArgumentsAccessor args(rbp, PropertyCallbackArguments::kArgsLength); 5019 StackArgumentsAccessor args(rbp, PropertyCallbackArguments::kArgsLength);
5020 Operand return_value_operand = args.GetArgumentOperand( 5020 Operand return_value_operand = args.GetArgumentOperand(
5021 PropertyCallbackArguments::kArgsLength - 1 - 5021 PropertyCallbackArguments::kArgsLength - 1 -
5022 PropertyCallbackArguments::kReturnValueOffset); 5022 PropertyCallbackArguments::kReturnValueOffset);
5023 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, getter_arg, 5023 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, getter_arg,
5024 kStackSpace, nullptr, return_value_operand, NULL); 5024 kStackSpace, nullptr, return_value_operand, NULL);
5025 } 5025 }
5026 5026
5027 5027
5028 // Updates holder to the correct api holder. info is preserved.
5029 static void SignatureCheck(MacroAssembler* masm, Register holder, Register info,
5030 Register scratch_0, Register scratch_1,
5031 Register scratch_2, Label* illegal_receiver) {
5032 Register signature = scratch_0;
5033 Register map = scratch_1;
5034 __ movp(signature,
5035 FieldOperand(info, FunctionTemplateInfo::kSignatureOffset));
5036 __ movp(map, FieldOperand(holder, HeapObject::kMapOffset));
5037
5038 // Loop over hidden prototype chain.
5039 Label prototype_chain_loop, prototype_chain_loop_next, legal_receiver;
5040 __ bind(&prototype_chain_loop);
5041
5042 // Verify signature for current map.
5043 Register cons = scratch_2;
5044 // Requires a constructor of type jsfunction.
5045 __ movp(cons, FieldOperand(map, Map::kConstructorOffset));
5046 __ CompareRoot(cons, Heap::kNullValueRootIndex);
5047 __ j(equal, &prototype_chain_loop_next, Label::kNear);
5048 #ifdef DEBUG
5049 {
5050 Label expected;
5051 // constructors should be null or js functions.
5052 __ CmpObjectType(cons, JS_FUNCTION_TYPE, kScratchRegister);
5053 __ j(equal, &expected);
5054 __ int3(); // Can't call abort without a frame.
5055 __ bind(&expected);
5056 }
5057 #endif
5058 // Load shared function data for checked object.
5059 Register type = cons;
5060 __ movp(type, FieldOperand(cons, JSFunction::kSharedFunctionInfoOffset));
5061 __ movp(type, FieldOperand(type, SharedFunctionInfo::kFunctionDataOffset));
5062
5063 {
5064 // Loop over function template info chain, hunting for signature.
5065 Label function_template_loop;
5066 __ bind(&function_template_loop);
5067 __ cmpp(signature, type);
5068 __ j(equal, &legal_receiver, Label::kNear);
5069 // Requires a data of type FunctionTemplateInfo.
5070 Condition is_smi = masm->CheckSmi(type);
5071 __ j(is_smi, &prototype_chain_loop_next, Label::kNear);
5072 __ CmpObjectType(type, FUNCTION_TEMPLATE_INFO_TYPE, kScratchRegister);
5073 __ j(not_equal, &prototype_chain_loop_next, Label::kNear);
5074 // Load parent and loop.
5075 __ movp(type,
5076 FieldOperand(type, FunctionTemplateInfo::kParentTemplateOffset));
5077 __ jmp(&function_template_loop, Label::kNear);
5078 }
5079
5080 __ bind(&prototype_chain_loop_next);
5081
5082 // Load next holder.
5083 __ movp(holder, FieldOperand(map, Map::kPrototypeOffset));
5084
5085 // End of prototype chain walk.
5086 __ CompareRoot(holder, Heap::kNullValueRootIndex);
5087 __ j(equal, illegal_receiver);
5088
5089 // Load next map.
5090 __ movp(map, FieldOperand(holder, HeapObject::kMapOffset));
5091
5092 // End of prototype chain walk.
5093 __ testb(FieldOperand(map, Map::kBitFieldOffset),
5094 Immediate(1 << Map::kIsHiddenPrototype));
5095 __ j(zero, illegal_receiver);
5096
5097 #ifdef DEBUG
5098 {
5099 Label expected;
5100 // Hidden prototypes should already be js objects.
5101 __ CmpInstanceType(map, FIRST_JS_OBJECT_TYPE);
5102 __ j(above_equal, &expected, Label::kNear);
5103 __ int3(); // Can't call abort without a frame.
5104 __ bind(&expected);
5105 }
5106 #endif
5107
5108 // Jump up to start of signature check loop for this map.
5109 __ jmp(&prototype_chain_loop, Label::kNear);
5110
5111 // Successful exit.
5112 __ bind(&legal_receiver);
5113 }
5114
5115
5116 void JSApiFunctionStub::Generate(MacroAssembler* masm) {
5117 // ----------- S t a t e -------------
5118 // -- rax : number of arguments excluding receiver
5119 // -- rdi : callee
5120 // -- rsi : context
5121 // -- rsp[0] : return address
5122 // -- rsp[8] : last argument
5123 // -- ...
5124 // -- rsp[8 * argc] : first argument (argc == rax)
5125 // -- rsp[8 * (argc + 1)] : receiver
5126 // -----------------------------------
5127
5128 StackArgumentsAccessor args(rsp, rax);
5129 __ movp(rcx, args.GetReceiverOperand());
5130
5131 // Update receiver if this is a contextual call.
5132 Label set_global_proxy, receiver_correct;
5133 __ CompareRoot(rcx, Heap::kUndefinedValueRootIndex);
5134 __ j(equal, &set_global_proxy);
5135 __ bind(&receiver_correct);
5136
5137 // Load FunctionTemplateInfo.
5138 __ movp(rbx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
5139 __ movp(rbx, FieldOperand(rbx, SharedFunctionInfo::kFunctionDataOffset));
5140
5141 Label illegal_receiver;
5142 if (has_signature()) {
5143 // Typecheck. Update receiver with api holder.
5144 SignatureCheck(masm, rcx, rbx, rdx, r8, r9, &illegal_receiver);
5145 }
5146
5147 if (!has_call_code()) {
5148 // Return receiver for non c call. Pop arguments and receiver.
5149 __ leap(rbx, Operand(rax, times_pointer_size, 1 * kPointerSize));
5150 __ movp(rax, args.GetReceiverOperand());
5151 __ PopReturnAddressTo(rcx);
5152 __ addp(rsp, rbx);
5153 __ jmp(rcx);
5154 } else {
5155 // c call.
5156 __ movp(rbx, FieldOperand(rbx, FunctionTemplateInfo::kCallCodeOffset));
5157 // Put call_data and function address in place.
5158 __ movp(rdx, FieldOperand(rbx, CallHandlerInfo::kCallbackOffset));
5159 __ movp(rdx, FieldOperand(rdx, Foreign::kForeignAddressOffset));
5160 __ movp(rbx, FieldOperand(rbx, CallHandlerInfo::kDataOffset));
5161 // Jump to stub.
5162 // TODO(dcarney): fix abi for CallApiFunctionStub.
5163 __ xchgp(rax, rdi); // Put callee in place. Put n_args in place.
5164 CallApiFunctionStub stub(masm->isolate(), call_data_undefined());
5165 __ TailCallStub(&stub);
5166 }
5167
5168 // Deferred code: Replace receiver on stack with global proxy for contextual
5169 // calls.
5170 __ bind(&set_global_proxy);
5171 __ movp(rcx, GlobalObjectOperand());
5172 __ movp(rcx, FieldOperand(rcx, GlobalObject::kGlobalProxyOffset));
5173 __ movp(args.GetReceiverOperand(), rcx);
5174 __ jmp(&receiver_correct);
5175
5176 if (!illegal_receiver.is_unused()) {
5177 // Deferred code: Receiver does not match signature. Throw exception.
5178 __ bind(&illegal_receiver);
5179
5180 // Pop return address, arguments and receiver.
5181 __ PopReturnAddressTo(rbx);
5182 __ leap(rax, Operand(rax, times_pointer_size, 1 * kPointerSize));
5183 __ addp(rsp, rax);
5184 __ PushReturnAddressFrom(rbx);
5185
5186 FrameScope frame(masm, StackFrame::INTERNAL);
5187 __ Push(rdi);
5188 __ TailCallRuntime(Runtime::kThrowIllegalInvocation, 1, 1);
5189 }
5190 }
5191
5028 #undef __ 5192 #undef __
5029 5193
5030 } } // namespace v8::internal 5194 } } // namespace v8::internal
5031 5195
5032 #endif // V8_TARGET_ARCH_X64 5196 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/runtime/runtime-api.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698