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 25 namespace panda::ecmascript::kungfu { 26 struct StringIdInfo { 27 enum class Offset : uint8_t { 28 BYTE_0, 29 BYTE_1, 30 BYTE_2, 31 INVALID, 32 }; 33 enum class Length : uint8_t { 34 BITS_16, 35 BITS_32, 36 INVALID, 37 }; 38 39 GateRef constpool { 0 }; 40 GateRef pc { 0 }; 41 Offset offset { Offset::INVALID }; 42 Length length { Length::INVALID }; 43 IsValidStringIdInfo44 bool IsValid() const 45 { 46 return (constpool != 0) && (pc != 0) && (offset != Offset::INVALID) && (length != Length::INVALID); 47 } 48 }; 49 50 class InterpreterStubBuilder : public StubBuilder { 51 public: InterpreterStubBuilder(CallSignature * callSignature,Environment * env)52 InterpreterStubBuilder(CallSignature *callSignature, Environment *env) 53 : StubBuilder(callSignature, env) {} 54 ~InterpreterStubBuilder() override = default; 55 NO_MOVE_SEMANTIC(InterpreterStubBuilder); 56 NO_COPY_SEMANTIC(InterpreterStubBuilder); 57 virtual void GenerateCircuit() override = 0; 58 59 inline void SetVregValue(GateRef glue, GateRef sp, GateRef idx, GateRef val); 60 inline GateRef GetVregValue(GateRef sp, GateRef idx); 61 inline GateRef ReadInst4_0(GateRef pc); 62 inline GateRef ReadInst4_1(GateRef pc); 63 inline GateRef ReadInst4_2(GateRef pc); 64 inline GateRef ReadInst4_3(GateRef pc); 65 inline GateRef ReadInst8_0(GateRef pc); 66 inline GateRef ReadInst8_1(GateRef pc); 67 inline GateRef ReadInst8_2(GateRef pc); 68 inline GateRef ReadInst8_3(GateRef pc); 69 inline GateRef ReadInst8_4(GateRef pc); 70 inline GateRef ReadInst8_5(GateRef pc); 71 inline GateRef ReadInst8_6(GateRef pc); 72 inline GateRef ReadInst8_7(GateRef pc); 73 inline GateRef ReadInst8_8(GateRef pc); 74 inline GateRef ReadInst8_9(GateRef pc); 75 inline GateRef ReadInst16_0(GateRef pc); 76 inline GateRef ReadInst16_1(GateRef pc); 77 inline GateRef ReadInst16_2(GateRef pc); 78 inline GateRef ReadInst16_3(GateRef pc); 79 inline GateRef ReadInst16_4(GateRef pc); 80 inline GateRef ReadInst16_5(GateRef pc); 81 inline GateRef ReadInst16_6(GateRef pc); 82 inline GateRef ReadInst16_7(GateRef pc); 83 inline GateRef ReadInstSigned8_0(GateRef pc); 84 inline GateRef ReadInstSigned16_0(GateRef pc); 85 inline GateRef ReadInstSigned32_0(GateRef pc); 86 inline GateRef ReadInst32_0(GateRef pc); 87 inline GateRef ReadInst32_1(GateRef pc); 88 inline GateRef ReadInst32_2(GateRef pc); 89 inline GateRef ReadInst64_0(GateRef pc); 90 91 inline GateRef GetFrame(GateRef frame); 92 inline GateRef GetCurrentSpFrame(GateRef glue); 93 inline GateRef GetLastLeaveFrame(GateRef glue); 94 inline GateRef GetCurrentFrame(GateRef glue); 95 inline GateRef GetPcFromFrame(GateRef frame); 96 inline GateRef GetCallSizeFromFrame(GateRef frame); 97 inline GateRef GetFunctionFromFrame(GateRef frame); 98 inline GateRef GetNewTarget(GateRef sp); 99 inline GateRef GetThisFromFrame(GateRef frame); 100 inline GateRef GetAccFromFrame(GateRef frame); 101 inline GateRef GetEnvFromFrame(GateRef frame); 102 inline GateRef GetEnvFromFunction(GateRef frame); 103 inline GateRef GetConstpoolFromMethod(GateRef function); 104 inline GateRef GetModule(GateRef sp); 105 inline GateRef GetProfileTypeInfoFromMethod(GateRef function); 106 inline GateRef GetModuleFromFunction(GateRef function); 107 inline GateRef GetHomeObjectFromFunction(GateRef function); 108 inline GateRef GetResumeModeFromGeneratorObject(GateRef obj); 109 inline GateRef GetResumeModeFromAsyncGeneratorObject(GateRef obj); 110 inline GateRef GetHotnessCounterFromMethod(GateRef method); 111 112 inline void SetCurrentSpFrame(GateRef glue, GateRef sp); 113 inline void SetLastLeaveFrame(GateRef glue, GateRef sp); 114 inline void SetPcToFrame(GateRef glue, GateRef frame, GateRef value); 115 inline void SetCallSizeToFrame(GateRef glue, GateRef frame, GateRef value); 116 inline void SetFunctionToFrame(GateRef glue, GateRef frame, GateRef value); 117 inline void SetAccToFrame(GateRef glue, GateRef frame, GateRef value); 118 inline void SetEnvToFrame(GateRef glue, GateRef frame, GateRef value); 119 inline void SetHomeObjectToFunction(GateRef glue, GateRef function, GateRef value); 120 inline void SetFrameState(GateRef glue, GateRef sp, GateRef function, GateRef acc, 121 GateRef env, GateRef pc, GateRef prev, GateRef type); 122 123 inline void CheckException(GateRef glue, GateRef sp, GateRef pc, GateRef constpool, 124 GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter, 125 GateRef res, GateRef offset); 126 inline void CheckPendingException(GateRef glue, GateRef sp, GateRef pc, GateRef constpool, 127 GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter, 128 GateRef res, GateRef offset); 129 inline void CheckExceptionWithJump(GateRef glue, GateRef sp, GateRef pc, GateRef constpool, 130 GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter, 131 GateRef res, Label *jump); 132 inline void CheckExceptionWithVar(GateRef glue, GateRef sp, GateRef pc, GateRef constpool, 133 GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter, 134 GateRef res, GateRef offset); 135 136 inline GateRef CheckStackOverflow(GateRef glue, GateRef sp); 137 inline GateRef PushArg(GateRef glue, GateRef sp, GateRef value); 138 inline GateRef PushUndefined(GateRef glue, GateRef sp, GateRef num); 139 inline GateRef PushRange(GateRef glue, GateRef sp, GateRef array, GateRef startIndex, GateRef endIndex); 140 inline GateRef GetStartIdxAndNumArgs(GateRef sp, GateRef restIdx); 141 inline void Dispatch(GateRef glue, GateRef sp, GateRef pc, GateRef constpool, 142 GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter, GateRef format); 143 inline void DispatchWithId(GateRef glue, GateRef sp, GateRef pc, GateRef constpool, 144 GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter, GateRef index); 145 inline void DispatchLast(GateRef glue, GateRef sp, GateRef pc, GateRef constpool, 146 GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter); 147 inline void DispatchDebugger(GateRef glue, GateRef sp, GateRef pc, GateRef constpool, 148 GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter); 149 inline void DispatchDebuggerLast(GateRef glue, GateRef sp, GateRef pc, GateRef constpool, 150 GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter); 151 152 template <bool needPrint> 153 void DebugPrintInstruction(); 154 private: 155 template<typename... Args> 156 void DispatchBase(GateRef target, GateRef glue, Args... args); 157 }; 158 159 class InterpreterToolsStubBuilder : private InterpreterStubBuilder { 160 public: InterpreterToolsStubBuilder(CallSignature * callSignature,Environment * env)161 InterpreterToolsStubBuilder(CallSignature *callSignature, Environment *env) 162 : InterpreterStubBuilder(callSignature, env) {} 163 ~InterpreterToolsStubBuilder() override = default; 164 NO_MOVE_SEMANTIC(InterpreterToolsStubBuilder); 165 NO_COPY_SEMANTIC(InterpreterToolsStubBuilder); GenerateCircuit()166 void GenerateCircuit() override {} 167 168 inline GateRef GetStringId(const StringIdInfo &info); 169 }; 170 171 #define DECLARE_HANDLE_STUB_CLASS(name) \ 172 class name##StubBuilder : public InterpreterStubBuilder { \ 173 public: \ 174 explicit name##StubBuilder(CallSignature *callSignature, Environment *env) \ 175 : InterpreterStubBuilder(callSignature, env) \ 176 { \ 177 env->GetCircuit()->SetFrameType(FrameType::ASM_INTERPRETER_FRAME); \ 178 } \ 179 ~name##StubBuilder() = default; \ 180 NO_MOVE_SEMANTIC(name##StubBuilder); \ 181 NO_COPY_SEMANTIC(name##StubBuilder); \ 182 void GenerateCircuit() override; \ 183 \ 184 protected: \ 185 void GenerateCircuitImpl(GateRef glue, GateRef sp, GateRef pc, GateRef constpool, \ 186 GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter, \ 187 ProfileOperation callback); \ 188 }; 189 INTERPRETER_BC_STUB_LIST(DECLARE_HANDLE_STUB_CLASS) 190 ASM_INTERPRETER_BC_HELPER_STUB_LIST(DECLARE_HANDLE_STUB_CLASS) 191 192 #define DECLARE_HANDLE_PROFILE_STUB_CLASS(name, base, ...) \ 193 class name##StubBuilder : public base##StubBuilder { \ 194 public: \ 195 explicit name##StubBuilder(CallSignature *callSignature, Environment *env) \ 196 : base##StubBuilder(callSignature, env) \ 197 { \ 198 } \ 199 ~name##StubBuilder() = default; \ 200 NO_MOVE_SEMANTIC(name##StubBuilder); \ 201 NO_COPY_SEMANTIC(name##StubBuilder); \ 202 void GenerateCircuit() override; \ 203 }; 204 ASM_INTERPRETER_BC_PROFILER_STUB_LIST(DECLARE_HANDLE_PROFILE_STUB_CLASS) 205 #undef DECLARE_HANDLE_PROFILE_STUB_CLASS 206 #define DECLARE_HANDLE_JIT_PROFILE_STUB_CLASS(name, base, ...) \ 207 class name##StubBuilder : public base##StubBuilder { \ 208 public: \ 209 explicit name##StubBuilder(CallSignature *callSignature, Environment *env) \ 210 : base##StubBuilder(callSignature, env) \ 211 { \ 212 } \ 213 ~name##StubBuilder() = default; \ 214 NO_MOVE_SEMANTIC(name##StubBuilder); \ 215 NO_COPY_SEMANTIC(name##StubBuilder); \ 216 void GenerateCircuit() override; \ 217 }; 218 ASM_INTERPRETER_BC_JIT_PROFILER_STUB_LIST(DECLARE_HANDLE_JIT_PROFILE_STUB_CLASS) 219 #undef DECLARE_HANDLE_PROFILE_STUB_CLASS 220 #undef DECLARE_HANDLE_STUB_CLASS 221 } // namespace panda::ecmascript::kungfu 222 #endif // ECMASCRIPT_COMPILER_INTERPRETER_STUB_H 223