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

Side by Side Diff: src/x64/builtins-x64.cc

Issue 1407313004: Adds the possibility of setting a Code object as the callback of a FunctionTemplate. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Update. Created 5 years, 1 month 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 #if V8_TARGET_ARCH_X64 5 #if V8_TARGET_ARCH_X64
6 6
7 #include "src/code-factory.h" 7 #include "src/code-factory.h"
8 #include "src/codegen.h" 8 #include "src/codegen.h"
9 #include "src/deoptimizer.h" 9 #include "src/deoptimizer.h"
10 #include "src/full-codegen/full-codegen.h" 10 #include "src/full-codegen/full-codegen.h"
(...skipping 1931 matching lines...) Expand 10 before | Expand all | Expand 10 after
1942 // method. 1942 // method.
1943 __ bind(&non_constructor); 1943 __ bind(&non_constructor);
1944 { 1944 {
1945 FrameScope scope(masm, StackFrame::INTERNAL); 1945 FrameScope scope(masm, StackFrame::INTERNAL);
1946 __ Push(rdi); 1946 __ Push(rdi);
1947 __ CallRuntime(Runtime::kThrowCalledNonCallable, 1); 1947 __ CallRuntime(Runtime::kThrowCalledNonCallable, 1);
1948 } 1948 }
1949 } 1949 }
1950 1950
1951 1951
1952 static void CompatibleReceiverCheck(MacroAssembler* masm, Register receiver,
1953 Register function_template_info,
1954 Register scratch0, Register scratch1,
1955 Register scratch2,
1956 Label* receiver_check_failed) {
1957 Register signature = scratch0;
1958 Register map = scratch1;
1959 Register constructor = scratch2;
1960
1961 // If receiver is not an object, jump to receiver_check_failed.
1962 __ CmpObjectType(receiver, FIRST_JS_OBJECT_TYPE, kScratchRegister);
1963 __ j(below, receiver_check_failed);
1964
1965 // If there is no signature, return the holder.
1966 __ movp(signature, FieldOperand(function_template_info,
1967 FunctionTemplateInfo::kSignatureOffset));
1968 __ CompareRoot(signature, Heap::kUndefinedValueRootIndex);
1969 Label receiver_check_passed;
1970 __ j(equal, &receiver_check_passed, Label::kNear);
1971
1972 // Walk the prototype chain.
1973 Label prototype_loop_start;
1974 __ bind(&prototype_loop_start);
1975
1976 // End if receiver is null or if it's a hidden prototype.
1977 __ CompareRoot(receiver, Heap::kNullValueRootIndex);
1978 __ j(equal, receiver_check_failed, Label::kNear);
1979 __ movp(map, FieldOperand(receiver, HeapObject::kMapOffset));
1980 __ testq(FieldOperand(map, Map::kBitField3Offset),
1981 Immediate(Map::IsHiddenPrototype::kMask));
1982 __ j(not_zero, receiver_check_failed, Label::kNear);
1983
1984 // Get the constructor, if any.
1985 __ GetMapConstructor(constructor, map, kScratchRegister);
1986 __ CmpInstanceType(kScratchRegister, JS_FUNCTION_TYPE);
1987 Label next_prototype;
1988 __ j(not_equal, &next_prototype, Label::kNear);
1989
1990 // Get the constructor's signature.
1991 Register type = constructor;
1992 __ movp(type,
1993 FieldOperand(constructor, JSFunction::kSharedFunctionInfoOffset));
1994 __ movp(type, FieldOperand(type, SharedFunctionInfo::kFunctionDataOffset));
1995
1996 // Loop through the chain of inheriting function templates.
1997 Label function_template_loop;
1998 __ bind(&function_template_loop);
1999
2000 // If the signatures match, we have a compatible receiver.
2001 __ cmpp(signature, type);
2002 __ j(equal, &receiver_check_passed, Label::kNear);
2003
2004 // If the current type is not a FunctionTemplateInfo, load the next prototype
2005 // in the chain.
2006 __ JumpIfSmi(type, &next_prototype, Label::kNear);
2007 __ CmpObjectType(type, FUNCTION_TEMPLATE_INFO_TYPE, kScratchRegister);
2008 __ j(not_equal, &next_prototype, Label::kNear);
2009
2010 // Otherwise load the parent function template and iterate.
2011 __ movp(type,
2012 FieldOperand(type, FunctionTemplateInfo::kParentTemplateOffset));
2013 __ jmp(&function_template_loop, Label::kNear);
2014
2015 // Load the next prototype and iterate.
2016 __ bind(&next_prototype);
2017 __ movp(receiver, FieldOperand(map, Map::kPrototypeOffset));
2018 __ jmp(&prototype_loop_start, Label::kNear);
2019
2020 __ bind(&receiver_check_passed);
2021 }
2022
2023
2024 void Builtins::Generate_HandleFastApiCall(MacroAssembler* masm) {
2025 // ----------- S t a t e -------------
2026 // -- rax : number of arguments (not including the receiver)
2027 // -- rdi : callee
2028 // -- rsi : context
2029 // -- rsp[0] : return address
2030 // -- rsp[8] : last argument
2031 // -- ...
2032 // -- rsp[rax * 8] : first argument
2033 // -- rsp[(rax + 1) * 8] : receiver
2034 // -----------------------------------
2035
2036 StackArgumentsAccessor args(rsp, rax);
2037 __ movp(rcx, args.GetReceiverOperand());
2038
2039 // Update the receiver if this is a contextual call.
2040 Label set_global_proxy, valid_receiver;
2041 __ CompareRoot(rcx, Heap::kUndefinedValueRootIndex);
2042 __ j(equal, &set_global_proxy);
2043 __ bind(&valid_receiver);
2044
2045 // Load the FunctionTemplateInfo.
2046 __ movp(rbx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
2047 __ movp(rbx, FieldOperand(rbx, SharedFunctionInfo::kFunctionDataOffset));
2048
2049 // Do the compatible receiver check.
2050 Label receiver_check_failed;
2051 CompatibleReceiverCheck(masm, rcx, rbx, rdx, r8, r9, &receiver_check_failed);
2052
2053 // Get the callback offset from the FunctionTemplateInfo, and jump to the
2054 // beginning of the code.
2055 __ movp(rdx, FieldOperand(rbx, FunctionTemplateInfo::kCallCodeOffset));
2056 __ movp(rdx, FieldOperand(rdx, CallHandlerInfo::kFastHandlerOffset));
2057 __ addp(rdx, Immediate(Code::kHeaderSize - kHeapObjectTag));
2058 __ jmp(rdx);
2059
2060 __ bind(&set_global_proxy);
2061 __ movp(rcx, GlobalObjectOperand());
2062 __ movp(rcx, FieldOperand(rcx, JSGlobalObject::kGlobalProxyOffset));
2063 __ movp(args.GetReceiverOperand(), rcx);
2064 __ jmp(&valid_receiver, Label::kNear);
2065
2066 // Compatible receiver check failed: pop return address, arguments and
2067 // receiver and throw an Illegal Invocation exception.
2068 __ bind(&receiver_check_failed);
2069 __ PopReturnAddressTo(rbx);
2070 __ leap(rax, Operand(rax, times_pointer_size, 1 * kPointerSize));
2071 __ addp(rsp, rax);
2072 __ PushReturnAddressFrom(rbx);
2073 {
2074 FrameScope scope(masm, StackFrame::INTERNAL);
2075 __ TailCallRuntime(Runtime::kThrowIllegalInvocation, 0, 1);
2076 }
2077 }
2078
2079
1952 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { 2080 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
1953 // Lookup the function in the JavaScript frame. 2081 // Lookup the function in the JavaScript frame.
1954 __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 2082 __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
1955 { 2083 {
1956 FrameScope scope(masm, StackFrame::INTERNAL); 2084 FrameScope scope(masm, StackFrame::INTERNAL);
1957 // Pass function as argument. 2085 // Pass function as argument.
1958 __ Push(rax); 2086 __ Push(rax);
1959 __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1); 2087 __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1);
1960 } 2088 }
1961 2089
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2001 __ ret(0); 2129 __ ret(0);
2002 } 2130 }
2003 2131
2004 2132
2005 #undef __ 2133 #undef __
2006 2134
2007 } // namespace internal 2135 } // namespace internal
2008 } // namespace v8 2136 } // namespace v8
2009 2137
2010 #endif // V8_TARGET_ARCH_X64 2138 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698