14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci 164514f5e3Sopenharmony_ci#ifndef ECMASCRIPT_COMPILER_CALL_STUB_BUILDER_H 174514f5e3Sopenharmony_ci#define ECMASCRIPT_COMPILER_CALL_STUB_BUILDER_H 184514f5e3Sopenharmony_ci 194514f5e3Sopenharmony_ci#include "ecmascript/compiler/profiler_operation.h" 204514f5e3Sopenharmony_ci#include "ecmascript/compiler/stub_builder.h" 214514f5e3Sopenharmony_ci 224514f5e3Sopenharmony_cinamespace panda::ecmascript::kungfu { 234514f5e3Sopenharmony_ci 244514f5e3Sopenharmony_cistruct CallArgs { 254514f5e3Sopenharmony_ci GateRef arg0; 264514f5e3Sopenharmony_ci GateRef arg1; 274514f5e3Sopenharmony_ci GateRef arg2; 284514f5e3Sopenharmony_ci}; 294514f5e3Sopenharmony_ci 304514f5e3Sopenharmony_cistruct CallArgsWithThis { 314514f5e3Sopenharmony_ci GateRef arg0; 324514f5e3Sopenharmony_ci GateRef arg1; 334514f5e3Sopenharmony_ci GateRef arg2; 344514f5e3Sopenharmony_ci GateRef thisValue; 354514f5e3Sopenharmony_ci}; 364514f5e3Sopenharmony_ci 374514f5e3Sopenharmony_cistruct CallArgv { 384514f5e3Sopenharmony_ci GateRef argc; 394514f5e3Sopenharmony_ci GateRef argv; 404514f5e3Sopenharmony_ci}; 414514f5e3Sopenharmony_ci 424514f5e3Sopenharmony_cistruct CallArgvWithThis { 434514f5e3Sopenharmony_ci GateRef argc; 444514f5e3Sopenharmony_ci GateRef argv; 454514f5e3Sopenharmony_ci GateRef thisValue; 464514f5e3Sopenharmony_ci}; 474514f5e3Sopenharmony_ci 484514f5e3Sopenharmony_cistruct SuperCallArgs { 494514f5e3Sopenharmony_ci GateRef thisFunc; 504514f5e3Sopenharmony_ci GateRef array; 514514f5e3Sopenharmony_ci GateRef argc; 524514f5e3Sopenharmony_ci GateRef argv; 534514f5e3Sopenharmony_ci GateRef thisObj; 544514f5e3Sopenharmony_ci GateRef newTarget; 554514f5e3Sopenharmony_ci}; 564514f5e3Sopenharmony_ci 574514f5e3Sopenharmony_cistruct CallConstructorArgs { 584514f5e3Sopenharmony_ci GateRef argc; 594514f5e3Sopenharmony_ci GateRef argv; 604514f5e3Sopenharmony_ci GateRef thisObj; 614514f5e3Sopenharmony_ci}; 624514f5e3Sopenharmony_ci 634514f5e3Sopenharmony_cistruct CallGetterArgs { 644514f5e3Sopenharmony_ci GateRef receiver; 654514f5e3Sopenharmony_ci}; 664514f5e3Sopenharmony_ci 674514f5e3Sopenharmony_cistruct CallSetterArgs { 684514f5e3Sopenharmony_ci GateRef receiver; 694514f5e3Sopenharmony_ci GateRef value; 704514f5e3Sopenharmony_ci}; 714514f5e3Sopenharmony_ci 724514f5e3Sopenharmony_cistruct CallThisArg2WithReturnArgs { 734514f5e3Sopenharmony_ci GateRef thisValue; 744514f5e3Sopenharmony_ci GateRef arg0; 754514f5e3Sopenharmony_ci GateRef arg1; 764514f5e3Sopenharmony_ci}; 774514f5e3Sopenharmony_ci 784514f5e3Sopenharmony_cistruct CallThisArg3WithReturnArgs { 794514f5e3Sopenharmony_ci GateRef argHandle; 804514f5e3Sopenharmony_ci GateRef value; 814514f5e3Sopenharmony_ci GateRef key; 824514f5e3Sopenharmony_ci GateRef thisValue; 834514f5e3Sopenharmony_ci}; 844514f5e3Sopenharmony_ci 854514f5e3Sopenharmony_cistruct CallThisArgvWithReturnArgs { 864514f5e3Sopenharmony_ci GateRef argc; 874514f5e3Sopenharmony_ci GateRef argv; 884514f5e3Sopenharmony_ci GateRef thisValue; 894514f5e3Sopenharmony_ci}; 904514f5e3Sopenharmony_ci 914514f5e3Sopenharmony_cistruct JSCallArgs { 924514f5e3Sopenharmony_ci JSCallArgs() {} 934514f5e3Sopenharmony_ci JSCallArgs(JSCallMode m) : mode(m) {} 944514f5e3Sopenharmony_ci JSCallMode mode {JSCallMode::CALL_ARG0}; 954514f5e3Sopenharmony_ci union { 964514f5e3Sopenharmony_ci CallArgs callArgs; 974514f5e3Sopenharmony_ci CallArgsWithThis callArgsWithThis; 984514f5e3Sopenharmony_ci CallArgv callArgv; 994514f5e3Sopenharmony_ci CallArgvWithThis callArgvWithThis; 1004514f5e3Sopenharmony_ci SuperCallArgs superCallArgs; 1014514f5e3Sopenharmony_ci CallConstructorArgs callConstructorArgs; 1024514f5e3Sopenharmony_ci CallGetterArgs callGetterArgs; 1034514f5e3Sopenharmony_ci CallSetterArgs callSetterArgs; 1044514f5e3Sopenharmony_ci CallThisArg2WithReturnArgs callThisArg2WithReturnArgs; 1054514f5e3Sopenharmony_ci CallThisArg3WithReturnArgs callThisArg3WithReturnArgs; 1064514f5e3Sopenharmony_ci CallThisArgvWithReturnArgs callThisArgvWithReturnArgs; 1074514f5e3Sopenharmony_ci }; 1084514f5e3Sopenharmony_ci}; 1094514f5e3Sopenharmony_ci 1104514f5e3Sopenharmony_ciclass CallStubBuilder : public StubBuilder { 1114514f5e3Sopenharmony_cipublic: 1124514f5e3Sopenharmony_ci explicit CallStubBuilder(StubBuilder *parent, GateRef glue, GateRef func, GateRef actualNumArgs, GateRef jumpSize, 1134514f5e3Sopenharmony_ci Variable *result, GateRef hotnessCounter, JSCallArgs callArgs, 1144514f5e3Sopenharmony_ci ProfileOperation callback = ProfileOperation(), 1154514f5e3Sopenharmony_ci bool checkIsCallable = true, GateRef hir = Circuit::NullGate()) 1164514f5e3Sopenharmony_ci : StubBuilder(parent) 1174514f5e3Sopenharmony_ci { 1184514f5e3Sopenharmony_ci this->glue_ = glue; 1194514f5e3Sopenharmony_ci this->func_ = func; 1204514f5e3Sopenharmony_ci this->jumpSize_ = jumpSize; 1214514f5e3Sopenharmony_ci this->actualNumArgs_ = actualNumArgs; 1224514f5e3Sopenharmony_ci this->result_ = result; 1234514f5e3Sopenharmony_ci this->hotnessCounter_ = hotnessCounter; 1244514f5e3Sopenharmony_ci this->callArgs_ = callArgs; 1254514f5e3Sopenharmony_ci this->callback_ = callback; 1264514f5e3Sopenharmony_ci this->checkIsCallable_ = checkIsCallable; 1274514f5e3Sopenharmony_ci this->hir_ = hir; 1284514f5e3Sopenharmony_ci } 1294514f5e3Sopenharmony_ci explicit CallStubBuilder(Environment *env) 1304514f5e3Sopenharmony_ci : StubBuilder(env) {} 1314514f5e3Sopenharmony_ci ~CallStubBuilder() override = default; 1324514f5e3Sopenharmony_ci NO_MOVE_SEMANTIC(CallStubBuilder); 1334514f5e3Sopenharmony_ci NO_COPY_SEMANTIC(CallStubBuilder); 1344514f5e3Sopenharmony_ci void GenerateCircuit() override {} 1354514f5e3Sopenharmony_ci 1364514f5e3Sopenharmony_ci void JSCallDispatchForBaseline(Label *exit, Label *noNeedCheckException = nullptr); 1374514f5e3Sopenharmony_ci GateRef JSCallDispatch(); 1384514f5e3Sopenharmony_ci 1394514f5e3Sopenharmony_ciprotected: 1404514f5e3Sopenharmony_ci 1414514f5e3Sopenharmony_ciprivate: 1424514f5e3Sopenharmony_ci GateRef glue_ {0}; 1434514f5e3Sopenharmony_ci GateRef func_ {0}; 1444514f5e3Sopenharmony_ci GateRef jumpSize_ {0}; 1454514f5e3Sopenharmony_ci GateRef actualNumArgs_ {0}; 1464514f5e3Sopenharmony_ci GateRef hotnessCounter_ {0}; 1474514f5e3Sopenharmony_ci Variable *result_ {nullptr}; 1484514f5e3Sopenharmony_ci JSCallArgs callArgs_; 1494514f5e3Sopenharmony_ci ProfileOperation callback_; 1504514f5e3Sopenharmony_ci bool checkIsCallable_ {true}; 1514514f5e3Sopenharmony_ci GateRef hir_ {0}; 1524514f5e3Sopenharmony_ci 1534514f5e3Sopenharmony_ci bool isFast_ {true}; 1544514f5e3Sopenharmony_ci bool isBridge_ {false}; 1554514f5e3Sopenharmony_ci bool isForBaseline_ {false}; 1564514f5e3Sopenharmony_ci GateRef sp_ {0}; 1574514f5e3Sopenharmony_ci GateRef method_ {0}; 1584514f5e3Sopenharmony_ci GateRef numArgs_ {0}; 1594514f5e3Sopenharmony_ci GateRef bitfield_ {0}; 1604514f5e3Sopenharmony_ci GateRef callField_ {0}; 1614514f5e3Sopenharmony_ci GateRef newTarget_ {0}; 1624514f5e3Sopenharmony_ci GateRef thisValue_ {0}; 1634514f5e3Sopenharmony_ci GateRef nativeCode_ {0}; 1644514f5e3Sopenharmony_ci GateRef realNumArgs_ {0}; 1654514f5e3Sopenharmony_ci GateRef isNativeMask_ {0}; 1664514f5e3Sopenharmony_ci GateRef baselineBuiltinFp_ {0}; 1674514f5e3Sopenharmony_ci 1684514f5e3Sopenharmony_ci void JSCallInit(Label *exit, Label *funcIsHeapObject, Label *funcIsCallable, Label *funcNotCallable); 1694514f5e3Sopenharmony_ci void JSCallNative(Label *exit); 1704514f5e3Sopenharmony_ci void JSCallJSFunction(Label *exit, Label *noNeedCheckException = nullptr); 1714514f5e3Sopenharmony_ci void JSFastAotCall(Label *exit); 1724514f5e3Sopenharmony_ci void JSSlowAotCall(Label *exit); 1734514f5e3Sopenharmony_ci GateRef CallConstructorBridge(const int idxForAot, const std::vector<GateRef> &argsForAot); 1744514f5e3Sopenharmony_ci void CallBridge(GateRef code, GateRef expectedNum, Label *exit); 1754514f5e3Sopenharmony_ci void JSCallAsmInterpreter(bool hasBaselineCode, Label *methodNotAot, Label *exit, Label *noNeedCheckException); 1764514f5e3Sopenharmony_ci 1774514f5e3Sopenharmony_ci int PrepareIdxForNative(); 1784514f5e3Sopenharmony_ci std::vector<GateRef> PrepareArgsForNative(); 1794514f5e3Sopenharmony_ci std::vector<GateRef> PrepareBasicArgsForNative(); 1804514f5e3Sopenharmony_ci std::vector<GateRef> PrepareAppendArgsForNative(); 1814514f5e3Sopenharmony_ci 1824514f5e3Sopenharmony_ci int PrepareIdxForAot(); 1834514f5e3Sopenharmony_ci std::vector<GateRef> PrepareArgsForAot(GateRef expectedNum); 1844514f5e3Sopenharmony_ci std::vector<GateRef> PrepareBasicArgsForAot(); 1854514f5e3Sopenharmony_ci std::vector<GateRef> PrepareAppendArgsForAotStep1(); 1864514f5e3Sopenharmony_ci std::vector<GateRef> PrepareAppendArgsForAotStep2(); 1874514f5e3Sopenharmony_ci std::vector<GateRef> PrepareAppendArgsForAotStep3(GateRef expectedNum); 1884514f5e3Sopenharmony_ci 1894514f5e3Sopenharmony_ci int PrepareIdxForAsmInterpreterForBaselineWithBaselineCode(); 1904514f5e3Sopenharmony_ci int PrepareIdxForAsmInterpreterForBaselineWithoutBaselineCode(); 1914514f5e3Sopenharmony_ci int PrepareIdxForAsmInterpreterWithBaselineCode(); 1924514f5e3Sopenharmony_ci int PrepareIdxForAsmInterpreterWithoutBaselineCode(); 1934514f5e3Sopenharmony_ci std::vector<GateRef> PrepareArgsForAsmInterpreter(); 1944514f5e3Sopenharmony_ci std::vector<GateRef> PrepareBasicArgsForAsmInterpreter(); 1954514f5e3Sopenharmony_ci std::vector<GateRef> PrepareAppendArgsForAsmInterpreter(); 1964514f5e3Sopenharmony_ci 1974514f5e3Sopenharmony_ci void CallFastBuiltin(Label* notFastBuiltins, Label *exit); 1984514f5e3Sopenharmony_ci std::vector<GateRef> PrepareArgsForFastBuiltin(); 1994514f5e3Sopenharmony_ci std::vector<GateRef> PrepareBasicArgsForFastBuiltin(); 2004514f5e3Sopenharmony_ci std::vector<GateRef> PrepareAppendArgsForFastBuiltin(); 2014514f5e3Sopenharmony_ci bool IsCallModeSupportPGO() const; 2024514f5e3Sopenharmony_ci bool IsCallModeSupportCallBuiltin() const; 2034514f5e3Sopenharmony_ci bool IsSlowAotCall() const; 2044514f5e3Sopenharmony_ci bool IsFastAotCall() const; 2054514f5e3Sopenharmony_ci bool IsSlowAotCallWithBridge() const; 2064514f5e3Sopenharmony_ci bool IsFastAotCallWithBridge() const; 2074514f5e3Sopenharmony_ci bool CheckResultValueChangedWithReturn(GateRef prevResRef) const; 2084514f5e3Sopenharmony_ci void HandleProfileCall(); 2094514f5e3Sopenharmony_ci void HandleProfileNativeCall(); 2104514f5e3Sopenharmony_ci bool IsCallModeGetterSetter(); 2114514f5e3Sopenharmony_ci}; 2124514f5e3Sopenharmony_ci 2134514f5e3Sopenharmony_ci} // panda::ecmascript::kungfu 2144514f5e3Sopenharmony_ci#endif // ECMASCRIPT_COMPILER_CALL_STUB_BUILDER_H