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 26namespace panda::ecmascript::kungfu { 27class StringIdInfo { 28public: 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 45 StringIdInfo() : constpool(0), pc(0), offset(Offset::INVALID), 46 length(Length::INVALID), stringId(0), stringIdType(StringIdType::STRING_ID_INFO) {} 47 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 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 56 GateRef GetConstantPool() const 57 { 58 return constpool; 59 } 60 61 GateRef GetPc() const 62 { 63 return pc; 64 } 65 66 Offset GetOffset() const 67 { 68 return offset; 69 } 70 71 Length GetLength() const 72 { 73 return length; 74 } 75 76 GateRef GetStringId() const 77 { 78 return stringId; 79 } 80 81 StringIdType GetStringIdType() const 82 { 83 return stringIdType; 84 } 85 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 94private: 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 103class InterpreterStubBuilder : public StubBuilder { 104public: 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(); 211private: 212 template<typename... Args> 213 void DispatchBase(GateRef target, GateRef glue, Args... args); 214}; 215 216class InterpreterToolsStubBuilder : private InterpreterStubBuilder { 217public: 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