• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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()56     GateRef GetConstantPool() const
57     {
58         return constpool;
59     }
60 
GetPc()61     GateRef GetPc() const
62     {
63         return pc;
64     }
65 
GetOffset()66     Offset GetOffset() const
67     {
68         return offset;
69     }
70 
GetLength()71     Length GetLength() const
72     {
73         return length;
74     }
75 
GetStringId()76     GateRef GetStringId() const
77     {
78         return stringId;
79     }
80 
GetStringIdType()81     StringIdType GetStringIdType() const
82     {
83         return stringIdType;
84     }
85 
IsValid()86     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 glue, GateRef sp, GateRef idx);
114     inline GateRef GetVregValueFromArray(GateRef glue, GateRef array, GateRef idx);
115     inline GateRef ReadInst4_0(GateRef pc);
116     inline GateRef ReadInst4_1(GateRef pc);
117     inline GateRef ReadInst4_2(GateRef pc);
118     inline GateRef ReadInst4_3(GateRef pc);
119     inline GateRef ReadInst8_0(GateRef pc);
120     inline GateRef ReadInst8_1(GateRef pc);
121     inline GateRef ReadInst8_2(GateRef pc);
122     inline GateRef ReadInst8_3(GateRef pc);
123     inline GateRef ReadInst8_4(GateRef pc);
124     inline GateRef ReadInst8_5(GateRef pc);
125     inline GateRef ReadInst8_6(GateRef pc);
126     inline GateRef ReadInst8_7(GateRef pc);
127     inline GateRef ReadInst8_8(GateRef pc);
128     inline GateRef ReadInst8_9(GateRef pc);
129     inline GateRef ReadInst16_0(GateRef pc);
130     inline GateRef ReadInst16_1(GateRef pc);
131     inline GateRef ReadInst16_2(GateRef pc);
132     inline GateRef ReadInst16_3(GateRef pc);
133     inline GateRef ReadInst16_4(GateRef pc);
134     inline GateRef ReadInst16_5(GateRef pc);
135     inline GateRef ReadInst16_6(GateRef pc);
136     inline GateRef ReadInst16_7(GateRef pc);
137     inline GateRef ReadInstSigned8_0(GateRef pc);
138     inline GateRef ReadInstSigned16_0(GateRef pc);
139     inline GateRef ReadInstSigned32_0(GateRef pc);
140     inline GateRef ReadInst32_0(GateRef pc);
141     inline GateRef ReadInst32_1(GateRef pc);
142     inline GateRef ReadInst32_2(GateRef pc);
143     inline GateRef ReadInst64_0(GateRef pc);
144 
145     inline GateRef GetFrame(GateRef frame);
146     inline GateRef GetCurrentSpFrame(GateRef glue);
147     inline GateRef GetLastLeaveFrame(GateRef glue);
148     inline GateRef GetCurrentFrame(GateRef glue);
149     inline GateRef GetPcFromFrame(GateRef frame);
150     inline GateRef GetCallSizeFromFrame(GateRef frame);
151     inline GateRef GetFunctionFromFrame(GateRef glue, GateRef frame);
152     inline GateRef GetNewTarget(GateRef glue, GateRef sp);
153     inline GateRef GetThisFromFrame(GateRef glue, GateRef frame);
154     inline GateRef GetAccFromFrame(GateRef glue, GateRef frame);
155     inline GateRef GetEnvFromFrame(GateRef glue, GateRef frame);
156     inline GateRef GetEnvFromFunction(GateRef glue, GateRef frame);
157     inline GateRef GetConstpoolFromMethod(GateRef glue, GateRef function);
158     inline GateRef GetModule(GateRef glue, GateRef sp);
159     inline GateRef GetProfileTypeInfoFromFunction(GateRef glue, GateRef function);
160     inline GateRef GetModuleFromFunction(GateRef glue, GateRef function);
161     inline GateRef GetSendableEnvFromModule(GateRef glue, GateRef module);
162     inline GateRef GetHomeObjectFromFunction(GateRef glue, GateRef function);
163     inline GateRef GetResumeModeFromGeneratorObject(GateRef obj);
164     inline GateRef GetResumeModeFromAsyncGeneratorObject(GateRef obj);
165     inline GateRef GetHotnessCounterFromMethod(GateRef method);
166 
167     inline void SetCurrentSpFrame(GateRef glue, GateRef sp);
168     inline void SetLastLeaveFrame(GateRef glue, GateRef sp);
169     inline void SetPcToFrame(GateRef glue, GateRef frame, GateRef value);
170     inline void SetCallSizeToFrame(GateRef glue, GateRef frame, GateRef value);
171     inline void SetFunctionToFrame(GateRef glue, GateRef frame, GateRef value);
172     inline void SetAccToFrame(GateRef glue, GateRef frame, GateRef value);
173     inline void SetEnvToFrame(GateRef glue, GateRef frame, GateRef value);
174     inline void SetHomeObjectToFunction(GateRef glue, GateRef function, GateRef value);
175     inline void SetFrameState(GateRef glue, GateRef sp, GateRef function, GateRef acc,
176                               GateRef env, GateRef pc, GateRef prev, GateRef type);
177 
178     inline void UpdateProfileTypeInfoCellToFunction(GateRef glue, GateRef function,
179                                                     GateRef profileTypeInfo, GateRef slotId);
180 
181     inline void CheckException(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
182 		               GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter,
183 			       GateRef res, GateRef offset);
184     inline void CheckPendingException(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
185 		                      GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter,
186 			              GateRef res, GateRef offset);
187     inline void CheckExceptionWithJump(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
188 		                       GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter,
189 			               GateRef res, Label *jump);
190     inline void CheckExceptionWithVar(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
191 		                      GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter,
192 			              GateRef res, GateRef offset);
193 
194     inline GateRef CheckStackOverflow(GateRef glue, GateRef sp);
195     inline GateRef PushArg(GateRef glue, GateRef sp, GateRef value);
196     inline GateRef PushUndefined(GateRef glue, GateRef sp, GateRef num);
197     inline GateRef PushRange(GateRef glue, GateRef sp, GateRef array, GateRef startIndex, GateRef endIndex);
198     inline GateRef GetStartIdxAndNumArgs(GateRef glue, GateRef sp, GateRef restIdx);
199     inline void Dispatch(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
200                          GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter, GateRef format);
201     inline void DispatchWithId(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
202                                GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter, GateRef index);
203     inline void DispatchLast(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
204                              GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter);
205     inline void DispatchDebugger(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
206                                  GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter);
207     inline void DispatchDebuggerLast(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
208                                      GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter);
209 
210     template <bool needPrint>
211     void DebugPrintInstruction();
212 private:
213     template<typename... Args>
214     void DispatchBase(GateRef target, GateRef glue, Args... args);
215 };
216 
217 class InterpreterToolsStubBuilder : private InterpreterStubBuilder {
218 public:
InterpreterToolsStubBuilder(CallSignature * callSignature,Environment * env)219     InterpreterToolsStubBuilder(CallSignature *callSignature, Environment *env)
220         : InterpreterStubBuilder(callSignature, env) {}
221     ~InterpreterToolsStubBuilder() override = default;
222     NO_MOVE_SEMANTIC(InterpreterToolsStubBuilder);
223     NO_COPY_SEMANTIC(InterpreterToolsStubBuilder);
GenerateCircuit()224     void GenerateCircuit() override {}
225 
226     inline GateRef GetStringId(const StringIdInfo &info);
227 };
228 
229 #define DECLARE_HANDLE_STUB_CLASS(name)                                                         \
230     class name##StubBuilder : public InterpreterStubBuilder {                                   \
231     public:                                                                                     \
232         explicit name##StubBuilder(CallSignature *callSignature, Environment *env)              \
233             : InterpreterStubBuilder(callSignature, env)                                        \
234         {                                                                                       \
235             env->GetCircuit()->SetFrameType(FrameType::ASM_INTERPRETER_FRAME);                  \
236         }                                                                                       \
237         ~name##StubBuilder() = default;                                                         \
238         NO_MOVE_SEMANTIC(name##StubBuilder);                                                    \
239         NO_COPY_SEMANTIC(name##StubBuilder);                                                    \
240         void GenerateCircuit() override;                                                        \
241                                                                                                 \
242     protected:                                                                                  \
243         void GenerateCircuitImpl(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,       \
244                                  GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter,  \
245                                  ProfileOperation callback);                                    \
246     };
247     INTERPRETER_BC_STUB_LIST(DECLARE_HANDLE_STUB_CLASS)
248     ASM_INTERPRETER_BC_HELPER_STUB_LIST(DECLARE_HANDLE_STUB_CLASS)
249 
250 #define DECLARE_HANDLE_PROFILE_STUB_CLASS(name, base, ...)                         \
251     class name##StubBuilder : public base##StubBuilder {                           \
252     public:                                                                        \
253         explicit name##StubBuilder(CallSignature *callSignature, Environment *env) \
254             : base##StubBuilder(callSignature, env)                                \
255         {                                                                          \
256         }                                                                          \
257         ~name##StubBuilder() = default;                                            \
258         NO_MOVE_SEMANTIC(name##StubBuilder);                                       \
259         NO_COPY_SEMANTIC(name##StubBuilder);                                       \
260         void GenerateCircuit() override;                                           \
261     };
262     ASM_INTERPRETER_BC_PROFILER_STUB_LIST(DECLARE_HANDLE_PROFILE_STUB_CLASS)
263 #undef DECLARE_HANDLE_PROFILE_STUB_CLASS
264 #define DECLARE_HANDLE_JIT_PROFILE_STUB_CLASS(name, base, ...)                     \
265     class name##StubBuilder : public base##StubBuilder {                           \
266     public:                                                                        \
267         explicit name##StubBuilder(CallSignature *callSignature, Environment *env) \
268             : base##StubBuilder(callSignature, env)                                \
269         {                                                                          \
270         }                                                                          \
271         ~name##StubBuilder() = default;                                            \
272         NO_MOVE_SEMANTIC(name##StubBuilder);                                       \
273         NO_COPY_SEMANTIC(name##StubBuilder);                                       \
274         void GenerateCircuit() override;                                           \
275     };
276     ASM_INTERPRETER_BC_JIT_PROFILER_STUB_LIST(DECLARE_HANDLE_JIT_PROFILE_STUB_CLASS)
277 #undef DECLARE_HANDLE_JIT_PROFILE_STUB_CLASS
278 #define DECLARE_HANDLE_STW_COPY_STUB_CLASS_SECOND(base)                            \
279     DECLARE_HANDLE_STW_COPY_STUB_CLASS(base##StwCopy, base)
280 #define DECLARE_HANDLE_STW_COPY_STUB_CLASS(name, base)                             \
281     class name##StubBuilder : public base##StubBuilder {                           \
282     public:                                                                        \
283         explicit name##StubBuilder(CallSignature *callSignature, Environment *env) \
284             : base##StubBuilder(callSignature, env)                                \
285         {                                                                          \
286         }                                                                          \
287         ~name##StubBuilder() = default;                                            \
288         NO_MOVE_SEMANTIC(name##StubBuilder);                                       \
289         NO_COPY_SEMANTIC(name##StubBuilder);                                       \
290         void GenerateCircuit() override;                                           \
291     };
292     ASM_INTERPRETER_BC_STW_COPY_STUB_LIST(DECLARE_HANDLE_STW_COPY_STUB_CLASS_SECOND)
293 #undef DECLARE_HANDLE_STW_COPY_STUB_CLASS
294 #undef DECLARE_HANDLE_STW_COPY_STUB_CLASS_SECOND
295 #undef DECLARE_HANDLE_STUB_CLASS
296 }  // namespace panda::ecmascript::kungfu
297 #endif  // ECMASCRIPT_COMPILER_INTERPRETER_STUB_H
298