• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef ECMASCRIPT_COMPILER_ASSEMBLER_MODULE_X64_H
17 #define ECMASCRIPT_COMPILER_ASSEMBLER_MODULE_X64_H
18 
19 #include "ecmascript/compiler/assembler/x64/assembler_x64.h"
20 #include "ecmascript/compiler/assembler/x64/extended_assembler_x64.h"
21 #include "ecmascript/frames.h"
22 
23 namespace panda::ecmascript::x64 {
24 class CommonCall {
25 public:
26     static constexpr int FRAME_SLOT_SIZE = 8;
27     static constexpr int DOUBLE_SLOT_SIZE = 16;
28     static constexpr int TRIPLE_SLOT_SIZE = 24;
29     static constexpr int QUADRUPLE_SLOT_SIZE = 32;
30     static constexpr int QUINTUPLE_SLOT_SIZE = 40;
31     static constexpr int SEXTUPLE_SLOT_SIZE = 48;
32     static void CopyArgumentWithArgV(ExtendedAssembler *assembler, Register argc, Register argV);
33     static void PushAsmInterpBridgeFrame(ExtendedAssembler *assembler);
34     static void PopAsmInterpBridgeFrame(ExtendedAssembler *assembler);
35     static void PushUndefinedWithArgc(ExtendedAssembler *assembler, Register argc);
36     static void GetArgvAtStack(ExtendedAssembler *assembler);
37     static void PushArgsWithArgvAndCheckStack(ExtendedAssembler *assembler, Register glue, Register argc, Register argv,
38         Register op1, Register op2, Label *stackOverflow);
39     static void StackOverflowCheck(ExtendedAssembler *assembler, Register glue, Register numArgs, Register op1,
40         Register op2, Label *stackOverflow);
41 };
42 
43 class OptimizedCall : public CommonCall {
44 public:
45     static void CallRuntime(ExtendedAssembler *assembler);
46 
47     static void JSFunctionEntry(ExtendedAssembler *assembler);
48 
49     static void OptimizedCallOptimized(ExtendedAssembler *assembler);
50 
51     static void CallBuiltinTrampoline(ExtendedAssembler *assembler);
52 
53     static void JSProxyCallInternalWithArgV(ExtendedAssembler *assembler);
54 
55     static void JSCall(ExtendedAssembler *assembler);
56 
57     static void ConstructorJSCall(ExtendedAssembler *assembler);
58 
59     static void CallRuntimeWithArgv(ExtendedAssembler *assembler);
60 
61     static void JSCallWithArgV(ExtendedAssembler *assembler);
62 
63     static void ConstructorJSCallWithArgV(ExtendedAssembler *assembler);
64 
65     static void DeoptHandlerAsm(ExtendedAssembler *assembler);
66 
67     static void JSCallNew(ExtendedAssembler *assembler);
68 
69     static void JSCallNewWithArgV(ExtendedAssembler *assembler);
70 
71     static void GenJSCall(ExtendedAssembler *assembler, bool isNew);
72 
73     static void GenJSCallWithArgV(ExtendedAssembler *assembler, bool isNew);
74 private:
75     static void DeoptEnterAsmInterp(ExtendedAssembler *assembler);
76     static void JSCallCheck(ExtendedAssembler *assembler, Register jsFuncReg,
77                             Label *lNonCallable, Label *lNotJSFunction, Label *lJSFunctionCall);
78     static void ThrowNonCallableInternal(ExtendedAssembler *assembler, Register glueReg);
79     static void CallOptimziedMethodInternal(ExtendedAssembler *assembler, Register glueReg, Register jsFuncReg,
80                                             Register methodCallField, Register argc, Register codeAddrReg,
81                                             Register expectedNumArgsReg);
82     static void JSBoundFunctionCallInternal(ExtendedAssembler *assembler, Register jsFuncReg, Label *jsCall);
83     static void JSProxyCallInternal(ExtendedAssembler *assembler, Register jsFuncReg);
84     static void OptimizedCallAsmInterpreter(ExtendedAssembler *assembler);
85     static void PushArgsWithArgV(ExtendedAssembler *assembler, Register jsfunc,
86                                  Register actualNumArgs, Register argV, Label *pushCallThis);
87     static void PushMandatoryJSArgs(ExtendedAssembler *assembler, Register jsfunc,
88                                     Register thisObj, Register newTarget);
89     static void PopJSFunctionArgs(ExtendedAssembler *assembler, Register expectedNumArgs);
90     static void PushJSFunctionEntryFrame (ExtendedAssembler *assembler, Register prevFp);
91     static void PopJSFunctionEntryFrame(ExtendedAssembler *assembler, Register glue);
92     static void PushOptimizedUnfoldArgVFrame(ExtendedAssembler *assembler, Register callSiteSp);
93     static void PopOptimizedUnfoldArgVFrame(ExtendedAssembler *assembler);
94 };
95 
96 class AsmInterpreterCall : public CommonCall {
97 public:
98     static void GeneratorReEnterAsmInterp(ExtendedAssembler *assembler);
99 
100     static void GeneratorReEnterAsmInterpDispatch(ExtendedAssembler *assembler);
101 
102     static void AsmInterpEntryDispatch(ExtendedAssembler *assembler);
103 
104     static void AsmInterpreterEntry(ExtendedAssembler *assembler);
105 
106     static void PushCallThisRangeAndDispatch(ExtendedAssembler *assembler);
107 
108     static void PushCallRangeAndDispatch(ExtendedAssembler *assembler);
109 
110     static void PushCallArgs3AndDispatch(ExtendedAssembler *assembler);
111 
112     static void PushCallArgs2AndDispatch(ExtendedAssembler *assembler);
113 
114     static void PushCallArg1AndDispatch(ExtendedAssembler *assembler);
115 
116     static void PushCallArg0AndDispatch(ExtendedAssembler *assembler);
117 
118     static void PushCallThisArg0AndDispatch(ExtendedAssembler *assembler);
119 
120     static void PushCallThisArg1AndDispatch(ExtendedAssembler *assembler);
121 
122     static void PushCallThisArgs2AndDispatch(ExtendedAssembler *assembler);
123 
124     static void PushCallThisArgs3AndDispatch(ExtendedAssembler *assembler);
125 
126     static void PushCallNewAndDispatch(ExtendedAssembler *assembler);
127 
128     static void PushCallNewAndDispatchNative(ExtendedAssembler *assembler);
129 
130     static void PushCallRangeAndDispatchNative(ExtendedAssembler *assembler);
131 
132     static void PushCallArgsAndDispatchNative(ExtendedAssembler *assembler);
133 
134     static void ResumeRspAndDispatch(ExtendedAssembler *assembler);
135 
136     static void ResumeRspAndReturn([[maybe_unused]] ExtendedAssembler *assembler);
137 
138     static void CallGetter(ExtendedAssembler *assembler);
139 
140     static void CallSetter(ExtendedAssembler *assembler);
141 
142     static void CallContainersArgs3(ExtendedAssembler *assembler);
143 
144     static void ResumeCaughtFrameAndDispatch(ExtendedAssembler *assembler);
145 
146     static void ResumeUncaughtFrameAndReturn(ExtendedAssembler *assembler);
147 
148 private:
149     static void PushFrameState(ExtendedAssembler *assembler, Register prevSpRegister, Register fpRegister,
150         Register callTargetRegister, Register thisRegister, Register methodRegister, Register pcRegister,
151         Register operatorRegister);
152     static void PushGeneratorFrameState(ExtendedAssembler *assembler, Register prevSpRegister,
153         Register fpRegister, Register callTargetRegister, Register thisRegister, Register methodRegister,
154         Register contextRegister, Register pcRegister, Register operatorRegister);
155     static void PushAsmInterpEntryFrame(ExtendedAssembler *assembler);
156     static void PopAsmInterpEntryFrame(ExtendedAssembler *assembler);
157     static void GetDeclaredNumArgsFromCallField(ExtendedAssembler *assembler, Register callFieldRegister,
158         Register declaredNumArgsRegister);
159     static void GetNumVregsFromCallField(ExtendedAssembler *assembler, Register callFieldRegister,
160         Register numVregsRegister);
161     static void PushUndefinedWithArgcAndCheckStack(ExtendedAssembler *assembler, Register glue, Register argc,
162         Register op1, Register op2, Label *stackOverflow);
163     static void ThrowStackOverflowExceptionAndReturn(ExtendedAssembler *assembler, Register glue, Register fp,
164         Register op);
165     static void HasPendingException(ExtendedAssembler *assembler, Register threadRegister);
166     static void PushCallThis(ExtendedAssembler *assembler, JSCallMode mode, Label *stackOverflow);
167     static Register GetThisRegsiter(ExtendedAssembler *assembler, JSCallMode mode, Register defaultRegister);
168     static Register GetNewTargetRegsiter(ExtendedAssembler *assembler, JSCallMode mode, Register defaultRegister);
169     static void PushVregs(ExtendedAssembler *assembler, Label *stackOverflow);
170     static void DispatchCall(ExtendedAssembler *assembler, Register pcRegister, Register newSpRegister,
171                              Register methodRegister, Register accRegister = rInvalid);
172     static void CallNativeEntry(ExtendedAssembler *assemblSer);
173     static void CallNativeWithArgv(ExtendedAssembler *assembler, bool callNew);
174     static void CallNativeInternal(ExtendedAssembler *assembler, Register nativeCode);
175     static void PushBuiltinFrame(ExtendedAssembler *assembler, Register glue, FrameType type);
176     static void JSCallCommonEntry(ExtendedAssembler *assembler, JSCallMode mode);
177     static void JSCallCommonFastPath(ExtendedAssembler *assembler, JSCallMode mode, Label *stackOverflow);
178     static void JSCallCommonSlowPath(ExtendedAssembler *assembler, JSCallMode mode,
179         Label *fastPathEntry, Label *pushCallThis, Label *stackOverflow);
180     friend class OptimizedCall;
181 };
182 }  // namespace panda::ecmascript::x64
183 #endif  // ECMASCRIPT_COMPILER_ASSEMBLER_MODULE_X64_H
184