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 ReadInst16_0(GateRef pc); 75 inline GateRef ReadInst16_1(GateRef pc); 76 inline GateRef ReadInst16_2(GateRef pc); 77 inline GateRef ReadInst16_3(GateRef pc); 78 inline GateRef ReadInst16_4(GateRef pc); 79 inline GateRef ReadInst16_5(GateRef pc); 80 inline GateRef ReadInst16_6(GateRef pc); 81 inline GateRef ReadInstSigned8_0(GateRef pc); 82 inline GateRef ReadInstSigned16_0(GateRef pc); 83 inline GateRef ReadInstSigned32_0(GateRef pc); 84 inline GateRef ReadInst32_0(GateRef pc); 85 inline GateRef ReadInst32_1(GateRef pc); 86 inline GateRef ReadInst32_2(GateRef pc); 87 inline GateRef ReadInst64_0(GateRef pc); 88 89 inline GateRef GetFrame(GateRef frame); 90 inline GateRef GetCurrentSpFrame(GateRef glue); 91 inline GateRef GetLastLeaveFrame(GateRef glue); 92 inline GateRef GetCurrentFrame(GateRef glue); 93 inline GateRef GetPcFromFrame(GateRef frame); 94 inline GateRef GetCallSizeFromFrame(GateRef frame); 95 inline GateRef GetFunctionFromFrame(GateRef frame); 96 inline GateRef GetThisFromFrame(GateRef frame); 97 inline GateRef GetAccFromFrame(GateRef frame); 98 inline GateRef GetEnvFromFrame(GateRef frame); 99 inline GateRef GetEnvFromFunction(GateRef frame); 100 inline GateRef GetConstpoolFromMethod(GateRef function); 101 inline GateRef GetProfileTypeInfoFromMethod(GateRef function); 102 inline GateRef GetModuleFromFunction(GateRef function); 103 inline GateRef GetHomeObjectFromFunction(GateRef function); 104 inline GateRef GetResumeModeFromGeneratorObject(GateRef obj); 105 inline GateRef GetResumeModeFromAsyncGeneratorObject(GateRef obj); 106 inline GateRef GetHotnessCounterFromMethod(GateRef method); 107 108 inline void SetCurrentSpFrame(GateRef glue, GateRef sp); 109 inline void SetLastLeaveFrame(GateRef glue, GateRef sp); 110 inline void SetPcToFrame(GateRef glue, GateRef frame, GateRef value); 111 inline void SetCallSizeToFrame(GateRef glue, GateRef frame, GateRef value); 112 inline void SetFunctionToFrame(GateRef glue, GateRef frame, GateRef value); 113 inline void SetAccToFrame(GateRef glue, GateRef frame, GateRef value); 114 inline void SetEnvToFrame(GateRef glue, GateRef frame, GateRef value); 115 inline void SetHomeObjectToFunction(GateRef glue, GateRef function, GateRef value); 116 inline void SetModuleToFunction(GateRef glue, GateRef function, GateRef value); 117 inline void SetFrameState(GateRef glue, GateRef sp, GateRef function, GateRef acc, 118 GateRef env, GateRef pc, GateRef prev, GateRef type); 119 120 inline void CheckException(GateRef glue, GateRef sp, GateRef pc, GateRef constpool, 121 GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter, 122 GateRef res, GateRef offset); 123 inline void CheckPendingException(GateRef glue, GateRef sp, GateRef pc, GateRef constpool, 124 GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter, 125 GateRef res, GateRef offset); 126 inline void CheckExceptionWithJump(GateRef glue, GateRef sp, GateRef pc, GateRef constpool, 127 GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter, 128 GateRef res, Label *jump); 129 inline void CheckExceptionWithVar(GateRef glue, GateRef sp, GateRef pc, GateRef constpool, 130 GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter, 131 GateRef res, GateRef offset); 132 133 inline GateRef CheckStackOverflow(GateRef glue, GateRef sp); 134 inline GateRef PushArg(GateRef glue, GateRef sp, GateRef value); 135 inline GateRef PushUndefined(GateRef glue, GateRef sp, GateRef num); 136 inline GateRef PushRange(GateRef glue, GateRef sp, GateRef array, GateRef startIndex, GateRef endIndex); 137 inline GateRef GetStartIdxAndNumArgs(GateRef sp, GateRef restIdx); 138 139 inline void Dispatch(GateRef glue, GateRef sp, GateRef pc, GateRef constpool, 140 GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter, GateRef format); 141 inline void DispatchWithId(GateRef glue, GateRef sp, GateRef pc, GateRef constpool, 142 GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter, GateRef index); 143 inline void DispatchLast(GateRef glue, GateRef sp, GateRef pc, GateRef constpool, 144 GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter); 145 inline void DispatchDebugger(GateRef glue, GateRef sp, GateRef pc, GateRef constpool, 146 GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter); 147 inline void DispatchDebuggerLast(GateRef glue, GateRef sp, GateRef pc, GateRef constpool, 148 GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter); 149 150 template <bool needPrint> 151 void DebugPrintInstruction(); 152 private: 153 template<typename... Args> 154 void DispatchBase(GateRef target, GateRef glue, Args... args); 155 }; 156 157 class InterpreterToolsStubBuilder : private InterpreterStubBuilder { 158 public: InterpreterToolsStubBuilder(CallSignature * callSignature,Environment * env)159 InterpreterToolsStubBuilder(CallSignature *callSignature, Environment *env) 160 : InterpreterStubBuilder(callSignature, env) {} 161 ~InterpreterToolsStubBuilder() override = default; 162 NO_MOVE_SEMANTIC(InterpreterToolsStubBuilder); 163 NO_COPY_SEMANTIC(InterpreterToolsStubBuilder); GenerateCircuit()164 void GenerateCircuit() override {} 165 166 inline GateRef GetStringId(const StringIdInfo &info); 167 }; 168 169 #define DECLARE_HANDLE_STUB_CLASS(name) \ 170 class name##StubBuilder : public InterpreterStubBuilder { \ 171 public: \ 172 explicit name##StubBuilder(CallSignature *callSignature, Environment *env) \ 173 : InterpreterStubBuilder(callSignature, env) \ 174 { \ 175 env->GetCircuit()->SetFrameType(FrameType::ASM_INTERPRETER_FRAME); \ 176 } \ 177 ~name##StubBuilder() = default; \ 178 NO_MOVE_SEMANTIC(name##StubBuilder); \ 179 NO_COPY_SEMANTIC(name##StubBuilder); \ 180 void GenerateCircuit() override; \ 181 \ 182 protected: \ 183 void GenerateCircuitImpl(GateRef glue, GateRef sp, GateRef pc, GateRef constpool, \ 184 GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter, \ 185 ProfileOperation callback); \ 186 }; 187 INTERPRETER_BC_STUB_LIST(DECLARE_HANDLE_STUB_CLASS) 188 ASM_INTERPRETER_BC_HELPER_STUB_LIST(DECLARE_HANDLE_STUB_CLASS) 189 190 #define DECLARE_HANDLE_PROFILE_STUB_CLASS(name, base) \ 191 class name##StubBuilder : public base##StubBuilder { \ 192 public: \ 193 explicit name##StubBuilder(CallSignature *callSignature, Environment *env) \ 194 : base##StubBuilder(callSignature, env) \ 195 { \ 196 } \ 197 ~name##StubBuilder() = default; \ 198 NO_MOVE_SEMANTIC(name##StubBuilder); \ 199 NO_COPY_SEMANTIC(name##StubBuilder); \ 200 void GenerateCircuit() override; \ 201 }; 202 ASM_INTERPRETER_BC_PROFILER_STUB_LIST(DECLARE_HANDLE_PROFILE_STUB_CLASS) 203 #undef DECLARE_HANDLE_PROFILE_STUB_CLASS 204 #undef DECLARE_HANDLE_STUB_CLASS 205 } // namespace panda::ecmascript::kungfu 206 #endif // ECMASCRIPT_COMPILER_INTERPRETER_STUB_H 207