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