1 /*
2  * Copyright (c) 2021 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_INTERPRETER_STUB_H
17 #define ECMASCRIPT_COMPILER_INTERPRETER_STUB_H
18 
19 #include "ecmascript/base/config.h"
20 #include "ecmascript/compiler/bc_call_signature.h"
21 #include "ecmascript/compiler/profiler_operation.h"
22 #include "ecmascript/compiler/rt_call_signature.h"
23 #include "ecmascript/compiler/stub_builder.h"
24 #include "ecmascript/compiler/circuit_builder-inl.h"
25 
26 namespace panda::ecmascript::kungfu {
27 class StringIdInfo {
28 public:
29     enum class Offset : uint8_t {
30         BYTE_0,
31         BYTE_1,
32         BYTE_2,
33         INVALID,
34     };
35     enum class Length : uint8_t {
36         BITS_16,
37         BITS_32,
38         INVALID,
39     };
40     enum class StringIdType : uint8_t {
41         STRING_ID,
42         STRING_ID_INFO,
43     };
44 
StringIdInfo()45     StringIdInfo() : constpool(0), pc(0), offset(Offset::INVALID),
46           length(Length::INVALID), stringId(0), stringIdType(StringIdType::STRING_ID_INFO) {}
47 
StringIdInfo(GateRef inputConstpool, GateRef inputPc, Offset inputOffset, Length inputLength)48     StringIdInfo(GateRef inputConstpool, GateRef inputPc, Offset inputOffset, Length inputLength)
49         : constpool(inputConstpool), pc(inputPc), offset(inputOffset),
50           length(inputLength), stringId(0), stringIdType(StringIdType::STRING_ID_INFO) {}
51 
StringIdInfo(GateRef inputConstpool, GateRef inputStringId)52     explicit StringIdInfo(GateRef inputConstpool, GateRef inputStringId)
53         : constpool(inputConstpool), pc(0), offset(Offset::INVALID),
54           length(Length::INVALID), stringId(inputStringId), stringIdType(StringIdType::STRING_ID) {}
55 
GetConstantPool() const56     GateRef GetConstantPool() const
57     {
58         return constpool;
59     }
60 
GetPc() const61     GateRef GetPc() const
62     {
63         return pc;
64     }
65 
GetOffset() const66     Offset GetOffset() const
67     {
68         return offset;
69     }
70 
GetLength() const71     Length GetLength() const
72     {
73         return length;
74     }
75 
GetStringId() const76     GateRef GetStringId() const
77     {
78         return stringId;
79     }
80 
GetStringIdType() const81     StringIdType GetStringIdType() const
82     {
83         return stringIdType;
84     }
85 
IsValid() const86     bool IsValid() const
87     {
88         if (stringIdType == StringIdType::STRING_ID_INFO) {
89             return (constpool != 0) && (pc != 0) && (offset != Offset::INVALID) && (length != Length::INVALID);
90         }
91         return stringId != 0;
92     }
93 
94 private:
95     GateRef constpool { 0 };
96     GateRef pc { 0 };
97     Offset offset { Offset::INVALID };
98     Length length { Length::INVALID };
99     GateRef stringId { 0 };
100     StringIdType stringIdType { StringIdType::STRING_ID_INFO };
101 };
102 
103 class InterpreterStubBuilder : public StubBuilder {
104 public:
InterpreterStubBuilder(CallSignature *callSignature, Environment *env)105     InterpreterStubBuilder(CallSignature *callSignature, Environment *env)
106         : StubBuilder(callSignature, env) {}
107     ~InterpreterStubBuilder() override = default;
108     NO_MOVE_SEMANTIC(InterpreterStubBuilder);
109     NO_COPY_SEMANTIC(InterpreterStubBuilder);
110     virtual void GenerateCircuit() override = 0;
111 
112     inline void SetVregValue(GateRef glue, GateRef sp, GateRef idx, GateRef val);
113     inline GateRef GetVregValue(GateRef sp, GateRef idx);
114     inline GateRef ReadInst4_0(GateRef pc);
115     inline GateRef ReadInst4_1(GateRef pc);
116     inline GateRef ReadInst4_2(GateRef pc);
117     inline GateRef ReadInst4_3(GateRef pc);
118     inline GateRef ReadInst8_0(GateRef pc);
119     inline GateRef ReadInst8_1(GateRef pc);
120     inline GateRef ReadInst8_2(GateRef pc);
121     inline GateRef ReadInst8_3(GateRef pc);
122     inline GateRef ReadInst8_4(GateRef pc);
123     inline GateRef ReadInst8_5(GateRef pc);
124     inline GateRef ReadInst8_6(GateRef pc);
125     inline GateRef ReadInst8_7(GateRef pc);
126     inline GateRef ReadInst8_8(GateRef pc);
127     inline GateRef ReadInst8_9(GateRef pc);
128     inline GateRef ReadInst16_0(GateRef pc);
129     inline GateRef ReadInst16_1(GateRef pc);
130     inline GateRef ReadInst16_2(GateRef pc);
131     inline GateRef ReadInst16_3(GateRef pc);
132     inline GateRef ReadInst16_4(GateRef pc);
133     inline GateRef ReadInst16_5(GateRef pc);
134     inline GateRef ReadInst16_6(GateRef pc);
135     inline GateRef ReadInst16_7(GateRef pc);
136     inline GateRef ReadInstSigned8_0(GateRef pc);
137     inline GateRef ReadInstSigned16_0(GateRef pc);
138     inline GateRef ReadInstSigned32_0(GateRef pc);
139     inline GateRef ReadInst32_0(GateRef pc);
140     inline GateRef ReadInst32_1(GateRef pc);
141     inline GateRef ReadInst32_2(GateRef pc);
142     inline GateRef ReadInst64_0(GateRef pc);
143 
144     inline GateRef GetFrame(GateRef frame);
145     inline GateRef GetCurrentSpFrame(GateRef glue);
146     inline GateRef GetLastLeaveFrame(GateRef glue);
147     inline GateRef GetCurrentFrame(GateRef glue);
148     inline GateRef GetPcFromFrame(GateRef frame);
149     inline GateRef GetCallSizeFromFrame(GateRef frame);
150     inline GateRef GetFunctionFromFrame(GateRef frame);
151     inline GateRef GetNewTarget(GateRef sp);
152     inline GateRef GetThisFromFrame(GateRef frame);
153     inline GateRef GetAccFromFrame(GateRef frame);
154     inline GateRef GetEnvFromFrame(GateRef frame);
155     inline GateRef GetEnvFromFunction(GateRef frame);
156     inline GateRef GetConstpoolFromMethod(GateRef function);
157     inline GateRef GetModule(GateRef sp);
158     inline GateRef GetProfileTypeInfoFromFunction(GateRef function);
159     inline GateRef GetModuleFromFunction(GateRef function);
160     inline GateRef GetSendableEnvFromModule(GateRef function);
161     inline GateRef GetHomeObjectFromFunction(GateRef function);
162     inline GateRef GetResumeModeFromGeneratorObject(GateRef obj);
163     inline GateRef GetResumeModeFromAsyncGeneratorObject(GateRef obj);
164     inline GateRef GetHotnessCounterFromMethod(GateRef method);
165 
166     inline void SetCurrentSpFrame(GateRef glue, GateRef sp);
167     inline void SetLastLeaveFrame(GateRef glue, GateRef sp);
168     inline void SetPcToFrame(GateRef glue, GateRef frame, GateRef value);
169     inline void SetCallSizeToFrame(GateRef glue, GateRef frame, GateRef value);
170     inline void SetFunctionToFrame(GateRef glue, GateRef frame, GateRef value);
171     inline void SetAccToFrame(GateRef glue, GateRef frame, GateRef value);
172     inline void SetEnvToFrame(GateRef glue, GateRef frame, GateRef value);
173     inline void SetHomeObjectToFunction(GateRef glue, GateRef function, GateRef value);
174     inline void SetFrameState(GateRef glue, GateRef sp, GateRef function, GateRef acc,
175                               GateRef env, GateRef pc, GateRef prev, GateRef type);
176 
177     inline void UpdateProfileTypeInfoCellToFunction(GateRef glue, GateRef function,
178                                                     GateRef profileTypeInfo, GateRef slotId);
179 
180     inline void CheckException(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
181 		               GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter,
182 			       GateRef res, GateRef offset);
183     inline void CheckPendingException(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
184 		                      GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter,
185 			              GateRef res, GateRef offset);
186     inline void CheckExceptionWithJump(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
187 		                       GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter,
188 			               GateRef res, Label *jump);
189     inline void CheckExceptionWithVar(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
190 		                      GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter,
191 			              GateRef res, GateRef offset);
192 
193     inline GateRef CheckStackOverflow(GateRef glue, GateRef sp);
194     inline GateRef PushArg(GateRef glue, GateRef sp, GateRef value);
195     inline GateRef PushUndefined(GateRef glue, GateRef sp, GateRef num);
196     inline GateRef PushRange(GateRef glue, GateRef sp, GateRef array, GateRef startIndex, GateRef endIndex);
197     inline GateRef GetStartIdxAndNumArgs(GateRef sp, GateRef restIdx);
198     inline void Dispatch(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
199                          GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter, GateRef format);
200     inline void DispatchWithId(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
201                                GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter, GateRef index);
202     inline void DispatchLast(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
203                              GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter);
204     inline void DispatchDebugger(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
205                                  GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter);
206     inline void DispatchDebuggerLast(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
207                                      GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter);
208 
209     template <bool needPrint>
210     void DebugPrintInstruction();
211 private:
212     template<typename... Args>
213     void DispatchBase(GateRef target, GateRef glue, Args... args);
214 };
215 
216 class InterpreterToolsStubBuilder : private InterpreterStubBuilder {
217 public:
InterpreterToolsStubBuilder(CallSignature *callSignature, Environment *env)218     InterpreterToolsStubBuilder(CallSignature *callSignature, Environment *env)
219         : InterpreterStubBuilder(callSignature, env) {}
220     ~InterpreterToolsStubBuilder() override = default;
221     NO_MOVE_SEMANTIC(InterpreterToolsStubBuilder);
222     NO_COPY_SEMANTIC(InterpreterToolsStubBuilder);
223     void GenerateCircuit() override {}
224 
225     inline GateRef GetStringId(const StringIdInfo &info);
226 };
227 
228 #define DECLARE_HANDLE_STUB_CLASS(name)                                                         \
229     class name##StubBuilder : public InterpreterStubBuilder {                                   \
230     public:                                                                                     \
231         explicit name##StubBuilder(CallSignature *callSignature, Environment *env)              \
232             : InterpreterStubBuilder(callSignature, env)                                        \
233         {                                                                                       \
234             env->GetCircuit()->SetFrameType(FrameType::ASM_INTERPRETER_FRAME);                  \
235         }                                                                                       \
236         ~name##StubBuilder() = default;                                                         \
237         NO_MOVE_SEMANTIC(name##StubBuilder);                                                    \
238         NO_COPY_SEMANTIC(name##StubBuilder);                                                    \
239         void GenerateCircuit() override;                                                        \
240                                                                                                 \
241     protected:                                                                                  \
242         void GenerateCircuitImpl(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,       \
243                                  GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter,  \
244                                  ProfileOperation callback);                                    \
245     };
246     INTERPRETER_BC_STUB_LIST(DECLARE_HANDLE_STUB_CLASS)
247     ASM_INTERPRETER_BC_HELPER_STUB_LIST(DECLARE_HANDLE_STUB_CLASS)
248 
249 #define DECLARE_HANDLE_PROFILE_STUB_CLASS(name, base, ...)                         \
250     class name##StubBuilder : public base##StubBuilder {                           \
251     public:                                                                        \
252         explicit name##StubBuilder(CallSignature *callSignature, Environment *env) \
253             : base##StubBuilder(callSignature, env)                                \
254         {                                                                          \
255         }                                                                          \
256         ~name##StubBuilder() = default;                                            \
257         NO_MOVE_SEMANTIC(name##StubBuilder);                                       \
258         NO_COPY_SEMANTIC(name##StubBuilder);                                       \
259         void GenerateCircuit() override;                                           \
260     };
261     ASM_INTERPRETER_BC_PROFILER_STUB_LIST(DECLARE_HANDLE_PROFILE_STUB_CLASS)
262 #undef DECLARE_HANDLE_PROFILE_STUB_CLASS
263 #define DECLARE_HANDLE_JIT_PROFILE_STUB_CLASS(name, base, ...)                     \
264     class name##StubBuilder : public base##StubBuilder {                           \
265     public:                                                                        \
266         explicit name##StubBuilder(CallSignature *callSignature, Environment *env) \
267             : base##StubBuilder(callSignature, env)                                \
268         {                                                                          \
269         }                                                                          \
270         ~name##StubBuilder() = default;                                            \
271         NO_MOVE_SEMANTIC(name##StubBuilder);                                       \
272         NO_COPY_SEMANTIC(name##StubBuilder);                                       \
273         void GenerateCircuit() override;                                           \
274     };
275     ASM_INTERPRETER_BC_JIT_PROFILER_STUB_LIST(DECLARE_HANDLE_JIT_PROFILE_STUB_CLASS)
276 #undef DECLARE_HANDLE_PROFILE_STUB_CLASS
277 #undef DECLARE_HANDLE_STUB_CLASS
278 }  // namespace panda::ecmascript::kungfu
279 #endif  // ECMASCRIPT_COMPILER_INTERPRETER_STUB_H
280