1 /* 2 * Copyright (c) 2022-2024 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_BUILTINS_STUB_H 17 #define ECMASCRIPT_COMPILER_BUILTINS_STUB_H 18 19 #include "ecmascript/compiler/builtins/builtins_call_signature.h" 20 #include "ecmascript/compiler/circuit_builder-inl.h" 21 #include "ecmascript/compiler/stub_builder.h" 22 #include "ecmascript/ecma_runtime_call_info.h" 23 24 namespace panda::ecmascript::kungfu { 25 class BuiltinsStubBuilder : public StubBuilder { 26 public: BuiltinsStubBuilder(StubBuilder * parent,GateRef globalEnv)27 BuiltinsStubBuilder(StubBuilder *parent, GateRef globalEnv) 28 : StubBuilder(parent, globalEnv) {} BuiltinsStubBuilder(CallSignature * callSignature,Environment * env,GateRef globalEnv)29 BuiltinsStubBuilder(CallSignature *callSignature, Environment *env, GateRef globalEnv) 30 : StubBuilder(callSignature, env, globalEnv) {} BuiltinsStubBuilder(Environment * env,GateRef globalEnv)31 BuiltinsStubBuilder(Environment* env, GateRef globalEnv) 32 : StubBuilder(env, globalEnv) {} 33 ~BuiltinsStubBuilder() override = default; 34 NO_MOVE_SEMANTIC(BuiltinsStubBuilder); 35 NO_COPY_SEMANTIC(BuiltinsStubBuilder); 36 virtual void GenerateCircuit() override = 0; 37 GetGlue(GateRef info)38 inline GateRef GetGlue(GateRef info) 39 { 40 return LoadPrimitive(VariableType::NATIVE_POINTER(), info, 41 IntPtr(EcmaRuntimeCallInfo::GetThreadOffset(GetEnvironment()->IsArch32Bit()))); 42 } 43 GetNumArgs(GateRef info)44 inline GateRef GetNumArgs(GateRef info) 45 { 46 return LoadPrimitive(VariableType::INT64(), info, 47 IntPtr(EcmaRuntimeCallInfo::GetNumArgsOffset(GetEnvironment()->IsArch32Bit()))); 48 } 49 GetFunction(GateRef info)50 inline GateRef GetFunction(GateRef info) 51 { 52 return Load(VariableType::JS_ANY(), GetGlue(info), info, 53 IntPtr(EcmaRuntimeCallInfo::GetStackArgsOffset(GetEnvironment()->IsArch32Bit()))); 54 } 55 GetNewTarget(GateRef info)56 inline GateRef GetNewTarget(GateRef info) 57 { 58 GateRef newTargetOffset = IntPtr(EcmaRuntimeCallInfo::GetNewTargetOffset(GetEnvironment()->IsArch32Bit())); 59 return Load(VariableType::JS_ANY(), GetGlue(info), info, newTargetOffset); 60 } 61 GetThis(GateRef info)62 inline GateRef GetThis(GateRef info) 63 { 64 GateRef thisOffset = IntPtr(EcmaRuntimeCallInfo::GetThisOffset(GetEnvironment()->IsArch32Bit())); 65 return Load(VariableType::JS_ANY(), GetGlue(info), info, thisOffset); 66 } 67 68 GateRef GetCallArg0(GateRef numArg); 69 GateRef GetCallArg1(GateRef numArg); 70 GateRef GetCallArg2(GateRef numArg); 71 GateRef GetGlobalEnvFromFunction(GateRef glue, GateRef func); 72 GetArgv()73 inline GateRef GetArgv() 74 { 75 return PtrArgument(static_cast<size_t>(BuiltinsArgs::ARG0_OR_ARGV)); 76 } 77 78 GateRef GetArgFromArgv(GateRef glue, GateRef index, GateRef numArgs = Gate::InvalidGateRef, bool needCheck = false); 79 80 GateRef CallSlowPath(GateRef nativeCode, GateRef glue, GateRef globalEnv, GateRef thisValue, 81 GateRef numArgs, GateRef func, GateRef newTarget); 82 IsNumberYearMonthDay(GateRef year,GateRef month,GateRef day)83 inline GateRef IsNumberYearMonthDay(GateRef year, GateRef month, GateRef day) 84 { 85 GateRef condition = BitAnd(TaggedIsNumber(year), TaggedIsNumber(month)); 86 return BitAnd(condition, TaggedIsNumber(day)); 87 } 88 }; 89 90 #define DECLARE_BUILTINS_STUB_CLASS(name) \ 91 class name##StubBuilder : public BuiltinsStubBuilder { \ 92 public: \ 93 name##StubBuilder(CallSignature *callSignature, Environment *env, GateRef globalEnv) \ 94 : BuiltinsStubBuilder(callSignature, env, globalEnv) {} \ 95 ~name##StubBuilder() = default; \ 96 NO_MOVE_SEMANTIC(name##StubBuilder); \ 97 NO_COPY_SEMANTIC(name##StubBuilder); \ 98 void GenerateCircuit() override; \ 99 \ 100 private: \ 101 void GenerateCircuitImpl(GateRef glue, GateRef nativeCode, GateRef func, GateRef newTarget, \ 102 GateRef thisValue, GateRef numArgs); \ 103 }; 104 105 106 #define DECLARE_BUILTINS_STUB_CLASS_DYN(name, type, ...) \ 107 class type##name##StubBuilder : public BuiltinsStubBuilder { \ 108 public: \ 109 type##name##StubBuilder(CallSignature *callSignature, Environment *env, GateRef globalEnv)\ 110 : BuiltinsStubBuilder(callSignature, env, globalEnv) {} \ 111 ~type##name##StubBuilder() = default; \ 112 NO_MOVE_SEMANTIC(type##name##StubBuilder); \ 113 NO_COPY_SEMANTIC(type##name##StubBuilder); \ 114 void GenerateCircuit() override; \ 115 \ 116 private: \ 117 void GenerateCircuitImpl(GateRef glue, GateRef nativeCode, GateRef func, GateRef newTarget, \ 118 GateRef thisValue, GateRef numArgs); \ 119 }; 120 BUILTINS_STUB_LIST(DECLARE_BUILTINS_STUB_CLASS, DECLARE_BUILTINS_STUB_CLASS_DYN, DECLARE_BUILTINS_STUB_CLASS) 121 122 #define DECLARE_BUILTINS_STW_COPY_STUB_CLASS(name, base) \ 123 class name##StubBuilder : public base##StubBuilder { \ 124 public: \ 125 name##StubBuilder(CallSignature *callSignature, Environment *env, GateRef globalEnv) \ 126 : base##StubBuilder(callSignature, env, globalEnv) {} \ 127 ~name##StubBuilder() = default; \ 128 NO_MOVE_SEMANTIC(name##StubBuilder); \ 129 NO_COPY_SEMANTIC(name##StubBuilder); \ 130 }; 131 132 #define DECLARE_BUILTINS_STW_COPY_STUB_CLASS_SECOND(base) \ 133 DECLARE_BUILTINS_STW_COPY_STUB_CLASS(base##StwCopy, base) 134 135 #define DECLARE_BUILTINS_STW_COPY_STUB_CLASS_DYN(name, base, type) \ 136 class type##name##StubBuilder : public type##base##StubBuilder { \ 137 public: \ 138 type##name##StubBuilder(CallSignature *callSignature, Environment *env, GateRef globalEnv) \ 139 : type##base##StubBuilder(callSignature, env, globalEnv) {} \ 140 ~type##name##StubBuilder() = default; \ 141 NO_MOVE_SEMANTIC(type##name##StubBuilder); \ 142 NO_COPY_SEMANTIC(type##name##StubBuilder); \ 143 }; 144 145 #define DECLARE_BUILTINS_STW_COPY_STUB_CLASS_DYN_SECOND(base, type, ...) \ 146 DECLARE_BUILTINS_STW_COPY_STUB_CLASS_DYN(base##StwCopy, base, type) 147 148 BUILTINS_STW_COPY_STUB_LIST(DECLARE_BUILTINS_STW_COPY_STUB_CLASS_SECOND, \ 149 DECLARE_BUILTINS_STW_COPY_STUB_CLASS_DYN_SECOND, DECLARE_BUILTINS_STW_COPY_STUB_CLASS_SECOND) 150 151 #undef DECLARE_BUILTINS_STW_COPY_STUB_CLASS_DYN_SECOND 152 #undef DECLARE_BUILTINS_STW_COPY_STUB_CLASS_DYN 153 #undef DECLARE_BUILTINS_STW_COPY_STUB_CLASS_SECOND 154 #undef DECLARE_BUILTINS_STW_COPY_STUB_CLASS 155 #undef DECLARE_BUILTINS_STUB_CLASS_DYN 156 #undef DECLARE_BUILTINS_STUB_CLASS 157 } // namespace panda::ecmascript::kungfu 158 #endif // ECMASCRIPT_COMPILER_BUILTINS_STUB_H 159