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

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: remove tests 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. Map may be trashed.
5029 static void SignatureCheck(MacroAssembler* masm, Register map, Register holder,
5030 Register signature, Register scratch,
5031 Label* illegal_receiver) {
5032 // Loop over hidden prototype chain.
5033 Label prototype_chain_loop, prototype_chain_loop_next, legal_receiver;
5034 __ bind(&prototype_chain_loop);
5035
5036 // Verify signature for current map.
5037 Register type = scratch;
5038 // Requires a constructor of type jsfunction.
5039 __ movp(type, FieldOperand(map, Map::kConstructorOffset));
5040 __ CmpObjectType(type, JS_FUNCTION_TYPE, kScratchRegister);
5041 __ j(not_equal, &prototype_chain_loop_next, Label::kNear);
jochen (gone - plz use gerrit) 2015/01/21 12:01:39 I wonder whether we can here already jump to illeg
5042 // Load shared function data.
5043 __ movp(type, FieldOperand(type, JSFunction::kSharedFunctionInfoOffset));
5044 __ movp(type, FieldOperand(type, SharedFunctionInfo::kFunctionDataOffset));
5045
5046 {
5047 // Loop over function template info chain, hunting for signature.
5048 Label function_template_loop;
5049 __ bind(&function_template_loop);
5050 // Requires a data of type FunctionTemplateInfo.
5051 __ CmpObjectType(type, FUNCTION_TEMPLATE_INFO_TYPE, kScratchRegister);
5052 __ j(not_equal, &prototype_chain_loop_next, Label::kNear);
5053 __ cmpp(signature, type);
5054 __ j(equal, &legal_receiver, Label::kNear);
5055 // Incorrect signature, load parent and loop.
5056 __ movp(type,
5057 FieldOperand(type, FunctionTemplateInfo::kParentTemplateOffset));
5058 __ jmp(&function_template_loop, Label::kNear);
5059 }
5060
5061 __ bind(&prototype_chain_loop_next);
5062 __ movp(holder, FieldOperand(map, Map::kPrototypeOffset));
5063
5064 // End of prototype chain walk.
5065 __ CompareRoot(holder, Heap::kNullValueRootIndex);
5066 __ j(equal, illegal_receiver);
5067
5068 __ movp(map, FieldOperand(holder, HeapObject::kMapOffset));
5069 // End of prototype chain walk.
5070 __ testb(FieldOperand(map, Map::kBitFieldOffset),
5071 Immediate(1 << Map::kIsHiddenPrototype));
5072 __ j(zero, illegal_receiver);
5073
5074 // TODO(dcarney): this check is probably unnecessary.
5075 // Requires a js object map.
5076 __ CmpInstanceType(map, FIRST_JS_OBJECT_TYPE);
5077 __ j(below, &prototype_chain_loop_next, Label::kNear);
5078
5079 // Jump up to start of signature check loop for this map.
5080 __ jmp(&prototype_chain_loop, Label::kNear);
5081
5082 // Successful exit.
5083 __ bind(&legal_receiver);
5084 }
5085
5086
5087 void JSApiFunctionStub::Generate(MacroAssembler* masm) {
5088 // ----------- S t a t e -------------
5089 // -- rax : number of arguments excluding receiver
5090 // -- rdi : callee
5091 // -- rsi : context
5092 // -- rsp[0] : return address
5093 // -- rsp[8] : last argument
5094 // -- ...
5095 // -- rsp[8 * argc] : first argument (argc == rax)
5096 // -- rsp[8 * (argc + 1)] : receiver
5097 // -----------------------------------
5098
5099 StackArgumentsAccessor args(rsp, rax);
5100 __ movp(rcx, args.GetReceiverOperand());
5101
5102 // Update receiver if this is a contextual call.
5103 Label set_global_proxy, receiver_correct;
5104 __ CompareRoot(rcx, Heap::kUndefinedValueRootIndex);
5105 __ j(equal, &set_global_proxy);
5106 __ bind(&receiver_correct);
5107
5108 // Load FunctionTemplateInfo.
5109 __ movp(rbx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
5110 __ movp(rbx, FieldOperand(rbx, SharedFunctionInfo::kFunctionDataOffset));
5111
5112 // TODO(dcarney): CHECK that !has_call_code implies !has_signature.
5113 Label illegal_receiver;
5114 if (has_signature()) {
5115 // Typecheck. Update receiver with api holder.
5116 __ movp(r8, FieldOperand(rbx, FunctionTemplateInfo::kSignatureOffset));
5117 __ movp(rdx, FieldOperand(rcx, HeapObject::kMapOffset));
5118 SignatureCheck(masm, rdx, rcx, r8, r9, &illegal_receiver);
5119 }
5120
5121 if (!has_call_code()) {
5122 // Return receiver for non c call. Pop arguments and receiver.
5123 __ leap(rbx, Operand(rax, times_pointer_size, 1 * kPointerSize));
5124 __ movp(rax, args.GetReceiverOperand());
5125 __ PopReturnAddressTo(rcx);
5126 __ addp(rsp, rbx);
5127 __ jmp(rcx);
5128 } else {
5129 // c call.
5130 __ movp(rbx, FieldOperand(rbx, FunctionTemplateInfo::kCallCodeOffset));
5131 // Put call_data and function address in place.
5132 __ movp(rdx, FieldOperand(rbx, CallHandlerInfo::kCallbackOffset));
5133 __ movp(rdx, FieldOperand(rdx, Foreign::kForeignAddressOffset));
5134 __ movp(rbx, FieldOperand(rbx, CallHandlerInfo::kDataOffset));
5135 // Jump to stub.
5136 // TODO(dcarney): fix abi for CallApiFunctionStub.
5137 __ xchgp(rax, rdi); // Put callee in place. Put n_args in place.
5138 CallApiFunctionStub stub(masm->isolate(), call_data_undefined());
5139 __ TailCallStub(&stub);
5140 }
5141
5142 // Deferred code: Replace receiver on stack with global proxy for contextual
5143 // calls.
5144 __ bind(&set_global_proxy);
5145 __ movp(rcx, GlobalObjectOperand());
5146 __ movp(rcx, FieldOperand(rcx, GlobalObject::kGlobalProxyOffset));
5147 __ movp(args.GetReceiverOperand(), rcx);
5148 __ jmp(&receiver_correct);
5149
5150 if (!illegal_receiver.is_unused()) {
5151 // Deferred code: Receiver does not match signature. Throw exception.
5152 __ bind(&illegal_receiver);
5153
5154 // Pop return address, arguments and receiver.
5155 __ PopReturnAddressTo(rbx);
5156 __ leap(rax, Operand(rax, times_pointer_size, 1 * kPointerSize));
5157 __ addp(rsp, rax);
5158 __ PushReturnAddressFrom(rbx);
5159
5160 FrameScope frame(masm, StackFrame::INTERNAL);
5161 __ Push(rdi);
5162 __ TailCallRuntime(Runtime::kThrowIllegalInvocation, 1, 1);
5163 }
5164 }
5165
5028 #undef __ 5166 #undef __
5029 5167
5030 } } // namespace v8::internal 5168 } } // namespace v8::internal
5031 5169
5032 #endif // V8_TARGET_ARCH_X64 5170 #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