1/* 2 * Copyright (c) 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_CALL_STUB_BUILDER_H 17#define ECMASCRIPT_COMPILER_CALL_STUB_BUILDER_H 18 19#include "ecmascript/compiler/profiler_operation.h" 20#include "ecmascript/compiler/stub_builder.h" 21 22namespace panda::ecmascript::kungfu { 23 24struct CallArgs { 25 GateRef arg0; 26 GateRef arg1; 27 GateRef arg2; 28}; 29 30struct CallArgsWithThis { 31 GateRef arg0; 32 GateRef arg1; 33 GateRef arg2; 34 GateRef thisValue; 35}; 36 37struct CallArgv { 38 GateRef argc; 39 GateRef argv; 40}; 41 42struct CallArgvWithThis { 43 GateRef argc; 44 GateRef argv; 45 GateRef thisValue; 46}; 47 48struct SuperCallArgs { 49 GateRef thisFunc; 50 GateRef array; 51 GateRef argc; 52 GateRef argv; 53 GateRef thisObj; 54 GateRef newTarget; 55}; 56 57struct CallConstructorArgs { 58 GateRef argc; 59 GateRef argv; 60 GateRef thisObj; 61}; 62 63struct CallGetterArgs { 64 GateRef receiver; 65}; 66 67struct CallSetterArgs { 68 GateRef receiver; 69 GateRef value; 70}; 71 72struct CallThisArg2WithReturnArgs { 73 GateRef thisValue; 74 GateRef arg0; 75 GateRef arg1; 76}; 77 78struct CallThisArg3WithReturnArgs { 79 GateRef argHandle; 80 GateRef value; 81 GateRef key; 82 GateRef thisValue; 83}; 84 85struct CallThisArgvWithReturnArgs { 86 GateRef argc; 87 GateRef argv; 88 GateRef thisValue; 89}; 90 91struct JSCallArgs { 92 JSCallArgs() {} 93 JSCallArgs(JSCallMode m) : mode(m) {} 94 JSCallMode mode {JSCallMode::CALL_ARG0}; 95 union { 96 CallArgs callArgs; 97 CallArgsWithThis callArgsWithThis; 98 CallArgv callArgv; 99 CallArgvWithThis callArgvWithThis; 100 SuperCallArgs superCallArgs; 101 CallConstructorArgs callConstructorArgs; 102 CallGetterArgs callGetterArgs; 103 CallSetterArgs callSetterArgs; 104 CallThisArg2WithReturnArgs callThisArg2WithReturnArgs; 105 CallThisArg3WithReturnArgs callThisArg3WithReturnArgs; 106 CallThisArgvWithReturnArgs callThisArgvWithReturnArgs; 107 }; 108}; 109 110class CallStubBuilder : public StubBuilder { 111public: 112 explicit CallStubBuilder(StubBuilder *parent, GateRef glue, GateRef func, GateRef actualNumArgs, GateRef jumpSize, 113 Variable *result, GateRef hotnessCounter, JSCallArgs callArgs, 114 ProfileOperation callback = ProfileOperation(), 115 bool checkIsCallable = true, GateRef hir = Circuit::NullGate()) 116 : StubBuilder(parent) 117 { 118 this->glue_ = glue; 119 this->func_ = func; 120 this->jumpSize_ = jumpSize; 121 this->actualNumArgs_ = actualNumArgs; 122 this->result_ = result; 123 this->hotnessCounter_ = hotnessCounter; 124 this->callArgs_ = callArgs; 125 this->callback_ = callback; 126 this->checkIsCallable_ = checkIsCallable; 127 this->hir_ = hir; 128 } 129 explicit CallStubBuilder(Environment *env) 130 : StubBuilder(env) {} 131 ~CallStubBuilder() override = default; 132 NO_MOVE_SEMANTIC(CallStubBuilder); 133 NO_COPY_SEMANTIC(CallStubBuilder); 134 void GenerateCircuit() override {} 135 136 void JSCallDispatchForBaseline(Label *exit, Label *noNeedCheckException = nullptr); 137 GateRef JSCallDispatch(); 138 139protected: 140 141private: 142 GateRef glue_ {0}; 143 GateRef func_ {0}; 144 GateRef jumpSize_ {0}; 145 GateRef actualNumArgs_ {0}; 146 GateRef hotnessCounter_ {0}; 147 Variable *result_ {nullptr}; 148 JSCallArgs callArgs_; 149 ProfileOperation callback_; 150 bool checkIsCallable_ {true}; 151 GateRef hir_ {0}; 152 153 bool isFast_ {true}; 154 bool isBridge_ {false}; 155 bool isForBaseline_ {false}; 156 GateRef sp_ {0}; 157 GateRef method_ {0}; 158 GateRef numArgs_ {0}; 159 GateRef bitfield_ {0}; 160 GateRef callField_ {0}; 161 GateRef newTarget_ {0}; 162 GateRef thisValue_ {0}; 163 GateRef nativeCode_ {0}; 164 GateRef realNumArgs_ {0}; 165 GateRef isNativeMask_ {0}; 166 GateRef baselineBuiltinFp_ {0}; 167 168 void JSCallInit(Label *exit, Label *funcIsHeapObject, Label *funcIsCallable, Label *funcNotCallable); 169 void JSCallNative(Label *exit); 170 void JSCallJSFunction(Label *exit, Label *noNeedCheckException = nullptr); 171 void JSFastAotCall(Label *exit); 172 void JSSlowAotCall(Label *exit); 173 GateRef CallConstructorBridge(const int idxForAot, const std::vector<GateRef> &argsForAot); 174 void CallBridge(GateRef code, GateRef expectedNum, Label *exit); 175 void JSCallAsmInterpreter(bool hasBaselineCode, Label *methodNotAot, Label *exit, Label *noNeedCheckException); 176 177 int PrepareIdxForNative(); 178 std::vector<GateRef> PrepareArgsForNative(); 179 std::vector<GateRef> PrepareBasicArgsForNative(); 180 std::vector<GateRef> PrepareAppendArgsForNative(); 181 182 int PrepareIdxForAot(); 183 std::vector<GateRef> PrepareArgsForAot(GateRef expectedNum); 184 std::vector<GateRef> PrepareBasicArgsForAot(); 185 std::vector<GateRef> PrepareAppendArgsForAotStep1(); 186 std::vector<GateRef> PrepareAppendArgsForAotStep2(); 187 std::vector<GateRef> PrepareAppendArgsForAotStep3(GateRef expectedNum); 188 189 int PrepareIdxForAsmInterpreterForBaselineWithBaselineCode(); 190 int PrepareIdxForAsmInterpreterForBaselineWithoutBaselineCode(); 191 int PrepareIdxForAsmInterpreterWithBaselineCode(); 192 int PrepareIdxForAsmInterpreterWithoutBaselineCode(); 193 std::vector<GateRef> PrepareArgsForAsmInterpreter(); 194 std::vector<GateRef> PrepareBasicArgsForAsmInterpreter(); 195 std::vector<GateRef> PrepareAppendArgsForAsmInterpreter(); 196 197 void CallFastBuiltin(Label* notFastBuiltins, Label *exit); 198 std::vector<GateRef> PrepareArgsForFastBuiltin(); 199 std::vector<GateRef> PrepareBasicArgsForFastBuiltin(); 200 std::vector<GateRef> PrepareAppendArgsForFastBuiltin(); 201 bool IsCallModeSupportPGO() const; 202 bool IsCallModeSupportCallBuiltin() const; 203 bool IsSlowAotCall() const; 204 bool IsFastAotCall() const; 205 bool IsSlowAotCallWithBridge() const; 206 bool IsFastAotCallWithBridge() const; 207 bool CheckResultValueChangedWithReturn(GateRef prevResRef) const; 208 void HandleProfileCall(); 209 void HandleProfileNativeCall(); 210 bool IsCallModeGetterSetter(); 211}; 212 213} // panda::ecmascript::kungfu 214#endif // ECMASCRIPT_COMPILER_CALL_STUB_BUILDER_H