14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2021-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#include "ecmascript/compiler/slowpath_lowering.h" 174514f5e3Sopenharmony_ci 184514f5e3Sopenharmony_ci#include "ecmascript/compiler/bytecodes.h" 194514f5e3Sopenharmony_ci#include "ecmascript/compiler/circuit_builder.h" 204514f5e3Sopenharmony_ci#include "ecmascript/compiler/share_gate_meta_data.h" 214514f5e3Sopenharmony_ci#include "ecmascript/dfx/vm_thread_control.h" 224514f5e3Sopenharmony_ci#include "ecmascript/dfx/vmstat/opt_code_profiler.h" 234514f5e3Sopenharmony_ci#include "ecmascript/js_async_generator_object.h" 244514f5e3Sopenharmony_ci#include "ecmascript/js_generator_object.h" 254514f5e3Sopenharmony_ci#include "ecmascript/js_thread.h" 264514f5e3Sopenharmony_ci#include "ecmascript/jit/jit.h" 274514f5e3Sopenharmony_ci#include "ecmascript/lexical_env.h" 284514f5e3Sopenharmony_ci 294514f5e3Sopenharmony_cinamespace panda::ecmascript::kungfu { 304514f5e3Sopenharmony_ciusing UseIterator = GateAccessor::UseIterator; 314514f5e3Sopenharmony_ci 324514f5e3Sopenharmony_ci#define CREATE_DOUBLE_EXIT(SuccessLabel, FailLabel) \ 334514f5e3Sopenharmony_ci StateDepend successControl; \ 344514f5e3Sopenharmony_ci StateDepend failControl; \ 354514f5e3Sopenharmony_ci builder_.Bind(&SuccessLabel); \ 364514f5e3Sopenharmony_ci { \ 374514f5e3Sopenharmony_ci successControl.SetState(builder_.GetState()); \ 384514f5e3Sopenharmony_ci successControl.SetDepend(builder_.GetDepend()); \ 394514f5e3Sopenharmony_ci } \ 404514f5e3Sopenharmony_ci builder_.Bind(&FailLabel); \ 414514f5e3Sopenharmony_ci { \ 424514f5e3Sopenharmony_ci failControl.SetState(builder_.GetState()); \ 434514f5e3Sopenharmony_ci failControl.SetDepend(builder_.GetDepend()); \ 444514f5e3Sopenharmony_ci } 454514f5e3Sopenharmony_ci 464514f5e3Sopenharmony_civoid SlowPathLowering::CallRuntimeLowering() 474514f5e3Sopenharmony_ci{ 484514f5e3Sopenharmony_ci std::vector<GateRef> gateList; 494514f5e3Sopenharmony_ci circuit_->GetAllGates(gateList); 504514f5e3Sopenharmony_ci 514514f5e3Sopenharmony_ci for (const auto &gate : gateList) { 524514f5e3Sopenharmony_ci auto op = acc_.GetOpCode(gate); 534514f5e3Sopenharmony_ci [[maybe_unused]] auto scopedGate = circuit_->VisitGateBegin(gate); 544514f5e3Sopenharmony_ci switch (op) { 554514f5e3Sopenharmony_ci case OpCode::JS_BYTECODE: 564514f5e3Sopenharmony_ci Lower(gate); 574514f5e3Sopenharmony_ci break; 584514f5e3Sopenharmony_ci case OpCode::GET_EXCEPTION: { 594514f5e3Sopenharmony_ci // initialize label manager 604514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 614514f5e3Sopenharmony_ci LowerExceptionHandler(gate); 624514f5e3Sopenharmony_ci break; 634514f5e3Sopenharmony_ci } 644514f5e3Sopenharmony_ci case OpCode::CONSTRUCT: 654514f5e3Sopenharmony_ci LowerConstruct(gate); 664514f5e3Sopenharmony_ci break; 674514f5e3Sopenharmony_ci case OpCode::CALLINTERNAL: 684514f5e3Sopenharmony_ci LowerCallInternal(gate); 694514f5e3Sopenharmony_ci break; 704514f5e3Sopenharmony_ci case OpCode::CALL_NEW: 714514f5e3Sopenharmony_ci LowerCallNew(gate); 724514f5e3Sopenharmony_ci break; 734514f5e3Sopenharmony_ci case OpCode::TYPEDCALL: 744514f5e3Sopenharmony_ci LowerTypedCall(gate); 754514f5e3Sopenharmony_ci break; 764514f5e3Sopenharmony_ci case OpCode::TYPEDFASTCALL: 774514f5e3Sopenharmony_ci LowerTypedFastCall(gate); 784514f5e3Sopenharmony_ci break; 794514f5e3Sopenharmony_ci case OpCode::CHECK_SAFEPOINT_AND_STACKOVER: 804514f5e3Sopenharmony_ci LowerCheckSafePointAndStackOver(gate); 814514f5e3Sopenharmony_ci break; 824514f5e3Sopenharmony_ci case OpCode::GET_ENV: 834514f5e3Sopenharmony_ci LowerGetEnv(gate); 844514f5e3Sopenharmony_ci break; 854514f5e3Sopenharmony_ci case OpCode::LOOP_EXIT: 864514f5e3Sopenharmony_ci DeleteLoopExit(gate); 874514f5e3Sopenharmony_ci break; 884514f5e3Sopenharmony_ci case OpCode::LOOP_EXIT_VALUE: 894514f5e3Sopenharmony_ci DeleteLoopExitValue(gate); 904514f5e3Sopenharmony_ci break; 914514f5e3Sopenharmony_ci case OpCode::GET_UNSHARED_CONSTPOOL: 924514f5e3Sopenharmony_ci unsharedCP_.emplace_back(gate); 934514f5e3Sopenharmony_ci break; 944514f5e3Sopenharmony_ci default: 954514f5e3Sopenharmony_ci break; 964514f5e3Sopenharmony_ci } 974514f5e3Sopenharmony_ci } 984514f5e3Sopenharmony_ci 994514f5e3Sopenharmony_ci // Make sure all IRs are lowered before lowering the constpool. If constpool is not used in CIR, it will be replaced 1004514f5e3Sopenharmony_ci // by undefined. 1014514f5e3Sopenharmony_ci for (const auto &gate : unsharedCP_) { 1024514f5e3Sopenharmony_ci GateRef sharedConstPool = acc_.GetValueIn(gate, 0); 1034514f5e3Sopenharmony_ci ASSERT(acc_.GetOpCode(sharedConstPool) == OpCode::GET_SHARED_CONSTPOOL); 1044514f5e3Sopenharmony_ci LowerGetUnsharedConstPool(gate); 1054514f5e3Sopenharmony_ci LowerGetSharedConstPool(sharedConstPool); 1064514f5e3Sopenharmony_ci } 1074514f5e3Sopenharmony_ci 1084514f5e3Sopenharmony_ci if (IsLogEnabled()) { 1094514f5e3Sopenharmony_ci LOG_COMPILER(INFO) << " "; 1104514f5e3Sopenharmony_ci LOG_COMPILER(INFO) << "\033[34m" << "=================" 1114514f5e3Sopenharmony_ci << " After slowpath Lowering " 1124514f5e3Sopenharmony_ci << "[" << GetMethodName() << "] " 1134514f5e3Sopenharmony_ci << "=================" << "\033[0m"; 1144514f5e3Sopenharmony_ci circuit_->PrintAllGatesWithBytecode(); 1154514f5e3Sopenharmony_ci LOG_COMPILER(INFO) << "\033[34m" << "=========================== End ===========================" << "\033[0m"; 1164514f5e3Sopenharmony_ci } 1174514f5e3Sopenharmony_ci} 1184514f5e3Sopenharmony_ci 1194514f5e3Sopenharmony_civoid SlowPathLowering::LowerGetEnv(GateRef gate) 1204514f5e3Sopenharmony_ci{ 1214514f5e3Sopenharmony_ci GateRef jsFunc = acc_.GetValueIn(gate, 0); 1224514f5e3Sopenharmony_ci GateRef envOffset = builder_.IntPtr(JSFunction::LEXICAL_ENV_OFFSET); 1234514f5e3Sopenharmony_ci GateRef env = builder_.Load(VariableType::JS_ANY(), jsFunc, envOffset, acc_.GetDep(gate)); 1244514f5e3Sopenharmony_ci acc_.UpdateAllUses(gate, env); 1254514f5e3Sopenharmony_ci acc_.DeleteGate(gate); 1264514f5e3Sopenharmony_ci} 1274514f5e3Sopenharmony_ci 1284514f5e3Sopenharmony_civoid SlowPathLowering::DeleteLoopExit(GateRef gate) 1294514f5e3Sopenharmony_ci{ 1304514f5e3Sopenharmony_ci auto state = acc_.GetState(gate); 1314514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, state, Circuit::NullGate(), Circuit::NullGate()); 1324514f5e3Sopenharmony_ci} 1334514f5e3Sopenharmony_ci 1344514f5e3Sopenharmony_civoid SlowPathLowering::DeleteLoopExitValue(GateRef gate) 1354514f5e3Sopenharmony_ci{ 1364514f5e3Sopenharmony_ci auto state = acc_.GetState(gate); 1374514f5e3Sopenharmony_ci auto value = acc_.GetValueIn(gate, 0); 1384514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, state, Circuit::NullGate(), value); 1394514f5e3Sopenharmony_ci} 1404514f5e3Sopenharmony_ci 1414514f5e3Sopenharmony_civoid SlowPathLowering::LowerToJSCall(GateRef hirGate, const std::vector<GateRef> &args, 1424514f5e3Sopenharmony_ci const std::vector<GateRef> &argsFastCall) 1434514f5e3Sopenharmony_ci{ 1444514f5e3Sopenharmony_ci Label exit(&builder_); 1454514f5e3Sopenharmony_ci DEFVALUE(res, (&builder_), VariableType::JS_ANY(), builder_.Undefined()); 1464514f5e3Sopenharmony_ci GateRef func = args[static_cast<size_t>(CommonArgIdx::FUNC)]; 1474514f5e3Sopenharmony_ci GateRef argc = args[static_cast<size_t>(CommonArgIdx::ACTUAL_ARGC)]; 1484514f5e3Sopenharmony_ci LowerFastCall(hirGate, glue_, func, argc, args, argsFastCall, &res, &exit, false); 1494514f5e3Sopenharmony_ci builder_.Bind(&exit); 1504514f5e3Sopenharmony_ci GateRef stateInGate = builder_.GetState(); 1514514f5e3Sopenharmony_ci GateRef depend = builder_.GetDepend(); 1524514f5e3Sopenharmony_ci ReplaceHirWithPendingException(hirGate, stateInGate, depend, *res); 1534514f5e3Sopenharmony_ci} 1544514f5e3Sopenharmony_ci 1554514f5e3Sopenharmony_civoid SlowPathLowering::ReplaceHirWithPendingException(GateRef hirGate, 1564514f5e3Sopenharmony_ci GateRef state, GateRef depend, GateRef value) 1574514f5e3Sopenharmony_ci{ 1584514f5e3Sopenharmony_ci auto condition = builder_.HasPendingException(glue_); 1594514f5e3Sopenharmony_ci GateRef ifBranch = builder_.Branch(state, condition, 1, BranchWeight::DEOPT_WEIGHT, "checkException"); 1604514f5e3Sopenharmony_ci GateRef ifTrue = builder_.IfTrue(ifBranch); 1614514f5e3Sopenharmony_ci GateRef ifFalse = builder_.IfFalse(ifBranch); 1624514f5e3Sopenharmony_ci GateRef eDepend = builder_.DependRelay(ifTrue, depend); 1634514f5e3Sopenharmony_ci GateRef sDepend = builder_.DependRelay(ifFalse, depend); 1644514f5e3Sopenharmony_ci 1654514f5e3Sopenharmony_ci StateDepend success(ifFalse, sDepend); 1664514f5e3Sopenharmony_ci StateDepend exception(ifTrue, eDepend); 1674514f5e3Sopenharmony_ci acc_.ReplaceHirWithIfBranch(hirGate, success, exception, value); 1684514f5e3Sopenharmony_ci} 1694514f5e3Sopenharmony_ci 1704514f5e3Sopenharmony_ci/* 1714514f5e3Sopenharmony_ci * lower to slowpath call like this pattern: 1724514f5e3Sopenharmony_ci * have throw: 1734514f5e3Sopenharmony_ci * res = Call(...); 1744514f5e3Sopenharmony_ci * if (res == VALUE_EXCEPTION) { 1754514f5e3Sopenharmony_ci * goto exception_handle; 1764514f5e3Sopenharmony_ci * } 1774514f5e3Sopenharmony_ci * Set(res); 1784514f5e3Sopenharmony_ci * 1794514f5e3Sopenharmony_ci * no throw: 1804514f5e3Sopenharmony_ci * res = Call(...); 1814514f5e3Sopenharmony_ci * Set(res); 1824514f5e3Sopenharmony_ci */ 1834514f5e3Sopenharmony_civoid SlowPathLowering::ReplaceHirWithValue(GateRef hirGate, GateRef value, bool noThrow) 1844514f5e3Sopenharmony_ci{ 1854514f5e3Sopenharmony_ci if (!noThrow) { 1864514f5e3Sopenharmony_ci GateRef state = builder_.GetState(); 1874514f5e3Sopenharmony_ci // copy depend-wire of hirGate to value 1884514f5e3Sopenharmony_ci GateRef depend = builder_.GetDepend(); 1894514f5e3Sopenharmony_ci // exception value 1904514f5e3Sopenharmony_ci GateRef exceptionVal = builder_.ExceptionConstant(); 1914514f5e3Sopenharmony_ci // compare with trampolines result 1924514f5e3Sopenharmony_ci GateRef equal = builder_.Equal(value, exceptionVal); 1934514f5e3Sopenharmony_ci auto ifBranch = builder_.Branch(state, equal, 1, BranchWeight::DEOPT_WEIGHT, "checkException"); 1944514f5e3Sopenharmony_ci 1954514f5e3Sopenharmony_ci GateRef ifTrue = builder_.IfTrue(ifBranch); 1964514f5e3Sopenharmony_ci GateRef ifFalse = builder_.IfFalse(ifBranch); 1974514f5e3Sopenharmony_ci GateRef eDepend = builder_.DependRelay(ifTrue, depend); 1984514f5e3Sopenharmony_ci GateRef sDepend = builder_.DependRelay(ifFalse, depend); 1994514f5e3Sopenharmony_ci StateDepend success(ifFalse, sDepend); 2004514f5e3Sopenharmony_ci StateDepend exception(ifTrue, eDepend); 2014514f5e3Sopenharmony_ci acc_.ReplaceHirWithIfBranch(hirGate, success, exception, value); 2024514f5e3Sopenharmony_ci } else { 2034514f5e3Sopenharmony_ci acc_.ReplaceHirDirectly(hirGate, builder_.GetStateDepend(), value); 2044514f5e3Sopenharmony_ci } 2054514f5e3Sopenharmony_ci} 2064514f5e3Sopenharmony_ci 2074514f5e3Sopenharmony_ci/* 2084514f5e3Sopenharmony_ci * lower to throw call like this pattern: 2094514f5e3Sopenharmony_ci * Call(...); 2104514f5e3Sopenharmony_ci * goto exception_handle; 2114514f5e3Sopenharmony_ci * 2124514f5e3Sopenharmony_ci */ 2134514f5e3Sopenharmony_civoid SlowPathLowering::ReplaceHirToThrowCall(GateRef hirGate, GateRef value) 2144514f5e3Sopenharmony_ci{ 2154514f5e3Sopenharmony_ci auto condition = builder_.HasPendingException(glue_); 2164514f5e3Sopenharmony_ci GateRef state = builder_.GetState(); 2174514f5e3Sopenharmony_ci GateRef depend = builder_.GetDepend(); 2184514f5e3Sopenharmony_ci GateRef ifBranch = builder_.Branch(state, condition, BranchWeight::DEOPT_WEIGHT, 1, "checkException"); 2194514f5e3Sopenharmony_ci GateRef ifTrue = builder_.IfTrue(ifBranch); 2204514f5e3Sopenharmony_ci GateRef ifFalse = builder_.IfFalse(ifBranch); 2214514f5e3Sopenharmony_ci GateRef eDepend = builder_.DependRelay(ifTrue, depend); 2224514f5e3Sopenharmony_ci GateRef sDepend = builder_.DependRelay(ifFalse, depend); 2234514f5e3Sopenharmony_ci 2244514f5e3Sopenharmony_ci StateDepend success(ifFalse, sDepend); 2254514f5e3Sopenharmony_ci StateDepend exception(ifTrue, eDepend); 2264514f5e3Sopenharmony_ci acc_.ReplaceHirWithIfBranch(hirGate, success, exception, value); 2274514f5e3Sopenharmony_ci} 2284514f5e3Sopenharmony_ci 2294514f5e3Sopenharmony_civoid SlowPathLowering::Lower(GateRef gate) 2304514f5e3Sopenharmony_ci{ 2314514f5e3Sopenharmony_ci EcmaOpcode ecmaOpcode = acc_.GetByteCodeOpcode(gate); 2324514f5e3Sopenharmony_ci // initialize label manager 2334514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 2344514f5e3Sopenharmony_ci AddProfiling(gate); 2354514f5e3Sopenharmony_ci switch (ecmaOpcode) { 2364514f5e3Sopenharmony_ci case EcmaOpcode::CALLARG0_IMM8: 2374514f5e3Sopenharmony_ci LowerCallArg0(gate); 2384514f5e3Sopenharmony_ci break; 2394514f5e3Sopenharmony_ci case EcmaOpcode::CALLTHIS0_IMM8_V8: 2404514f5e3Sopenharmony_ci LowerCallthis0Imm8V8(gate); 2414514f5e3Sopenharmony_ci break; 2424514f5e3Sopenharmony_ci case EcmaOpcode::CALLARG1_IMM8_V8: 2434514f5e3Sopenharmony_ci LowerCallArg1Imm8V8(gate); 2444514f5e3Sopenharmony_ci break; 2454514f5e3Sopenharmony_ci case EcmaOpcode::WIDE_CALLRANGE_PREF_IMM16_V8: 2464514f5e3Sopenharmony_ci LowerWideCallrangePrefImm16V8(gate); 2474514f5e3Sopenharmony_ci break; 2484514f5e3Sopenharmony_ci case EcmaOpcode::CALLTHIS1_IMM8_V8_V8: 2494514f5e3Sopenharmony_ci LowerCallThisArg1(gate); 2504514f5e3Sopenharmony_ci break; 2514514f5e3Sopenharmony_ci case EcmaOpcode::CALLARGS2_IMM8_V8_V8: 2524514f5e3Sopenharmony_ci LowerCallargs2Imm8V8V8(gate); 2534514f5e3Sopenharmony_ci break; 2544514f5e3Sopenharmony_ci case EcmaOpcode::CALLTHIS2_IMM8_V8_V8_V8: 2554514f5e3Sopenharmony_ci LowerCallthis2Imm8V8V8V8(gate); 2564514f5e3Sopenharmony_ci break; 2574514f5e3Sopenharmony_ci case EcmaOpcode::CALLARGS3_IMM8_V8_V8_V8: 2584514f5e3Sopenharmony_ci LowerCallargs3Imm8V8V8(gate); 2594514f5e3Sopenharmony_ci break; 2604514f5e3Sopenharmony_ci case EcmaOpcode::CALLTHIS3_IMM8_V8_V8_V8_V8: 2614514f5e3Sopenharmony_ci LowerCallthis3Imm8V8V8V8V8(gate); 2624514f5e3Sopenharmony_ci break; 2634514f5e3Sopenharmony_ci case EcmaOpcode::CALLTHISRANGE_IMM8_IMM8_V8: 2644514f5e3Sopenharmony_ci LowerCallthisrangeImm8Imm8V8(gate); 2654514f5e3Sopenharmony_ci break; 2664514f5e3Sopenharmony_ci case EcmaOpcode::WIDE_CALLTHISRANGE_PREF_IMM16_V8: 2674514f5e3Sopenharmony_ci LowerWideCallthisrangePrefImm16V8(gate); 2684514f5e3Sopenharmony_ci break; 2694514f5e3Sopenharmony_ci case EcmaOpcode::APPLY_IMM8_V8_V8: 2704514f5e3Sopenharmony_ci LowerCallSpread(gate); 2714514f5e3Sopenharmony_ci break; 2724514f5e3Sopenharmony_ci case EcmaOpcode::CALLRANGE_IMM8_IMM8_V8: 2734514f5e3Sopenharmony_ci LowerCallrangeImm8Imm8V8(gate); 2744514f5e3Sopenharmony_ci break; 2754514f5e3Sopenharmony_ci case EcmaOpcode::GETUNMAPPEDARGS: 2764514f5e3Sopenharmony_ci LowerGetUnmappedArgs(gate); 2774514f5e3Sopenharmony_ci break; 2784514f5e3Sopenharmony_ci case EcmaOpcode::ASYNCFUNCTIONENTER: 2794514f5e3Sopenharmony_ci LowerAsyncFunctionEnter(gate); 2804514f5e3Sopenharmony_ci break; 2814514f5e3Sopenharmony_ci case EcmaOpcode::INC_IMM8: 2824514f5e3Sopenharmony_ci LowerInc(gate); 2834514f5e3Sopenharmony_ci break; 2844514f5e3Sopenharmony_ci case EcmaOpcode::DEC_IMM8: 2854514f5e3Sopenharmony_ci LowerDec(gate); 2864514f5e3Sopenharmony_ci break; 2874514f5e3Sopenharmony_ci case EcmaOpcode::GETPROPITERATOR: 2884514f5e3Sopenharmony_ci LowerGetPropIterator(gate); 2894514f5e3Sopenharmony_ci break; 2904514f5e3Sopenharmony_ci case EcmaOpcode::RESUMEGENERATOR: 2914514f5e3Sopenharmony_ci LowerResumeGenerator(gate); 2924514f5e3Sopenharmony_ci break; 2934514f5e3Sopenharmony_ci case EcmaOpcode::GETRESUMEMODE: 2944514f5e3Sopenharmony_ci LowerGetResumeMode(gate); 2954514f5e3Sopenharmony_ci break; 2964514f5e3Sopenharmony_ci case EcmaOpcode::CLOSEITERATOR_IMM8_V8: 2974514f5e3Sopenharmony_ci case EcmaOpcode::CLOSEITERATOR_IMM16_V8: 2984514f5e3Sopenharmony_ci LowerCloseIterator(gate); 2994514f5e3Sopenharmony_ci break; 3004514f5e3Sopenharmony_ci case EcmaOpcode::ADD2_IMM8_V8: 3014514f5e3Sopenharmony_ci LowerAdd2(gate); 3024514f5e3Sopenharmony_ci break; 3034514f5e3Sopenharmony_ci case EcmaOpcode::SUB2_IMM8_V8: 3044514f5e3Sopenharmony_ci LowerSub2(gate); 3054514f5e3Sopenharmony_ci break; 3064514f5e3Sopenharmony_ci case EcmaOpcode::MUL2_IMM8_V8: 3074514f5e3Sopenharmony_ci LowerMul2(gate); 3084514f5e3Sopenharmony_ci break; 3094514f5e3Sopenharmony_ci case EcmaOpcode::DIV2_IMM8_V8: 3104514f5e3Sopenharmony_ci LowerDiv2(gate); 3114514f5e3Sopenharmony_ci break; 3124514f5e3Sopenharmony_ci case EcmaOpcode::MOD2_IMM8_V8: 3134514f5e3Sopenharmony_ci LowerMod2(gate); 3144514f5e3Sopenharmony_ci break; 3154514f5e3Sopenharmony_ci case EcmaOpcode::EQ_IMM8_V8: 3164514f5e3Sopenharmony_ci LowerEq(gate); 3174514f5e3Sopenharmony_ci break; 3184514f5e3Sopenharmony_ci case EcmaOpcode::NOTEQ_IMM8_V8: 3194514f5e3Sopenharmony_ci LowerNotEq(gate); 3204514f5e3Sopenharmony_ci break; 3214514f5e3Sopenharmony_ci case EcmaOpcode::LESS_IMM8_V8: 3224514f5e3Sopenharmony_ci LowerLess(gate); 3234514f5e3Sopenharmony_ci break; 3244514f5e3Sopenharmony_ci case EcmaOpcode::LESSEQ_IMM8_V8: 3254514f5e3Sopenharmony_ci LowerLessEq(gate); 3264514f5e3Sopenharmony_ci break; 3274514f5e3Sopenharmony_ci case EcmaOpcode::GREATER_IMM8_V8: 3284514f5e3Sopenharmony_ci LowerGreater(gate); 3294514f5e3Sopenharmony_ci break; 3304514f5e3Sopenharmony_ci case EcmaOpcode::GREATEREQ_IMM8_V8: 3314514f5e3Sopenharmony_ci LowerGreaterEq(gate); 3324514f5e3Sopenharmony_ci break; 3334514f5e3Sopenharmony_ci case EcmaOpcode::CREATEITERRESULTOBJ_V8_V8: 3344514f5e3Sopenharmony_ci LowerCreateIterResultObj(gate); 3354514f5e3Sopenharmony_ci break; 3364514f5e3Sopenharmony_ci case EcmaOpcode::SUSPENDGENERATOR_V8: 3374514f5e3Sopenharmony_ci LowerSuspendGenerator(gate); 3384514f5e3Sopenharmony_ci break; 3394514f5e3Sopenharmony_ci case EcmaOpcode::ASYNCFUNCTIONAWAITUNCAUGHT_V8: 3404514f5e3Sopenharmony_ci LowerAsyncFunctionAwaitUncaught(gate); 3414514f5e3Sopenharmony_ci break; 3424514f5e3Sopenharmony_ci case EcmaOpcode::ASYNCFUNCTIONRESOLVE_V8: 3434514f5e3Sopenharmony_ci LowerAsyncFunctionResolve(gate); 3444514f5e3Sopenharmony_ci break; 3454514f5e3Sopenharmony_ci case EcmaOpcode::ASYNCFUNCTIONREJECT_V8: 3464514f5e3Sopenharmony_ci LowerAsyncFunctionReject(gate); 3474514f5e3Sopenharmony_ci break; 3484514f5e3Sopenharmony_ci case EcmaOpcode::TRYLDGLOBALBYNAME_IMM8_ID16: 3494514f5e3Sopenharmony_ci case EcmaOpcode::TRYLDGLOBALBYNAME_IMM16_ID16: 3504514f5e3Sopenharmony_ci LowerTryLdGlobalByName(gate); 3514514f5e3Sopenharmony_ci break; 3524514f5e3Sopenharmony_ci case EcmaOpcode::STGLOBALVAR_IMM16_ID16: 3534514f5e3Sopenharmony_ci LowerStGlobalVar(gate); 3544514f5e3Sopenharmony_ci break; 3554514f5e3Sopenharmony_ci case EcmaOpcode::GETITERATOR_IMM8: 3564514f5e3Sopenharmony_ci case EcmaOpcode::GETITERATOR_IMM16: 3574514f5e3Sopenharmony_ci LowerGetIterator(gate); 3584514f5e3Sopenharmony_ci break; 3594514f5e3Sopenharmony_ci case EcmaOpcode::GETASYNCITERATOR_IMM8: 3604514f5e3Sopenharmony_ci LowerGetAsyncIterator(gate); 3614514f5e3Sopenharmony_ci break; 3624514f5e3Sopenharmony_ci case EcmaOpcode::NEWOBJAPPLY_IMM8_V8: 3634514f5e3Sopenharmony_ci case EcmaOpcode::NEWOBJAPPLY_IMM16_V8: 3644514f5e3Sopenharmony_ci LowerNewObjApply(gate); 3654514f5e3Sopenharmony_ci break; 3664514f5e3Sopenharmony_ci case EcmaOpcode::THROW_PREF_NONE: 3674514f5e3Sopenharmony_ci LowerThrow(gate); 3684514f5e3Sopenharmony_ci break; 3694514f5e3Sopenharmony_ci case EcmaOpcode::TYPEOF_IMM8: 3704514f5e3Sopenharmony_ci case EcmaOpcode::TYPEOF_IMM16: 3714514f5e3Sopenharmony_ci LowerTypeof(gate); 3724514f5e3Sopenharmony_ci break; 3734514f5e3Sopenharmony_ci case EcmaOpcode::THROW_CONSTASSIGNMENT_PREF_V8: 3744514f5e3Sopenharmony_ci LowerThrowConstAssignment(gate); 3754514f5e3Sopenharmony_ci break; 3764514f5e3Sopenharmony_ci case EcmaOpcode::THROW_NOTEXISTS_PREF_NONE: 3774514f5e3Sopenharmony_ci LowerThrowThrowNotExists(gate); 3784514f5e3Sopenharmony_ci break; 3794514f5e3Sopenharmony_ci case EcmaOpcode::THROW_PATTERNNONCOERCIBLE_PREF_NONE: 3804514f5e3Sopenharmony_ci LowerThrowPatternNonCoercible(gate); 3814514f5e3Sopenharmony_ci break; 3824514f5e3Sopenharmony_ci case EcmaOpcode::THROW_IFNOTOBJECT_PREF_V8: 3834514f5e3Sopenharmony_ci LowerThrowIfNotObject(gate); 3844514f5e3Sopenharmony_ci break; 3854514f5e3Sopenharmony_ci case EcmaOpcode::THROW_UNDEFINEDIFHOLE_PREF_V8_V8: 3864514f5e3Sopenharmony_ci LowerThrowUndefinedIfHole(gate); 3874514f5e3Sopenharmony_ci break; 3884514f5e3Sopenharmony_ci case EcmaOpcode::THROW_UNDEFINEDIFHOLEWITHNAME_PREF_ID16: 3894514f5e3Sopenharmony_ci LowerThrowUndefinedIfHoleWithName(gate); 3904514f5e3Sopenharmony_ci break; 3914514f5e3Sopenharmony_ci case EcmaOpcode::THROW_IFSUPERNOTCORRECTCALL_PREF_IMM8: 3924514f5e3Sopenharmony_ci case EcmaOpcode::THROW_IFSUPERNOTCORRECTCALL_PREF_IMM16: 3934514f5e3Sopenharmony_ci LowerThrowIfSuperNotCorrectCall(gate); 3944514f5e3Sopenharmony_ci break; 3954514f5e3Sopenharmony_ci case EcmaOpcode::THROW_DELETESUPERPROPERTY_PREF_NONE: 3964514f5e3Sopenharmony_ci LowerThrowDeleteSuperProperty(gate); 3974514f5e3Sopenharmony_ci break; 3984514f5e3Sopenharmony_ci case EcmaOpcode::LDSYMBOL: 3994514f5e3Sopenharmony_ci LowerLdSymbol(gate); 4004514f5e3Sopenharmony_ci break; 4014514f5e3Sopenharmony_ci case EcmaOpcode::LDGLOBAL: 4024514f5e3Sopenharmony_ci LowerLdGlobal(gate); 4034514f5e3Sopenharmony_ci break; 4044514f5e3Sopenharmony_ci case EcmaOpcode::TONUMBER_IMM8: 4054514f5e3Sopenharmony_ci LowerToNumber(gate); 4064514f5e3Sopenharmony_ci break; 4074514f5e3Sopenharmony_ci case EcmaOpcode::NEG_IMM8: 4084514f5e3Sopenharmony_ci LowerNeg(gate); 4094514f5e3Sopenharmony_ci break; 4104514f5e3Sopenharmony_ci case EcmaOpcode::NOT_IMM8: 4114514f5e3Sopenharmony_ci LowerNot(gate); 4124514f5e3Sopenharmony_ci break; 4134514f5e3Sopenharmony_ci case EcmaOpcode::SHL2_IMM8_V8: 4144514f5e3Sopenharmony_ci LowerShl2(gate); 4154514f5e3Sopenharmony_ci break; 4164514f5e3Sopenharmony_ci case EcmaOpcode::SHR2_IMM8_V8: 4174514f5e3Sopenharmony_ci LowerShr2(gate); 4184514f5e3Sopenharmony_ci break; 4194514f5e3Sopenharmony_ci case EcmaOpcode::ASHR2_IMM8_V8: 4204514f5e3Sopenharmony_ci LowerAshr2(gate); 4214514f5e3Sopenharmony_ci break; 4224514f5e3Sopenharmony_ci case EcmaOpcode::AND2_IMM8_V8: 4234514f5e3Sopenharmony_ci LowerAnd2(gate); 4244514f5e3Sopenharmony_ci break; 4254514f5e3Sopenharmony_ci case EcmaOpcode::OR2_IMM8_V8: 4264514f5e3Sopenharmony_ci LowerOr2(gate); 4274514f5e3Sopenharmony_ci break; 4284514f5e3Sopenharmony_ci case EcmaOpcode::XOR2_IMM8_V8: 4294514f5e3Sopenharmony_ci LowerXor2(gate); 4304514f5e3Sopenharmony_ci break; 4314514f5e3Sopenharmony_ci case EcmaOpcode::DELOBJPROP_V8: 4324514f5e3Sopenharmony_ci LowerDelObjProp(gate); 4334514f5e3Sopenharmony_ci break; 4344514f5e3Sopenharmony_ci case EcmaOpcode::DEFINEMETHOD_IMM8_ID16_IMM8: 4354514f5e3Sopenharmony_ci case EcmaOpcode::DEFINEMETHOD_IMM16_ID16_IMM8: 4364514f5e3Sopenharmony_ci LowerDefineMethod(gate); 4374514f5e3Sopenharmony_ci break; 4384514f5e3Sopenharmony_ci case EcmaOpcode::EXP_IMM8_V8: 4394514f5e3Sopenharmony_ci LowerExp(gate); 4404514f5e3Sopenharmony_ci break; 4414514f5e3Sopenharmony_ci case EcmaOpcode::ISIN_IMM8_V8: 4424514f5e3Sopenharmony_ci LowerIsIn(gate); 4434514f5e3Sopenharmony_ci break; 4444514f5e3Sopenharmony_ci case EcmaOpcode::INSTANCEOF_IMM8_V8: 4454514f5e3Sopenharmony_ci LowerInstanceof(gate); 4464514f5e3Sopenharmony_ci break; 4474514f5e3Sopenharmony_ci case EcmaOpcode::STRICTNOTEQ_IMM8_V8: 4484514f5e3Sopenharmony_ci LowerFastStrictNotEqual(gate); 4494514f5e3Sopenharmony_ci break; 4504514f5e3Sopenharmony_ci case EcmaOpcode::STRICTEQ_IMM8_V8: 4514514f5e3Sopenharmony_ci LowerFastStrictEqual(gate); 4524514f5e3Sopenharmony_ci break; 4534514f5e3Sopenharmony_ci case EcmaOpcode::CREATEEMPTYARRAY_IMM8: 4544514f5e3Sopenharmony_ci case EcmaOpcode::CREATEEMPTYARRAY_IMM16: 4554514f5e3Sopenharmony_ci LowerCreateEmptyArray(gate); 4564514f5e3Sopenharmony_ci break; 4574514f5e3Sopenharmony_ci case EcmaOpcode::CREATEEMPTYOBJECT: 4584514f5e3Sopenharmony_ci LowerCreateEmptyObject(gate); 4594514f5e3Sopenharmony_ci break; 4604514f5e3Sopenharmony_ci case EcmaOpcode::CREATEOBJECTWITHBUFFER_IMM8_ID16: 4614514f5e3Sopenharmony_ci case EcmaOpcode::CREATEOBJECTWITHBUFFER_IMM16_ID16: 4624514f5e3Sopenharmony_ci LowerCreateObjectWithBuffer(gate); 4634514f5e3Sopenharmony_ci break; 4644514f5e3Sopenharmony_ci case EcmaOpcode::CREATEARRAYWITHBUFFER_IMM8_ID16: 4654514f5e3Sopenharmony_ci case EcmaOpcode::CREATEARRAYWITHBUFFER_IMM16_ID16: 4664514f5e3Sopenharmony_ci LowerCreateArrayWithBuffer(gate); 4674514f5e3Sopenharmony_ci break; 4684514f5e3Sopenharmony_ci case EcmaOpcode::STMODULEVAR_IMM8: 4694514f5e3Sopenharmony_ci case EcmaOpcode::WIDE_STMODULEVAR_PREF_IMM16: 4704514f5e3Sopenharmony_ci LowerStModuleVar(gate); 4714514f5e3Sopenharmony_ci break; 4724514f5e3Sopenharmony_ci case EcmaOpcode::SETGENERATORSTATE_IMM8: 4734514f5e3Sopenharmony_ci LowerSetGeneratorState(gate); 4744514f5e3Sopenharmony_ci break; 4754514f5e3Sopenharmony_ci case EcmaOpcode::GETTEMPLATEOBJECT_IMM8: 4764514f5e3Sopenharmony_ci case EcmaOpcode::GETTEMPLATEOBJECT_IMM16: 4774514f5e3Sopenharmony_ci LowerGetTemplateObject(gate); 4784514f5e3Sopenharmony_ci break; 4794514f5e3Sopenharmony_ci case EcmaOpcode::SETOBJECTWITHPROTO_IMM8_V8: 4804514f5e3Sopenharmony_ci case EcmaOpcode::SETOBJECTWITHPROTO_IMM16_V8: 4814514f5e3Sopenharmony_ci LowerSetObjectWithProto(gate); 4824514f5e3Sopenharmony_ci break; 4834514f5e3Sopenharmony_ci case EcmaOpcode::LDBIGINT_ID16: 4844514f5e3Sopenharmony_ci LowerLdBigInt(gate); 4854514f5e3Sopenharmony_ci break; 4864514f5e3Sopenharmony_ci case EcmaOpcode::TONUMERIC_IMM8: 4874514f5e3Sopenharmony_ci LowerToNumeric(gate); 4884514f5e3Sopenharmony_ci break; 4894514f5e3Sopenharmony_ci case EcmaOpcode::DYNAMICIMPORT: 4904514f5e3Sopenharmony_ci LowerDynamicImport(gate); 4914514f5e3Sopenharmony_ci break; 4924514f5e3Sopenharmony_ci case EcmaOpcode::LDEXTERNALMODULEVAR_IMM8: 4934514f5e3Sopenharmony_ci case EcmaOpcode::WIDE_LDEXTERNALMODULEVAR_PREF_IMM16: 4944514f5e3Sopenharmony_ci LowerExternalModule(gate); 4954514f5e3Sopenharmony_ci break; 4964514f5e3Sopenharmony_ci case EcmaOpcode::GETMODULENAMESPACE_IMM8: 4974514f5e3Sopenharmony_ci case EcmaOpcode::WIDE_GETMODULENAMESPACE_PREF_IMM16: 4984514f5e3Sopenharmony_ci LowerGetModuleNamespace(gate); 4994514f5e3Sopenharmony_ci break; 5004514f5e3Sopenharmony_ci case EcmaOpcode::NEWOBJRANGE_IMM8_IMM8_V8: 5014514f5e3Sopenharmony_ci case EcmaOpcode::NEWOBJRANGE_IMM16_IMM8_V8: 5024514f5e3Sopenharmony_ci case EcmaOpcode::WIDE_NEWOBJRANGE_PREF_IMM16_V8: 5034514f5e3Sopenharmony_ci LowerNewObjRange(gate); 5044514f5e3Sopenharmony_ci break; 5054514f5e3Sopenharmony_ci case EcmaOpcode::JEQZ_IMM8: 5064514f5e3Sopenharmony_ci case EcmaOpcode::JEQZ_IMM16: 5074514f5e3Sopenharmony_ci case EcmaOpcode::JEQZ_IMM32: 5084514f5e3Sopenharmony_ci LowerConditionJump(gate, true); 5094514f5e3Sopenharmony_ci break; 5104514f5e3Sopenharmony_ci case EcmaOpcode::JNEZ_IMM8: 5114514f5e3Sopenharmony_ci case EcmaOpcode::JNEZ_IMM16: 5124514f5e3Sopenharmony_ci case EcmaOpcode::JNEZ_IMM32: 5134514f5e3Sopenharmony_ci LowerConditionJump(gate, false); 5144514f5e3Sopenharmony_ci break; 5154514f5e3Sopenharmony_ci case EcmaOpcode::SUPERCALLTHISRANGE_IMM8_IMM8_V8: 5164514f5e3Sopenharmony_ci case EcmaOpcode::WIDE_SUPERCALLTHISRANGE_PREF_IMM16_V8: 5174514f5e3Sopenharmony_ci LowerSuperCall(gate); 5184514f5e3Sopenharmony_ci break; 5194514f5e3Sopenharmony_ci case EcmaOpcode::SUPERCALLARROWRANGE_IMM8_IMM8_V8: 5204514f5e3Sopenharmony_ci case EcmaOpcode::WIDE_SUPERCALLARROWRANGE_PREF_IMM16_V8: 5214514f5e3Sopenharmony_ci LowerSuperCallArrow(gate); 5224514f5e3Sopenharmony_ci break; 5234514f5e3Sopenharmony_ci case EcmaOpcode::SUPERCALLSPREAD_IMM8_V8: 5244514f5e3Sopenharmony_ci LowerSuperCallSpread(gate); 5254514f5e3Sopenharmony_ci break; 5264514f5e3Sopenharmony_ci case EcmaOpcode::CALLRUNTIME_SUPERCALLFORWARDALLARGS_PREF_V8: 5274514f5e3Sopenharmony_ci LowerSuperCallForwardAllArgs(gate); 5284514f5e3Sopenharmony_ci break; 5294514f5e3Sopenharmony_ci case EcmaOpcode::ISTRUE: 5304514f5e3Sopenharmony_ci case EcmaOpcode::CALLRUNTIME_ISTRUE_PREF_IMM8: 5314514f5e3Sopenharmony_ci LowerIsTrueOrFalse(gate, true); 5324514f5e3Sopenharmony_ci break; 5334514f5e3Sopenharmony_ci case EcmaOpcode::ISFALSE: 5344514f5e3Sopenharmony_ci case EcmaOpcode::CALLRUNTIME_ISFALSE_PREF_IMM8: 5354514f5e3Sopenharmony_ci LowerIsTrueOrFalse(gate, false); 5364514f5e3Sopenharmony_ci break; 5374514f5e3Sopenharmony_ci case EcmaOpcode::GETNEXTPROPNAME_V8: 5384514f5e3Sopenharmony_ci LowerGetNextPropName(gate); 5394514f5e3Sopenharmony_ci break; 5404514f5e3Sopenharmony_ci case EcmaOpcode::COPYDATAPROPERTIES_V8: 5414514f5e3Sopenharmony_ci LowerCopyDataProperties(gate); 5424514f5e3Sopenharmony_ci break; 5434514f5e3Sopenharmony_ci case EcmaOpcode::CREATEOBJECTWITHEXCLUDEDKEYS_IMM8_V8_V8: 5444514f5e3Sopenharmony_ci case EcmaOpcode::WIDE_CREATEOBJECTWITHEXCLUDEDKEYS_PREF_IMM16_V8_V8: 5454514f5e3Sopenharmony_ci LowerCreateObjectWithExcludedKeys(gate); 5464514f5e3Sopenharmony_ci break; 5474514f5e3Sopenharmony_ci case EcmaOpcode::CREATEREGEXPWITHLITERAL_IMM8_ID16_IMM8: 5484514f5e3Sopenharmony_ci case EcmaOpcode::CREATEREGEXPWITHLITERAL_IMM16_ID16_IMM8: 5494514f5e3Sopenharmony_ci LowerCreateRegExpWithLiteral(gate); 5504514f5e3Sopenharmony_ci break; 5514514f5e3Sopenharmony_ci case EcmaOpcode::STOWNBYVALUE_IMM8_V8_V8: 5524514f5e3Sopenharmony_ci case EcmaOpcode::STOWNBYVALUE_IMM16_V8_V8: 5534514f5e3Sopenharmony_ci LowerStOwnByValue(gate); 5544514f5e3Sopenharmony_ci break; 5554514f5e3Sopenharmony_ci case EcmaOpcode::STOWNBYINDEX_IMM8_V8_IMM16: 5564514f5e3Sopenharmony_ci case EcmaOpcode::STOWNBYINDEX_IMM16_V8_IMM16: 5574514f5e3Sopenharmony_ci case EcmaOpcode::WIDE_STOWNBYINDEX_PREF_V8_IMM32: 5584514f5e3Sopenharmony_ci LowerStOwnByIndex(gate); 5594514f5e3Sopenharmony_ci break; 5604514f5e3Sopenharmony_ci case EcmaOpcode::STOWNBYNAME_IMM8_ID16_V8: 5614514f5e3Sopenharmony_ci case EcmaOpcode::STOWNBYNAME_IMM16_ID16_V8: 5624514f5e3Sopenharmony_ci LowerStOwnByName(gate); 5634514f5e3Sopenharmony_ci break; 5644514f5e3Sopenharmony_ci case EcmaOpcode::NEWLEXENV_IMM8: 5654514f5e3Sopenharmony_ci case EcmaOpcode::WIDE_NEWLEXENV_PREF_IMM16: 5664514f5e3Sopenharmony_ci LowerNewLexicalEnv(gate); 5674514f5e3Sopenharmony_ci break; 5684514f5e3Sopenharmony_ci case EcmaOpcode::NEWLEXENVWITHNAME_IMM8_ID16: 5694514f5e3Sopenharmony_ci case EcmaOpcode::WIDE_NEWLEXENVWITHNAME_PREF_IMM16_ID16: 5704514f5e3Sopenharmony_ci LowerNewLexicalEnvWithName(gate); 5714514f5e3Sopenharmony_ci break; 5724514f5e3Sopenharmony_ci case EcmaOpcode::POPLEXENV: 5734514f5e3Sopenharmony_ci LowerPopLexicalEnv(gate); 5744514f5e3Sopenharmony_ci break; 5754514f5e3Sopenharmony_ci case EcmaOpcode::LDSUPERBYVALUE_IMM8_V8: 5764514f5e3Sopenharmony_ci case EcmaOpcode::LDSUPERBYVALUE_IMM16_V8: 5774514f5e3Sopenharmony_ci LowerLdSuperByValue(gate); 5784514f5e3Sopenharmony_ci break; 5794514f5e3Sopenharmony_ci case EcmaOpcode::STSUPERBYVALUE_IMM16_V8_V8: 5804514f5e3Sopenharmony_ci case EcmaOpcode::STSUPERBYVALUE_IMM8_V8_V8: 5814514f5e3Sopenharmony_ci LowerStSuperByValue(gate); 5824514f5e3Sopenharmony_ci break; 5834514f5e3Sopenharmony_ci case EcmaOpcode::TRYSTGLOBALBYNAME_IMM8_ID16: 5844514f5e3Sopenharmony_ci case EcmaOpcode::TRYSTGLOBALBYNAME_IMM16_ID16: 5854514f5e3Sopenharmony_ci LowerTryStGlobalByName(gate); 5864514f5e3Sopenharmony_ci break; 5874514f5e3Sopenharmony_ci case EcmaOpcode::STCONSTTOGLOBALRECORD_IMM16_ID16: 5884514f5e3Sopenharmony_ci LowerStConstToGlobalRecord(gate, true); 5894514f5e3Sopenharmony_ci break; 5904514f5e3Sopenharmony_ci case EcmaOpcode::STTOGLOBALRECORD_IMM16_ID16: 5914514f5e3Sopenharmony_ci LowerStConstToGlobalRecord(gate, false); 5924514f5e3Sopenharmony_ci break; 5934514f5e3Sopenharmony_ci case EcmaOpcode::STOWNBYVALUEWITHNAMESET_IMM8_V8_V8: 5944514f5e3Sopenharmony_ci case EcmaOpcode::STOWNBYVALUEWITHNAMESET_IMM16_V8_V8: 5954514f5e3Sopenharmony_ci LowerStOwnByValueWithNameSet(gate); 5964514f5e3Sopenharmony_ci break; 5974514f5e3Sopenharmony_ci case EcmaOpcode::STOWNBYNAMEWITHNAMESET_IMM8_ID16_V8: 5984514f5e3Sopenharmony_ci case EcmaOpcode::STOWNBYNAMEWITHNAMESET_IMM16_ID16_V8: 5994514f5e3Sopenharmony_ci LowerStOwnByNameWithNameSet(gate); 6004514f5e3Sopenharmony_ci break; 6014514f5e3Sopenharmony_ci case EcmaOpcode::LDGLOBALVAR_IMM16_ID16: 6024514f5e3Sopenharmony_ci LowerLdGlobalVar(gate); 6034514f5e3Sopenharmony_ci break; 6044514f5e3Sopenharmony_ci case EcmaOpcode::LDOBJBYNAME_IMM8_ID16: 6054514f5e3Sopenharmony_ci case EcmaOpcode::LDOBJBYNAME_IMM16_ID16: 6064514f5e3Sopenharmony_ci LowerLdObjByName(gate); 6074514f5e3Sopenharmony_ci break; 6084514f5e3Sopenharmony_ci case EcmaOpcode::STOBJBYNAME_IMM8_ID16_V8: 6094514f5e3Sopenharmony_ci case EcmaOpcode::STOBJBYNAME_IMM16_ID16_V8: 6104514f5e3Sopenharmony_ci LowerStObjByName(gate, false); 6114514f5e3Sopenharmony_ci break; 6124514f5e3Sopenharmony_ci case EcmaOpcode::DEFINEGETTERSETTERBYVALUE_V8_V8_V8_V8: 6134514f5e3Sopenharmony_ci LowerDefineGetterSetterByValue(gate); 6144514f5e3Sopenharmony_ci break; 6154514f5e3Sopenharmony_ci case EcmaOpcode::LDOBJBYINDEX_IMM8_IMM16: 6164514f5e3Sopenharmony_ci case EcmaOpcode::LDOBJBYINDEX_IMM16_IMM16: 6174514f5e3Sopenharmony_ci case EcmaOpcode::WIDE_LDOBJBYINDEX_PREF_IMM32: 6184514f5e3Sopenharmony_ci LowerLdObjByIndex(gate); 6194514f5e3Sopenharmony_ci break; 6204514f5e3Sopenharmony_ci case EcmaOpcode::STOBJBYINDEX_IMM8_V8_IMM16: 6214514f5e3Sopenharmony_ci case EcmaOpcode::STOBJBYINDEX_IMM16_V8_IMM16: 6224514f5e3Sopenharmony_ci case EcmaOpcode::WIDE_STOBJBYINDEX_PREF_V8_IMM32: 6234514f5e3Sopenharmony_ci LowerStObjByIndex(gate); 6244514f5e3Sopenharmony_ci break; 6254514f5e3Sopenharmony_ci case EcmaOpcode::LDOBJBYVALUE_IMM8_V8: 6264514f5e3Sopenharmony_ci case EcmaOpcode::LDOBJBYVALUE_IMM16_V8: 6274514f5e3Sopenharmony_ci LowerLdObjByValue(gate, false); 6284514f5e3Sopenharmony_ci break; 6294514f5e3Sopenharmony_ci case EcmaOpcode::LDTHISBYVALUE_IMM8: 6304514f5e3Sopenharmony_ci case EcmaOpcode::LDTHISBYVALUE_IMM16: 6314514f5e3Sopenharmony_ci LowerLdObjByValue(gate, true); 6324514f5e3Sopenharmony_ci break; 6334514f5e3Sopenharmony_ci case EcmaOpcode::STOBJBYVALUE_IMM8_V8_V8: 6344514f5e3Sopenharmony_ci case EcmaOpcode::STOBJBYVALUE_IMM16_V8_V8: 6354514f5e3Sopenharmony_ci LowerStObjByValue(gate, false); 6364514f5e3Sopenharmony_ci break; 6374514f5e3Sopenharmony_ci case EcmaOpcode::STTHISBYVALUE_IMM8_V8: 6384514f5e3Sopenharmony_ci case EcmaOpcode::STTHISBYVALUE_IMM16_V8: 6394514f5e3Sopenharmony_ci LowerStObjByValue(gate, true); 6404514f5e3Sopenharmony_ci break; 6414514f5e3Sopenharmony_ci case EcmaOpcode::LDSUPERBYNAME_IMM8_ID16: 6424514f5e3Sopenharmony_ci case EcmaOpcode::LDSUPERBYNAME_IMM16_ID16: 6434514f5e3Sopenharmony_ci LowerLdSuperByName(gate); 6444514f5e3Sopenharmony_ci break; 6454514f5e3Sopenharmony_ci case EcmaOpcode::STSUPERBYNAME_IMM8_ID16_V8: 6464514f5e3Sopenharmony_ci case EcmaOpcode::STSUPERBYNAME_IMM16_ID16_V8: 6474514f5e3Sopenharmony_ci LowerStSuperByName(gate); 6484514f5e3Sopenharmony_ci break; 6494514f5e3Sopenharmony_ci case EcmaOpcode::CREATEGENERATOROBJ_V8: 6504514f5e3Sopenharmony_ci LowerCreateGeneratorObj(gate); 6514514f5e3Sopenharmony_ci break; 6524514f5e3Sopenharmony_ci case EcmaOpcode::CREATEASYNCGENERATOROBJ_V8: 6534514f5e3Sopenharmony_ci LowerCreateAsyncGeneratorObj(gate); 6544514f5e3Sopenharmony_ci break; 6554514f5e3Sopenharmony_ci case EcmaOpcode::ASYNCGENERATORRESOLVE_V8_V8_V8: 6564514f5e3Sopenharmony_ci LowerAsyncGeneratorResolve(gate); 6574514f5e3Sopenharmony_ci break; 6584514f5e3Sopenharmony_ci case EcmaOpcode::ASYNCGENERATORREJECT_V8: 6594514f5e3Sopenharmony_ci LowerAsyncGeneratorReject(gate); 6604514f5e3Sopenharmony_ci break; 6614514f5e3Sopenharmony_ci case EcmaOpcode::STARRAYSPREAD_V8_V8: 6624514f5e3Sopenharmony_ci LowerStArraySpread(gate); 6634514f5e3Sopenharmony_ci break; 6644514f5e3Sopenharmony_ci case EcmaOpcode::LDLEXVAR_IMM4_IMM4: 6654514f5e3Sopenharmony_ci case EcmaOpcode::LDLEXVAR_IMM8_IMM8: 6664514f5e3Sopenharmony_ci case EcmaOpcode::WIDE_LDLEXVAR_PREF_IMM16_IMM16: 6674514f5e3Sopenharmony_ci LowerLdLexVar(gate); 6684514f5e3Sopenharmony_ci break; 6694514f5e3Sopenharmony_ci case EcmaOpcode::STLEXVAR_IMM4_IMM4: 6704514f5e3Sopenharmony_ci case EcmaOpcode::STLEXVAR_IMM8_IMM8: 6714514f5e3Sopenharmony_ci case EcmaOpcode::WIDE_STLEXVAR_PREF_IMM16_IMM16: 6724514f5e3Sopenharmony_ci LowerStLexVar(gate); 6734514f5e3Sopenharmony_ci break; 6744514f5e3Sopenharmony_ci case EcmaOpcode::DEFINECLASSWITHBUFFER_IMM8_ID16_ID16_IMM16_V8: 6754514f5e3Sopenharmony_ci case EcmaOpcode::DEFINECLASSWITHBUFFER_IMM16_ID16_ID16_IMM16_V8: 6764514f5e3Sopenharmony_ci LowerDefineClassWithBuffer(gate); 6774514f5e3Sopenharmony_ci break; 6784514f5e3Sopenharmony_ci case EcmaOpcode::DEFINEFUNC_IMM8_ID16_IMM8: 6794514f5e3Sopenharmony_ci case EcmaOpcode::DEFINEFUNC_IMM16_ID16_IMM8: 6804514f5e3Sopenharmony_ci LowerDefineFunc(gate); 6814514f5e3Sopenharmony_ci break; 6824514f5e3Sopenharmony_ci case EcmaOpcode::COPYRESTARGS_IMM8: 6834514f5e3Sopenharmony_ci case EcmaOpcode::WIDE_COPYRESTARGS_PREF_IMM16: 6844514f5e3Sopenharmony_ci LowerCopyRestArgs(gate); 6854514f5e3Sopenharmony_ci break; 6864514f5e3Sopenharmony_ci case EcmaOpcode::WIDE_LDPATCHVAR_PREF_IMM16: 6874514f5e3Sopenharmony_ci LowerWideLdPatchVar(gate); 6884514f5e3Sopenharmony_ci break; 6894514f5e3Sopenharmony_ci case EcmaOpcode::WIDE_STPATCHVAR_PREF_IMM16: 6904514f5e3Sopenharmony_ci LowerWideStPatchVar(gate); 6914514f5e3Sopenharmony_ci break; 6924514f5e3Sopenharmony_ci case EcmaOpcode::LDLOCALMODULEVAR_IMM8: 6934514f5e3Sopenharmony_ci case EcmaOpcode::WIDE_LDLOCALMODULEVAR_PREF_IMM16: 6944514f5e3Sopenharmony_ci LowerLdLocalModuleVarByIndex(gate); 6954514f5e3Sopenharmony_ci break; 6964514f5e3Sopenharmony_ci case EcmaOpcode::DEBUGGER: 6974514f5e3Sopenharmony_ci case EcmaOpcode::JSTRICTEQZ_IMM8: 6984514f5e3Sopenharmony_ci case EcmaOpcode::JSTRICTEQZ_IMM16: 6994514f5e3Sopenharmony_ci case EcmaOpcode::JNSTRICTEQZ_IMM8: 7004514f5e3Sopenharmony_ci case EcmaOpcode::JNSTRICTEQZ_IMM16: 7014514f5e3Sopenharmony_ci case EcmaOpcode::JEQNULL_IMM8: 7024514f5e3Sopenharmony_ci case EcmaOpcode::JEQNULL_IMM16: 7034514f5e3Sopenharmony_ci case EcmaOpcode::JNENULL_IMM8: 7044514f5e3Sopenharmony_ci case EcmaOpcode::JNENULL_IMM16: 7054514f5e3Sopenharmony_ci case EcmaOpcode::JSTRICTEQNULL_IMM8: 7064514f5e3Sopenharmony_ci case EcmaOpcode::JSTRICTEQNULL_IMM16: 7074514f5e3Sopenharmony_ci case EcmaOpcode::JNSTRICTEQNULL_IMM8: 7084514f5e3Sopenharmony_ci case EcmaOpcode::JNSTRICTEQNULL_IMM16: 7094514f5e3Sopenharmony_ci case EcmaOpcode::JEQUNDEFINED_IMM8: 7104514f5e3Sopenharmony_ci case EcmaOpcode::JEQUNDEFINED_IMM16: 7114514f5e3Sopenharmony_ci case EcmaOpcode::JNEUNDEFINED_IMM8: 7124514f5e3Sopenharmony_ci case EcmaOpcode::JNEUNDEFINED_IMM16: 7134514f5e3Sopenharmony_ci case EcmaOpcode::JSTRICTEQUNDEFINED_IMM8: 7144514f5e3Sopenharmony_ci case EcmaOpcode::JSTRICTEQUNDEFINED_IMM16: 7154514f5e3Sopenharmony_ci case EcmaOpcode::JNSTRICTEQUNDEFINED_IMM8: 7164514f5e3Sopenharmony_ci case EcmaOpcode::JNSTRICTEQUNDEFINED_IMM16: 7174514f5e3Sopenharmony_ci case EcmaOpcode::JEQ_V8_IMM8: 7184514f5e3Sopenharmony_ci case EcmaOpcode::JEQ_V8_IMM16: 7194514f5e3Sopenharmony_ci case EcmaOpcode::JNE_V8_IMM8: 7204514f5e3Sopenharmony_ci case EcmaOpcode::JNE_V8_IMM16: 7214514f5e3Sopenharmony_ci case EcmaOpcode::JSTRICTEQ_V8_IMM8: 7224514f5e3Sopenharmony_ci case EcmaOpcode::JSTRICTEQ_V8_IMM16: 7234514f5e3Sopenharmony_ci case EcmaOpcode::JNSTRICTEQ_V8_IMM8: 7244514f5e3Sopenharmony_ci case EcmaOpcode::JNSTRICTEQ_V8_IMM16: 7254514f5e3Sopenharmony_ci break; 7264514f5e3Sopenharmony_ci case EcmaOpcode::LDTHISBYNAME_IMM8_ID16: 7274514f5e3Sopenharmony_ci case EcmaOpcode::LDTHISBYNAME_IMM16_ID16: 7284514f5e3Sopenharmony_ci LowerLdThisByName(gate); 7294514f5e3Sopenharmony_ci break; 7304514f5e3Sopenharmony_ci case EcmaOpcode::STTHISBYNAME_IMM8_ID16: 7314514f5e3Sopenharmony_ci case EcmaOpcode::STTHISBYNAME_IMM16_ID16: 7324514f5e3Sopenharmony_ci LowerStObjByName(gate, true); 7334514f5e3Sopenharmony_ci break; 7344514f5e3Sopenharmony_ci case EcmaOpcode::LDPRIVATEPROPERTY_IMM8_IMM16_IMM16: 7354514f5e3Sopenharmony_ci LowerLdPrivateProperty(gate); 7364514f5e3Sopenharmony_ci break; 7374514f5e3Sopenharmony_ci case EcmaOpcode::STPRIVATEPROPERTY_IMM8_IMM16_IMM16_V8: 7384514f5e3Sopenharmony_ci LowerStPrivateProperty(gate); 7394514f5e3Sopenharmony_ci break; 7404514f5e3Sopenharmony_ci case EcmaOpcode::TESTIN_IMM8_IMM16_IMM16: 7414514f5e3Sopenharmony_ci LowerTestIn(gate); 7424514f5e3Sopenharmony_ci break; 7434514f5e3Sopenharmony_ci case EcmaOpcode::CALLRUNTIME_NOTIFYCONCURRENTRESULT_PREF_NONE: 7444514f5e3Sopenharmony_ci LowerNotifyConcurrentResult(gate); 7454514f5e3Sopenharmony_ci break; 7464514f5e3Sopenharmony_ci case EcmaOpcode::DEFINEPROPERTYBYNAME_IMM8_ID16_V8: 7474514f5e3Sopenharmony_ci case EcmaOpcode::DEFINEFIELDBYNAME_IMM8_ID16_V8: 7484514f5e3Sopenharmony_ci LowerDefineFieldByName(gate); 7494514f5e3Sopenharmony_ci break; 7504514f5e3Sopenharmony_ci case EcmaOpcode::CALLRUNTIME_DEFINEFIELDBYVALUE_PREF_IMM8_V8_V8: 7514514f5e3Sopenharmony_ci LowerDefineFieldByValue(gate); 7524514f5e3Sopenharmony_ci break; 7534514f5e3Sopenharmony_ci case EcmaOpcode::CALLRUNTIME_DEFINEFIELDBYINDEX_PREF_IMM8_IMM32_V8: 7544514f5e3Sopenharmony_ci LowerDefineFieldByIndex(gate); 7554514f5e3Sopenharmony_ci break; 7564514f5e3Sopenharmony_ci case EcmaOpcode::CALLRUNTIME_TOPROPERTYKEY_PREF_NONE: 7574514f5e3Sopenharmony_ci LowerToPropertyKey(gate); 7584514f5e3Sopenharmony_ci break; 7594514f5e3Sopenharmony_ci case EcmaOpcode::CALLRUNTIME_CREATEPRIVATEPROPERTY_PREF_IMM16_ID16: 7604514f5e3Sopenharmony_ci LowerCreatePrivateProperty(gate); 7614514f5e3Sopenharmony_ci break; 7624514f5e3Sopenharmony_ci case EcmaOpcode::CALLRUNTIME_DEFINEPRIVATEPROPERTY_PREF_IMM8_IMM16_IMM16_V8: 7634514f5e3Sopenharmony_ci LowerDefinePrivateProperty(gate); 7644514f5e3Sopenharmony_ci break; 7654514f5e3Sopenharmony_ci case EcmaOpcode::CALLRUNTIME_CALLINIT_PREF_IMM8_V8: 7664514f5e3Sopenharmony_ci LowerCallInit(gate); 7674514f5e3Sopenharmony_ci break; 7684514f5e3Sopenharmony_ci case EcmaOpcode::CALLRUNTIME_DEFINESENDABLECLASS_PREF_IMM16_ID16_ID16_IMM16_V8: 7694514f5e3Sopenharmony_ci LowerDefineSendableClass(gate); 7704514f5e3Sopenharmony_ci break; 7714514f5e3Sopenharmony_ci case EcmaOpcode::CALLRUNTIME_LDSENDABLECLASS_PREF_IMM16: 7724514f5e3Sopenharmony_ci LowerLdSendableClass(gate); 7734514f5e3Sopenharmony_ci break; 7744514f5e3Sopenharmony_ci case EcmaOpcode::CALLRUNTIME_LDSENDABLEEXTERNALMODULEVAR_PREF_IMM8: 7754514f5e3Sopenharmony_ci case EcmaOpcode::CALLRUNTIME_WIDELDSENDABLEEXTERNALMODULEVAR_PREF_IMM16: 7764514f5e3Sopenharmony_ci LowerSendableExternalModule(gate); 7774514f5e3Sopenharmony_ci break; 7784514f5e3Sopenharmony_ci case EcmaOpcode::CALLRUNTIME_NEWSENDABLEENV_PREF_IMM8: 7794514f5e3Sopenharmony_ci case EcmaOpcode::CALLRUNTIME_WIDENEWSENDABLEENV_PREF_IMM16: 7804514f5e3Sopenharmony_ci LowerNewSendableEnv(gate); 7814514f5e3Sopenharmony_ci break; 7824514f5e3Sopenharmony_ci case EcmaOpcode::CALLRUNTIME_STSENDABLEVAR_PREF_IMM4_IMM4: 7834514f5e3Sopenharmony_ci case EcmaOpcode::CALLRUNTIME_STSENDABLEVAR_PREF_IMM8_IMM8: 7844514f5e3Sopenharmony_ci case EcmaOpcode::CALLRUNTIME_WIDESTSENDABLEVAR_PREF_IMM16_IMM16: 7854514f5e3Sopenharmony_ci LowerStSendableVar(gate); 7864514f5e3Sopenharmony_ci break; 7874514f5e3Sopenharmony_ci case EcmaOpcode::CALLRUNTIME_LDSENDABLEVAR_PREF_IMM4_IMM4: 7884514f5e3Sopenharmony_ci case EcmaOpcode::CALLRUNTIME_LDSENDABLEVAR_PREF_IMM8_IMM8: 7894514f5e3Sopenharmony_ci case EcmaOpcode::CALLRUNTIME_WIDELDSENDABLEVAR_PREF_IMM16_IMM16: 7904514f5e3Sopenharmony_ci LowerLdSendableVar(gate); 7914514f5e3Sopenharmony_ci break; 7924514f5e3Sopenharmony_ci case EcmaOpcode::CALLRUNTIME_LDLAZYMODULEVAR_PREF_IMM8: 7934514f5e3Sopenharmony_ci case EcmaOpcode::CALLRUNTIME_WIDELDLAZYMODULEVAR_PREF_IMM16: 7944514f5e3Sopenharmony_ci LowerLdLazyExternalModuleVar(gate); 7954514f5e3Sopenharmony_ci break; 7964514f5e3Sopenharmony_ci case EcmaOpcode::CALLRUNTIME_LDLAZYSENDABLEMODULEVAR_PREF_IMM8: 7974514f5e3Sopenharmony_ci case EcmaOpcode::CALLRUNTIME_WIDELDLAZYSENDABLEMODULEVAR_PREF_IMM16: 7984514f5e3Sopenharmony_ci LowerLdLazySendableExternalModuleVar(gate); 7994514f5e3Sopenharmony_ci break; 8004514f5e3Sopenharmony_ci case EcmaOpcode::LDA_STR_ID16: 8014514f5e3Sopenharmony_ci LowerLdStr(gate); 8024514f5e3Sopenharmony_ci break; 8034514f5e3Sopenharmony_ci default: 8044514f5e3Sopenharmony_ci break; 8054514f5e3Sopenharmony_ci } 8064514f5e3Sopenharmony_ci} 8074514f5e3Sopenharmony_ci 8084514f5e3Sopenharmony_civoid SlowPathLowering::LowerCallStubWithIC(GateRef gate, int sign, const std::vector<GateRef> &args) 8094514f5e3Sopenharmony_ci{ 8104514f5e3Sopenharmony_ci std::vector<GateRef> inputs { glue_ }; 8114514f5e3Sopenharmony_ci inputs.insert(inputs.end(), args.begin(), args.end()); 8124514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 8134514f5e3Sopenharmony_ci GateRef slotId = builder_.ZExtInt16ToInt32(acc_.GetValueIn(gate, 0)); 8144514f5e3Sopenharmony_ci inputs.emplace_back(jsFunc); 8154514f5e3Sopenharmony_ci inputs.emplace_back(slotId); 8164514f5e3Sopenharmony_ci 8174514f5e3Sopenharmony_ci GateRef result = builder_.CallStub(glue_, gate, sign, inputs); 8184514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 8194514f5e3Sopenharmony_ci} 8204514f5e3Sopenharmony_ci 8214514f5e3Sopenharmony_ciGateRef SlowPathLowering::LowerCallRuntime(GateRef gate, int index, const std::vector<GateRef> &args, bool useLabel) 8224514f5e3Sopenharmony_ci{ 8234514f5e3Sopenharmony_ci const std::string name = RuntimeStubCSigns::GetRTName(index); 8244514f5e3Sopenharmony_ci if (useLabel) { 8254514f5e3Sopenharmony_ci GateRef result = builder_.CallRuntime(glue_, index, Gate::InvalidGateRef, args, gate, name.c_str()); 8264514f5e3Sopenharmony_ci return result; 8274514f5e3Sopenharmony_ci } else { 8284514f5e3Sopenharmony_ci const CallSignature *cs = RuntimeStubCSigns::Get(RTSTUB_ID(CallRuntime)); 8294514f5e3Sopenharmony_ci GateRef target = builder_.IntPtr(index); 8304514f5e3Sopenharmony_ci GateRef result = builder_.Call(cs, glue_, target, builder_.GetDepend(), args, gate, name.c_str()); 8314514f5e3Sopenharmony_ci return result; 8324514f5e3Sopenharmony_ci } 8334514f5e3Sopenharmony_ci} 8344514f5e3Sopenharmony_ci 8354514f5e3Sopenharmony_ciGateRef SlowPathLowering::LowerCallNGCRuntime(GateRef gate, int index, const std::vector<GateRef> &args, bool useLabel) 8364514f5e3Sopenharmony_ci{ 8374514f5e3Sopenharmony_ci const std::string name = RuntimeStubCSigns::GetRTName(index); 8384514f5e3Sopenharmony_ci if (useLabel) { 8394514f5e3Sopenharmony_ci GateRef result = builder_.CallNGCRuntime(glue_, index, Gate::InvalidGateRef, args, gate, name.c_str()); 8404514f5e3Sopenharmony_ci return result; 8414514f5e3Sopenharmony_ci } else { 8424514f5e3Sopenharmony_ci const CallSignature *cs = RuntimeStubCSigns::Get(index); 8434514f5e3Sopenharmony_ci GateRef target = builder_.IntPtr(index); 8444514f5e3Sopenharmony_ci GateRef result = builder_.Call(cs, glue_, target, builder_.GetDepend(), args, gate, name.c_str()); 8454514f5e3Sopenharmony_ci return result; 8464514f5e3Sopenharmony_ci } 8474514f5e3Sopenharmony_ci} 8484514f5e3Sopenharmony_ci 8494514f5e3Sopenharmony_civoid SlowPathLowering::LowerAdd2(GateRef gate) 8504514f5e3Sopenharmony_ci{ 8514514f5e3Sopenharmony_ci // 2: number of value inputs 8524514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 8534514f5e3Sopenharmony_ci GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::Add, 8544514f5e3Sopenharmony_ci { glue_, acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1) }); 8554514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 8564514f5e3Sopenharmony_ci} 8574514f5e3Sopenharmony_ci 8584514f5e3Sopenharmony_civoid SlowPathLowering::LowerCreateIterResultObj(GateRef gate) 8594514f5e3Sopenharmony_ci{ 8604514f5e3Sopenharmony_ci const int id = RTSTUB_ID(CreateIterResultObj); 8614514f5e3Sopenharmony_ci // 2: number of value inputs 8624514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 8634514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, {acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1)}); 8644514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 8654514f5e3Sopenharmony_ci} 8664514f5e3Sopenharmony_ci 8674514f5e3Sopenharmony_ci// When executing to SUSPENDGENERATOR instruction, save contextual information to GeneratorContext, 8684514f5e3Sopenharmony_ci// including registers, acc, etc. 8694514f5e3Sopenharmony_civoid SlowPathLowering::SaveFrameToContext(GateRef gate) 8704514f5e3Sopenharmony_ci{ 8714514f5e3Sopenharmony_ci GateRef genObj = acc_.GetValueIn(gate, 1); 8724514f5e3Sopenharmony_ci GateRef saveRegister = acc_.GetDep(gate); 8734514f5e3Sopenharmony_ci while (acc_.GetOpCode(saveRegister) != OpCode::SAVE_REGISTER) { 8744514f5e3Sopenharmony_ci saveRegister = acc_.GetDep(saveRegister); 8754514f5e3Sopenharmony_ci } 8764514f5e3Sopenharmony_ci ASSERT(acc_.GetOpCode(saveRegister) == OpCode::SAVE_REGISTER); 8774514f5e3Sopenharmony_ci 8784514f5e3Sopenharmony_ci acc_.SetDep(gate, acc_.GetDep(saveRegister)); 8794514f5e3Sopenharmony_ci builder_.SetDepend(acc_.GetDep(saveRegister)); 8804514f5e3Sopenharmony_ci GateRef context = 8814514f5e3Sopenharmony_ci builder_.Load(VariableType::JS_POINTER(), genObj, builder_.IntPtr(JSGeneratorObject::GENERATOR_CONTEXT_OFFSET)); 8824514f5e3Sopenharmony_ci // new tagged array 8834514f5e3Sopenharmony_ci auto method = methodLiteral_; 8844514f5e3Sopenharmony_ci const size_t arrLength = method->GetNumberVRegs() + 1; // 1: env vreg 8854514f5e3Sopenharmony_ci GateRef length = builder_.Int32(arrLength); 8864514f5e3Sopenharmony_ci GateRef taggedLength = builder_.ToTaggedInt(builder_.ZExtInt32ToInt64(length)); 8874514f5e3Sopenharmony_ci const int arrayId = RTSTUB_ID(NewTaggedArray); 8884514f5e3Sopenharmony_ci GateRef taggedArray = LowerCallRuntime(gate, arrayId, {taggedLength}); 8894514f5e3Sopenharmony_ci // setRegsArrays 8904514f5e3Sopenharmony_ci auto hole = builder_.HoleConstant(); 8914514f5e3Sopenharmony_ci size_t numVreg = acc_.GetNumValueIn(saveRegister); 8924514f5e3Sopenharmony_ci for (size_t idx = 0; idx < numVreg; idx++) { 8934514f5e3Sopenharmony_ci GateRef tmpGate = acc_.GetValueIn(saveRegister, idx); 8944514f5e3Sopenharmony_ci if (tmpGate != hole) { 8954514f5e3Sopenharmony_ci builder_.SetValueToTaggedArray(VariableType::JS_ANY(), glue_, taggedArray, builder_.Int32(idx), tmpGate); 8964514f5e3Sopenharmony_ci } 8974514f5e3Sopenharmony_ci } 8984514f5e3Sopenharmony_ci ASSERT(numVreg > 0); 8994514f5e3Sopenharmony_ci GateRef lexicalEnvGate = acc_.GetValueIn(saveRegister, numVreg - 1); 9004514f5e3Sopenharmony_ci acc_.DeleteGate(saveRegister); 9014514f5e3Sopenharmony_ci 9024514f5e3Sopenharmony_ci // setRegsArrays 9034514f5e3Sopenharmony_ci GateRef regsArrayOffset = builder_.IntPtr(GeneratorContext::GENERATOR_REGS_ARRAY_OFFSET); 9044514f5e3Sopenharmony_ci builder_.Store(VariableType::JS_POINTER(), glue_, context, regsArrayOffset, taggedArray); 9054514f5e3Sopenharmony_ci 9064514f5e3Sopenharmony_ci // set this 9074514f5e3Sopenharmony_ci GateRef thisOffset = builder_.IntPtr(GeneratorContext::GENERATOR_THIS_OFFSET); 9084514f5e3Sopenharmony_ci GateRef thisObj = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::THIS_OBJECT); 9094514f5e3Sopenharmony_ci builder_.Store(VariableType::JS_ANY(), glue_, context, thisOffset, thisObj); 9104514f5e3Sopenharmony_ci 9114514f5e3Sopenharmony_ci // set method 9124514f5e3Sopenharmony_ci GateRef methodOffset = builder_.IntPtr(GeneratorContext::GENERATOR_METHOD_OFFSET); 9134514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 9144514f5e3Sopenharmony_ci builder_.Store(VariableType::JS_ANY(), glue_, context, methodOffset, jsFunc); 9154514f5e3Sopenharmony_ci 9164514f5e3Sopenharmony_ci // set acc 9174514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) > 0); 9184514f5e3Sopenharmony_ci GateRef accOffset = builder_.IntPtr(GeneratorContext::GENERATOR_ACC_OFFSET); 9194514f5e3Sopenharmony_ci GateRef curAccGate = acc_.GetValueIn(gate, acc_.GetNumValueIn(gate) - 1); // get current acc 9204514f5e3Sopenharmony_ci builder_.Store(VariableType::JS_ANY(), glue_, context, accOffset, curAccGate); 9214514f5e3Sopenharmony_ci 9224514f5e3Sopenharmony_ci // set generator object 9234514f5e3Sopenharmony_ci GateRef generatorObjectOffset = builder_.IntPtr(GeneratorContext::GENERATOR_GENERATOR_OBJECT_OFFSET); 9244514f5e3Sopenharmony_ci builder_.Store(VariableType::JS_ANY(), glue_, context, generatorObjectOffset, genObj); 9254514f5e3Sopenharmony_ci 9264514f5e3Sopenharmony_ci // set lexical env 9274514f5e3Sopenharmony_ci GateRef lexicalEnvOffset = builder_.IntPtr(GeneratorContext::GENERATOR_LEXICALENV_OFFSET); 9284514f5e3Sopenharmony_ci builder_.Store(VariableType::JS_ANY(), glue_, context, lexicalEnvOffset, lexicalEnvGate); 9294514f5e3Sopenharmony_ci 9304514f5e3Sopenharmony_ci // set nregs 9314514f5e3Sopenharmony_ci GateRef nregsOffset = builder_.IntPtr(GeneratorContext::GENERATOR_NREGS_OFFSET); 9324514f5e3Sopenharmony_ci builder_.Store(VariableType::INT32(), glue_, context, nregsOffset, length); 9334514f5e3Sopenharmony_ci 9344514f5e3Sopenharmony_ci // set bc size 9354514f5e3Sopenharmony_ci GateRef bcSizeOffset = builder_.IntPtr(GeneratorContext::GENERATOR_BC_OFFSET_OFFSET); 9364514f5e3Sopenharmony_ci GateRef bcSizeGate = acc_.GetValueIn(gate, 0); // saved bc_offset 9374514f5e3Sopenharmony_ci bcSizeGate = builder_.TruncInt64ToInt32(bcSizeGate); 9384514f5e3Sopenharmony_ci builder_.Store(VariableType::INT32(), glue_, context, bcSizeOffset, bcSizeGate); 9394514f5e3Sopenharmony_ci 9404514f5e3Sopenharmony_ci // set context to generator object 9414514f5e3Sopenharmony_ci GateRef contextOffset = builder_.IntPtr(JSGeneratorObject::GENERATOR_CONTEXT_OFFSET); 9424514f5e3Sopenharmony_ci builder_.Store(VariableType::JS_POINTER(), glue_, genObj, contextOffset, context); 9434514f5e3Sopenharmony_ci 9444514f5e3Sopenharmony_ci // set generator object to context 9454514f5e3Sopenharmony_ci builder_.Store(VariableType::JS_POINTER(), glue_, context, generatorObjectOffset, genObj); 9464514f5e3Sopenharmony_ci} 9474514f5e3Sopenharmony_ci 9484514f5e3Sopenharmony_civoid SlowPathLowering::LowerSuspendGenerator(GateRef gate) 9494514f5e3Sopenharmony_ci{ 9504514f5e3Sopenharmony_ci SaveFrameToContext(gate); 9514514f5e3Sopenharmony_ci acc_.SetDep(gate, builder_.GetDepend()); 9524514f5e3Sopenharmony_ci AddProfiling(gate, false); 9534514f5e3Sopenharmony_ci const int id = RTSTUB_ID(OptSuspendGenerator); 9544514f5e3Sopenharmony_ci auto value = acc_.GetValueIn(gate, 2); // 2: acc 9554514f5e3Sopenharmony_ci auto genObj = acc_.GetValueIn(gate, 1); 9564514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, { genObj, value }); 9574514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 9584514f5e3Sopenharmony_ci} 9594514f5e3Sopenharmony_ci 9604514f5e3Sopenharmony_civoid SlowPathLowering::LowerAsyncFunctionAwaitUncaught(GateRef gate) 9614514f5e3Sopenharmony_ci{ 9624514f5e3Sopenharmony_ci const int id = RTSTUB_ID(AsyncFunctionAwaitUncaught); 9634514f5e3Sopenharmony_ci // 2: number of value inputs 9644514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 9654514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, {acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1)}); 9664514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 9674514f5e3Sopenharmony_ci} 9684514f5e3Sopenharmony_ci 9694514f5e3Sopenharmony_civoid SlowPathLowering::LowerAsyncFunctionResolve(GateRef gate) 9704514f5e3Sopenharmony_ci{ 9714514f5e3Sopenharmony_ci const int id = RTSTUB_ID(AsyncFunctionResolveOrReject); 9724514f5e3Sopenharmony_ci // 2: number of value inputs 9734514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 9744514f5e3Sopenharmony_ci GateRef taggedTrue = builder_.TaggedTrue(); 9754514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, {acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1), taggedTrue}); 9764514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 9774514f5e3Sopenharmony_ci} 9784514f5e3Sopenharmony_ci 9794514f5e3Sopenharmony_civoid SlowPathLowering::LowerAsyncFunctionReject(GateRef gate) 9804514f5e3Sopenharmony_ci{ 9814514f5e3Sopenharmony_ci const int id = RTSTUB_ID(AsyncFunctionResolveOrReject); 9824514f5e3Sopenharmony_ci // 2: number of value inputs 9834514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 9844514f5e3Sopenharmony_ci GateRef taggedFalse = builder_.TaggedFalse(); 9854514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, {acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1), taggedFalse}); 9864514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 9874514f5e3Sopenharmony_ci} 9884514f5e3Sopenharmony_ci 9894514f5e3Sopenharmony_civoid SlowPathLowering::LowerTryLdGlobalByName(GateRef gate) 9904514f5e3Sopenharmony_ci{ 9914514f5e3Sopenharmony_ci // 2: number of value inputs 9924514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 9934514f5e3Sopenharmony_ci GateRef stringId = acc_.GetValueIn(gate, 1); // 1: the second parameter 9944514f5e3Sopenharmony_ci LowerCallStubWithIC(gate, CommonStubCSigns::TryLdGlobalByName, { stringId }); 9954514f5e3Sopenharmony_ci} 9964514f5e3Sopenharmony_ci 9974514f5e3Sopenharmony_civoid SlowPathLowering::LowerStGlobalVar(GateRef gate) 9984514f5e3Sopenharmony_ci{ 9994514f5e3Sopenharmony_ci // 3: number of value inputs 10004514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 3); 10014514f5e3Sopenharmony_ci GateRef id = acc_.GetValueIn(gate, 1); // 1: the second parameter 10024514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 2); // 2: the 2nd para is value 10034514f5e3Sopenharmony_ci LowerCallStubWithIC(gate, CommonStubCSigns::StGlobalVar, { id, value }); 10044514f5e3Sopenharmony_ci} 10054514f5e3Sopenharmony_ci 10064514f5e3Sopenharmony_civoid SlowPathLowering::LowerGetIterator(GateRef gate) 10074514f5e3Sopenharmony_ci{ 10084514f5e3Sopenharmony_ci auto result = LowerCallRuntime(gate, RTSTUB_ID(GetIterator), {acc_.GetValueIn(gate, 0)}, true); 10094514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 10104514f5e3Sopenharmony_ci} 10114514f5e3Sopenharmony_ci 10124514f5e3Sopenharmony_civoid SlowPathLowering::LowerGetAsyncIterator(GateRef gate) 10134514f5e3Sopenharmony_ci{ 10144514f5e3Sopenharmony_ci auto result = LowerCallRuntime(gate, RTSTUB_ID(GetAsyncIterator), {acc_.GetValueIn(gate, 0)}, true); 10154514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 10164514f5e3Sopenharmony_ci} 10174514f5e3Sopenharmony_ci 10184514f5e3Sopenharmony_civoid SlowPathLowering::LowerCallArg0(GateRef gate) 10194514f5e3Sopenharmony_ci{ 10204514f5e3Sopenharmony_ci // 1: number of value inputs 10214514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 1); 10224514f5e3Sopenharmony_ci 10234514f5e3Sopenharmony_ci GateRef actualArgc = builder_.Int64(BytecodeCallArgc::ComputeCallArgc(acc_.GetNumValueIn(gate), 10244514f5e3Sopenharmony_ci EcmaOpcode::CALLARG0_IMM8)); 10254514f5e3Sopenharmony_ci GateRef actualArgv = builder_.IntPtr(0); 10264514f5e3Sopenharmony_ci GateRef newTarget = builder_.Undefined(); 10274514f5e3Sopenharmony_ci GateRef thisObj = builder_.Undefined(); 10284514f5e3Sopenharmony_ci GateRef func = acc_.GetValueIn(gate, 0); 10294514f5e3Sopenharmony_ci LowerToJSCall(gate, {glue_, actualArgc, actualArgv, func, newTarget, thisObj}, {glue_, func, thisObj}); 10304514f5e3Sopenharmony_ci} 10314514f5e3Sopenharmony_ci 10324514f5e3Sopenharmony_civoid SlowPathLowering::LowerCallthisrangeImm8Imm8V8(GateRef gate) 10334514f5e3Sopenharmony_ci{ 10344514f5e3Sopenharmony_ci // this 10354514f5e3Sopenharmony_ci size_t fixedInputsNum = 1; 10364514f5e3Sopenharmony_ci size_t numIns = acc_.GetNumValueIn(gate); 10374514f5e3Sopenharmony_ci ASSERT(numIns >= fixedInputsNum); 10384514f5e3Sopenharmony_ci GateRef actualArgc = builder_.Int64(BytecodeCallArgc::ComputeCallArgc(acc_.GetNumValueIn(gate), 10394514f5e3Sopenharmony_ci EcmaOpcode::CALLTHISRANGE_IMM8_IMM8_V8)); 10404514f5e3Sopenharmony_ci GateRef actualArgv = builder_.IntPtr(0); 10414514f5e3Sopenharmony_ci const size_t callTargetIndex = 1; // 1: acc 10424514f5e3Sopenharmony_ci GateRef callTarget = acc_.GetValueIn(gate, numIns - callTargetIndex); // acc 10434514f5e3Sopenharmony_ci GateRef thisObj = acc_.GetValueIn(gate, 0); 10444514f5e3Sopenharmony_ci GateRef newTarget = builder_.Undefined(); 10454514f5e3Sopenharmony_ci std::vector<GateRef> vec { glue_, actualArgc, actualArgv, callTarget, newTarget, thisObj }; 10464514f5e3Sopenharmony_ci // add common args 10474514f5e3Sopenharmony_ci for (size_t i = fixedInputsNum; i < numIns - callTargetIndex; i++) { 10484514f5e3Sopenharmony_ci vec.emplace_back(acc_.GetValueIn(gate, i)); 10494514f5e3Sopenharmony_ci } 10504514f5e3Sopenharmony_ci std::vector<GateRef> vec1 { glue_, callTarget, thisObj }; 10514514f5e3Sopenharmony_ci // add common args 10524514f5e3Sopenharmony_ci for (size_t i = fixedInputsNum; i < numIns - callTargetIndex; i++) { 10534514f5e3Sopenharmony_ci vec1.emplace_back(acc_.GetValueIn(gate, i)); 10544514f5e3Sopenharmony_ci } 10554514f5e3Sopenharmony_ci LowerToJSCall(gate, vec, vec1); 10564514f5e3Sopenharmony_ci} 10574514f5e3Sopenharmony_ci 10584514f5e3Sopenharmony_civoid SlowPathLowering::LowerWideCallthisrangePrefImm16V8(GateRef gate) 10594514f5e3Sopenharmony_ci{ 10604514f5e3Sopenharmony_ci // The first register input is thisobj, second is thisObj and other inputs are common args. 10614514f5e3Sopenharmony_ci size_t fixedInputsNum = 1; // 1: acc 10624514f5e3Sopenharmony_ci size_t numIns = acc_.GetNumValueIn(gate); 10634514f5e3Sopenharmony_ci ASSERT(numIns >= fixedInputsNum); 10644514f5e3Sopenharmony_ci GateRef actualArgc = builder_.Int64(BytecodeCallArgc::ComputeCallArgc(acc_.GetNumValueIn(gate), 10654514f5e3Sopenharmony_ci EcmaOpcode::WIDE_CALLTHISRANGE_PREF_IMM16_V8)); 10664514f5e3Sopenharmony_ci GateRef actualArgv = builder_.IntPtr(0); 10674514f5e3Sopenharmony_ci const size_t callTargetIndex = 1; 10684514f5e3Sopenharmony_ci GateRef callTarget = acc_.GetValueIn(gate, numIns - callTargetIndex); 10694514f5e3Sopenharmony_ci GateRef thisObj = acc_.GetValueIn(gate, 0); 10704514f5e3Sopenharmony_ci GateRef newTarget = builder_.Undefined(); 10714514f5e3Sopenharmony_ci std::vector<GateRef> vec {glue_, actualArgc, actualArgv, callTarget, newTarget, thisObj}; 10724514f5e3Sopenharmony_ci // add common args 10734514f5e3Sopenharmony_ci for (size_t i = fixedInputsNum; i < numIns - callTargetIndex; i++) { 10744514f5e3Sopenharmony_ci vec.emplace_back(acc_.GetValueIn(gate, i)); 10754514f5e3Sopenharmony_ci } 10764514f5e3Sopenharmony_ci std::vector<GateRef> vec1 {glue_, callTarget, thisObj}; 10774514f5e3Sopenharmony_ci // add common args 10784514f5e3Sopenharmony_ci for (size_t i = fixedInputsNum; i < numIns - callTargetIndex; i++) { 10794514f5e3Sopenharmony_ci vec1.emplace_back(acc_.GetValueIn(gate, i)); 10804514f5e3Sopenharmony_ci } 10814514f5e3Sopenharmony_ci LowerToJSCall(gate, vec, vec1); 10824514f5e3Sopenharmony_ci} 10834514f5e3Sopenharmony_ci 10844514f5e3Sopenharmony_civoid SlowPathLowering::LowerCallSpread(GateRef gate) 10854514f5e3Sopenharmony_ci{ 10864514f5e3Sopenharmony_ci // need to fixed in later 10874514f5e3Sopenharmony_ci const int id = RTSTUB_ID(CallSpread); 10884514f5e3Sopenharmony_ci // 3: number of value inputs 10894514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 3); 10904514f5e3Sopenharmony_ci GateRef stateInGate = builder_.GetState(); 10914514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, 10924514f5e3Sopenharmony_ci {acc_.GetValueIn(gate, 2), acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1)}); 10934514f5e3Sopenharmony_ci ReplaceHirWithPendingException(gate, stateInGate, newGate, newGate); 10944514f5e3Sopenharmony_ci} 10954514f5e3Sopenharmony_ci 10964514f5e3Sopenharmony_civoid SlowPathLowering::LowerCallrangeImm8Imm8V8(GateRef gate) 10974514f5e3Sopenharmony_ci{ 10984514f5e3Sopenharmony_ci size_t numArgs = acc_.GetNumValueIn(gate); 10994514f5e3Sopenharmony_ci GateRef actualArgc = builder_.Int64(BytecodeCallArgc::ComputeCallArgc(acc_.GetNumValueIn(gate), 11004514f5e3Sopenharmony_ci EcmaOpcode::CALLRANGE_IMM8_IMM8_V8)); 11014514f5e3Sopenharmony_ci GateRef actualArgv = builder_.IntPtr(0); 11024514f5e3Sopenharmony_ci const size_t callTargetIndex = 1; // acc 11034514f5e3Sopenharmony_ci ASSERT(numArgs > 0); 11044514f5e3Sopenharmony_ci GateRef callTarget = acc_.GetValueIn(gate, numArgs - callTargetIndex); 11054514f5e3Sopenharmony_ci GateRef newTarget = builder_.Undefined(); 11064514f5e3Sopenharmony_ci GateRef thisObj = builder_.Undefined(); 11074514f5e3Sopenharmony_ci std::vector<GateRef> vec {glue_, actualArgc, actualArgv, callTarget, newTarget, thisObj}; 11084514f5e3Sopenharmony_ci for (size_t i = 0; i < numArgs - callTargetIndex; i++) { // 2: skip acc 11094514f5e3Sopenharmony_ci vec.emplace_back(acc_.GetValueIn(gate, i)); 11104514f5e3Sopenharmony_ci } 11114514f5e3Sopenharmony_ci std::vector<GateRef> vec1 {glue_, callTarget, thisObj}; 11124514f5e3Sopenharmony_ci for (size_t i = 0; i < numArgs - callTargetIndex; i++) { // 2: skip acc 11134514f5e3Sopenharmony_ci vec1.emplace_back(acc_.GetValueIn(gate, i)); 11144514f5e3Sopenharmony_ci } 11154514f5e3Sopenharmony_ci LowerToJSCall(gate, vec, vec1); 11164514f5e3Sopenharmony_ci} 11174514f5e3Sopenharmony_ci 11184514f5e3Sopenharmony_civoid SlowPathLowering::LowerNewObjApply(GateRef gate) 11194514f5e3Sopenharmony_ci{ 11204514f5e3Sopenharmony_ci const int id = RTSTUB_ID(NewObjApply); 11214514f5e3Sopenharmony_ci // 2: number of value inputs 11224514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 11234514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, 11244514f5e3Sopenharmony_ci {acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1) }); 11254514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 11264514f5e3Sopenharmony_ci} 11274514f5e3Sopenharmony_ci 11284514f5e3Sopenharmony_civoid SlowPathLowering::LowerThrow(GateRef gate) 11294514f5e3Sopenharmony_ci{ 11304514f5e3Sopenharmony_ci GateRef exception = acc_.GetValueIn(gate, 0); 11314514f5e3Sopenharmony_ci GateRef exceptionOffset = builder_.Int64(JSThread::GlueData::GetExceptionOffset(false)); 11324514f5e3Sopenharmony_ci builder_.Store(VariableType::INT64(), glue_, glue_, exceptionOffset, exception); 11334514f5e3Sopenharmony_ci // store gate value == depend 11344514f5e3Sopenharmony_ci GateRef result = builder_.GetDepend(); 11354514f5e3Sopenharmony_ci ReplaceHirToThrowCall(gate, result); 11364514f5e3Sopenharmony_ci} 11374514f5e3Sopenharmony_ci 11384514f5e3Sopenharmony_civoid SlowPathLowering::LowerThrowConstAssignment(GateRef gate) 11394514f5e3Sopenharmony_ci{ 11404514f5e3Sopenharmony_ci const int id = RTSTUB_ID(ThrowConstAssignment); 11414514f5e3Sopenharmony_ci // 1: number of value inputs 11424514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 1); 11434514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, {acc_.GetValueIn(gate, 0)}); 11444514f5e3Sopenharmony_ci ReplaceHirToThrowCall(gate, newGate); 11454514f5e3Sopenharmony_ci} 11464514f5e3Sopenharmony_ci 11474514f5e3Sopenharmony_civoid SlowPathLowering::LowerThrowThrowNotExists(GateRef gate) 11484514f5e3Sopenharmony_ci{ 11494514f5e3Sopenharmony_ci const int id = RTSTUB_ID(ThrowThrowNotExists); 11504514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, {}); 11514514f5e3Sopenharmony_ci ReplaceHirToThrowCall(gate, newGate); 11524514f5e3Sopenharmony_ci} 11534514f5e3Sopenharmony_ci 11544514f5e3Sopenharmony_civoid SlowPathLowering::LowerThrowPatternNonCoercible(GateRef gate) 11554514f5e3Sopenharmony_ci{ 11564514f5e3Sopenharmony_ci const int id = RTSTUB_ID(ThrowPatternNonCoercible); 11574514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, {}); 11584514f5e3Sopenharmony_ci ReplaceHirToThrowCall(gate, newGate); 11594514f5e3Sopenharmony_ci} 11604514f5e3Sopenharmony_ci 11614514f5e3Sopenharmony_civoid SlowPathLowering::LowerThrowIfNotObject(GateRef gate) 11624514f5e3Sopenharmony_ci{ 11634514f5e3Sopenharmony_ci // 1: number of value inputs 11644514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 1); 11654514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 0); 11664514f5e3Sopenharmony_ci Label successExit(&builder_); 11674514f5e3Sopenharmony_ci Label exceptionExit(&builder_); 11684514f5e3Sopenharmony_ci Label isEcmaObject(&builder_); 11694514f5e3Sopenharmony_ci Label notEcmaObject(&builder_); 11704514f5e3Sopenharmony_ci Label isHeapObject(&builder_); 11714514f5e3Sopenharmony_ci BRANCH_CIR(builder_.TaggedIsHeapObject(value), &isHeapObject, ¬EcmaObject); 11724514f5e3Sopenharmony_ci builder_.Bind(&isHeapObject); 11734514f5e3Sopenharmony_ci BRANCH_CIR(builder_.TaggedObjectIsEcmaObject(value), &isEcmaObject, ¬EcmaObject); 11744514f5e3Sopenharmony_ci builder_.Bind(&isEcmaObject); 11754514f5e3Sopenharmony_ci { 11764514f5e3Sopenharmony_ci builder_.Jump(&successExit); 11774514f5e3Sopenharmony_ci } 11784514f5e3Sopenharmony_ci builder_.Bind(¬EcmaObject); 11794514f5e3Sopenharmony_ci { 11804514f5e3Sopenharmony_ci LowerCallRuntime(gate, RTSTUB_ID(ThrowIfNotObject), {}, true); 11814514f5e3Sopenharmony_ci builder_.Jump(&exceptionExit); 11824514f5e3Sopenharmony_ci } 11834514f5e3Sopenharmony_ci CREATE_DOUBLE_EXIT(successExit, exceptionExit) 11844514f5e3Sopenharmony_ci acc_.ReplaceHirWithIfBranch(gate, successControl, failControl, Circuit::NullGate()); 11854514f5e3Sopenharmony_ci} 11864514f5e3Sopenharmony_ci 11874514f5e3Sopenharmony_civoid SlowPathLowering::LowerThrowUndefinedIfHole(GateRef gate) 11884514f5e3Sopenharmony_ci{ 11894514f5e3Sopenharmony_ci // 2: number of value inputs 11904514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 11914514f5e3Sopenharmony_ci GateRef hole = acc_.GetValueIn(gate, 0); 11924514f5e3Sopenharmony_ci GateRef obj = acc_.GetValueIn(gate, 1); 11934514f5e3Sopenharmony_ci Label successExit(&builder_); 11944514f5e3Sopenharmony_ci Label exceptionExit(&builder_); 11954514f5e3Sopenharmony_ci Label isHole(&builder_); 11964514f5e3Sopenharmony_ci Label notHole(&builder_); 11974514f5e3Sopenharmony_ci BRANCH_CIR(builder_.TaggedIsHole(hole), &isHole, ¬Hole); 11984514f5e3Sopenharmony_ci builder_.Bind(¬Hole); 11994514f5e3Sopenharmony_ci { 12004514f5e3Sopenharmony_ci builder_.Jump(&successExit); 12014514f5e3Sopenharmony_ci } 12024514f5e3Sopenharmony_ci builder_.Bind(&isHole); 12034514f5e3Sopenharmony_ci { 12044514f5e3Sopenharmony_ci LowerCallRuntime(gate, RTSTUB_ID(ThrowUndefinedIfHole), {obj}, true); 12054514f5e3Sopenharmony_ci builder_.Jump(&exceptionExit); 12064514f5e3Sopenharmony_ci } 12074514f5e3Sopenharmony_ci CREATE_DOUBLE_EXIT(successExit, exceptionExit) 12084514f5e3Sopenharmony_ci acc_.ReplaceHirWithIfBranch(gate, successControl, failControl, Circuit::NullGate()); 12094514f5e3Sopenharmony_ci} 12104514f5e3Sopenharmony_ci 12114514f5e3Sopenharmony_civoid SlowPathLowering::LowerThrowUndefinedIfHoleWithName(GateRef gate) 12124514f5e3Sopenharmony_ci{ 12134514f5e3Sopenharmony_ci // 2: number of value inputs 12144514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 12154514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 12164514f5e3Sopenharmony_ci GateRef sharedConstPool = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::SHARED_CONST_POOL); 12174514f5e3Sopenharmony_ci GateRef hole = acc_.GetValueIn(gate, 1); 12184514f5e3Sopenharmony_ci Label successExit(&builder_); 12194514f5e3Sopenharmony_ci Label exceptionExit(&builder_); 12204514f5e3Sopenharmony_ci Label isHole(&builder_); 12214514f5e3Sopenharmony_ci Label notHole(&builder_); 12224514f5e3Sopenharmony_ci BRANCH_CIR(builder_.TaggedIsHole(hole), &isHole, ¬Hole); 12234514f5e3Sopenharmony_ci builder_.Bind(¬Hole); 12244514f5e3Sopenharmony_ci { 12254514f5e3Sopenharmony_ci builder_.Jump(&successExit); 12264514f5e3Sopenharmony_ci } 12274514f5e3Sopenharmony_ci builder_.Bind(&isHole); 12284514f5e3Sopenharmony_ci { 12294514f5e3Sopenharmony_ci GateRef module = builder_.GetModuleFromFunction(jsFunc); 12304514f5e3Sopenharmony_ci GateRef obj = builder_.GetObjectFromConstPool(glue_, gate, sharedConstPool, Circuit::NullGate(), module, 12314514f5e3Sopenharmony_ci builder_.ZExtInt16ToInt32(acc_.GetValueIn(gate, 0)), 12324514f5e3Sopenharmony_ci ConstPoolType::STRING); 12334514f5e3Sopenharmony_ci LowerCallRuntime(gate, RTSTUB_ID(ThrowUndefinedIfHole), {obj}, true); 12344514f5e3Sopenharmony_ci builder_.Jump(&exceptionExit); 12354514f5e3Sopenharmony_ci } 12364514f5e3Sopenharmony_ci CREATE_DOUBLE_EXIT(successExit, exceptionExit) 12374514f5e3Sopenharmony_ci acc_.ReplaceHirWithIfBranch(gate, successControl, failControl, Circuit::NullGate()); 12384514f5e3Sopenharmony_ci} 12394514f5e3Sopenharmony_ci 12404514f5e3Sopenharmony_civoid SlowPathLowering::LowerThrowIfSuperNotCorrectCall(GateRef gate) 12414514f5e3Sopenharmony_ci{ 12424514f5e3Sopenharmony_ci // 2: number of value inputs 12434514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 12444514f5e3Sopenharmony_ci GateRef result = LowerCallRuntime(gate, RTSTUB_ID(ThrowIfSuperNotCorrectCall), 12454514f5e3Sopenharmony_ci {builder_.ToTaggedInt(acc_.GetValueIn(gate, 0)), acc_.GetValueIn(gate, 1)}, true); 12464514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 12474514f5e3Sopenharmony_ci} 12484514f5e3Sopenharmony_ci 12494514f5e3Sopenharmony_civoid SlowPathLowering::LowerThrowDeleteSuperProperty(GateRef gate) 12504514f5e3Sopenharmony_ci{ 12514514f5e3Sopenharmony_ci const int id = RTSTUB_ID(ThrowDeleteSuperProperty); 12524514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, {}); 12534514f5e3Sopenharmony_ci ReplaceHirToThrowCall(gate, newGate); 12544514f5e3Sopenharmony_ci} 12554514f5e3Sopenharmony_ci 12564514f5e3Sopenharmony_civoid SlowPathLowering::LowerExceptionHandler(GateRef hirGate) 12574514f5e3Sopenharmony_ci{ 12584514f5e3Sopenharmony_ci GateRef depend = acc_.GetDep(hirGate); 12594514f5e3Sopenharmony_ci GateRef exceptionOffset = builder_.Int64(JSThread::GlueData::GetExceptionOffset(false)); 12604514f5e3Sopenharmony_ci GateRef val = builder_.Int64Add(glue_, exceptionOffset); 12614514f5e3Sopenharmony_ci auto bit = LoadStoreAccessor::ToValue(MemoryAttribute::Default()); 12624514f5e3Sopenharmony_ci GateRef loadException = circuit_->NewGate(circuit_->Load(bit), VariableType::JS_ANY().GetMachineType(), 12634514f5e3Sopenharmony_ci { depend, val }, VariableType::JS_ANY().GetGateType()); 12644514f5e3Sopenharmony_ci acc_.SetDep(loadException, depend); 12654514f5e3Sopenharmony_ci GateRef holeCst = builder_.HoleConstant(); 12664514f5e3Sopenharmony_ci GateRef clearException = circuit_->NewGate(circuit_->Store(bit), MachineType::NOVALUE, 12674514f5e3Sopenharmony_ci { loadException, glue_, glue_, exceptionOffset, holeCst }, VariableType::INT64().GetGateType()); 12684514f5e3Sopenharmony_ci auto uses = acc_.Uses(hirGate); 12694514f5e3Sopenharmony_ci for (auto it = uses.begin(); it != uses.end();) { 12704514f5e3Sopenharmony_ci if (acc_.GetOpCode(*it) != OpCode::VALUE_SELECTOR && acc_.IsDependIn(it)) { 12714514f5e3Sopenharmony_ci it = acc_.ReplaceIn(it, clearException); 12724514f5e3Sopenharmony_ci } else { 12734514f5e3Sopenharmony_ci it = acc_.ReplaceIn(it, loadException); 12744514f5e3Sopenharmony_ci } 12754514f5e3Sopenharmony_ci } 12764514f5e3Sopenharmony_ci acc_.DeleteGate(hirGate); 12774514f5e3Sopenharmony_ci} 12784514f5e3Sopenharmony_ci 12794514f5e3Sopenharmony_civoid SlowPathLowering::LowerLdSymbol(GateRef gate) 12804514f5e3Sopenharmony_ci{ 12814514f5e3Sopenharmony_ci const int id = RTSTUB_ID(GetSymbolFunction); 12824514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, {}); 12834514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 12844514f5e3Sopenharmony_ci} 12854514f5e3Sopenharmony_ci 12864514f5e3Sopenharmony_civoid SlowPathLowering::LowerLdGlobal(GateRef gate) 12874514f5e3Sopenharmony_ci{ 12884514f5e3Sopenharmony_ci GateRef offset = builder_.Int64(JSThread::GlueData::GetGlobalObjOffset(false)); 12894514f5e3Sopenharmony_ci GateRef val = builder_.Int64Add(glue_, offset); 12904514f5e3Sopenharmony_ci auto bit = LoadStoreAccessor::ToValue(MemoryAttribute::Default()); 12914514f5e3Sopenharmony_ci GateRef newGate = circuit_->NewGate(circuit_->Load(bit), VariableType::JS_ANY().GetMachineType(), 12924514f5e3Sopenharmony_ci { builder_.GetDepend(), val }, VariableType::JS_ANY().GetGateType()); 12934514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 12944514f5e3Sopenharmony_ci} 12954514f5e3Sopenharmony_ci 12964514f5e3Sopenharmony_civoid SlowPathLowering::LowerSub2(GateRef gate) 12974514f5e3Sopenharmony_ci{ 12984514f5e3Sopenharmony_ci // 2: number of value inputs 12994514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 13004514f5e3Sopenharmony_ci GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::Sub, 13014514f5e3Sopenharmony_ci { glue_, acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1) }); 13024514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 13034514f5e3Sopenharmony_ci} 13044514f5e3Sopenharmony_ci 13054514f5e3Sopenharmony_civoid SlowPathLowering::LowerMul2(GateRef gate) 13064514f5e3Sopenharmony_ci{ 13074514f5e3Sopenharmony_ci // 2: number of value inputs 13084514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 13094514f5e3Sopenharmony_ci GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::Mul, 13104514f5e3Sopenharmony_ci { glue_, acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1) }); 13114514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 13124514f5e3Sopenharmony_ci} 13134514f5e3Sopenharmony_ci 13144514f5e3Sopenharmony_civoid SlowPathLowering::LowerDiv2(GateRef gate) 13154514f5e3Sopenharmony_ci{ 13164514f5e3Sopenharmony_ci // 2: number of value inputs 13174514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 13184514f5e3Sopenharmony_ci GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::Div, 13194514f5e3Sopenharmony_ci { glue_, acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1) }); 13204514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 13214514f5e3Sopenharmony_ci} 13224514f5e3Sopenharmony_ci 13234514f5e3Sopenharmony_civoid SlowPathLowering::LowerMod2(GateRef gate) 13244514f5e3Sopenharmony_ci{ 13254514f5e3Sopenharmony_ci // 2: number of value inputs 13264514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 13274514f5e3Sopenharmony_ci GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::Mod, 13284514f5e3Sopenharmony_ci { glue_, acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1) }); 13294514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 13304514f5e3Sopenharmony_ci} 13314514f5e3Sopenharmony_ci 13324514f5e3Sopenharmony_civoid SlowPathLowering::LowerEq(GateRef gate) 13334514f5e3Sopenharmony_ci{ 13344514f5e3Sopenharmony_ci // 2: number of value inputs 13354514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 13364514f5e3Sopenharmony_ci GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::Equal, 13374514f5e3Sopenharmony_ci { glue_, acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1) }); 13384514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 13394514f5e3Sopenharmony_ci} 13404514f5e3Sopenharmony_ci 13414514f5e3Sopenharmony_civoid SlowPathLowering::LowerNotEq(GateRef gate) 13424514f5e3Sopenharmony_ci{ 13434514f5e3Sopenharmony_ci // 2: number of value inputs 13444514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 13454514f5e3Sopenharmony_ci GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::NotEqual, 13464514f5e3Sopenharmony_ci { glue_, acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1) }); 13474514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 13484514f5e3Sopenharmony_ci} 13494514f5e3Sopenharmony_ci 13504514f5e3Sopenharmony_civoid SlowPathLowering::LowerLess(GateRef gate) 13514514f5e3Sopenharmony_ci{ 13524514f5e3Sopenharmony_ci // 2: number of value inputs 13534514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 13544514f5e3Sopenharmony_ci GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::Less, 13554514f5e3Sopenharmony_ci { glue_, acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1) }); 13564514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 13574514f5e3Sopenharmony_ci} 13584514f5e3Sopenharmony_ci 13594514f5e3Sopenharmony_civoid SlowPathLowering::LowerLessEq(GateRef gate) 13604514f5e3Sopenharmony_ci{ 13614514f5e3Sopenharmony_ci // 2: number of value inputs 13624514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 13634514f5e3Sopenharmony_ci GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::LessEq, 13644514f5e3Sopenharmony_ci { glue_, acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1) }); 13654514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 13664514f5e3Sopenharmony_ci} 13674514f5e3Sopenharmony_ci 13684514f5e3Sopenharmony_civoid SlowPathLowering::LowerGreater(GateRef gate) 13694514f5e3Sopenharmony_ci{ 13704514f5e3Sopenharmony_ci // 2: number of value inputs 13714514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 13724514f5e3Sopenharmony_ci GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::Greater, 13734514f5e3Sopenharmony_ci { glue_, acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1) }); 13744514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 13754514f5e3Sopenharmony_ci} 13764514f5e3Sopenharmony_ci 13774514f5e3Sopenharmony_civoid SlowPathLowering::LowerGreaterEq(GateRef gate) 13784514f5e3Sopenharmony_ci{ 13794514f5e3Sopenharmony_ci // 2: number of value inputs 13804514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 13814514f5e3Sopenharmony_ci GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::GreaterEq, 13824514f5e3Sopenharmony_ci { glue_, acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1) }); 13834514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 13844514f5e3Sopenharmony_ci} 13854514f5e3Sopenharmony_ci 13864514f5e3Sopenharmony_civoid SlowPathLowering::LowerGetPropIterator(GateRef gate) 13874514f5e3Sopenharmony_ci{ 13884514f5e3Sopenharmony_ci // 1: number of value inputs 13894514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 1); 13904514f5e3Sopenharmony_ci GateRef object = {acc_.GetValueIn(gate, 0)}; 13914514f5e3Sopenharmony_ci GateRef newGate = builder_.CallStub(glue_, gate, CommonStubCSigns::Getpropiterator, {glue_, object}); 13924514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 13934514f5e3Sopenharmony_ci} 13944514f5e3Sopenharmony_ci 13954514f5e3Sopenharmony_civoid SlowPathLowering::LowerCloseIterator(GateRef gate) 13964514f5e3Sopenharmony_ci{ 13974514f5e3Sopenharmony_ci const int id = RTSTUB_ID(CloseIterator); 13984514f5e3Sopenharmony_ci // 1: number of value inputs 13994514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 1); 14004514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, {acc_.GetValueIn(gate, 0)}); 14014514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 14024514f5e3Sopenharmony_ci} 14034514f5e3Sopenharmony_ci 14044514f5e3Sopenharmony_civoid SlowPathLowering::LowerInc(GateRef gate) 14054514f5e3Sopenharmony_ci{ 14064514f5e3Sopenharmony_ci // 1: number of value inputs 14074514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 1); 14084514f5e3Sopenharmony_ci GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::Inc, 14094514f5e3Sopenharmony_ci { glue_, acc_.GetValueIn(gate, 0) }); 14104514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 14114514f5e3Sopenharmony_ci} 14124514f5e3Sopenharmony_ci 14134514f5e3Sopenharmony_civoid SlowPathLowering::LowerDec(GateRef gate) 14144514f5e3Sopenharmony_ci{ 14154514f5e3Sopenharmony_ci // 1: number of value inputs 14164514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 1); 14174514f5e3Sopenharmony_ci GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::Dec, 14184514f5e3Sopenharmony_ci { glue_, acc_.GetValueIn(gate, 0) }); 14194514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 14204514f5e3Sopenharmony_ci} 14214514f5e3Sopenharmony_ci 14224514f5e3Sopenharmony_civoid SlowPathLowering::LowerToNumber(GateRef gate) 14234514f5e3Sopenharmony_ci{ 14244514f5e3Sopenharmony_ci // 1: number of value inputs 14254514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 1); 14264514f5e3Sopenharmony_ci Label notNumber(&builder_); 14274514f5e3Sopenharmony_ci Label checkResult(&builder_); 14284514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 0); 14294514f5e3Sopenharmony_ci DEFVALUE(result, (&builder_), VariableType::JS_ANY(), value); 14304514f5e3Sopenharmony_ci BRANCH_CIR(builder_.TaggedIsNumber(value), &checkResult, ¬Number); 14314514f5e3Sopenharmony_ci builder_.Bind(¬Number); 14324514f5e3Sopenharmony_ci { 14334514f5e3Sopenharmony_ci result = LowerCallRuntime(gate, RTSTUB_ID(ToNumber), { value }, true); 14344514f5e3Sopenharmony_ci builder_.Jump(&checkResult); 14354514f5e3Sopenharmony_ci } 14364514f5e3Sopenharmony_ci builder_.Bind(&checkResult); 14374514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, *result); 14384514f5e3Sopenharmony_ci} 14394514f5e3Sopenharmony_ci 14404514f5e3Sopenharmony_civoid SlowPathLowering::LowerNeg(GateRef gate) 14414514f5e3Sopenharmony_ci{ 14424514f5e3Sopenharmony_ci // 1: number of value inputs 14434514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 1); 14444514f5e3Sopenharmony_ci GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::Neg, 14454514f5e3Sopenharmony_ci { glue_, acc_.GetValueIn(gate, 0) }); 14464514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 14474514f5e3Sopenharmony_ci} 14484514f5e3Sopenharmony_ci 14494514f5e3Sopenharmony_civoid SlowPathLowering::LowerNot(GateRef gate) 14504514f5e3Sopenharmony_ci{ 14514514f5e3Sopenharmony_ci // 1: number of value inputs 14524514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 1); 14534514f5e3Sopenharmony_ci GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::Not, 14544514f5e3Sopenharmony_ci { glue_, acc_.GetValueIn(gate, 0) }); 14554514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 14564514f5e3Sopenharmony_ci} 14574514f5e3Sopenharmony_ci 14584514f5e3Sopenharmony_civoid SlowPathLowering::LowerShl2(GateRef gate) 14594514f5e3Sopenharmony_ci{ 14604514f5e3Sopenharmony_ci // 2: number of value inputs 14614514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 14624514f5e3Sopenharmony_ci GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::Shl, 14634514f5e3Sopenharmony_ci { glue_, acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1) }); 14644514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 14654514f5e3Sopenharmony_ci} 14664514f5e3Sopenharmony_ci 14674514f5e3Sopenharmony_civoid SlowPathLowering::LowerShr2(GateRef gate) 14684514f5e3Sopenharmony_ci{ 14694514f5e3Sopenharmony_ci // 2: number of value inputs 14704514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 14714514f5e3Sopenharmony_ci GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::Shr, 14724514f5e3Sopenharmony_ci { glue_, acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1) }); 14734514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 14744514f5e3Sopenharmony_ci} 14754514f5e3Sopenharmony_ci 14764514f5e3Sopenharmony_civoid SlowPathLowering::LowerAshr2(GateRef gate) 14774514f5e3Sopenharmony_ci{ 14784514f5e3Sopenharmony_ci // 2: number of value inputs 14794514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 14804514f5e3Sopenharmony_ci GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::Ashr, 14814514f5e3Sopenharmony_ci { glue_, acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1) }); 14824514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 14834514f5e3Sopenharmony_ci} 14844514f5e3Sopenharmony_ci 14854514f5e3Sopenharmony_civoid SlowPathLowering::LowerAnd2(GateRef gate) 14864514f5e3Sopenharmony_ci{ 14874514f5e3Sopenharmony_ci // 2: number of value inputs 14884514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 14894514f5e3Sopenharmony_ci GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::And, 14904514f5e3Sopenharmony_ci { glue_, acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1) }); 14914514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 14924514f5e3Sopenharmony_ci} 14934514f5e3Sopenharmony_ci 14944514f5e3Sopenharmony_civoid SlowPathLowering::LowerOr2(GateRef gate) 14954514f5e3Sopenharmony_ci{ 14964514f5e3Sopenharmony_ci // 2: number of value inputs 14974514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 14984514f5e3Sopenharmony_ci GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::Or, 14994514f5e3Sopenharmony_ci { glue_, acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1) }); 15004514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 15014514f5e3Sopenharmony_ci} 15024514f5e3Sopenharmony_ci 15034514f5e3Sopenharmony_civoid SlowPathLowering::LowerXor2(GateRef gate) 15044514f5e3Sopenharmony_ci{ 15054514f5e3Sopenharmony_ci // 2: number of value inputs 15064514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 15074514f5e3Sopenharmony_ci GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::Xor, 15084514f5e3Sopenharmony_ci { glue_, acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1) }); 15094514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 15104514f5e3Sopenharmony_ci} 15114514f5e3Sopenharmony_ci 15124514f5e3Sopenharmony_civoid SlowPathLowering::LowerDelObjProp(GateRef gate) 15134514f5e3Sopenharmony_ci{ 15144514f5e3Sopenharmony_ci // 2: number of value inputs 15154514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 15164514f5e3Sopenharmony_ci Label successExit(&builder_); 15174514f5e3Sopenharmony_ci Label exceptionExit(&builder_); 15184514f5e3Sopenharmony_ci GateRef newGate = builder_.CallStub(glue_, gate, CommonStubCSigns::DeleteObjectProperty, 15194514f5e3Sopenharmony_ci { glue_, acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1) }); 15204514f5e3Sopenharmony_ci BRANCH_CIR(builder_.IsSpecial(newGate, JSTaggedValue::VALUE_EXCEPTION), 15214514f5e3Sopenharmony_ci &exceptionExit, &successExit); 15224514f5e3Sopenharmony_ci CREATE_DOUBLE_EXIT(successExit, exceptionExit) 15234514f5e3Sopenharmony_ci acc_.ReplaceHirWithIfBranch(gate, successControl, failControl, newGate); 15244514f5e3Sopenharmony_ci} 15254514f5e3Sopenharmony_ci 15264514f5e3Sopenharmony_civoid SlowPathLowering::LowerExp(GateRef gate) 15274514f5e3Sopenharmony_ci{ 15284514f5e3Sopenharmony_ci const int id = RTSTUB_ID(Exp); 15294514f5e3Sopenharmony_ci // 2: number of value inputs 15304514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 15314514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, {acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1)}); 15324514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 15334514f5e3Sopenharmony_ci} 15344514f5e3Sopenharmony_ci 15354514f5e3Sopenharmony_civoid SlowPathLowering::LowerIsIn(GateRef gate) 15364514f5e3Sopenharmony_ci{ 15374514f5e3Sopenharmony_ci const int id = RTSTUB_ID(IsIn); 15384514f5e3Sopenharmony_ci // 2: number of value inputs 15394514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 15404514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, {acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1)}); 15414514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 15424514f5e3Sopenharmony_ci} 15434514f5e3Sopenharmony_ci 15444514f5e3Sopenharmony_civoid SlowPathLowering::LowerInstanceof(GateRef gate) 15454514f5e3Sopenharmony_ci{ 15464514f5e3Sopenharmony_ci // 3: number of value inputs 15474514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 3); 15484514f5e3Sopenharmony_ci GateRef obj = acc_.GetValueIn(gate, 1); // 1: the second parameter 15494514f5e3Sopenharmony_ci GateRef target = acc_.GetValueIn(gate, 2); // 2: the third parameter 15504514f5e3Sopenharmony_ci LowerCallStubWithIC(gate, CommonStubCSigns::Instanceof, { obj, target }); 15514514f5e3Sopenharmony_ci} 15524514f5e3Sopenharmony_ci 15534514f5e3Sopenharmony_civoid SlowPathLowering::LowerFastStrictNotEqual(GateRef gate) 15544514f5e3Sopenharmony_ci{ 15554514f5e3Sopenharmony_ci // 2: number of value inputs 15564514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 15574514f5e3Sopenharmony_ci // 2: number of value inputs 15584514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 15594514f5e3Sopenharmony_ci GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::StrictNotEqual, 15604514f5e3Sopenharmony_ci { glue_, acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1) }); 15614514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 15624514f5e3Sopenharmony_ci} 15634514f5e3Sopenharmony_ci 15644514f5e3Sopenharmony_civoid SlowPathLowering::LowerFastStrictEqual(GateRef gate) 15654514f5e3Sopenharmony_ci{ 15664514f5e3Sopenharmony_ci // 2: number of value inputs 15674514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 15684514f5e3Sopenharmony_ci GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::StrictEqual, 15694514f5e3Sopenharmony_ci { glue_, acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1) }); 15704514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 15714514f5e3Sopenharmony_ci} 15724514f5e3Sopenharmony_ci 15734514f5e3Sopenharmony_civoid SlowPathLowering::LowerCreateEmptyArray(GateRef gate) 15744514f5e3Sopenharmony_ci{ 15754514f5e3Sopenharmony_ci GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::CreateEmptyArray, { glue_ }); 15764514f5e3Sopenharmony_ci GateRef newRes = LowerUpdateArrayHClassAtDefine(gate, result); 15774514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newRes, true); 15784514f5e3Sopenharmony_ci} 15794514f5e3Sopenharmony_ci 15804514f5e3Sopenharmony_civoid SlowPathLowering::LowerCreateEmptyObject(GateRef gate) 15814514f5e3Sopenharmony_ci{ 15824514f5e3Sopenharmony_ci GateRef result = LowerCallRuntime(gate, RTSTUB_ID(CreateEmptyObject), {}, true); 15834514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result, true); 15844514f5e3Sopenharmony_ci} 15854514f5e3Sopenharmony_ci 15864514f5e3Sopenharmony_civoid SlowPathLowering::LowerCreateArrayWithBuffer(GateRef gate) 15874514f5e3Sopenharmony_ci{ 15884514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 15894514f5e3Sopenharmony_ci GateRef index = builder_.TruncInt64ToInt32(acc_.GetValueIn(gate, 0)); 15904514f5e3Sopenharmony_ci GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::CreateArrayWithBuffer, { glue_, index, jsFunc }); 15914514f5e3Sopenharmony_ci // when elementsKind switch on, we should not update arrayHClass here. 15924514f5e3Sopenharmony_ci GateRef newRes = LowerUpdateArrayHClassAtDefine(gate, result); 15934514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newRes, true); 15944514f5e3Sopenharmony_ci} 15954514f5e3Sopenharmony_ci 15964514f5e3Sopenharmony_ciGateRef SlowPathLowering::LowerUpdateArrayHClassAtDefine(GateRef gate, GateRef array) 15974514f5e3Sopenharmony_ci{ 15984514f5e3Sopenharmony_ci ElementsKind kind = acc_.TryGetElementsKind(gate); 15994514f5e3Sopenharmony_ci if (!Elements::IsGeneric(kind)) { 16004514f5e3Sopenharmony_ci size_t hclassIndex = static_cast<size_t>(compilationEnv_->GetArrayHClassIndexMap().at(kind).first); 16014514f5e3Sopenharmony_ci GateRef gConstAddr = builder_.Load(VariableType::JS_POINTER(), glue_, 16024514f5e3Sopenharmony_ci builder_.IntPtr(JSThread::GlueData::GetGlobalConstOffset(false))); 16034514f5e3Sopenharmony_ci GateRef constantIndex = builder_.IntPtr(JSTaggedValue::TaggedTypeSize() * hclassIndex); 16044514f5e3Sopenharmony_ci GateRef hclass = builder_.Load(VariableType::JS_POINTER(), gConstAddr, constantIndex); 16054514f5e3Sopenharmony_ci builder_.Store(VariableType::JS_POINTER(), glue_, array, builder_.IntPtr(0), hclass); 16064514f5e3Sopenharmony_ci } 16074514f5e3Sopenharmony_ci return array; 16084514f5e3Sopenharmony_ci} 16094514f5e3Sopenharmony_ci 16104514f5e3Sopenharmony_civoid SlowPathLowering::LowerCreateObjectWithBuffer(GateRef gate) 16114514f5e3Sopenharmony_ci{ 16124514f5e3Sopenharmony_ci // 2: number of value inputs 16134514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 16144514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 16154514f5e3Sopenharmony_ci GateRef sharedConstPool = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::SHARED_CONST_POOL); 16164514f5e3Sopenharmony_ci GateRef unsharedConstPool = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::UNSHARED_CONST_POOL); 16174514f5e3Sopenharmony_ci GateRef index = acc_.GetValueIn(gate, 0); 16184514f5e3Sopenharmony_ci GateRef module = builder_.GetModuleFromFunction(jsFunc); 16194514f5e3Sopenharmony_ci GateRef obj = builder_.GetObjectFromConstPool(glue_, gate, sharedConstPool, unsharedConstPool, module, 16204514f5e3Sopenharmony_ci builder_.TruncInt64ToInt32(index), ConstPoolType::OBJECT_LITERAL); 16214514f5e3Sopenharmony_ci GateRef lexEnv = acc_.GetValueIn(gate, 1); 16224514f5e3Sopenharmony_ci GateRef result = LowerCallRuntime(gate, RTSTUB_ID(CreateObjectHavingMethod), { obj, lexEnv }, true); 16234514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 16244514f5e3Sopenharmony_ci} 16254514f5e3Sopenharmony_ci 16264514f5e3Sopenharmony_civoid SlowPathLowering::LowerStModuleVar(GateRef gate) 16274514f5e3Sopenharmony_ci{ 16284514f5e3Sopenharmony_ci // 2: number of value inputs 16294514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 16304514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 16314514f5e3Sopenharmony_ci GateRef index = builder_.ToTaggedInt(acc_.GetValueIn(gate, 0)); 16324514f5e3Sopenharmony_ci auto result = LowerCallRuntime(gate, RTSTUB_ID(StModuleVarByIndexOnJSFunc), 16334514f5e3Sopenharmony_ci {index, acc_.GetValueIn(gate, 1), jsFunc}, true); 16344514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result, true); 16354514f5e3Sopenharmony_ci} 16364514f5e3Sopenharmony_ci 16374514f5e3Sopenharmony_civoid SlowPathLowering::LowerSetGeneratorState(GateRef gate) 16384514f5e3Sopenharmony_ci{ 16394514f5e3Sopenharmony_ci // 2: number of value inputs 16404514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 16414514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 16424514f5e3Sopenharmony_ci GateRef index = builder_.ToTaggedInt(acc_.GetValueIn(gate, 0)); 16434514f5e3Sopenharmony_ci auto result = LowerCallRuntime(gate, RTSTUB_ID(SetGeneratorState), 16444514f5e3Sopenharmony_ci {acc_.GetValueIn(gate, 1), index, jsFunc}, true); 16454514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result, true); 16464514f5e3Sopenharmony_ci} 16474514f5e3Sopenharmony_ci 16484514f5e3Sopenharmony_civoid SlowPathLowering::LowerGetTemplateObject(GateRef gate) 16494514f5e3Sopenharmony_ci{ 16504514f5e3Sopenharmony_ci const int id = RTSTUB_ID(GetTemplateObject); 16514514f5e3Sopenharmony_ci // 1: number of value inputs 16524514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 1); 16534514f5e3Sopenharmony_ci GateRef literal = acc_.GetValueIn(gate, 0); 16544514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, { literal }); 16554514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 16564514f5e3Sopenharmony_ci} 16574514f5e3Sopenharmony_ci 16584514f5e3Sopenharmony_civoid SlowPathLowering::LowerSetObjectWithProto(GateRef gate) 16594514f5e3Sopenharmony_ci{ 16604514f5e3Sopenharmony_ci const int id = RTSTUB_ID(SetObjectWithProto); 16614514f5e3Sopenharmony_ci // 2: number of value inputs 16624514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 16634514f5e3Sopenharmony_ci GateRef proto = acc_.GetValueIn(gate, 0); 16644514f5e3Sopenharmony_ci GateRef obj = acc_.GetValueIn(gate, 1); 16654514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, { proto, obj }); 16664514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 16674514f5e3Sopenharmony_ci} 16684514f5e3Sopenharmony_ci 16694514f5e3Sopenharmony_civoid SlowPathLowering::LowerLdBigInt(GateRef gate) 16704514f5e3Sopenharmony_ci{ 16714514f5e3Sopenharmony_ci // 1: number of value inputs 16724514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 1); 16734514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 16744514f5e3Sopenharmony_ci GateRef sharedConstPool = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::SHARED_CONST_POOL); 16754514f5e3Sopenharmony_ci GateRef stringId = builder_.TruncInt64ToInt32(acc_.GetValueIn(gate, 0)); 16764514f5e3Sopenharmony_ci GateRef module = builder_.GetModuleFromFunction(jsFunc); 16774514f5e3Sopenharmony_ci GateRef numberBigInt = builder_.GetObjectFromConstPool(glue_, gate, sharedConstPool, Circuit::NullGate(), module, 16784514f5e3Sopenharmony_ci stringId, ConstPoolType::STRING); 16794514f5e3Sopenharmony_ci GateRef result = LowerCallRuntime(gate, RTSTUB_ID(LdBigInt), {numberBigInt}, true); 16804514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 16814514f5e3Sopenharmony_ci} 16824514f5e3Sopenharmony_ci 16834514f5e3Sopenharmony_civoid SlowPathLowering::LowerToNumeric(GateRef gate) 16844514f5e3Sopenharmony_ci{ 16854514f5e3Sopenharmony_ci // 1: number of value inputs 16864514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 1); 16874514f5e3Sopenharmony_ci Label notNumber(&builder_); 16884514f5e3Sopenharmony_ci Label checkResult(&builder_); 16894514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 0); 16904514f5e3Sopenharmony_ci DEFVALUE(result, (&builder_), VariableType::JS_ANY(), value); 16914514f5e3Sopenharmony_ci BRANCH_CIR(builder_.TaggedIsNumeric(value), &checkResult, ¬Number); 16924514f5e3Sopenharmony_ci builder_.Bind(¬Number); 16934514f5e3Sopenharmony_ci { 16944514f5e3Sopenharmony_ci result = LowerCallRuntime(gate, RTSTUB_ID(ToNumeric), { value }, true); 16954514f5e3Sopenharmony_ci builder_.Jump(&checkResult); 16964514f5e3Sopenharmony_ci } 16974514f5e3Sopenharmony_ci builder_.Bind(&checkResult); 16984514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, *result); 16994514f5e3Sopenharmony_ci} 17004514f5e3Sopenharmony_ci 17014514f5e3Sopenharmony_civoid SlowPathLowering::LowerDynamicImport(GateRef gate) 17024514f5e3Sopenharmony_ci{ 17034514f5e3Sopenharmony_ci const int id = RTSTUB_ID(DynamicImport); 17044514f5e3Sopenharmony_ci // 1: number of value inputs 17054514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 1); 17064514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 17074514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, {acc_.GetValueIn(gate, 0), jsFunc}); 17084514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 17094514f5e3Sopenharmony_ci} 17104514f5e3Sopenharmony_ci 17114514f5e3Sopenharmony_civoid SlowPathLowering::LowerLdLocalModuleVarByIndex(GateRef gate) 17124514f5e3Sopenharmony_ci{ 17134514f5e3Sopenharmony_ci // 2: number of value inputs 17144514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 1); 17154514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 17164514f5e3Sopenharmony_ci GateRef index = builder_.ToTaggedInt(acc_.GetValueIn(gate, 0)); 17174514f5e3Sopenharmony_ci GateRef result = LowerCallRuntime(gate, RTSTUB_ID(LdLocalModuleVarByIndexOnJSFunc), {index, jsFunc}, true); 17184514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 17194514f5e3Sopenharmony_ci} 17204514f5e3Sopenharmony_ci 17214514f5e3Sopenharmony_civoid SlowPathLowering::LowerExternalModule(GateRef gate) 17224514f5e3Sopenharmony_ci{ 17234514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 1); 17244514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 17254514f5e3Sopenharmony_ci GateRef index = builder_.ToTaggedInt(acc_.GetValueIn(gate, 0)); 17264514f5e3Sopenharmony_ci GateRef result = LowerCallRuntime(gate, RTSTUB_ID(LdExternalModuleVarByIndexOnJSFunc), {index, jsFunc}, true); 17274514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 17284514f5e3Sopenharmony_ci} 17294514f5e3Sopenharmony_ci 17304514f5e3Sopenharmony_civoid SlowPathLowering::LowerGetModuleNamespace(GateRef gate) 17314514f5e3Sopenharmony_ci{ 17324514f5e3Sopenharmony_ci // 1: number of value inputs 17334514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 1); 17344514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 17354514f5e3Sopenharmony_ci GateRef index = builder_.ToTaggedInt(acc_.GetValueIn(gate, 0)); 17364514f5e3Sopenharmony_ci GateRef result = LowerCallRuntime(gate, RTSTUB_ID(GetModuleNamespaceByIndexOnJSFunc), {index, jsFunc}, true); 17374514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 17384514f5e3Sopenharmony_ci} 17394514f5e3Sopenharmony_ci 17404514f5e3Sopenharmony_ciGateRef SlowPathLowering::GetTaggedArrayFromValueIn(Environment *env, GateRef gate, size_t length) 17414514f5e3Sopenharmony_ci{ 17424514f5e3Sopenharmony_ci NewObjectStubBuilder objBuilder(env); 17434514f5e3Sopenharmony_ci GateRef taggedArray = objBuilder.NewTaggedArray(glue_, builder_.Int32(length)); 17444514f5e3Sopenharmony_ci for (size_t i = 0; i < length; i++) { 17454514f5e3Sopenharmony_ci builder_.SetValueToTaggedArray(VariableType::JS_ANY(), glue_, taggedArray, 17464514f5e3Sopenharmony_ci builder_.Int32(i), acc_.GetValueIn(gate, i)); 17474514f5e3Sopenharmony_ci } 17484514f5e3Sopenharmony_ci return taggedArray; 17494514f5e3Sopenharmony_ci} 17504514f5e3Sopenharmony_ci 17514514f5e3Sopenharmony_civoid SlowPathLowering::LowerSuperCall(GateRef gate) 17524514f5e3Sopenharmony_ci{ 17534514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 17544514f5e3Sopenharmony_ci NewObjectStubBuilder objBuilder(&env); 17554514f5e3Sopenharmony_ci DEFVALUE(result, (&builder_), VariableType::JS_ANY(), builder_.Undefined()); 17564514f5e3Sopenharmony_ci DEFVALUE(thisObj, (&builder_), VariableType::JS_ANY(), builder_.Undefined()); 17574514f5e3Sopenharmony_ci DEFVALUE(newTarget, (&builder_), VariableType::JS_ANY(), argAcc_.GetFrameArgsIn(gate, FrameArgIdx::NEW_TARGET)); 17584514f5e3Sopenharmony_ci Label fastPath(&builder_); 17594514f5e3Sopenharmony_ci Label slowPath(&builder_); 17604514f5e3Sopenharmony_ci Label callExit(&builder_); 17614514f5e3Sopenharmony_ci Label replaceGate(&builder_); 17624514f5e3Sopenharmony_ci size_t length = acc_.GetNumValueIn(gate); 17634514f5e3Sopenharmony_ci GateRef taggedLength = builder_.ToTaggedInt(builder_.Int64(length)); 17644514f5e3Sopenharmony_ci GateRef taggedArray = GetTaggedArrayFromValueIn(&env, gate, length); 17654514f5e3Sopenharmony_ci GateRef func = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 17664514f5e3Sopenharmony_ci GateRef superFunc = objBuilder.GetPrototype(glue_, func); 17674514f5e3Sopenharmony_ci 17684514f5e3Sopenharmony_ci CheckSuperAndNewTarget(objBuilder, superFunc, newTarget, thisObj, fastPath, slowPath); 17694514f5e3Sopenharmony_ci builder_.Bind(&fastPath); 17704514f5e3Sopenharmony_ci { 17714514f5e3Sopenharmony_ci LowerFastSuperCallWithArgArray(taggedArray, {gate, superFunc, *newTarget, *thisObj, 17724514f5e3Sopenharmony_ci builder_.Int64(length)}, false, result, callExit); // false: not spread 17734514f5e3Sopenharmony_ci builder_.Bind(&callExit); 17744514f5e3Sopenharmony_ci result = objBuilder.ConstructorCheck(glue_, superFunc, *result, *thisObj); 17754514f5e3Sopenharmony_ci builder_.Jump(&replaceGate); 17764514f5e3Sopenharmony_ci } 17774514f5e3Sopenharmony_ci builder_.Bind(&slowPath); 17784514f5e3Sopenharmony_ci { 17794514f5e3Sopenharmony_ci result = LowerCallRuntime(gate, RTSTUB_ID(OptSuperCall), { func, *newTarget, taggedArray, taggedLength }); 17804514f5e3Sopenharmony_ci builder_.Jump(&replaceGate); 17814514f5e3Sopenharmony_ci } 17824514f5e3Sopenharmony_ci builder_.Bind(&replaceGate); 17834514f5e3Sopenharmony_ci ReplaceHirWithPendingException(gate, builder_.GetState(), builder_.GetDepend(), *result); 17844514f5e3Sopenharmony_ci} 17854514f5e3Sopenharmony_ci 17864514f5e3Sopenharmony_civoid SlowPathLowering::LowerSuperCallArrow(GateRef gate) 17874514f5e3Sopenharmony_ci{ 17884514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 17894514f5e3Sopenharmony_ci NewObjectStubBuilder objBuilder(&env); 17904514f5e3Sopenharmony_ci const int id = RTSTUB_ID(OptSuperCall); 17914514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) > 0); 17924514f5e3Sopenharmony_ci GateRef newTarget = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::NEW_TARGET); 17934514f5e3Sopenharmony_ci size_t funcIndex = acc_.GetNumValueIn(gate) - 1; 17944514f5e3Sopenharmony_ci GateRef taggedLength = builder_.ToTaggedInt(builder_.Int64(funcIndex)); 17954514f5e3Sopenharmony_ci GateRef taggedArray = GetTaggedArrayFromValueIn(&env, gate, funcIndex); 17964514f5e3Sopenharmony_ci GateRef func = acc_.GetValueIn(gate, funcIndex); 17974514f5e3Sopenharmony_ci std::vector<GateRef> vec { func, newTarget, taggedArray, taggedLength}; 17984514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, vec); 17994514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 18004514f5e3Sopenharmony_ci} 18014514f5e3Sopenharmony_ci 18024514f5e3Sopenharmony_civoid SlowPathLowering::LowerSuperCallSpread(GateRef gate) 18034514f5e3Sopenharmony_ci{ 18044514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 18054514f5e3Sopenharmony_ci NewObjectStubBuilder objBuilder(&env); 18064514f5e3Sopenharmony_ci DEFVALUE(result, (&builder_), VariableType::JS_ANY(), builder_.Undefined()); 18074514f5e3Sopenharmony_ci DEFVALUE(thisObj, (&builder_), VariableType::JS_ANY(), builder_.Undefined()); 18084514f5e3Sopenharmony_ci DEFVALUE(newTarget, (&builder_), VariableType::JS_ANY(), argAcc_.GetFrameArgsIn(gate, FrameArgIdx::NEW_TARGET)); 18094514f5e3Sopenharmony_ci Label fastPath(&builder_); 18104514f5e3Sopenharmony_ci Label slowPath(&builder_); 18114514f5e3Sopenharmony_ci Label callExit(&builder_); 18124514f5e3Sopenharmony_ci Label replaceGate(&builder_); 18134514f5e3Sopenharmony_ci 18144514f5e3Sopenharmony_ci GateRef array = acc_.GetValueIn(gate, 0); 18154514f5e3Sopenharmony_ci GateRef func = acc_.GetValueIn(gate, 1); 18164514f5e3Sopenharmony_ci GateRef superFunc = objBuilder.GetPrototype(glue_, func); 18174514f5e3Sopenharmony_ci CheckSuperAndNewTarget(objBuilder, superFunc, newTarget, thisObj, fastPath, slowPath); 18184514f5e3Sopenharmony_ci builder_.Bind(&fastPath); 18194514f5e3Sopenharmony_ci { 18204514f5e3Sopenharmony_ci GateRef actualArgc = builder_.ZExtInt32ToInt64( 18214514f5e3Sopenharmony_ci builder_.Load(VariableType::INT32(), array, builder_.IntPtr(JSArray::LENGTH_OFFSET))); 18224514f5e3Sopenharmony_ci LowerFastSuperCallWithArgArray(array, {gate, superFunc, *newTarget, *thisObj, actualArgc}, 18234514f5e3Sopenharmony_ci true, result, callExit); // true: is spread 18244514f5e3Sopenharmony_ci builder_.Bind(&callExit); 18254514f5e3Sopenharmony_ci result = objBuilder.ConstructorCheck(glue_, superFunc, *result, *thisObj); 18264514f5e3Sopenharmony_ci builder_.Jump(&replaceGate); 18274514f5e3Sopenharmony_ci } 18284514f5e3Sopenharmony_ci builder_.Bind(&slowPath); 18294514f5e3Sopenharmony_ci { 18304514f5e3Sopenharmony_ci result = LowerCallRuntime(gate, RTSTUB_ID(OptSuperCallSpread), { func, *newTarget, array }); 18314514f5e3Sopenharmony_ci builder_.Jump(&replaceGate); 18324514f5e3Sopenharmony_ci } 18334514f5e3Sopenharmony_ci builder_.Bind(&replaceGate); 18344514f5e3Sopenharmony_ci ReplaceHirWithPendingException(gate, builder_.GetState(), builder_.GetDepend(), *result); 18354514f5e3Sopenharmony_ci} 18364514f5e3Sopenharmony_ci 18374514f5e3Sopenharmony_ciGateRef SlowPathLowering::IsAotOrFastCall(GateRef func, CircuitBuilder::JudgeMethodType type) 18384514f5e3Sopenharmony_ci{ 18394514f5e3Sopenharmony_ci return builder_.JudgeAotAndFastCall(func, type); 18404514f5e3Sopenharmony_ci} 18414514f5e3Sopenharmony_ci 18424514f5e3Sopenharmony_civoid SlowPathLowering::LowerFastSuperCallWithArgArray(GateRef array, const std::vector<GateRef> &args, 18434514f5e3Sopenharmony_ci bool isSpread, Variable &result, Label &exit) 18444514f5e3Sopenharmony_ci{ 18454514f5e3Sopenharmony_ci ASSERT(args.size() == 5); // 5: size of args 18464514f5e3Sopenharmony_ci GateRef srcElements; 18474514f5e3Sopenharmony_ci if (isSpread) { 18484514f5e3Sopenharmony_ci GateRef gate = args[0]; // 0: index of gate 18494514f5e3Sopenharmony_ci srcElements = builder_.CallStub(glue_, gate, CommonStubCSigns::GetCallSpreadArgs, {glue_, array}); 18504514f5e3Sopenharmony_ci } else { 18514514f5e3Sopenharmony_ci srcElements = array; 18524514f5e3Sopenharmony_ci } 18534514f5e3Sopenharmony_ci GateRef elementsPtr = builder_.GetDataOfTaggedArray(srcElements); 18544514f5e3Sopenharmony_ci LowerFastSuperCall(args, elementsPtr, result, exit); 18554514f5e3Sopenharmony_ci} 18564514f5e3Sopenharmony_ci 18574514f5e3Sopenharmony_civoid SlowPathLowering::LowerFastSuperCall(const std::vector<GateRef> &args, GateRef elementsPtr, 18584514f5e3Sopenharmony_ci Variable &result, Label &exit) 18594514f5e3Sopenharmony_ci{ 18604514f5e3Sopenharmony_ci Label fastCall(&builder_); 18614514f5e3Sopenharmony_ci Label notFastCall(&builder_); 18624514f5e3Sopenharmony_ci Label aotCall(&builder_); 18634514f5e3Sopenharmony_ci Label notAotCall(&builder_); 18644514f5e3Sopenharmony_ci ASSERT(args.size() == 5); // 5: size of args 18654514f5e3Sopenharmony_ci GateRef gate = args[0]; // 0: index of gate 18664514f5e3Sopenharmony_ci GateRef superFunc = args[1]; // 1: index of superFunc 18674514f5e3Sopenharmony_ci GateRef newTartget = args[2]; // 2: index of newTarget 18684514f5e3Sopenharmony_ci GateRef thisObj = args[3]; // 3: index of thisObj 18694514f5e3Sopenharmony_ci GateRef actualArgc = args[4]; // 4: index of actualArgc 18704514f5e3Sopenharmony_ci 18714514f5e3Sopenharmony_ci GateRef method = builder_.GetMethodFromFunction(superFunc); 18724514f5e3Sopenharmony_ci GateRef expectedNum = builder_.GetExpectedNumOfArgs(method); 18734514f5e3Sopenharmony_ci BRANCH_CIR(IsAotOrFastCall(superFunc, CircuitBuilder::JudgeMethodType::HAS_AOT_FASTCALL), &fastCall, ¬FastCall); 18744514f5e3Sopenharmony_ci builder_.Bind(&fastCall); 18754514f5e3Sopenharmony_ci { 18764514f5e3Sopenharmony_ci Label notBridge(&builder_); 18774514f5e3Sopenharmony_ci Label bridge(&builder_); 18784514f5e3Sopenharmony_ci BRANCH_CIR(builder_.Int64Equal(expectedNum, actualArgc), ¬Bridge, &bridge); 18794514f5e3Sopenharmony_ci builder_.Bind(¬Bridge); 18804514f5e3Sopenharmony_ci CallNGCRuntimeWithCallTimer(RTSTUB_ID(JSFastCallWithArgV), gate, superFunc, result, 18814514f5e3Sopenharmony_ci {glue_, superFunc, thisObj, actualArgc, elementsPtr}); 18824514f5e3Sopenharmony_ci builder_.Jump(&exit); 18834514f5e3Sopenharmony_ci builder_.Bind(&bridge); 18844514f5e3Sopenharmony_ci CallNGCRuntimeWithCallTimer(RTSTUB_ID(JSFastCallWithArgVAndPushArgv), gate, superFunc, result, 18854514f5e3Sopenharmony_ci {glue_, superFunc, thisObj, actualArgc, elementsPtr, expectedNum}); 18864514f5e3Sopenharmony_ci builder_.Jump(&exit); 18874514f5e3Sopenharmony_ci } 18884514f5e3Sopenharmony_ci builder_.Bind(¬FastCall); 18894514f5e3Sopenharmony_ci BRANCH_CIR(IsAotOrFastCall(superFunc, CircuitBuilder::JudgeMethodType::HAS_AOT), &aotCall, ¬AotCall); 18904514f5e3Sopenharmony_ci builder_.Bind(&aotCall); 18914514f5e3Sopenharmony_ci { 18924514f5e3Sopenharmony_ci Label notBridge(&builder_); 18934514f5e3Sopenharmony_ci Label bridge(&builder_); 18944514f5e3Sopenharmony_ci std::vector<GateRef> callArgs {glue_, actualArgc, superFunc, newTartget, thisObj, elementsPtr}; 18954514f5e3Sopenharmony_ci BRANCH_CIR(builder_.Int64Equal(expectedNum, actualArgc), ¬Bridge, &bridge); 18964514f5e3Sopenharmony_ci builder_.Bind(¬Bridge); 18974514f5e3Sopenharmony_ci CallNGCRuntimeWithCallTimer(RTSTUB_ID(JSCallWithArgV), gate, superFunc, result, callArgs); 18984514f5e3Sopenharmony_ci builder_.Jump(&exit); 18994514f5e3Sopenharmony_ci builder_.Bind(&bridge); 19004514f5e3Sopenharmony_ci CallNGCRuntimeWithCallTimer(RTSTUB_ID(JSCallWithArgVAndPushArgv), gate, superFunc, result, callArgs); 19014514f5e3Sopenharmony_ci builder_.Jump(&exit); 19024514f5e3Sopenharmony_ci } 19034514f5e3Sopenharmony_ci builder_.Bind(¬AotCall); 19044514f5e3Sopenharmony_ci CallNGCRuntimeWithCallTimer(RTSTUB_ID(SuperCallWithArgV), gate, superFunc, result, 19054514f5e3Sopenharmony_ci {glue_, actualArgc, superFunc, newTartget, thisObj, elementsPtr}); 19064514f5e3Sopenharmony_ci builder_.Jump(&exit); 19074514f5e3Sopenharmony_ci} 19084514f5e3Sopenharmony_ci 19094514f5e3Sopenharmony_civoid SlowPathLowering::CallNGCRuntimeWithCallTimer(int index, GateRef gate, GateRef func, Variable &result, 19104514f5e3Sopenharmony_ci const std::vector<GateRef> &args) 19114514f5e3Sopenharmony_ci{ 19124514f5e3Sopenharmony_ci builder_.StartCallTimer(glue_, gate, {glue_, func, builder_.True()}, true); 19134514f5e3Sopenharmony_ci result = LowerCallNGCRuntime(gate, index, args, true); 19144514f5e3Sopenharmony_ci builder_.EndCallTimer(glue_, gate, {glue_, func}, true); 19154514f5e3Sopenharmony_ci} 19164514f5e3Sopenharmony_ci 19174514f5e3Sopenharmony_civoid SlowPathLowering::CheckSuperAndNewTarget(NewObjectStubBuilder &objBuilder, GateRef super, Variable &newTarget, 19184514f5e3Sopenharmony_ci Variable &thisObj, Label &fastPath, Label &slowPath) 19194514f5e3Sopenharmony_ci{ 19204514f5e3Sopenharmony_ci Label isHeapObj(&builder_); 19214514f5e3Sopenharmony_ci Label isJsFunc(&builder_); 19224514f5e3Sopenharmony_ci Label isCtor(&builder_); 19234514f5e3Sopenharmony_ci Label targetUndefined(&builder_); 19244514f5e3Sopenharmony_ci Label normalPath(&builder_); 19254514f5e3Sopenharmony_ci Label needAllocateThis(&builder_); 19264514f5e3Sopenharmony_ci 19274514f5e3Sopenharmony_ci BRANCH_CIR(builder_.TaggedIsHeapObject(super), &isHeapObj, &slowPath); 19284514f5e3Sopenharmony_ci builder_.Bind(&isHeapObj); 19294514f5e3Sopenharmony_ci BRANCH_CIR(builder_.IsJSFunction(super), &isJsFunc, &slowPath); 19304514f5e3Sopenharmony_ci builder_.Bind(&isJsFunc); 19314514f5e3Sopenharmony_ci BRANCH_CIR(builder_.IsConstructor(super), &isCtor, &slowPath); 19324514f5e3Sopenharmony_ci builder_.Bind(&isCtor); 19334514f5e3Sopenharmony_ci BRANCH_CIR(builder_.TaggedIsUndefined(*newTarget), &targetUndefined, &normalPath); 19344514f5e3Sopenharmony_ci builder_.Bind(&targetUndefined); 19354514f5e3Sopenharmony_ci newTarget = super; 19364514f5e3Sopenharmony_ci builder_.Jump(&normalPath); 19374514f5e3Sopenharmony_ci builder_.Bind(&normalPath); 19384514f5e3Sopenharmony_ci BRANCH_CIR(builder_.IsBase(super), &needAllocateThis, &fastPath); 19394514f5e3Sopenharmony_ci builder_.Bind(&needAllocateThis); 19404514f5e3Sopenharmony_ci thisObj = objBuilder.FastSuperAllocateThis(glue_, super, *newTarget); 19414514f5e3Sopenharmony_ci builder_.Jump(&fastPath); 19424514f5e3Sopenharmony_ci} 19434514f5e3Sopenharmony_ci 19444514f5e3Sopenharmony_civoid SlowPathLowering::LowerSuperCallForwardAllArgs(GateRef gate) 19454514f5e3Sopenharmony_ci{ 19464514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 19474514f5e3Sopenharmony_ci NewObjectStubBuilder objBuilder(&env); 19484514f5e3Sopenharmony_ci DEFVALUE(newTarget, (&builder_), VariableType::JS_ANY(), argAcc_.GetFrameArgsIn(gate, FrameArgIdx::NEW_TARGET)); 19494514f5e3Sopenharmony_ci DEFVALUE(result, (&builder_), VariableType::JS_ANY(), builder_.Undefined()); 19504514f5e3Sopenharmony_ci DEFVALUE(thisObj, (&builder_), VariableType::JS_ANY(), builder_.Undefined()); 19514514f5e3Sopenharmony_ci GateRef func = acc_.GetValueIn(gate, 0); 19524514f5e3Sopenharmony_ci GateRef actualArgc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::ACTUAL_ARGC); 19534514f5e3Sopenharmony_ci GateRef actualArgv = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::ACTUAL_ARGV); 19544514f5e3Sopenharmony_ci GateRef super = objBuilder.GetPrototype(glue_, func); 19554514f5e3Sopenharmony_ci Label fastPath(&builder_); 19564514f5e3Sopenharmony_ci Label fastPathWithArgv(&builder_); 19574514f5e3Sopenharmony_ci Label callExit(&builder_); 19584514f5e3Sopenharmony_ci Label slowPath(&builder_); 19594514f5e3Sopenharmony_ci Label threadCheck(&builder_); 19604514f5e3Sopenharmony_ci Label argvIsNull(&builder_); 19614514f5e3Sopenharmony_ci Label getArgsFromArgAcc(&builder_); 19624514f5e3Sopenharmony_ci 19634514f5e3Sopenharmony_ci CheckSuperAndNewTarget(objBuilder, super, newTarget, thisObj, fastPath, slowPath); 19644514f5e3Sopenharmony_ci builder_.Bind(&fastPath); 19654514f5e3Sopenharmony_ci { 19664514f5e3Sopenharmony_ci BRANCH_CIR(builder_.Equal(actualArgv, builder_.IntPtr(0)), &argvIsNull, &fastPathWithArgv); 19674514f5e3Sopenharmony_ci builder_.Bind(&argvIsNull); 19684514f5e3Sopenharmony_ci { 19694514f5e3Sopenharmony_ci GateRef method = builder_.GetMethodFromFunction(func); 19704514f5e3Sopenharmony_ci GateRef expectedFuncArgNum = builder_.ZExtInt32ToInt64(builder_.GetExpectedNumOfArgs(method)); 19714514f5e3Sopenharmony_ci GateRef expected = builder_.Int64Add(expectedFuncArgNum, builder_.Int64(NUM_MANDATORY_JSFUNC_ARGS)); 19724514f5e3Sopenharmony_ci BRANCH_CIR(builder_.Int64Equal(expected, actualArgc), &getArgsFromArgAcc, &slowPath); 19734514f5e3Sopenharmony_ci builder_.Bind(&getArgsFromArgAcc); 19744514f5e3Sopenharmony_ci std::vector<GateRef> args { gate, super, actualArgc, *newTarget, *thisObj }; 19754514f5e3Sopenharmony_ci GenerateSuperCallForwardAllArgsWithoutArgv(args, result, threadCheck); 19764514f5e3Sopenharmony_ci } 19774514f5e3Sopenharmony_ci builder_.Bind(&fastPathWithArgv); 19784514f5e3Sopenharmony_ci { 19794514f5e3Sopenharmony_ci GateRef argc = builder_.Int64Sub(actualArgc, builder_.Int64(NUM_MANDATORY_JSFUNC_ARGS)); 19804514f5e3Sopenharmony_ci GateRef argv = builder_.PtrAdd(actualArgv, builder_.IntPtr(NUM_MANDATORY_JSFUNC_ARGS * 8)); // 8: ptr size 19814514f5e3Sopenharmony_ci LowerFastSuperCall({ gate, super, *newTarget, *thisObj, argc }, argv, result, callExit); 19824514f5e3Sopenharmony_ci builder_.Bind(&callExit); 19834514f5e3Sopenharmony_ci result = objBuilder.ConstructorCheck(glue_, super, *result, *thisObj); 19844514f5e3Sopenharmony_ci builder_.Jump(&threadCheck); 19854514f5e3Sopenharmony_ci } 19864514f5e3Sopenharmony_ci } 19874514f5e3Sopenharmony_ci builder_.Bind(&slowPath); 19884514f5e3Sopenharmony_ci { 19894514f5e3Sopenharmony_ci std::vector<GateRef> args { super, *newTarget, builder_.ToTaggedInt(actualArgc) }; 19904514f5e3Sopenharmony_ci result = LowerCallRuntime(gate, RTSTUB_ID(OptSuperCallForwardAllArgs), args, true); 19914514f5e3Sopenharmony_ci builder_.Jump(&threadCheck); 19924514f5e3Sopenharmony_ci } 19934514f5e3Sopenharmony_ci builder_.Bind(&threadCheck); 19944514f5e3Sopenharmony_ci ReplaceHirWithPendingException(gate, builder_.GetState(), builder_.GetDepend(), *result); 19954514f5e3Sopenharmony_ci} 19964514f5e3Sopenharmony_ci 19974514f5e3Sopenharmony_civoid SlowPathLowering::GenerateSuperCallForwardAllArgsWithoutArgv(const std::vector<GateRef> &args, Variable &result, 19984514f5e3Sopenharmony_ci Label &exit) 19994514f5e3Sopenharmony_ci{ 20004514f5e3Sopenharmony_ci ASSERT(args.size() == 5); // 5: size of args 20014514f5e3Sopenharmony_ci GateRef gate = args[0]; // 0: gate 20024514f5e3Sopenharmony_ci GateRef super = args[1]; // 1: super constructor 20034514f5e3Sopenharmony_ci GateRef actualArgc = args[2]; // 2: num of args 20044514f5e3Sopenharmony_ci GateRef newTarget = args[3]; // 3: argv 20054514f5e3Sopenharmony_ci GateRef thisObj = args[4]; // 4: newTarget 20064514f5e3Sopenharmony_ci 20074514f5e3Sopenharmony_ci Label afterCallSuper(&builder_); 20084514f5e3Sopenharmony_ci std::vector<GateRef> callArgs { glue_, actualArgc, builder_.IntPtr(0), super, newTarget, thisObj }; 20094514f5e3Sopenharmony_ci std::vector<GateRef> argsFastCall { glue_, super, thisObj }; 20104514f5e3Sopenharmony_ci 20114514f5e3Sopenharmony_ci uint32_t startIdx = static_cast<uint32_t>(CommonArgIdx::NUM_OF_ARGS); 20124514f5e3Sopenharmony_ci ASSERT(argAcc_.ArgsCount() >= startIdx); 20134514f5e3Sopenharmony_ci for (uint32_t i = startIdx; i < argAcc_.ArgsCount(); ++i) { 20144514f5e3Sopenharmony_ci GateRef value = argAcc_.ArgsAt(i); 20154514f5e3Sopenharmony_ci callArgs.emplace_back(value); 20164514f5e3Sopenharmony_ci argsFastCall.emplace_back(value); 20174514f5e3Sopenharmony_ci } 20184514f5e3Sopenharmony_ci 20194514f5e3Sopenharmony_ci LowerFastCall(gate, glue_, super, actualArgc, callArgs, argsFastCall, &result, &afterCallSuper, true); 20204514f5e3Sopenharmony_ci 20214514f5e3Sopenharmony_ci builder_.Bind(&afterCallSuper); 20224514f5e3Sopenharmony_ci result = builder_.CallStub(glue_, gate, CommonStubCSigns::ConstructorCheck, { glue_, super, *result, thisObj }); 20234514f5e3Sopenharmony_ci builder_.Jump(&exit); 20244514f5e3Sopenharmony_ci} 20254514f5e3Sopenharmony_ci 20264514f5e3Sopenharmony_civoid SlowPathLowering::LowerIsTrueOrFalse(GateRef gate, bool flag) 20274514f5e3Sopenharmony_ci{ 20284514f5e3Sopenharmony_ci Label slowpath(&builder_); 20294514f5e3Sopenharmony_ci Label isTrue(&builder_); 20304514f5e3Sopenharmony_ci Label isFalse(&builder_); 20314514f5e3Sopenharmony_ci Label successExit(&builder_); 20324514f5e3Sopenharmony_ci // 1: number of value inputs 20334514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 1); 20344514f5e3Sopenharmony_ci auto value = acc_.GetValueIn(gate, 0); 20354514f5e3Sopenharmony_ci DEFVALUE(result, (&builder_), VariableType::JS_ANY(), value); 20364514f5e3Sopenharmony_ci if (flag) { 20374514f5e3Sopenharmony_ci result = builder_.CallStub(glue_, gate, CommonStubCSigns::ToBooleanTrue, { glue_, value }); 20384514f5e3Sopenharmony_ci } else { 20394514f5e3Sopenharmony_ci result = builder_.CallStub(glue_, gate, CommonStubCSigns::ToBooleanFalse, { glue_, value }); 20404514f5e3Sopenharmony_ci } 20414514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, *result, true); 20424514f5e3Sopenharmony_ci} 20434514f5e3Sopenharmony_ci 20444514f5e3Sopenharmony_civoid SlowPathLowering::LowerNewObjRange(GateRef gate) 20454514f5e3Sopenharmony_ci{ 20464514f5e3Sopenharmony_ci Label fastPath(&builder_); 20474514f5e3Sopenharmony_ci Label slowPath(&builder_); 20484514f5e3Sopenharmony_ci Label threadCheck(&builder_); 20494514f5e3Sopenharmony_ci Label successExit(&builder_); 20504514f5e3Sopenharmony_ci Label exit(&builder_); 20514514f5e3Sopenharmony_ci 20524514f5e3Sopenharmony_ci DEFVALUE(result, (&builder_), VariableType::JS_ANY(), builder_.Undefined()); 20534514f5e3Sopenharmony_ci 20544514f5e3Sopenharmony_ci GateRef ctor = acc_.GetValueIn(gate, 0); 20554514f5e3Sopenharmony_ci GateRef thisObj = builder_.CallStub(glue_, gate, CommonStubCSigns::NewThisObjectChecked, { glue_, ctor }); 20564514f5e3Sopenharmony_ci BRANCH_CIR(builder_.TaggedIsHole(thisObj), &slowPath, &fastPath); 20574514f5e3Sopenharmony_ci builder_.Bind(&fastPath); 20584514f5e3Sopenharmony_ci { 20594514f5e3Sopenharmony_ci GateRef actualArgc = builder_.Int64(BytecodeCallArgc::ComputeCallArgc(acc_.GetNumValueIn(gate), 20604514f5e3Sopenharmony_ci EcmaOpcode::NEWOBJRANGE_IMM8_IMM8_V8)); 20614514f5e3Sopenharmony_ci GateRef actualArgv = builder_.IntPtr(0); 20624514f5e3Sopenharmony_ci size_t range = acc_.GetNumValueIn(gate); 20634514f5e3Sopenharmony_ci std::vector<GateRef> args{glue_, actualArgc, actualArgv, ctor, ctor, thisObj}; 20644514f5e3Sopenharmony_ci std::vector<GateRef> argsFastCall{glue_, ctor, thisObj}; 20654514f5e3Sopenharmony_ci for (size_t i = 1; i < range; ++i) { 20664514f5e3Sopenharmony_ci args.emplace_back(acc_.GetValueIn(gate, i)); 20674514f5e3Sopenharmony_ci argsFastCall.emplace_back(acc_.GetValueIn(gate, i)); 20684514f5e3Sopenharmony_ci } 20694514f5e3Sopenharmony_ci LowerFastCall(gate, glue_, ctor, actualArgc, args, argsFastCall, &result, &exit, true); 20704514f5e3Sopenharmony_ci builder_.Bind(&exit); 20714514f5e3Sopenharmony_ci result = builder_.CallStub(glue_, gate, CommonStubCSigns::ConstructorCheck, { glue_, ctor, *result, thisObj }); 20724514f5e3Sopenharmony_ci builder_.Jump(&threadCheck); 20734514f5e3Sopenharmony_ci } 20744514f5e3Sopenharmony_ci builder_.Bind(&slowPath); 20754514f5e3Sopenharmony_ci { 20764514f5e3Sopenharmony_ci size_t range = acc_.GetNumValueIn(gate); 20774514f5e3Sopenharmony_ci std::vector<GateRef> args(range); 20784514f5e3Sopenharmony_ci for (size_t i = 0; i < range; ++i) { 20794514f5e3Sopenharmony_ci args[i] = acc_.GetValueIn(gate, i); 20804514f5e3Sopenharmony_ci } 20814514f5e3Sopenharmony_ci result = LowerCallRuntime(gate, RTSTUB_ID(OptNewObjRange), args, true); 20824514f5e3Sopenharmony_ci builder_.Jump(&threadCheck); 20834514f5e3Sopenharmony_ci } 20844514f5e3Sopenharmony_ci builder_.Bind(&threadCheck); 20854514f5e3Sopenharmony_ci ReplaceHirWithPendingException(gate, builder_.GetState(), builder_.GetDepend(), *result); 20864514f5e3Sopenharmony_ci} 20874514f5e3Sopenharmony_ci 20884514f5e3Sopenharmony_cibool SlowPathLowering::IsDependIfStateMent(GateRef gate, size_t idx) 20894514f5e3Sopenharmony_ci{ 20904514f5e3Sopenharmony_ci return ((acc_.GetOpCode(gate) == OpCode::DEPEND_SELECTOR) || (acc_.GetOpCode(gate) == OpCode::DEPEND_RELAY)) && 20914514f5e3Sopenharmony_ci (idx > 0 && (acc_.GetOpCode(acc_.GetIn(acc_.GetIn(gate, 0), idx - 1)) != OpCode::IF_EXCEPTION)); 20924514f5e3Sopenharmony_ci} 20934514f5e3Sopenharmony_ci 20944514f5e3Sopenharmony_civoid SlowPathLowering::LowerConditionJump(GateRef gate, bool isEqualJump) 20954514f5e3Sopenharmony_ci{ 20964514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 0); 20974514f5e3Sopenharmony_ci 20984514f5e3Sopenharmony_ci Label isZero(&builder_); 20994514f5e3Sopenharmony_ci Label notZero(&builder_); 21004514f5e3Sopenharmony_ci // GET_ACC().IsFalse() 21014514f5e3Sopenharmony_ci Label notFalse(&builder_); 21024514f5e3Sopenharmony_ci BRANCH_CIR(builder_.IsSpecial(value, JSTaggedValue::VALUE_FALSE), &isZero, ¬False); 21034514f5e3Sopenharmony_ci builder_.Bind(¬False); 21044514f5e3Sopenharmony_ci { 21054514f5e3Sopenharmony_ci // (GET_ACC().IsInt() && GET_ACC().GetInt() == 0) 21064514f5e3Sopenharmony_ci Label isInt(&builder_); 21074514f5e3Sopenharmony_ci Label notIntZero(&builder_); 21084514f5e3Sopenharmony_ci BRANCH_CIR(builder_.TaggedIsInt(value), &isInt, ¬IntZero); 21094514f5e3Sopenharmony_ci builder_.Bind(&isInt); 21104514f5e3Sopenharmony_ci BRANCH_CIR(builder_.Equal(builder_.TaggedGetInt(value), builder_.Int32(0)), &isZero, ¬IntZero); 21114514f5e3Sopenharmony_ci builder_.Bind(¬IntZero); 21124514f5e3Sopenharmony_ci { 21134514f5e3Sopenharmony_ci // (GET_ACC().IsDouble() && GET_ACC().GetDouble() == 0.0) 21144514f5e3Sopenharmony_ci Label isDouble(&builder_); 21154514f5e3Sopenharmony_ci BRANCH_CIR(builder_.TaggedIsDouble(value), &isDouble, ¬Zero); 21164514f5e3Sopenharmony_ci builder_.Bind(&isDouble); 21174514f5e3Sopenharmony_ci BRANCH_CIR(builder_.Equal(builder_.GetDoubleOfTDouble(value), builder_.Double(0.0)), &isZero, ¬Zero); 21184514f5e3Sopenharmony_ci builder_.Bind(¬Zero); 21194514f5e3Sopenharmony_ci } 21204514f5e3Sopenharmony_ci } 21214514f5e3Sopenharmony_ci builder_.Bind(&isZero); 21224514f5e3Sopenharmony_ci 21234514f5e3Sopenharmony_ci Label &ifTrue = isEqualJump ? isZero : notZero; 21244514f5e3Sopenharmony_ci Label &ifFalse = isEqualJump ? notZero : isZero; 21254514f5e3Sopenharmony_ci auto uses = acc_.Uses(gate); 21264514f5e3Sopenharmony_ci for (auto it = uses.begin(); it != uses.end();) { 21274514f5e3Sopenharmony_ci if (acc_.GetOpCode(*it) == OpCode::IF_TRUE) { 21284514f5e3Sopenharmony_ci acc_.SetMetaData(*it, circuit_->OrdinaryBlock()); 21294514f5e3Sopenharmony_ci it = acc_.ReplaceIn(it, ifTrue.GetControl()); 21304514f5e3Sopenharmony_ci } else if (acc_.GetOpCode(*it) == OpCode::IF_FALSE) { 21314514f5e3Sopenharmony_ci acc_.SetMetaData(*it, circuit_->OrdinaryBlock()); 21324514f5e3Sopenharmony_ci it = acc_.ReplaceIn(it, ifFalse.GetControl()); 21334514f5e3Sopenharmony_ci } else if (IsDependIfStateMent(*it, it.GetIndex())) { 21344514f5e3Sopenharmony_ci it = acc_.ReplaceIn(it, acc_.GetDep(gate)); 21354514f5e3Sopenharmony_ci } else { 21364514f5e3Sopenharmony_ci LOG_ECMA(FATAL) << "this branch is unreachable"; 21374514f5e3Sopenharmony_ci UNREACHABLE(); 21384514f5e3Sopenharmony_ci } 21394514f5e3Sopenharmony_ci } 21404514f5e3Sopenharmony_ci // delete old gate 21414514f5e3Sopenharmony_ci acc_.DeleteGate(gate); 21424514f5e3Sopenharmony_ci} 21434514f5e3Sopenharmony_ci 21444514f5e3Sopenharmony_civoid SlowPathLowering::LowerGetNextPropName(GateRef gate) 21454514f5e3Sopenharmony_ci{ 21464514f5e3Sopenharmony_ci // 1: number of value inputs 21474514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 1); 21484514f5e3Sopenharmony_ci GateRef iter = acc_.GetValueIn(gate, 0); 21494514f5e3Sopenharmony_ci 21504514f5e3Sopenharmony_ci DEFVALUE(result, (&builder_), VariableType::JS_ANY(), builder_.Undefined()); 21514514f5e3Sopenharmony_ci 21524514f5e3Sopenharmony_ci Label notFinish(&builder_); 21534514f5e3Sopenharmony_ci Label notEnumCacheValid(&builder_); 21544514f5e3Sopenharmony_ci Label fastGetKey(&builder_); 21554514f5e3Sopenharmony_ci Label slowpath(&builder_); 21564514f5e3Sopenharmony_ci Label exit(&builder_); 21574514f5e3Sopenharmony_ci 21584514f5e3Sopenharmony_ci GateRef index = builder_.GetIndexFromForInIterator(iter); 21594514f5e3Sopenharmony_ci GateRef length = builder_.GetLengthFromForInIterator(iter); 21604514f5e3Sopenharmony_ci BRANCH_CIR(builder_.Int32GreaterThanOrEqual(index, length), &exit, ¬Finish); 21614514f5e3Sopenharmony_ci builder_.Bind(¬Finish); 21624514f5e3Sopenharmony_ci GateRef keys = builder_.GetKeysFromForInIterator(iter); 21634514f5e3Sopenharmony_ci GateRef receiver = builder_.GetObjectFromForInIterator(iter); 21644514f5e3Sopenharmony_ci GateRef cachedHclass = builder_.GetCachedHclassFromForInIterator(iter); 21654514f5e3Sopenharmony_ci GateRef kind = builder_.GetEnumCacheKind(glue_, keys); 21664514f5e3Sopenharmony_ci BRANCH_CIR(builder_.IsEnumCacheValid(receiver, cachedHclass, kind), &fastGetKey, ¬EnumCacheValid); 21674514f5e3Sopenharmony_ci builder_.Bind(¬EnumCacheValid); 21684514f5e3Sopenharmony_ci BRANCH_CIR(builder_.NeedCheckProperty(receiver), &slowpath, &fastGetKey); 21694514f5e3Sopenharmony_ci builder_.Bind(&fastGetKey); 21704514f5e3Sopenharmony_ci { 21714514f5e3Sopenharmony_ci result = builder_.GetValueFromTaggedArray(keys, index); 21724514f5e3Sopenharmony_ci builder_.IncreaseInteratorIndex(glue_, iter, index); 21734514f5e3Sopenharmony_ci builder_.Jump(&exit); 21744514f5e3Sopenharmony_ci } 21754514f5e3Sopenharmony_ci builder_.Bind(&slowpath); 21764514f5e3Sopenharmony_ci { 21774514f5e3Sopenharmony_ci result = LowerCallRuntime(gate, RTSTUB_ID(GetNextPropNameSlowpath), { iter }, true); 21784514f5e3Sopenharmony_ci builder_.Jump(&exit); 21794514f5e3Sopenharmony_ci } 21804514f5e3Sopenharmony_ci 21814514f5e3Sopenharmony_ci builder_.Bind(&exit); 21824514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, *result); 21834514f5e3Sopenharmony_ci} 21844514f5e3Sopenharmony_ci 21854514f5e3Sopenharmony_civoid SlowPathLowering::LowerCopyDataProperties(GateRef gate) 21864514f5e3Sopenharmony_ci{ 21874514f5e3Sopenharmony_ci const int id = RTSTUB_ID(CopyDataProperties); 21884514f5e3Sopenharmony_ci // 2: number of value inputs 21894514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 21904514f5e3Sopenharmony_ci GateRef dst = acc_.GetValueIn(gate, 0); 21914514f5e3Sopenharmony_ci GateRef src = acc_.GetValueIn(gate, 1); 21924514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, { dst, src }); 21934514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 21944514f5e3Sopenharmony_ci} 21954514f5e3Sopenharmony_ci 21964514f5e3Sopenharmony_civoid SlowPathLowering::LowerCreateObjectWithExcludedKeys(GateRef gate) 21974514f5e3Sopenharmony_ci{ 21984514f5e3Sopenharmony_ci const int id = RTSTUB_ID(OptCreateObjectWithExcludedKeys); 21994514f5e3Sopenharmony_ci // 2: number of value inputs 22004514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) >= 2); 22014514f5e3Sopenharmony_ci size_t numIn = acc_.GetNumValueIn(gate); 22024514f5e3Sopenharmony_ci std::vector<GateRef> args; 22034514f5e3Sopenharmony_ci for (size_t idx = 0; idx < numIn; idx++) { 22044514f5e3Sopenharmony_ci GateRef tmpGate = acc_.GetValueIn(gate, idx); 22054514f5e3Sopenharmony_ci args.emplace_back(tmpGate); 22064514f5e3Sopenharmony_ci } 22074514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, args); 22084514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 22094514f5e3Sopenharmony_ci} 22104514f5e3Sopenharmony_ci 22114514f5e3Sopenharmony_civoid SlowPathLowering::LowerCreateRegExpWithLiteral(GateRef gate) 22124514f5e3Sopenharmony_ci{ 22134514f5e3Sopenharmony_ci const int id = RTSTUB_ID(CreateRegExpWithLiteral); 22144514f5e3Sopenharmony_ci // 2: number of value inputs 22154514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 22164514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 22174514f5e3Sopenharmony_ci GateRef sharedConstPool = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::SHARED_CONST_POOL); 22184514f5e3Sopenharmony_ci GateRef stringId = builder_.TruncInt64ToInt32(acc_.GetValueIn(gate, 0)); 22194514f5e3Sopenharmony_ci GateRef module = builder_.GetModuleFromFunction(jsFunc); 22204514f5e3Sopenharmony_ci GateRef pattern = builder_.GetObjectFromConstPool(glue_, gate, sharedConstPool, Circuit::NullGate(), module, 22214514f5e3Sopenharmony_ci stringId, ConstPoolType::STRING); 22224514f5e3Sopenharmony_ci GateRef flags = acc_.GetValueIn(gate, 1); 22234514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, { pattern, builder_.ToTaggedInt(flags) }, true); 22244514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 22254514f5e3Sopenharmony_ci} 22264514f5e3Sopenharmony_ci 22274514f5e3Sopenharmony_civoid SlowPathLowering::LowerStOwnByValue(GateRef gate) 22284514f5e3Sopenharmony_ci{ 22294514f5e3Sopenharmony_ci // 3: number of value inputs 22304514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 3); 22314514f5e3Sopenharmony_ci GateRef receiver = acc_.GetValueIn(gate, 0); 22324514f5e3Sopenharmony_ci GateRef propKey = acc_.GetValueIn(gate, 1); 22334514f5e3Sopenharmony_ci GateRef accValue = acc_.GetValueIn(gate, 2); 22344514f5e3Sopenharmony_ci // we do not need to merge outValueGate, so using GateRef directly instead of using Variable 22354514f5e3Sopenharmony_ci GateRef holeConst = builder_.HoleConstant(); 22364514f5e3Sopenharmony_ci DEFVALUE(result, (&builder_), VariableType::JS_ANY(), holeConst); 22374514f5e3Sopenharmony_ci result = builder_.CallStub(glue_, gate, CommonStubCSigns::StOwnByValue, 22384514f5e3Sopenharmony_ci { glue_, receiver, propKey, accValue }); 22394514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, *result); 22404514f5e3Sopenharmony_ci} 22414514f5e3Sopenharmony_ci 22424514f5e3Sopenharmony_civoid SlowPathLowering::LowerStOwnByIndex(GateRef gate) 22434514f5e3Sopenharmony_ci{ 22444514f5e3Sopenharmony_ci // 3: number of value inputs 22454514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 3); 22464514f5e3Sopenharmony_ci GateRef receiver = acc_.GetValueIn(gate, 0); 22474514f5e3Sopenharmony_ci GateRef index = acc_.GetValueIn(gate, 1); 22484514f5e3Sopenharmony_ci GateRef accValue = acc_.GetValueIn(gate, 2); 22494514f5e3Sopenharmony_ci // we do not need to merge outValueGate, so using GateRef directly instead of using Variable 22504514f5e3Sopenharmony_ci GateRef holeConst = builder_.HoleConstant(); 22514514f5e3Sopenharmony_ci DEFVALUE(result, (&builder_), VariableType::JS_ANY(), holeConst); 22524514f5e3Sopenharmony_ci result = builder_.CallStub(glue_, gate, CommonStubCSigns::StOwnByIndex, 22534514f5e3Sopenharmony_ci { glue_, receiver, builder_.TruncInt64ToInt32(index), accValue }); 22544514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, *result); 22554514f5e3Sopenharmony_ci} 22564514f5e3Sopenharmony_ci 22574514f5e3Sopenharmony_civoid SlowPathLowering::LowerStOwnByName(GateRef gate) 22584514f5e3Sopenharmony_ci{ 22594514f5e3Sopenharmony_ci // 3: number of value inputs 22604514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 3); 22614514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 22624514f5e3Sopenharmony_ci GateRef sharedConstPool = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::SHARED_CONST_POOL); 22634514f5e3Sopenharmony_ci GateRef stringId = builder_.TruncInt64ToInt32(acc_.GetValueIn(gate, 0)); 22644514f5e3Sopenharmony_ci GateRef module = builder_.GetModuleFromFunction(jsFunc); 22654514f5e3Sopenharmony_ci GateRef propKey = builder_.GetObjectFromConstPool(glue_, gate, sharedConstPool, Circuit::NullGate(), module, 22664514f5e3Sopenharmony_ci stringId, ConstPoolType::STRING); 22674514f5e3Sopenharmony_ci GateRef receiver = acc_.GetValueIn(gate, 1); 22684514f5e3Sopenharmony_ci GateRef accValue = acc_.GetValueIn(gate, 2); 22694514f5e3Sopenharmony_ci // we do not need to merge outValueGate, so using GateRef directly instead of using Variable 22704514f5e3Sopenharmony_ci GateRef holeConst = builder_.HoleConstant(); 22714514f5e3Sopenharmony_ci DEFVALUE(result, (&builder_), VariableType::JS_ANY(), holeConst); 22724514f5e3Sopenharmony_ci result = builder_.CallStub(glue_, gate, CommonStubCSigns::StOwnByName, 22734514f5e3Sopenharmony_ci { glue_, receiver, propKey, accValue }); 22744514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, *result); 22754514f5e3Sopenharmony_ci} 22764514f5e3Sopenharmony_ci 22774514f5e3Sopenharmony_civoid SlowPathLowering::LowerNewLexicalEnv(GateRef gate) 22784514f5e3Sopenharmony_ci{ 22794514f5e3Sopenharmony_ci // 2: number of value inputs 22804514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 22814514f5e3Sopenharmony_ci GateRef lexEnv = acc_.GetValueIn(gate, 1); 22824514f5e3Sopenharmony_ci GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::NewLexicalEnv, 22834514f5e3Sopenharmony_ci { glue_, lexEnv, builder_.TruncInt64ToInt32(acc_.GetValueIn(gate, 0)) }); 22844514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 22854514f5e3Sopenharmony_ci} 22864514f5e3Sopenharmony_ci 22874514f5e3Sopenharmony_civoid SlowPathLowering::LowerNewLexicalEnvWithName(GateRef gate) 22884514f5e3Sopenharmony_ci{ 22894514f5e3Sopenharmony_ci // 3: number of value inputs 22904514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 3); 22914514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 22924514f5e3Sopenharmony_ci GateRef lexEnv = acc_.GetValueIn(gate, 2); // 2: Get current lexEnv 22934514f5e3Sopenharmony_ci auto args = { builder_.ToTaggedInt(acc_.GetValueIn(gate, 0)), 22944514f5e3Sopenharmony_ci builder_.ToTaggedInt(acc_.GetValueIn(gate, 1)), 22954514f5e3Sopenharmony_ci lexEnv, jsFunc }; 22964514f5e3Sopenharmony_ci GateRef result = LowerCallRuntime(gate, RTSTUB_ID(OptNewLexicalEnvWithName), args, true); 22974514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result, true); 22984514f5e3Sopenharmony_ci} 22994514f5e3Sopenharmony_ci 23004514f5e3Sopenharmony_civoid SlowPathLowering::LowerNewSendableEnv(GateRef gate) 23014514f5e3Sopenharmony_ci{ 23024514f5e3Sopenharmony_ci // 2: number of value inputs 23034514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 1); 23044514f5e3Sopenharmony_ci auto args = { builder_.ToTaggedInt(acc_.GetValueIn(gate, 0)) }; 23054514f5e3Sopenharmony_ci GateRef result = LowerCallRuntime(gate, RTSTUB_ID(NewSendableEnv), args, true); 23064514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 23074514f5e3Sopenharmony_ci GateRef module = builder_.GetModuleFromFunction(jsFunc); 23084514f5e3Sopenharmony_ci builder_.SetSendableEnvToModule(glue_, module, result); 23094514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 23104514f5e3Sopenharmony_ci} 23114514f5e3Sopenharmony_ci 23124514f5e3Sopenharmony_civoid SlowPathLowering::LowerPopLexicalEnv(GateRef gate) 23134514f5e3Sopenharmony_ci{ 23144514f5e3Sopenharmony_ci GateRef currentEnv = acc_.GetValueIn(gate, 0); 23154514f5e3Sopenharmony_ci GateRef index = builder_.Int32(LexicalEnv::PARENT_ENV_INDEX); 23164514f5e3Sopenharmony_ci GateRef parentEnv = builder_.GetValueFromTaggedArray(currentEnv, index); 23174514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, parentEnv, true); 23184514f5e3Sopenharmony_ci} 23194514f5e3Sopenharmony_ci 23204514f5e3Sopenharmony_civoid SlowPathLowering::LowerLdSuperByValue(GateRef gate) 23214514f5e3Sopenharmony_ci{ 23224514f5e3Sopenharmony_ci const int id = RTSTUB_ID(OptLdSuperByValue); 23234514f5e3Sopenharmony_ci // 2: number of value inputs 23244514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 23254514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 23264514f5e3Sopenharmony_ci GateRef receiver = acc_.GetValueIn(gate, 0); 23274514f5e3Sopenharmony_ci GateRef propKey = acc_.GetValueIn(gate, 1); 23284514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, { receiver, propKey, jsFunc }); 23294514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 23304514f5e3Sopenharmony_ci} 23314514f5e3Sopenharmony_ci 23324514f5e3Sopenharmony_civoid SlowPathLowering::LowerStSuperByValue(GateRef gate) 23334514f5e3Sopenharmony_ci{ 23344514f5e3Sopenharmony_ci const int id = RTSTUB_ID(OptStSuperByValue); 23354514f5e3Sopenharmony_ci // 3: number of value inputs 23364514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 3); 23374514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 23384514f5e3Sopenharmony_ci GateRef receiver = acc_.GetValueIn(gate, 0); 23394514f5e3Sopenharmony_ci GateRef propKey = acc_.GetValueIn(gate, 1); 23404514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 2); 23414514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, { receiver, propKey, value, jsFunc}); 23424514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 23434514f5e3Sopenharmony_ci} 23444514f5e3Sopenharmony_ci 23454514f5e3Sopenharmony_civoid SlowPathLowering::LowerTryStGlobalByName(GateRef gate) 23464514f5e3Sopenharmony_ci{ 23474514f5e3Sopenharmony_ci // 3: number of value inputs 23484514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 3); 23494514f5e3Sopenharmony_ci GateRef stringId = acc_.GetValueIn(gate, 1); // 1: the second parameter 23504514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 2); // 2: the 2nd para is value 23514514f5e3Sopenharmony_ci LowerCallStubWithIC(gate, CommonStubCSigns::TryStGlobalByName, { stringId, value }); 23524514f5e3Sopenharmony_ci} 23534514f5e3Sopenharmony_ci 23544514f5e3Sopenharmony_civoid SlowPathLowering::LowerStConstToGlobalRecord(GateRef gate, bool isConst) 23554514f5e3Sopenharmony_ci{ 23564514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 23574514f5e3Sopenharmony_ci GateRef sharedConstPool = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::SHARED_CONST_POOL); 23584514f5e3Sopenharmony_ci GateRef stringId = builder_.TruncInt64ToInt32(acc_.GetValueIn(gate, 0)); 23594514f5e3Sopenharmony_ci GateRef module = builder_.GetModuleFromFunction(jsFunc); 23604514f5e3Sopenharmony_ci GateRef propKey = builder_.GetObjectFromConstPool(glue_, gate, sharedConstPool, Circuit::NullGate(), module, 23614514f5e3Sopenharmony_ci stringId, ConstPoolType::STRING); 23624514f5e3Sopenharmony_ci acc_.SetDep(gate, propKey); 23634514f5e3Sopenharmony_ci // 2 : number of value inputs 23644514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 23654514f5e3Sopenharmony_ci const int id = RTSTUB_ID(StGlobalRecord); 23664514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 1); 23674514f5e3Sopenharmony_ci GateRef isConstGate = isConst ? builder_.TaggedTrue() : builder_.TaggedFalse(); 23684514f5e3Sopenharmony_ci GateRef result = LowerCallRuntime(gate, id, { propKey, value, isConstGate }, true); 23694514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 23704514f5e3Sopenharmony_ci} 23714514f5e3Sopenharmony_ci 23724514f5e3Sopenharmony_civoid SlowPathLowering::LowerStOwnByValueWithNameSet(GateRef gate) 23734514f5e3Sopenharmony_ci{ 23744514f5e3Sopenharmony_ci // 3: number of value inputs 23754514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 3); 23764514f5e3Sopenharmony_ci GateRef receiver = acc_.GetValueIn(gate, 0); 23774514f5e3Sopenharmony_ci GateRef propKey = acc_.GetValueIn(gate, 1); 23784514f5e3Sopenharmony_ci GateRef accValue = acc_.GetValueIn(gate, 2); 23794514f5e3Sopenharmony_ci Label successExit(&builder_); 23804514f5e3Sopenharmony_ci Label exceptionExit(&builder_); 23814514f5e3Sopenharmony_ci GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::StOwnByValueWithNameSet, 23824514f5e3Sopenharmony_ci { glue_, receiver, propKey, accValue }); 23834514f5e3Sopenharmony_ci BRANCH_CIR(builder_.IsSpecial(result, JSTaggedValue::VALUE_EXCEPTION), 23844514f5e3Sopenharmony_ci &exceptionExit, &successExit); 23854514f5e3Sopenharmony_ci CREATE_DOUBLE_EXIT(successExit, exceptionExit) 23864514f5e3Sopenharmony_ci acc_.ReplaceHirWithIfBranch(gate, successControl, failControl, Circuit::NullGate()); 23874514f5e3Sopenharmony_ci} 23884514f5e3Sopenharmony_ci 23894514f5e3Sopenharmony_civoid SlowPathLowering::LowerStOwnByNameWithNameSet(GateRef gate) 23904514f5e3Sopenharmony_ci{ 23914514f5e3Sopenharmony_ci // 3: number of value inputs 23924514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 3); 23934514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 23944514f5e3Sopenharmony_ci GateRef sharedConstPool = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::SHARED_CONST_POOL); 23954514f5e3Sopenharmony_ci GateRef stringId = builder_.TruncInt64ToInt32(acc_.GetValueIn(gate, 0)); 23964514f5e3Sopenharmony_ci GateRef module = builder_.GetModuleFromFunction(jsFunc); 23974514f5e3Sopenharmony_ci GateRef propKey = builder_.GetObjectFromConstPool(glue_, gate, sharedConstPool, Circuit::NullGate(), module, 23984514f5e3Sopenharmony_ci stringId, ConstPoolType::STRING); 23994514f5e3Sopenharmony_ci GateRef receiver = acc_.GetValueIn(gate, 1); 24004514f5e3Sopenharmony_ci GateRef accValue = acc_.GetValueIn(gate, 2); 24014514f5e3Sopenharmony_ci Label successExit(&builder_); 24024514f5e3Sopenharmony_ci Label exceptionExit(&builder_); 24034514f5e3Sopenharmony_ci GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::StOwnByNameWithNameSet, 24044514f5e3Sopenharmony_ci { glue_, receiver, propKey, accValue }); 24054514f5e3Sopenharmony_ci BRANCH_CIR(builder_.IsSpecial(result, JSTaggedValue::VALUE_EXCEPTION), 24064514f5e3Sopenharmony_ci &exceptionExit, &successExit); 24074514f5e3Sopenharmony_ci CREATE_DOUBLE_EXIT(successExit, exceptionExit) 24084514f5e3Sopenharmony_ci acc_.ReplaceHirWithIfBranch(gate, successControl, failControl, Circuit::NullGate()); 24094514f5e3Sopenharmony_ci} 24104514f5e3Sopenharmony_ci 24114514f5e3Sopenharmony_civoid SlowPathLowering::LowerLdGlobalVar(GateRef gate) 24124514f5e3Sopenharmony_ci{ 24134514f5e3Sopenharmony_ci // 2: number of value inputs 24144514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 24154514f5e3Sopenharmony_ci GateRef stringId = acc_.GetValueIn(gate, 1); // 1: the second parameter 24164514f5e3Sopenharmony_ci LowerCallStubWithIC(gate, CommonStubCSigns::LdGlobalVar, { stringId }); 24174514f5e3Sopenharmony_ci} 24184514f5e3Sopenharmony_ci 24194514f5e3Sopenharmony_civoid SlowPathLowering::LowerLdObjByName(GateRef gate) 24204514f5e3Sopenharmony_ci{ 24214514f5e3Sopenharmony_ci // 3: number of value inputs 24224514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 3); 24234514f5e3Sopenharmony_ci GateRef stringId = acc_.GetValueIn(gate, 1); // 1: the second parameter 24244514f5e3Sopenharmony_ci GateRef receiver = acc_.GetValueIn(gate, 2); // 2: the third parameter 24254514f5e3Sopenharmony_ci LowerCallStubWithIC(gate, CommonStubCSigns::GetPropertyByName, { receiver, stringId }); 24264514f5e3Sopenharmony_ci} 24274514f5e3Sopenharmony_ci 24284514f5e3Sopenharmony_civoid SlowPathLowering::LowerStObjByName(GateRef gate, bool isThis) 24294514f5e3Sopenharmony_ci{ 24304514f5e3Sopenharmony_ci GateRef receiver; 24314514f5e3Sopenharmony_ci GateRef value; 24324514f5e3Sopenharmony_ci if (isThis) { 24334514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 3); // 3: number of value inputs 24344514f5e3Sopenharmony_ci receiver = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::THIS_OBJECT); 24354514f5e3Sopenharmony_ci value = acc_.GetValueIn(gate, 2); // 2: the third para is value 24364514f5e3Sopenharmony_ci } else { 24374514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 4); // 4: number of value inputs 24384514f5e3Sopenharmony_ci receiver = acc_.GetValueIn(gate, 2); // 2: the third para is receiver 24394514f5e3Sopenharmony_ci value = acc_.GetValueIn(gate, 3); // 3: the 4th para is value 24404514f5e3Sopenharmony_ci } 24414514f5e3Sopenharmony_ci GateRef stringId = acc_.GetValueIn(gate, 1); // 1: the second parameter 24424514f5e3Sopenharmony_ci LowerCallStubWithIC(gate, CommonStubCSigns::SetPropertyByName, { receiver, stringId, value }); 24434514f5e3Sopenharmony_ci} 24444514f5e3Sopenharmony_ci 24454514f5e3Sopenharmony_civoid SlowPathLowering::LowerDefineGetterSetterByValue(GateRef gate) 24464514f5e3Sopenharmony_ci{ 24474514f5e3Sopenharmony_ci const int id = RTSTUB_ID(DefineGetterSetterByValue); 24484514f5e3Sopenharmony_ci // 5: number of value inputs 24494514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 5); 24504514f5e3Sopenharmony_ci GateRef obj = acc_.GetValueIn(gate, 0); 24514514f5e3Sopenharmony_ci GateRef prop = acc_.GetValueIn(gate, 1); 24524514f5e3Sopenharmony_ci GateRef getter = acc_.GetValueIn(gate, 2); 24534514f5e3Sopenharmony_ci GateRef setter = acc_.GetValueIn(gate, 3); 24544514f5e3Sopenharmony_ci GateRef acc = acc_.GetValueIn(gate, 4); 24554514f5e3Sopenharmony_ci auto args = { obj, prop, getter, setter, acc, 24564514f5e3Sopenharmony_ci builder_.UndefineConstant(), builder_.Int32ToTaggedInt(builder_.Int32(1)) }; 24574514f5e3Sopenharmony_ci GateRef result = LowerCallRuntime(gate, id, args); 24584514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 24594514f5e3Sopenharmony_ci} 24604514f5e3Sopenharmony_ci 24614514f5e3Sopenharmony_civoid SlowPathLowering::LowerLdObjByIndex(GateRef gate) 24624514f5e3Sopenharmony_ci{ 24634514f5e3Sopenharmony_ci // 2: number of value inputs 24644514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 24654514f5e3Sopenharmony_ci GateRef holeConst = builder_.HoleConstant(); 24664514f5e3Sopenharmony_ci DEFVALUE(varAcc, (&builder_), VariableType::JS_ANY(), holeConst); 24674514f5e3Sopenharmony_ci GateRef index = acc_.GetValueIn(gate, 0); 24684514f5e3Sopenharmony_ci GateRef receiver = acc_.GetValueIn(gate, 1); 24694514f5e3Sopenharmony_ci varAcc = builder_.CallStub(glue_, gate, CommonStubCSigns::LdObjByIndex, 24704514f5e3Sopenharmony_ci {glue_, receiver, builder_.TruncInt64ToInt32(index)}); 24714514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, *varAcc); 24724514f5e3Sopenharmony_ci} 24734514f5e3Sopenharmony_ci 24744514f5e3Sopenharmony_civoid SlowPathLowering::LowerStObjByIndex(GateRef gate) 24754514f5e3Sopenharmony_ci{ 24764514f5e3Sopenharmony_ci // 3: number of value inputs 24774514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 3); 24784514f5e3Sopenharmony_ci GateRef receiver = acc_.GetValueIn(gate, 0); 24794514f5e3Sopenharmony_ci GateRef index = acc_.GetValueIn(gate, 1); 24804514f5e3Sopenharmony_ci GateRef accValue = acc_.GetValueIn(gate, 2); 24814514f5e3Sopenharmony_ci DEFVALUE(result, (&builder_), VariableType::JS_ANY(), builder_.HoleConstant()); 24824514f5e3Sopenharmony_ci result = builder_.CallStub(glue_, gate, CommonStubCSigns::StObjByIndex, 24834514f5e3Sopenharmony_ci {glue_, receiver, builder_.TruncInt64ToInt32(index), accValue}); 24844514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, *result); 24854514f5e3Sopenharmony_ci} 24864514f5e3Sopenharmony_ci 24874514f5e3Sopenharmony_civoid SlowPathLowering::LowerLdObjByValue(GateRef gate, bool isThis) 24884514f5e3Sopenharmony_ci{ 24894514f5e3Sopenharmony_ci GateRef receiver; 24904514f5e3Sopenharmony_ci GateRef propKey; 24914514f5e3Sopenharmony_ci if (isThis) { 24924514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); // 2: number of value inputs 24934514f5e3Sopenharmony_ci receiver = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::THIS_OBJECT); 24944514f5e3Sopenharmony_ci propKey = acc_.GetValueIn(gate, 1); 24954514f5e3Sopenharmony_ci } else { 24964514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 3); // 3: number of value inputs 24974514f5e3Sopenharmony_ci receiver = acc_.GetValueIn(gate, 1); 24984514f5e3Sopenharmony_ci propKey = acc_.GetValueIn(gate, 2); // 2: the third parameter 24994514f5e3Sopenharmony_ci } 25004514f5e3Sopenharmony_ci LowerCallStubWithIC(gate, CommonStubCSigns::GetPropertyByValue, { receiver, propKey }); 25014514f5e3Sopenharmony_ci} 25024514f5e3Sopenharmony_ci 25034514f5e3Sopenharmony_civoid SlowPathLowering::LowerStObjByValue(GateRef gate, bool isThis) 25044514f5e3Sopenharmony_ci{ 25054514f5e3Sopenharmony_ci GateRef receiver; 25064514f5e3Sopenharmony_ci GateRef propKey; 25074514f5e3Sopenharmony_ci GateRef value; 25084514f5e3Sopenharmony_ci if (isThis) { 25094514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 3); // 3: number of value inputs 25104514f5e3Sopenharmony_ci receiver = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::THIS_OBJECT); 25114514f5e3Sopenharmony_ci propKey = acc_.GetValueIn(gate, 1); 25124514f5e3Sopenharmony_ci value = acc_.GetValueIn(gate, 2); // 2: the third parameter 25134514f5e3Sopenharmony_ci } else { 25144514f5e3Sopenharmony_ci // 4: number of value inputs 25154514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 4); 25164514f5e3Sopenharmony_ci receiver = acc_.GetValueIn(gate, 1); 25174514f5e3Sopenharmony_ci propKey = acc_.GetValueIn(gate, 2); // 2: the third parameter 25184514f5e3Sopenharmony_ci value = acc_.GetValueIn(gate, 3); // 3: the 4th parameter 25194514f5e3Sopenharmony_ci } 25204514f5e3Sopenharmony_ci LowerCallStubWithIC(gate, CommonStubCSigns::SetPropertyByValue, { receiver, propKey, value }); 25214514f5e3Sopenharmony_ci} 25224514f5e3Sopenharmony_ci 25234514f5e3Sopenharmony_civoid SlowPathLowering::LowerLdSuperByName(GateRef gate) 25244514f5e3Sopenharmony_ci{ 25254514f5e3Sopenharmony_ci // 2: number of value inputs 25264514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 25274514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 25284514f5e3Sopenharmony_ci GateRef sharedConstPool = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::SHARED_CONST_POOL); 25294514f5e3Sopenharmony_ci GateRef stringId = builder_.TruncInt64ToInt32(acc_.GetValueIn(gate, 0)); 25304514f5e3Sopenharmony_ci GateRef module = builder_.GetModuleFromFunction(jsFunc); 25314514f5e3Sopenharmony_ci GateRef prop = builder_.GetObjectFromConstPool(glue_, gate, sharedConstPool, Circuit::NullGate(), module, stringId, 25324514f5e3Sopenharmony_ci ConstPoolType::STRING); 25334514f5e3Sopenharmony_ci GateRef result = 25344514f5e3Sopenharmony_ci LowerCallRuntime(gate, RTSTUB_ID(OptLdSuperByValue), {acc_.GetValueIn(gate, 1), prop, jsFunc}, true); 25354514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 25364514f5e3Sopenharmony_ci} 25374514f5e3Sopenharmony_ci 25384514f5e3Sopenharmony_civoid SlowPathLowering::LowerStSuperByName(GateRef gate) 25394514f5e3Sopenharmony_ci{ 25404514f5e3Sopenharmony_ci // 3: number of value inputs 25414514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 3); 25424514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 25434514f5e3Sopenharmony_ci GateRef sharedConstPool = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::SHARED_CONST_POOL); 25444514f5e3Sopenharmony_ci GateRef stringId = builder_.TruncInt64ToInt32(acc_.GetValueIn(gate, 0)); 25454514f5e3Sopenharmony_ci GateRef module = builder_.GetModuleFromFunction(jsFunc); 25464514f5e3Sopenharmony_ci GateRef prop = builder_.GetObjectFromConstPool(glue_, gate, sharedConstPool, Circuit::NullGate(), module, stringId, 25474514f5e3Sopenharmony_ci ConstPoolType::STRING); 25484514f5e3Sopenharmony_ci auto args2 = { acc_.GetValueIn(gate, 1), prop, acc_.GetValueIn(gate, 2), jsFunc }; 25494514f5e3Sopenharmony_ci GateRef result = LowerCallRuntime(gate, RTSTUB_ID(OptStSuperByValue), args2, true); 25504514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 25514514f5e3Sopenharmony_ci} 25524514f5e3Sopenharmony_ci 25534514f5e3Sopenharmony_civoid SlowPathLowering::LowerCreateGeneratorObj(GateRef gate) 25544514f5e3Sopenharmony_ci{ 25554514f5e3Sopenharmony_ci const int id = RTSTUB_ID(CreateGeneratorObj); 25564514f5e3Sopenharmony_ci // 1: number of value inputs 25574514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 1); 25584514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, {acc_.GetValueIn(gate, 0)}); 25594514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 25604514f5e3Sopenharmony_ci} 25614514f5e3Sopenharmony_ci 25624514f5e3Sopenharmony_civoid SlowPathLowering::LowerCreateAsyncGeneratorObj(GateRef gate) 25634514f5e3Sopenharmony_ci{ 25644514f5e3Sopenharmony_ci int id = RTSTUB_ID(CreateAsyncGeneratorObj); 25654514f5e3Sopenharmony_ci // 1: number of value inputs 25664514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 1); 25674514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, {acc_.GetValueIn(gate, 0)}); 25684514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 25694514f5e3Sopenharmony_ci} 25704514f5e3Sopenharmony_ci 25714514f5e3Sopenharmony_civoid SlowPathLowering::LowerAsyncGeneratorResolve(GateRef gate) 25724514f5e3Sopenharmony_ci{ 25734514f5e3Sopenharmony_ci SaveFrameToContext(gate); 25744514f5e3Sopenharmony_ci acc_.SetDep(gate, builder_.GetDepend()); 25754514f5e3Sopenharmony_ci int id = RTSTUB_ID(OptAsyncGeneratorResolve); 25764514f5e3Sopenharmony_ci GateRef asyncGen = acc_.GetValueIn(gate, 1); 25774514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 2); 25784514f5e3Sopenharmony_ci GateRef flag = acc_.GetValueIn(gate, 3); 25794514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, {asyncGen, value, flag}); 25804514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 25814514f5e3Sopenharmony_ci} 25824514f5e3Sopenharmony_ci 25834514f5e3Sopenharmony_civoid SlowPathLowering::LowerAsyncGeneratorReject(GateRef gate) 25844514f5e3Sopenharmony_ci{ 25854514f5e3Sopenharmony_ci int id = RTSTUB_ID(AsyncGeneratorReject); 25864514f5e3Sopenharmony_ci // 2: number of value inputs 25874514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 25884514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, {acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1)}); 25894514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 25904514f5e3Sopenharmony_ci} 25914514f5e3Sopenharmony_ci 25924514f5e3Sopenharmony_civoid SlowPathLowering::LowerStArraySpread(GateRef gate) 25934514f5e3Sopenharmony_ci{ 25944514f5e3Sopenharmony_ci const int id = RTSTUB_ID(StArraySpread); 25954514f5e3Sopenharmony_ci // 3: number of value inputs 25964514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 3); 25974514f5e3Sopenharmony_ci auto args = { acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1), acc_.GetValueIn(gate, 2) }; 25984514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, args); 25994514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 26004514f5e3Sopenharmony_ci} 26014514f5e3Sopenharmony_ci 26024514f5e3Sopenharmony_civoid SlowPathLowering::LowerLdLexVar(GateRef gate) 26034514f5e3Sopenharmony_ci{ 26044514f5e3Sopenharmony_ci // 3: number of value inputs 26054514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 3); 26064514f5e3Sopenharmony_ci GateRef level = builder_.TruncInt64ToInt32(acc_.GetValueIn(gate, 0)); 26074514f5e3Sopenharmony_ci GateRef slot = builder_.TruncInt64ToInt32(acc_.GetValueIn(gate, 1)); 26084514f5e3Sopenharmony_ci DEFVALUE(currentEnv, (&builder_), VariableType::JS_ANY(), acc_.GetValueIn(gate, 2)); // 2: Get current lexEnv 26094514f5e3Sopenharmony_ci GateRef index = builder_.Int32(LexicalEnv::PARENT_ENV_INDEX); 26104514f5e3Sopenharmony_ci Label exit(&builder_); 26114514f5e3Sopenharmony_ci uint64_t constLevel = acc_.TryGetValue(acc_.GetValueIn(gate, 0)); 26124514f5e3Sopenharmony_ci if (constLevel == 0) { 26134514f5e3Sopenharmony_ci builder_.Jump(&exit); 26144514f5e3Sopenharmony_ci } else if (constLevel == 1) { 26154514f5e3Sopenharmony_ci currentEnv = builder_.GetValueFromTaggedArray(*currentEnv, index); 26164514f5e3Sopenharmony_ci builder_.Jump(&exit); 26174514f5e3Sopenharmony_ci } else { 26184514f5e3Sopenharmony_ci DEFVALUE(i, (&builder_), VariableType::INT32(), builder_.Int32(0)); 26194514f5e3Sopenharmony_ci Label loopHead(&builder_); 26204514f5e3Sopenharmony_ci Label loopEnd(&builder_); 26214514f5e3Sopenharmony_ci BRANCH_CIR(builder_.Int32LessThan(*i, level), &loopHead, &exit); 26224514f5e3Sopenharmony_ci builder_.LoopBegin(&loopHead); 26234514f5e3Sopenharmony_ci currentEnv = builder_.GetValueFromTaggedArray(*currentEnv, index); 26244514f5e3Sopenharmony_ci i = builder_.Int32Add(*i, builder_.Int32(1)); 26254514f5e3Sopenharmony_ci BRANCH_CIR(builder_.Int32LessThan(*i, level), &loopEnd, &exit); 26264514f5e3Sopenharmony_ci builder_.Bind(&loopEnd); 26274514f5e3Sopenharmony_ci builder_.LoopEnd(&loopHead); 26284514f5e3Sopenharmony_ci } 26294514f5e3Sopenharmony_ci builder_.Bind(&exit); 26304514f5e3Sopenharmony_ci GateRef valueIndex = builder_.Int32Add(slot, builder_.Int32(LexicalEnv::RESERVED_ENV_LENGTH)); 26314514f5e3Sopenharmony_ci GateRef result = builder_.GetValueFromTaggedArray(*currentEnv, valueIndex); 26324514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result, true); 26334514f5e3Sopenharmony_ci} 26344514f5e3Sopenharmony_ci 26354514f5e3Sopenharmony_civoid SlowPathLowering::LowerLdSendableVar(GateRef gate) 26364514f5e3Sopenharmony_ci{ 26374514f5e3Sopenharmony_ci // 2: number of value inputs 26384514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 26394514f5e3Sopenharmony_ci GateRef level = builder_.TruncInt64ToInt32(acc_.GetValueIn(gate, 0)); 26404514f5e3Sopenharmony_ci GateRef slot = builder_.TruncInt64ToInt32(acc_.GetValueIn(gate, 1)); 26414514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 26424514f5e3Sopenharmony_ci GateRef module = builder_.GetModuleFromFunction(jsFunc); 26434514f5e3Sopenharmony_ci DEFVALUE(currentEnv, (&builder_), VariableType::JS_ANY(), builder_.GetSendableEnvFromModule(module)); 26444514f5e3Sopenharmony_ci GateRef index = builder_.Int32(SendableEnv::SENDABLE_PARENT_ENV_INDEX); 26454514f5e3Sopenharmony_ci Label exit(&builder_); 26464514f5e3Sopenharmony_ci uint64_t constLevel = acc_.TryGetValue(acc_.GetValueIn(gate, 0)); 26474514f5e3Sopenharmony_ci if (constLevel == 0) { 26484514f5e3Sopenharmony_ci builder_.Jump(&exit); 26494514f5e3Sopenharmony_ci } else if (constLevel == 1) { 26504514f5e3Sopenharmony_ci currentEnv = builder_.GetValueFromTaggedArray(*currentEnv, index); 26514514f5e3Sopenharmony_ci builder_.Jump(&exit); 26524514f5e3Sopenharmony_ci } else { 26534514f5e3Sopenharmony_ci DEFVALUE(i, (&builder_), VariableType::INT32(), builder_.Int32(0)); 26544514f5e3Sopenharmony_ci Label loopHead(&builder_); 26554514f5e3Sopenharmony_ci Label loopEnd(&builder_); 26564514f5e3Sopenharmony_ci BRANCH_CIR(builder_.Int32LessThan(*i, level), &loopHead, &exit); 26574514f5e3Sopenharmony_ci builder_.LoopBegin(&loopHead); 26584514f5e3Sopenharmony_ci currentEnv = builder_.GetValueFromTaggedArray(*currentEnv, index); 26594514f5e3Sopenharmony_ci i = builder_.Int32Add(*i, builder_.Int32(1)); 26604514f5e3Sopenharmony_ci BRANCH_CIR(builder_.Int32LessThan(*i, level), &loopEnd, &exit); 26614514f5e3Sopenharmony_ci builder_.Bind(&loopEnd); 26624514f5e3Sopenharmony_ci builder_.LoopEnd(&loopHead); 26634514f5e3Sopenharmony_ci } 26644514f5e3Sopenharmony_ci builder_.Bind(&exit); 26654514f5e3Sopenharmony_ci GateRef valueIndex = builder_.Int32Add(slot, builder_.Int32(SendableEnv::SENDABLE_RESERVED_ENV_LENGTH)); 26664514f5e3Sopenharmony_ci GateRef result = builder_.GetValueFromTaggedArray(*currentEnv, valueIndex); 26674514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result, true); 26684514f5e3Sopenharmony_ci} 26694514f5e3Sopenharmony_ci 26704514f5e3Sopenharmony_civoid SlowPathLowering::LowerStLexVar(GateRef gate) 26714514f5e3Sopenharmony_ci{ 26724514f5e3Sopenharmony_ci // 4: number of value inputs 26734514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 4); 26744514f5e3Sopenharmony_ci GateRef level = builder_.TruncInt64ToInt32(acc_.GetValueIn(gate, 0)); 26754514f5e3Sopenharmony_ci GateRef slot = builder_.TruncInt64ToInt32(acc_.GetValueIn(gate, 1)); 26764514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 3); 26774514f5e3Sopenharmony_ci DEFVALUE(currentEnv, (&builder_), VariableType::JS_ANY(), acc_.GetValueIn(gate, 2)); // 2: Get current lexEnv 26784514f5e3Sopenharmony_ci GateRef index = builder_.Int32(LexicalEnv::PARENT_ENV_INDEX); 26794514f5e3Sopenharmony_ci Label exit(&builder_); 26804514f5e3Sopenharmony_ci uint64_t constLevel = acc_.TryGetValue(acc_.GetValueIn(gate, 0)); 26814514f5e3Sopenharmony_ci if (constLevel == 0) { 26824514f5e3Sopenharmony_ci builder_.Jump(&exit); 26834514f5e3Sopenharmony_ci } else if (constLevel == 1) { 26844514f5e3Sopenharmony_ci currentEnv = builder_.GetValueFromTaggedArray(*currentEnv, index); 26854514f5e3Sopenharmony_ci builder_.Jump(&exit); 26864514f5e3Sopenharmony_ci } else { 26874514f5e3Sopenharmony_ci DEFVALUE(i, (&builder_), VariableType::INT32(), builder_.Int32(0)); 26884514f5e3Sopenharmony_ci Label loopHead(&builder_); 26894514f5e3Sopenharmony_ci Label loopEnd(&builder_); 26904514f5e3Sopenharmony_ci BRANCH_CIR(builder_.Int32LessThan(*i, level), &loopHead, &exit); 26914514f5e3Sopenharmony_ci builder_.LoopBegin(&loopHead); 26924514f5e3Sopenharmony_ci currentEnv = builder_.GetValueFromTaggedArray(*currentEnv, index); 26934514f5e3Sopenharmony_ci i = builder_.Int32Add(*i, builder_.Int32(1)); 26944514f5e3Sopenharmony_ci BRANCH_CIR(builder_.Int32LessThan(*i, level), &loopEnd, &exit); 26954514f5e3Sopenharmony_ci builder_.Bind(&loopEnd); 26964514f5e3Sopenharmony_ci builder_.LoopEnd(&loopHead); 26974514f5e3Sopenharmony_ci } 26984514f5e3Sopenharmony_ci builder_.Bind(&exit); 26994514f5e3Sopenharmony_ci GateRef valueIndex = builder_.Int32Add(slot, builder_.Int32(LexicalEnv::RESERVED_ENV_LENGTH)); 27004514f5e3Sopenharmony_ci builder_.SetValueToTaggedArray(VariableType::JS_ANY(), glue_, *currentEnv, valueIndex, value); 27014514f5e3Sopenharmony_ci auto result = *currentEnv; 27024514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result, true); 27034514f5e3Sopenharmony_ci} 27044514f5e3Sopenharmony_ci 27054514f5e3Sopenharmony_civoid SlowPathLowering::LowerStSendableVar(GateRef gate) 27064514f5e3Sopenharmony_ci{ 27074514f5e3Sopenharmony_ci // 3: number of value inputs 27084514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 3); 27094514f5e3Sopenharmony_ci GateRef level = builder_.TruncInt64ToInt32(acc_.GetValueIn(gate, 0)); 27104514f5e3Sopenharmony_ci GateRef slot = builder_.TruncInt64ToInt32(acc_.GetValueIn(gate, 1)); 27114514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 2); 27124514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 27134514f5e3Sopenharmony_ci GateRef module = builder_.GetModuleFromFunction(jsFunc); 27144514f5e3Sopenharmony_ci DEFVALUE(currentEnv, (&builder_), VariableType::JS_ANY(), builder_.GetSendableEnvFromModule(module)); 27154514f5e3Sopenharmony_ci GateRef index = builder_.Int32(SendableEnv::SENDABLE_PARENT_ENV_INDEX); 27164514f5e3Sopenharmony_ci Label exit(&builder_); 27174514f5e3Sopenharmony_ci uint64_t constLevel = acc_.TryGetValue(acc_.GetValueIn(gate, 0)); 27184514f5e3Sopenharmony_ci if (constLevel == 0) { 27194514f5e3Sopenharmony_ci builder_.Jump(&exit); 27204514f5e3Sopenharmony_ci } else if (constLevel == 1) { 27214514f5e3Sopenharmony_ci currentEnv = builder_.GetValueFromTaggedArray(*currentEnv, index); 27224514f5e3Sopenharmony_ci builder_.Jump(&exit); 27234514f5e3Sopenharmony_ci } else { 27244514f5e3Sopenharmony_ci DEFVALUE(i, (&builder_), VariableType::INT32(), builder_.Int32(0)); 27254514f5e3Sopenharmony_ci Label loopHead(&builder_); 27264514f5e3Sopenharmony_ci Label loopEnd(&builder_); 27274514f5e3Sopenharmony_ci BRANCH_CIR(builder_.Int32LessThan(*i, level), &loopHead, &exit); 27284514f5e3Sopenharmony_ci builder_.LoopBegin(&loopHead); 27294514f5e3Sopenharmony_ci currentEnv = builder_.GetValueFromTaggedArray(*currentEnv, index); 27304514f5e3Sopenharmony_ci i = builder_.Int32Add(*i, builder_.Int32(1)); 27314514f5e3Sopenharmony_ci BRANCH_CIR(builder_.Int32LessThan(*i, level), &loopEnd, &exit); 27324514f5e3Sopenharmony_ci builder_.Bind(&loopEnd); 27334514f5e3Sopenharmony_ci builder_.LoopEnd(&loopHead); 27344514f5e3Sopenharmony_ci } 27354514f5e3Sopenharmony_ci builder_.Bind(&exit); 27364514f5e3Sopenharmony_ci GateRef valueIndex = builder_.Int32Add(slot, builder_.Int32(SendableEnv::SENDABLE_RESERVED_ENV_LENGTH)); 27374514f5e3Sopenharmony_ci builder_.SetValueToTaggedArray(VariableType::JS_ANY(), glue_, *currentEnv, valueIndex, value); 27384514f5e3Sopenharmony_ci auto result = *currentEnv; 27394514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result, true); 27404514f5e3Sopenharmony_ci} 27414514f5e3Sopenharmony_ci 27424514f5e3Sopenharmony_civoid SlowPathLowering::LowerDefineClassWithBuffer(GateRef gate) 27434514f5e3Sopenharmony_ci{ 27444514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 6); // 6: number of value inputs 27454514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 27464514f5e3Sopenharmony_ci GateRef methodId = acc_.GetValueIn(gate, 0); 27474514f5e3Sopenharmony_ci GateRef proto = acc_.GetValueIn(gate, 3); 27484514f5e3Sopenharmony_ci GateRef literalId = acc_.GetValueIn(gate, 1); 27494514f5e3Sopenharmony_ci GateRef length = acc_.GetValueIn(gate, 2); // 2: second arg 27504514f5e3Sopenharmony_ci GateRef lexicalEnv = acc_.GetValueIn(gate, 4); // 4: Get current env 27514514f5e3Sopenharmony_ci GateRef sharedConstPool = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::SHARED_CONST_POOL); 27524514f5e3Sopenharmony_ci GateRef module = builder_.GetModuleFromFunction(jsFunc); 27534514f5e3Sopenharmony_ci Label isException(&builder_); 27544514f5e3Sopenharmony_ci Label isNotException(&builder_); 27554514f5e3Sopenharmony_ci 27564514f5e3Sopenharmony_ci GateRef result; 27574514f5e3Sopenharmony_ci auto args = { proto, lexicalEnv, sharedConstPool, 27584514f5e3Sopenharmony_ci builder_.ToTaggedInt(methodId), builder_.ToTaggedInt(literalId), module, 27594514f5e3Sopenharmony_ci builder_.ToTaggedInt(length), 27604514f5e3Sopenharmony_ci#if ECMASCRIPT_ENABLE_IC 27614514f5e3Sopenharmony_ci // 5: slot id 27624514f5e3Sopenharmony_ci builder_.Int32ToTaggedInt(builder_.ZExtInt16ToInt32(acc_.GetValueIn(gate, 5))), jsFunc 27634514f5e3Sopenharmony_ci#endif 27644514f5e3Sopenharmony_ci }; 27654514f5e3Sopenharmony_ci result = LowerCallRuntime(gate, RTSTUB_ID(CreateClassWithBuffer), args, true); 27664514f5e3Sopenharmony_ci BRANCH_CIR(builder_.IsSpecial(result, JSTaggedValue::VALUE_EXCEPTION), &isException, &isNotException); 27674514f5e3Sopenharmony_ci CREATE_DOUBLE_EXIT(isNotException, isException) 27684514f5e3Sopenharmony_ci acc_.ReplaceHirWithIfBranch(gate, successControl, failControl, result); 27694514f5e3Sopenharmony_ci} 27704514f5e3Sopenharmony_ci 27714514f5e3Sopenharmony_civoid SlowPathLowering::LowerDefineFunc(GateRef gate) 27724514f5e3Sopenharmony_ci{ 27734514f5e3Sopenharmony_ci Jit::JitLockHolder lock(compilationEnv_, "SlowPathLowering"); 27744514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 27754514f5e3Sopenharmony_ci GateRef methodId = acc_.GetValueIn(gate, 1); 27764514f5e3Sopenharmony_ci 27774514f5e3Sopenharmony_ci FunctionKind kind = FunctionKind::LAST_FUNCTION_KIND; 27784514f5e3Sopenharmony_ci if (acc_.IsConstantNumber(methodId)) { 27794514f5e3Sopenharmony_ci // try to speed up the kind checking 27804514f5e3Sopenharmony_ci JSTaggedValue unsharedCp; 27814514f5e3Sopenharmony_ci if (compilationEnv_->IsJitCompiler()) { 27824514f5e3Sopenharmony_ci unsharedCp = compilationEnv_->FindConstpool(compilationEnv_->GetJSPandaFile(), 0); 27834514f5e3Sopenharmony_ci } else { 27844514f5e3Sopenharmony_ci auto methodOffset = acc_.TryGetMethodOffset(gate); 27854514f5e3Sopenharmony_ci unsharedCp = compilationEnv_->FindOrCreateUnsharedConstpool(methodOffset); 27864514f5e3Sopenharmony_ci } 27874514f5e3Sopenharmony_ci auto obj = compilationEnv_->GetMethodFromCache(unsharedCp, acc_.GetConstantValue(methodId)); 27884514f5e3Sopenharmony_ci if (obj != JSTaggedValue::Undefined()) { 27894514f5e3Sopenharmony_ci kind = Method::Cast(obj)->GetFunctionKind(); 27904514f5e3Sopenharmony_ci } 27914514f5e3Sopenharmony_ci } 27924514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 27934514f5e3Sopenharmony_ci GateRef length = acc_.GetValueIn(gate, 2); 27944514f5e3Sopenharmony_ci GateRef lexEnv = acc_.GetValueIn(gate, 3); // 3: Get current env 27954514f5e3Sopenharmony_ci GateRef slotId = acc_.GetValueIn(gate, 0); 27964514f5e3Sopenharmony_ci Label success(&builder_); 27974514f5e3Sopenharmony_ci Label failed(&builder_); 27984514f5e3Sopenharmony_ci GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::Definefunc, 27994514f5e3Sopenharmony_ci {glue_, jsFunc, builder_.TruncInt64ToInt32(methodId), builder_.TruncInt64ToInt32(length), lexEnv, slotId}); 28004514f5e3Sopenharmony_ci BRANCH_CIR(builder_.TaggedIsException(result), &failed, &success); 28014514f5e3Sopenharmony_ci CREATE_DOUBLE_EXIT(success, failed) 28024514f5e3Sopenharmony_ci acc_.ReplaceHirWithIfBranch(gate, successControl, failControl, result); 28034514f5e3Sopenharmony_ci} 28044514f5e3Sopenharmony_ci 28054514f5e3Sopenharmony_civoid SlowPathLowering::LowerAsyncFunctionEnter(GateRef gate) 28064514f5e3Sopenharmony_ci{ 28074514f5e3Sopenharmony_ci const int id = RTSTUB_ID(AsyncFunctionEnter); 28084514f5e3Sopenharmony_ci // 0: number of value inputs 28094514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 0); 28104514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, {}); 28114514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 28124514f5e3Sopenharmony_ci} 28134514f5e3Sopenharmony_ci 28144514f5e3Sopenharmony_civoid SlowPathLowering::LowerTypeof(GateRef gate) 28154514f5e3Sopenharmony_ci{ 28164514f5e3Sopenharmony_ci // 1: number of value inputs 28174514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 1); 28184514f5e3Sopenharmony_ci GateRef obj = acc_.GetValueIn(gate, 0); 28194514f5e3Sopenharmony_ci Label entry(&builder_); 28204514f5e3Sopenharmony_ci Label exit(&builder_); 28214514f5e3Sopenharmony_ci 28224514f5e3Sopenharmony_ci GateRef gConstAddr = builder_.Load(VariableType::JS_POINTER(), glue_, 28234514f5e3Sopenharmony_ci builder_.IntPtr(JSThread::GlueData::GetGlobalConstOffset(builder_.GetCompilationConfig()->Is32Bit()))); 28244514f5e3Sopenharmony_ci GateRef undefinedIndex = builder_.GetGlobalConstantOffset(ConstantIndex::UNDEFINED_STRING_INDEX); 28254514f5e3Sopenharmony_ci GateRef gConstUndefinedStr = builder_.Load(VariableType::JS_POINTER(), gConstAddr, undefinedIndex); 28264514f5e3Sopenharmony_ci DEFVALUE(result, (&builder_), VariableType::JS_POINTER(), gConstUndefinedStr); 28274514f5e3Sopenharmony_ci Label objIsTrue(&builder_); 28284514f5e3Sopenharmony_ci Label objNotTrue(&builder_); 28294514f5e3Sopenharmony_ci Label defaultLabel(&builder_); 28304514f5e3Sopenharmony_ci GateRef gConstBooleanStr = builder_.Load(VariableType::JS_POINTER(), gConstAddr, 28314514f5e3Sopenharmony_ci builder_.GetGlobalConstantOffset(ConstantIndex::BOOLEAN_STRING_INDEX)); 28324514f5e3Sopenharmony_ci BRANCH_CIR(builder_.TaggedIsTrue(obj), &objIsTrue, &objNotTrue); 28334514f5e3Sopenharmony_ci builder_.Bind(&objIsTrue); 28344514f5e3Sopenharmony_ci { 28354514f5e3Sopenharmony_ci result = gConstBooleanStr; 28364514f5e3Sopenharmony_ci builder_.Jump(&exit); 28374514f5e3Sopenharmony_ci } 28384514f5e3Sopenharmony_ci builder_.Bind(&objNotTrue); 28394514f5e3Sopenharmony_ci { 28404514f5e3Sopenharmony_ci Label objIsFalse(&builder_); 28414514f5e3Sopenharmony_ci Label objNotFalse(&builder_); 28424514f5e3Sopenharmony_ci BRANCH_CIR(builder_.TaggedIsFalse(obj), &objIsFalse, &objNotFalse); 28434514f5e3Sopenharmony_ci builder_.Bind(&objIsFalse); 28444514f5e3Sopenharmony_ci { 28454514f5e3Sopenharmony_ci result = gConstBooleanStr; 28464514f5e3Sopenharmony_ci builder_.Jump(&exit); 28474514f5e3Sopenharmony_ci } 28484514f5e3Sopenharmony_ci builder_.Bind(&objNotFalse); 28494514f5e3Sopenharmony_ci { 28504514f5e3Sopenharmony_ci Label objIsNull(&builder_); 28514514f5e3Sopenharmony_ci Label objNotNull(&builder_); 28524514f5e3Sopenharmony_ci BRANCH_CIR(builder_.TaggedIsNull(obj), &objIsNull, &objNotNull); 28534514f5e3Sopenharmony_ci builder_.Bind(&objIsNull); 28544514f5e3Sopenharmony_ci { 28554514f5e3Sopenharmony_ci result = builder_.Load(VariableType::JS_POINTER(), gConstAddr, 28564514f5e3Sopenharmony_ci builder_.GetGlobalConstantOffset(ConstantIndex::OBJECT_STRING_INDEX)); 28574514f5e3Sopenharmony_ci builder_.Jump(&exit); 28584514f5e3Sopenharmony_ci } 28594514f5e3Sopenharmony_ci builder_.Bind(&objNotNull); 28604514f5e3Sopenharmony_ci { 28614514f5e3Sopenharmony_ci Label objIsUndefined(&builder_); 28624514f5e3Sopenharmony_ci Label objNotUndefined(&builder_); 28634514f5e3Sopenharmony_ci BRANCH_CIR(builder_.TaggedIsUndefined(obj), &objIsUndefined, &objNotUndefined); 28644514f5e3Sopenharmony_ci builder_.Bind(&objIsUndefined); 28654514f5e3Sopenharmony_ci { 28664514f5e3Sopenharmony_ci result = builder_.Load(VariableType::JS_POINTER(), gConstAddr, 28674514f5e3Sopenharmony_ci builder_.GetGlobalConstantOffset(ConstantIndex::UNDEFINED_STRING_INDEX)); 28684514f5e3Sopenharmony_ci builder_.Jump(&exit); 28694514f5e3Sopenharmony_ci } 28704514f5e3Sopenharmony_ci builder_.Bind(&objNotUndefined); 28714514f5e3Sopenharmony_ci builder_.Jump(&defaultLabel); 28724514f5e3Sopenharmony_ci } 28734514f5e3Sopenharmony_ci } 28744514f5e3Sopenharmony_ci } 28754514f5e3Sopenharmony_ci builder_.Bind(&defaultLabel); 28764514f5e3Sopenharmony_ci { 28774514f5e3Sopenharmony_ci Label objIsHeapObject(&builder_); 28784514f5e3Sopenharmony_ci Label objNotHeapObject(&builder_); 28794514f5e3Sopenharmony_ci BRANCH_CIR(builder_.TaggedIsHeapObject(obj), &objIsHeapObject, &objNotHeapObject); 28804514f5e3Sopenharmony_ci builder_.Bind(&objIsHeapObject); 28814514f5e3Sopenharmony_ci { 28824514f5e3Sopenharmony_ci Label objIsString(&builder_); 28834514f5e3Sopenharmony_ci Label objNotString(&builder_); 28844514f5e3Sopenharmony_ci BRANCH_CIR(builder_.TaggedObjectIsString(obj), &objIsString, &objNotString); 28854514f5e3Sopenharmony_ci builder_.Bind(&objIsString); 28864514f5e3Sopenharmony_ci { 28874514f5e3Sopenharmony_ci result = builder_.Load(VariableType::JS_POINTER(), gConstAddr, 28884514f5e3Sopenharmony_ci builder_.GetGlobalConstantOffset(ConstantIndex::STRING_STRING_INDEX)); 28894514f5e3Sopenharmony_ci builder_.Jump(&exit); 28904514f5e3Sopenharmony_ci } 28914514f5e3Sopenharmony_ci builder_.Bind(&objNotString); 28924514f5e3Sopenharmony_ci { 28934514f5e3Sopenharmony_ci Label objIsSymbol(&builder_); 28944514f5e3Sopenharmony_ci Label objNotSymbol(&builder_); 28954514f5e3Sopenharmony_ci BRANCH_CIR(builder_.IsJsType(obj, JSType::SYMBOL), &objIsSymbol, &objNotSymbol); 28964514f5e3Sopenharmony_ci builder_.Bind(&objIsSymbol); 28974514f5e3Sopenharmony_ci { 28984514f5e3Sopenharmony_ci result = builder_.Load(VariableType::JS_POINTER(), gConstAddr, 28994514f5e3Sopenharmony_ci builder_.GetGlobalConstantOffset(ConstantIndex::SYMBOL_STRING_INDEX)); 29004514f5e3Sopenharmony_ci builder_.Jump(&exit); 29014514f5e3Sopenharmony_ci } 29024514f5e3Sopenharmony_ci builder_.Bind(&objNotSymbol); 29034514f5e3Sopenharmony_ci { 29044514f5e3Sopenharmony_ci Label objIsCallable(&builder_); 29054514f5e3Sopenharmony_ci Label objNotCallable(&builder_); 29064514f5e3Sopenharmony_ci BRANCH_CIR(builder_.IsCallable(obj), &objIsCallable, &objNotCallable); 29074514f5e3Sopenharmony_ci builder_.Bind(&objIsCallable); 29084514f5e3Sopenharmony_ci { 29094514f5e3Sopenharmony_ci result = builder_.Load(VariableType::JS_POINTER(), gConstAddr, 29104514f5e3Sopenharmony_ci builder_.GetGlobalConstantOffset(ConstantIndex::FUNCTION_STRING_INDEX)); 29114514f5e3Sopenharmony_ci builder_.Jump(&exit); 29124514f5e3Sopenharmony_ci } 29134514f5e3Sopenharmony_ci builder_.Bind(&objNotCallable); 29144514f5e3Sopenharmony_ci { 29154514f5e3Sopenharmony_ci Label objIsBigInt(&builder_); 29164514f5e3Sopenharmony_ci Label objNotBigInt(&builder_); 29174514f5e3Sopenharmony_ci BRANCH_CIR(builder_.IsJsType(obj, JSType::BIGINT), &objIsBigInt, &objNotBigInt); 29184514f5e3Sopenharmony_ci builder_.Bind(&objIsBigInt); 29194514f5e3Sopenharmony_ci { 29204514f5e3Sopenharmony_ci result = builder_.Load(VariableType::JS_POINTER(), gConstAddr, 29214514f5e3Sopenharmony_ci builder_.GetGlobalConstantOffset(ConstantIndex::BIGINT_STRING_INDEX)); 29224514f5e3Sopenharmony_ci builder_.Jump(&exit); 29234514f5e3Sopenharmony_ci } 29244514f5e3Sopenharmony_ci builder_.Bind(&objNotBigInt); 29254514f5e3Sopenharmony_ci { 29264514f5e3Sopenharmony_ci result = builder_.Load(VariableType::JS_POINTER(), gConstAddr, 29274514f5e3Sopenharmony_ci builder_.GetGlobalConstantOffset(ConstantIndex::OBJECT_STRING_INDEX)); 29284514f5e3Sopenharmony_ci builder_.Jump(&exit); 29294514f5e3Sopenharmony_ci } 29304514f5e3Sopenharmony_ci } 29314514f5e3Sopenharmony_ci } 29324514f5e3Sopenharmony_ci } 29334514f5e3Sopenharmony_ci } 29344514f5e3Sopenharmony_ci builder_.Bind(&objNotHeapObject); 29354514f5e3Sopenharmony_ci { 29364514f5e3Sopenharmony_ci Label objIsNum(&builder_); 29374514f5e3Sopenharmony_ci Label objNotNum(&builder_); 29384514f5e3Sopenharmony_ci BRANCH_CIR(builder_.TaggedIsNumber(obj), &objIsNum, &objNotNum); 29394514f5e3Sopenharmony_ci builder_.Bind(&objIsNum); 29404514f5e3Sopenharmony_ci { 29414514f5e3Sopenharmony_ci result = builder_.Load(VariableType::JS_POINTER(), gConstAddr, 29424514f5e3Sopenharmony_ci builder_.GetGlobalConstantOffset(ConstantIndex::NUMBER_STRING_INDEX)); 29434514f5e3Sopenharmony_ci builder_.Jump(&exit); 29444514f5e3Sopenharmony_ci } 29454514f5e3Sopenharmony_ci builder_.Bind(&objNotNum); 29464514f5e3Sopenharmony_ci builder_.Jump(&exit); 29474514f5e3Sopenharmony_ci } 29484514f5e3Sopenharmony_ci } 29494514f5e3Sopenharmony_ci builder_.Bind(&exit); 29504514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, *result, true); 29514514f5e3Sopenharmony_ci} 29524514f5e3Sopenharmony_ci 29534514f5e3Sopenharmony_ciGateRef SlowPathLowering::GetValueFromTaggedArray(GateRef arrayGate, GateRef indexOffset) 29544514f5e3Sopenharmony_ci{ 29554514f5e3Sopenharmony_ci GateRef offset = builder_.PtrMul(builder_.ZExtInt32ToPtr(indexOffset), 29564514f5e3Sopenharmony_ci builder_.IntPtr(JSTaggedValue::TaggedTypeSize())); 29574514f5e3Sopenharmony_ci GateRef dataOffset = builder_.PtrAdd(offset, builder_.IntPtr(TaggedArray::DATA_OFFSET)); 29584514f5e3Sopenharmony_ci GateRef value = builder_.Load(VariableType::JS_ANY(), arrayGate, dataOffset); 29594514f5e3Sopenharmony_ci return value; 29604514f5e3Sopenharmony_ci} 29614514f5e3Sopenharmony_ci 29624514f5e3Sopenharmony_civoid SlowPathLowering::LowerStoreRegister(GateRef gate, GateRef arrayGate) 29634514f5e3Sopenharmony_ci{ 29644514f5e3Sopenharmony_ci ASSERT((acc_.GetOpCode(gate) == OpCode::RESTORE_REGISTER)); 29654514f5e3Sopenharmony_ci auto index = acc_.GetVirtualRegisterIndex(gate); 29664514f5e3Sopenharmony_ci auto indexOffset = builder_.Int32(index); 29674514f5e3Sopenharmony_ci GateRef value = GetValueFromTaggedArray(arrayGate, indexOffset); 29684514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, Circuit::NullGate(), Circuit::NullGate(), value); 29694514f5e3Sopenharmony_ci} 29704514f5e3Sopenharmony_ci 29714514f5e3Sopenharmony_civoid SlowPathLowering::LowerResumeGenerator(GateRef gate) 29724514f5e3Sopenharmony_ci{ 29734514f5e3Sopenharmony_ci GateRef obj = acc_.GetValueIn(gate, 0); 29744514f5e3Sopenharmony_ci std::vector<GateRef> registerGates {}; 29754514f5e3Sopenharmony_ci 29764514f5e3Sopenharmony_ci AddProfiling(gate, false); 29774514f5e3Sopenharmony_ci GateRef contextOffset = builder_.IntPtr(JSGeneratorObject::GENERATOR_CONTEXT_OFFSET); 29784514f5e3Sopenharmony_ci GateRef contextGate = builder_.Load(VariableType::JS_POINTER(), obj, contextOffset); 29794514f5e3Sopenharmony_ci GateRef arrayOffset = builder_.IntPtr(GeneratorContext::GENERATOR_REGS_ARRAY_OFFSET); 29804514f5e3Sopenharmony_ci GateRef arrayGate = builder_.Load(VariableType::JS_POINTER(), contextGate, arrayOffset); 29814514f5e3Sopenharmony_ci 29824514f5e3Sopenharmony_ci auto uses = acc_.Uses(gate); 29834514f5e3Sopenharmony_ci for (auto it = uses.begin(); it != uses.end(); it++) { 29844514f5e3Sopenharmony_ci if (acc_.IsValueIn(it) && acc_.GetOpCode(*it) == OpCode::RESTORE_REGISTER) { 29854514f5e3Sopenharmony_ci registerGates.emplace_back(*it); 29864514f5e3Sopenharmony_ci } 29874514f5e3Sopenharmony_ci } 29884514f5e3Sopenharmony_ci for (auto item : registerGates) { 29894514f5e3Sopenharmony_ci LowerStoreRegister(item, arrayGate); 29904514f5e3Sopenharmony_ci } 29914514f5e3Sopenharmony_ci 29924514f5e3Sopenharmony_ci // 1: number of value inputs 29934514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 1); 29944514f5e3Sopenharmony_ci Label isAsyncGeneratorObj(&builder_); 29954514f5e3Sopenharmony_ci Label notAsyncGeneratorObj(&builder_); 29964514f5e3Sopenharmony_ci Label exit(&builder_); 29974514f5e3Sopenharmony_ci DEFVALUE(result, (&builder_), VariableType::JS_ANY(), builder_.HoleConstant()); 29984514f5e3Sopenharmony_ci BRANCH_CIR(builder_.TaggedIsAsyncGeneratorObject(obj), &isAsyncGeneratorObj, ¬AsyncGeneratorObj); 29994514f5e3Sopenharmony_ci builder_.Bind(&isAsyncGeneratorObj); 30004514f5e3Sopenharmony_ci { 30014514f5e3Sopenharmony_ci GateRef resumeResultOffset = builder_.IntPtr(JSAsyncGeneratorObject::GENERATOR_RESUME_RESULT_OFFSET); 30024514f5e3Sopenharmony_ci result = builder_.Load(VariableType::JS_ANY(), obj, resumeResultOffset); 30034514f5e3Sopenharmony_ci builder_.Jump(&exit); 30044514f5e3Sopenharmony_ci } 30054514f5e3Sopenharmony_ci builder_.Bind(¬AsyncGeneratorObj); 30064514f5e3Sopenharmony_ci { 30074514f5e3Sopenharmony_ci GateRef resumeResultOffset = builder_.IntPtr(JSGeneratorObject::GENERATOR_RESUME_RESULT_OFFSET); 30084514f5e3Sopenharmony_ci result = builder_.Load(VariableType::JS_ANY(), obj, resumeResultOffset); 30094514f5e3Sopenharmony_ci GateRef taskInfoOffset = builder_.IntPtr(JSGeneratorObject::TASK_INFO_OFFSET); 30104514f5e3Sopenharmony_ci GateRef taskInfo = builder_.Load(VariableType::NATIVE_POINTER(), obj, taskInfoOffset); 30114514f5e3Sopenharmony_ci GateRef glueTaskOffset = 30124514f5e3Sopenharmony_ci builder_.IntPtr(JSThread::GlueData::GetTaskInfoOffset(builder_.GetCompilationConfig()->Is32Bit())); 30134514f5e3Sopenharmony_ci builder_.Store(VariableType::NATIVE_POINTER(), glue_, glue_, glueTaskOffset, taskInfo); 30144514f5e3Sopenharmony_ci builder_.Store(VariableType::NATIVE_POINTER(), glue_, obj, taskInfoOffset, builder_.IntPtr(0)); 30154514f5e3Sopenharmony_ci builder_.Jump(&exit); 30164514f5e3Sopenharmony_ci } 30174514f5e3Sopenharmony_ci builder_.Bind(&exit); 30184514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, *result, true); 30194514f5e3Sopenharmony_ci} 30204514f5e3Sopenharmony_ci 30214514f5e3Sopenharmony_civoid SlowPathLowering::LowerGetResumeMode(GateRef gate) 30224514f5e3Sopenharmony_ci{ 30234514f5e3Sopenharmony_ci // 1: number of value inputs 30244514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 1); 30254514f5e3Sopenharmony_ci DEFVALUE(result, (&builder_), VariableType::JS_ANY(), builder_.Undefined()); 30264514f5e3Sopenharmony_ci Label isAsyncGeneratorObj(&builder_); 30274514f5e3Sopenharmony_ci Label notAsyncGeneratorObj(&builder_); 30284514f5e3Sopenharmony_ci Label exit(&builder_); 30294514f5e3Sopenharmony_ci GateRef obj = acc_.GetValueIn(gate, 0); 30304514f5e3Sopenharmony_ci BRANCH_CIR(builder_.TaggedIsAsyncGeneratorObject(obj), &isAsyncGeneratorObj, ¬AsyncGeneratorObj); 30314514f5e3Sopenharmony_ci builder_.Bind(&isAsyncGeneratorObj); 30324514f5e3Sopenharmony_ci { 30334514f5e3Sopenharmony_ci GateRef bitFieldOffset = builder_.IntPtr(JSAsyncGeneratorObject::BIT_FIELD_OFFSET); 30344514f5e3Sopenharmony_ci GateRef bitField = builder_.Load(VariableType::INT32(), obj, bitFieldOffset); 30354514f5e3Sopenharmony_ci auto bitfieldlsr = builder_.Int32LSR(bitField, 30364514f5e3Sopenharmony_ci builder_.Int32(JSAsyncGeneratorObject::ResumeModeBits::START_BIT)); 30374514f5e3Sopenharmony_ci GateRef modeBits = builder_.Int32And(bitfieldlsr, 30384514f5e3Sopenharmony_ci builder_.Int32((1LU << JSAsyncGeneratorObject::ResumeModeBits::SIZE) - 1)); 30394514f5e3Sopenharmony_ci auto resumeMode = builder_.SExtInt32ToInt64(modeBits); 30404514f5e3Sopenharmony_ci result = builder_.ToTaggedIntPtr(resumeMode); 30414514f5e3Sopenharmony_ci builder_.Jump(&exit); 30424514f5e3Sopenharmony_ci } 30434514f5e3Sopenharmony_ci builder_.Bind(¬AsyncGeneratorObj); 30444514f5e3Sopenharmony_ci { 30454514f5e3Sopenharmony_ci GateRef bitFieldOffset = builder_.IntPtr(JSGeneratorObject::BIT_FIELD_OFFSET); 30464514f5e3Sopenharmony_ci GateRef bitField = builder_.Load(VariableType::INT32(), obj, bitFieldOffset); 30474514f5e3Sopenharmony_ci auto bitfieldlsr = builder_.Int32LSR(bitField, builder_.Int32(JSGeneratorObject::ResumeModeBits::START_BIT)); 30484514f5e3Sopenharmony_ci GateRef modeBits = builder_.Int32And(bitfieldlsr, 30494514f5e3Sopenharmony_ci builder_.Int32((1LU << JSGeneratorObject::ResumeModeBits::SIZE) - 1)); 30504514f5e3Sopenharmony_ci auto resumeMode = builder_.SExtInt32ToInt64(modeBits); 30514514f5e3Sopenharmony_ci result = builder_.ToTaggedIntPtr(resumeMode); 30524514f5e3Sopenharmony_ci builder_.Jump(&exit); 30534514f5e3Sopenharmony_ci } 30544514f5e3Sopenharmony_ci builder_.Bind(&exit); 30554514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, *result, true); 30564514f5e3Sopenharmony_ci} 30574514f5e3Sopenharmony_ci 30584514f5e3Sopenharmony_civoid SlowPathLowering::LowerDefineMethod(GateRef gate) 30594514f5e3Sopenharmony_ci{ 30604514f5e3Sopenharmony_ci // 5: number of value inputs 30614514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 5); 30624514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 30634514f5e3Sopenharmony_ci GateRef sharedConstPool = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::SHARED_CONST_POOL); 30644514f5e3Sopenharmony_ci GateRef methodId = builder_.TruncInt64ToInt32(acc_.GetValueIn(gate, 0)); 30654514f5e3Sopenharmony_ci GateRef module = builder_.GetModuleFromFunction(jsFunc); 30664514f5e3Sopenharmony_ci auto method = builder_.GetObjectFromConstPool(glue_, gate, sharedConstPool, Circuit::NullGate(), module, methodId, 30674514f5e3Sopenharmony_ci ConstPoolType::METHOD); 30684514f5e3Sopenharmony_ci GateRef length = acc_.GetValueIn(gate, 1); 30694514f5e3Sopenharmony_ci GateRef env = acc_.GetValueIn(gate, 2); // 2: Get current env 30704514f5e3Sopenharmony_ci GateRef homeObject = acc_.GetValueIn(gate, 4); // 4: homeObject 30714514f5e3Sopenharmony_ci 30724514f5e3Sopenharmony_ci Label defaultLabel(&builder_); 30734514f5e3Sopenharmony_ci Label successExit(&builder_); 30744514f5e3Sopenharmony_ci Label exceptionExit(&builder_); 30754514f5e3Sopenharmony_ci auto args = {method, homeObject, builder_.ToTaggedInt(length), env, builder_.GetModuleFromFunction(jsFunc), 30764514f5e3Sopenharmony_ci#if ECMASCRIPT_ENABLE_IC 30774514f5e3Sopenharmony_ci builder_.Int32ToTaggedInt(builder_.ZExtInt16ToInt32(acc_.GetValueIn(gate, 3))), jsFunc // 3: slot id 30784514f5e3Sopenharmony_ci#endif 30794514f5e3Sopenharmony_ci }; 30804514f5e3Sopenharmony_ci GateRef result = LowerCallRuntime(gate, RTSTUB_ID(DefineMethod), args, true); 30814514f5e3Sopenharmony_ci BRANCH_CIR(builder_.IsSpecial(result, JSTaggedValue::VALUE_EXCEPTION), 30824514f5e3Sopenharmony_ci &exceptionExit, &successExit); 30834514f5e3Sopenharmony_ci CREATE_DOUBLE_EXIT(successExit, exceptionExit) 30844514f5e3Sopenharmony_ci acc_.ReplaceHirWithIfBranch(gate, successControl, failControl, result); 30854514f5e3Sopenharmony_ci} 30864514f5e3Sopenharmony_ci 30874514f5e3Sopenharmony_civoid SlowPathLowering::LowerGetUnmappedArgs(GateRef gate) 30884514f5e3Sopenharmony_ci{ 30894514f5e3Sopenharmony_ci GateRef actualArgc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::ACTUAL_ARGC); 30904514f5e3Sopenharmony_ci GateRef newGate = builder_.CallStub(glue_, gate, CommonStubCSigns::GetUnmappedArgs, 30914514f5e3Sopenharmony_ci { glue_, builder_.IntPtr(0), builder_.TruncInt64ToInt32(actualArgc), builder_.Undefined() }); 30924514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 30934514f5e3Sopenharmony_ci} 30944514f5e3Sopenharmony_ci 30954514f5e3Sopenharmony_civoid SlowPathLowering::LowerCopyRestArgs(GateRef gate) 30964514f5e3Sopenharmony_ci{ 30974514f5e3Sopenharmony_ci GateRef actualArgc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::ACTUAL_ARGC); 30984514f5e3Sopenharmony_ci GateRef taggedArgc = builder_.ToTaggedInt(actualArgc); 30994514f5e3Sopenharmony_ci GateRef restIdx = acc_.GetValueIn(gate, 0); 31004514f5e3Sopenharmony_ci GateRef taggedRestIdx = builder_.ToTaggedInt(restIdx); 31014514f5e3Sopenharmony_ci 31024514f5e3Sopenharmony_ci const int id = RTSTUB_ID(OptCopyRestArgs); 31034514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, {taggedArgc, taggedRestIdx}); 31044514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 31054514f5e3Sopenharmony_ci} 31064514f5e3Sopenharmony_ci 31074514f5e3Sopenharmony_civoid SlowPathLowering::LowerWideLdPatchVar(GateRef gate) 31084514f5e3Sopenharmony_ci{ 31094514f5e3Sopenharmony_ci const int id = RTSTUB_ID(LdPatchVar); 31104514f5e3Sopenharmony_ci GateRef index = acc_.GetValueIn(gate, 0); 31114514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, {builder_.ToTaggedInt(index)}); 31124514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 31134514f5e3Sopenharmony_ci} 31144514f5e3Sopenharmony_ci 31154514f5e3Sopenharmony_civoid SlowPathLowering::LowerWideStPatchVar(GateRef gate) 31164514f5e3Sopenharmony_ci{ 31174514f5e3Sopenharmony_ci const int id = RTSTUB_ID(StPatchVar); 31184514f5e3Sopenharmony_ci GateRef index = acc_.GetValueIn(gate, 0); 31194514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, {builder_.ToTaggedInt(index)}); 31204514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 31214514f5e3Sopenharmony_ci} 31224514f5e3Sopenharmony_ci 31234514f5e3Sopenharmony_civoid SlowPathLowering::AddProfiling(GateRef gate, bool skipGenerator) 31244514f5e3Sopenharmony_ci{ 31254514f5e3Sopenharmony_ci if (IsTraceBC()) { 31264514f5e3Sopenharmony_ci EcmaOpcode ecmaOpcode = acc_.GetByteCodeOpcode(gate); 31274514f5e3Sopenharmony_ci if ((ecmaOpcode == EcmaOpcode::SUSPENDGENERATOR_V8 || ecmaOpcode == EcmaOpcode::RESUMEGENERATOR) && 31284514f5e3Sopenharmony_ci skipGenerator) { 31294514f5e3Sopenharmony_ci return; 31304514f5e3Sopenharmony_ci } 31314514f5e3Sopenharmony_ci auto ecmaOpcodeGate = builder_.Int32(static_cast<uint32_t>(ecmaOpcode)); 31324514f5e3Sopenharmony_ci GateRef constOpcode = builder_.ToTaggedInt(builder_.ZExtInt32ToInt64(ecmaOpcodeGate)); 31334514f5e3Sopenharmony_ci GateRef slowPath = builder_.Int32ToTaggedInt(builder_.Int32(0)); 31344514f5e3Sopenharmony_ci GateRef debugGate = builder_.CallRuntime(glue_, RTSTUB_ID(DebugAOTPrint), acc_.GetDep(gate), 31354514f5e3Sopenharmony_ci { constOpcode, slowPath }, gate); 31364514f5e3Sopenharmony_ci acc_.SetDep(gate, debugGate); 31374514f5e3Sopenharmony_ci } 31384514f5e3Sopenharmony_ci 31394514f5e3Sopenharmony_ci if (IsProfiling()) { 31404514f5e3Sopenharmony_ci EcmaOpcode ecmaOpcode = acc_.GetByteCodeOpcode(gate); 31414514f5e3Sopenharmony_ci if ((ecmaOpcode == EcmaOpcode::SUSPENDGENERATOR_V8 || ecmaOpcode == EcmaOpcode::RESUMEGENERATOR) && 31424514f5e3Sopenharmony_ci skipGenerator) { 31434514f5e3Sopenharmony_ci return; 31444514f5e3Sopenharmony_ci } 31454514f5e3Sopenharmony_ci 31464514f5e3Sopenharmony_ci GateRef func = builder_.Undefined(); 31474514f5e3Sopenharmony_ci if (acc_.HasFrameState(gate)) { 31484514f5e3Sopenharmony_ci func = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 31494514f5e3Sopenharmony_ci } 31504514f5e3Sopenharmony_ci GateRef bcIndex = builder_.Int32ToTaggedInt(builder_.Int32(acc_.TryGetBcIndex(gate))); 31514514f5e3Sopenharmony_ci auto ecmaOpcodeGate = builder_.Int32(static_cast<uint32_t>(ecmaOpcode)); 31524514f5e3Sopenharmony_ci GateRef constOpcode = builder_.Int32ToTaggedInt(ecmaOpcodeGate); 31534514f5e3Sopenharmony_ci GateRef mode = 31544514f5e3Sopenharmony_ci builder_.Int32ToTaggedInt(builder_.Int32(static_cast<int32_t>(OptCodeProfiler::Mode::SLOW_PATH))); 31554514f5e3Sopenharmony_ci GateRef profiling = builder_.CallRuntime(glue_, RTSTUB_ID(ProfileOptimizedCode), acc_.GetDep(gate), 31564514f5e3Sopenharmony_ci { func, bcIndex, constOpcode, mode }, gate); 31574514f5e3Sopenharmony_ci acc_.SetDep(gate, profiling); 31584514f5e3Sopenharmony_ci } 31594514f5e3Sopenharmony_ci} 31604514f5e3Sopenharmony_ci 31614514f5e3Sopenharmony_civoid SlowPathLowering::LowerCallthis0Imm8V8(GateRef gate) 31624514f5e3Sopenharmony_ci{ 31634514f5e3Sopenharmony_ci // 2: number of value inputs 31644514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 31654514f5e3Sopenharmony_ci 31664514f5e3Sopenharmony_ci GateRef actualArgc = builder_.Int64(BytecodeCallArgc::ComputeCallArgc(acc_.GetNumValueIn(gate), 31674514f5e3Sopenharmony_ci EcmaOpcode::CALLTHIS0_IMM8_V8)); 31684514f5e3Sopenharmony_ci GateRef actualArgv = builder_.IntPtr(0); 31694514f5e3Sopenharmony_ci GateRef newTarget = builder_.Undefined(); 31704514f5e3Sopenharmony_ci GateRef thisObj = acc_.GetValueIn(gate, 0); 31714514f5e3Sopenharmony_ci GateRef func = acc_.GetValueIn(gate, 1); 31724514f5e3Sopenharmony_ci LowerToJSCall(gate, {glue_, actualArgc, actualArgv, func, newTarget, thisObj}, {glue_, func, thisObj}); 31734514f5e3Sopenharmony_ci} 31744514f5e3Sopenharmony_ci 31754514f5e3Sopenharmony_civoid SlowPathLowering::LowerCallArg1Imm8V8(GateRef gate) 31764514f5e3Sopenharmony_ci{ 31774514f5e3Sopenharmony_ci // 2: number of value inputs 31784514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 31794514f5e3Sopenharmony_ci GateRef actualArgc = builder_.Int64(BytecodeCallArgc::ComputeCallArgc(acc_.GetNumValueIn(gate), 31804514f5e3Sopenharmony_ci EcmaOpcode::CALLARG1_IMM8_V8)); 31814514f5e3Sopenharmony_ci GateRef actualArgv = builder_.IntPtr(0); 31824514f5e3Sopenharmony_ci GateRef newTarget = builder_.Undefined(); 31834514f5e3Sopenharmony_ci GateRef a0Value = acc_.GetValueIn(gate, 0); 31844514f5e3Sopenharmony_ci GateRef thisObj = builder_.Undefined(); 31854514f5e3Sopenharmony_ci GateRef func = acc_.GetValueIn(gate, 1); // acc 31864514f5e3Sopenharmony_ci LowerToJSCall(gate, {glue_, actualArgc, actualArgv, func, newTarget, thisObj, a0Value}, 31874514f5e3Sopenharmony_ci {glue_, func, thisObj, a0Value}); 31884514f5e3Sopenharmony_ci} 31894514f5e3Sopenharmony_ci 31904514f5e3Sopenharmony_civoid SlowPathLowering::LowerWideCallrangePrefImm16V8(GateRef gate) 31914514f5e3Sopenharmony_ci{ 31924514f5e3Sopenharmony_ci std::vector<GateRef> vec; 31934514f5e3Sopenharmony_ci std::vector<GateRef> vec1; 31944514f5e3Sopenharmony_ci size_t numIns = acc_.GetNumValueIn(gate); 31954514f5e3Sopenharmony_ci size_t fixedInputsNum = 1; // 1: acc 31964514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) >= fixedInputsNum); 31974514f5e3Sopenharmony_ci GateRef actualArgc = builder_.Int64(BytecodeCallArgc::ComputeCallArgc(acc_.GetNumValueIn(gate), 31984514f5e3Sopenharmony_ci EcmaOpcode::WIDE_CALLRANGE_PREF_IMM16_V8)); 31994514f5e3Sopenharmony_ci GateRef actualArgv = builder_.IntPtr(0); 32004514f5e3Sopenharmony_ci GateRef callTarget = acc_.GetValueIn(gate, numIns - fixedInputsNum); // acc 32014514f5e3Sopenharmony_ci GateRef newTarget = builder_.Undefined(); 32024514f5e3Sopenharmony_ci GateRef thisObj = builder_.Undefined(); 32034514f5e3Sopenharmony_ci 32044514f5e3Sopenharmony_ci vec.emplace_back(glue_); 32054514f5e3Sopenharmony_ci vec.emplace_back(actualArgc); 32064514f5e3Sopenharmony_ci vec.emplace_back(actualArgv); 32074514f5e3Sopenharmony_ci vec.emplace_back(callTarget); 32084514f5e3Sopenharmony_ci vec.emplace_back(newTarget); 32094514f5e3Sopenharmony_ci vec.emplace_back(thisObj); 32104514f5e3Sopenharmony_ci // add args 32114514f5e3Sopenharmony_ci for (size_t i = 0; i < numIns - fixedInputsNum; i++) { // skip acc 32124514f5e3Sopenharmony_ci vec.emplace_back(acc_.GetValueIn(gate, i)); 32134514f5e3Sopenharmony_ci } 32144514f5e3Sopenharmony_ci 32154514f5e3Sopenharmony_ci vec.emplace_back(glue_); 32164514f5e3Sopenharmony_ci vec.emplace_back(callTarget); 32174514f5e3Sopenharmony_ci vec.emplace_back(thisObj); 32184514f5e3Sopenharmony_ci // add args 32194514f5e3Sopenharmony_ci for (size_t i = 0; i < numIns - fixedInputsNum; i++) { // skip acc 32204514f5e3Sopenharmony_ci vec.emplace_back(acc_.GetValueIn(gate, i)); 32214514f5e3Sopenharmony_ci } 32224514f5e3Sopenharmony_ci LowerToJSCall(gate, vec, vec1); 32234514f5e3Sopenharmony_ci} 32244514f5e3Sopenharmony_ci 32254514f5e3Sopenharmony_civoid SlowPathLowering::LowerCallThisArg1(GateRef gate) 32264514f5e3Sopenharmony_ci{ 32274514f5e3Sopenharmony_ci // 3: number of value inputs 32284514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 3); 32294514f5e3Sopenharmony_ci GateRef actualArgc = builder_.Int64(BytecodeCallArgc::ComputeCallArgc(acc_.GetNumValueIn(gate), 32304514f5e3Sopenharmony_ci EcmaOpcode::CALLTHIS1_IMM8_V8_V8)); 32314514f5e3Sopenharmony_ci GateRef actualArgv = builder_.IntPtr(0); 32324514f5e3Sopenharmony_ci GateRef newTarget = builder_.Undefined(); 32334514f5e3Sopenharmony_ci GateRef thisObj = acc_.GetValueIn(gate, 0); 32344514f5e3Sopenharmony_ci GateRef a0 = acc_.GetValueIn(gate, 1); // 1:first parameter 32354514f5e3Sopenharmony_ci GateRef func = acc_.GetValueIn(gate, 2); // 2:function 32364514f5e3Sopenharmony_ci LowerToJSCall(gate, {glue_, actualArgc, actualArgv, func, newTarget, thisObj, a0}, {glue_, func, thisObj, a0}); 32374514f5e3Sopenharmony_ci} 32384514f5e3Sopenharmony_ci 32394514f5e3Sopenharmony_civoid SlowPathLowering::LowerCallargs2Imm8V8V8(GateRef gate) 32404514f5e3Sopenharmony_ci{ 32414514f5e3Sopenharmony_ci // 3: number of value inputs 32424514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 3); 32434514f5e3Sopenharmony_ci GateRef actualArgc = builder_.Int64(BytecodeCallArgc::ComputeCallArgc(acc_.GetNumValueIn(gate), 32444514f5e3Sopenharmony_ci EcmaOpcode::CALLARGS2_IMM8_V8_V8)); 32454514f5e3Sopenharmony_ci GateRef actualArgv = builder_.IntPtr(0); 32464514f5e3Sopenharmony_ci GateRef newTarget = builder_.Undefined(); 32474514f5e3Sopenharmony_ci GateRef thisObj = builder_.Undefined(); 32484514f5e3Sopenharmony_ci GateRef a0 = acc_.GetValueIn(gate, 0); 32494514f5e3Sopenharmony_ci GateRef a1 = acc_.GetValueIn(gate, 1); // 1:first parameter 32504514f5e3Sopenharmony_ci GateRef func = acc_.GetValueIn(gate, 2); // 2:function 32514514f5e3Sopenharmony_ci 32524514f5e3Sopenharmony_ci LowerToJSCall(gate, {glue_, actualArgc, actualArgv, func, newTarget, thisObj, a0, a1}, 32534514f5e3Sopenharmony_ci {glue_, func, thisObj, a0, a1}); 32544514f5e3Sopenharmony_ci} 32554514f5e3Sopenharmony_ci 32564514f5e3Sopenharmony_civoid SlowPathLowering::LowerCallargs3Imm8V8V8(GateRef gate) 32574514f5e3Sopenharmony_ci{ 32584514f5e3Sopenharmony_ci // 4: number of value inputs 32594514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 4); 32604514f5e3Sopenharmony_ci GateRef actualArgc = builder_.Int64(BytecodeCallArgc::ComputeCallArgc(acc_.GetNumValueIn(gate), 32614514f5e3Sopenharmony_ci EcmaOpcode::CALLARGS3_IMM8_V8_V8_V8)); 32624514f5e3Sopenharmony_ci GateRef actualArgv = builder_.IntPtr(0); 32634514f5e3Sopenharmony_ci GateRef newTarget = builder_.Undefined(); 32644514f5e3Sopenharmony_ci GateRef thisObj = builder_.Undefined(); 32654514f5e3Sopenharmony_ci GateRef a0 = acc_.GetValueIn(gate, 0); 32664514f5e3Sopenharmony_ci GateRef a1 = acc_.GetValueIn(gate, 1); 32674514f5e3Sopenharmony_ci GateRef a2 = acc_.GetValueIn(gate, 2); 32684514f5e3Sopenharmony_ci GateRef func = acc_.GetValueIn(gate, 3); 32694514f5e3Sopenharmony_ci 32704514f5e3Sopenharmony_ci LowerToJSCall(gate, {glue_, actualArgc, actualArgv, func, newTarget, thisObj, a0, a1, a2}, 32714514f5e3Sopenharmony_ci {glue_, func, thisObj, a0, a1, a2}); 32724514f5e3Sopenharmony_ci} 32734514f5e3Sopenharmony_ci 32744514f5e3Sopenharmony_civoid SlowPathLowering::LowerCallthis2Imm8V8V8V8(GateRef gate) 32754514f5e3Sopenharmony_ci{ 32764514f5e3Sopenharmony_ci // 4: number of value inputs 32774514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 4); 32784514f5e3Sopenharmony_ci GateRef actualArgc = builder_.Int64(BytecodeCallArgc::ComputeCallArgc(acc_.GetNumValueIn(gate), 32794514f5e3Sopenharmony_ci EcmaOpcode::CALLTHIS2_IMM8_V8_V8_V8)); 32804514f5e3Sopenharmony_ci GateRef actualArgv = builder_.IntPtr(0); 32814514f5e3Sopenharmony_ci GateRef newTarget = builder_.Undefined(); 32824514f5e3Sopenharmony_ci GateRef thisObj = acc_.GetValueIn(gate, 0); 32834514f5e3Sopenharmony_ci GateRef a0Value = acc_.GetValueIn(gate, 1); 32844514f5e3Sopenharmony_ci GateRef a1Value = acc_.GetValueIn(gate, 2); 32854514f5e3Sopenharmony_ci GateRef func = acc_.GetValueIn(gate, 3); //acc 32864514f5e3Sopenharmony_ci 32874514f5e3Sopenharmony_ci LowerToJSCall(gate, {glue_, actualArgc, actualArgv, func, newTarget, thisObj, a0Value, a1Value}, 32884514f5e3Sopenharmony_ci {glue_, func, thisObj, a0Value, a1Value}); 32894514f5e3Sopenharmony_ci} 32904514f5e3Sopenharmony_ci 32914514f5e3Sopenharmony_civoid SlowPathLowering::LowerCallthis3Imm8V8V8V8V8(GateRef gate) 32924514f5e3Sopenharmony_ci{ 32934514f5e3Sopenharmony_ci // 5: number of value inputs 32944514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 5); 32954514f5e3Sopenharmony_ci GateRef actualArgc = builder_.Int64(BytecodeCallArgc::ComputeCallArgc(acc_.GetNumValueIn(gate), 32964514f5e3Sopenharmony_ci EcmaOpcode::CALLTHIS3_IMM8_V8_V8_V8_V8)); 32974514f5e3Sopenharmony_ci GateRef actualArgv = builder_.IntPtr(0); 32984514f5e3Sopenharmony_ci GateRef newTarget = builder_.Undefined(); 32994514f5e3Sopenharmony_ci GateRef thisObj = acc_.GetValueIn(gate, 0); 33004514f5e3Sopenharmony_ci GateRef a0Value = acc_.GetValueIn(gate, 1); 33014514f5e3Sopenharmony_ci GateRef a1Value = acc_.GetValueIn(gate, 2); 33024514f5e3Sopenharmony_ci GateRef a2Value = acc_.GetValueIn(gate, 3); 33034514f5e3Sopenharmony_ci GateRef func = acc_.GetValueIn(gate, 4); 33044514f5e3Sopenharmony_ci LowerToJSCall(gate, {glue_, actualArgc, actualArgv, func, newTarget, thisObj, a0Value, a1Value, a2Value}, 33054514f5e3Sopenharmony_ci {glue_, func, thisObj, a0Value, a1Value, a2Value}); 33064514f5e3Sopenharmony_ci} 33074514f5e3Sopenharmony_ci 33084514f5e3Sopenharmony_civoid SlowPathLowering::LowerLdThisByName(GateRef gate) 33094514f5e3Sopenharmony_ci{ 33104514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); // 2: number of parameter 33114514f5e3Sopenharmony_ci GateRef thisObj = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::THIS_OBJECT); 33124514f5e3Sopenharmony_ci GateRef prop = acc_.GetValueIn(gate, 1); // 1: the second parameter 33134514f5e3Sopenharmony_ci LowerCallStubWithIC(gate, CommonStubCSigns::GetPropertyByName, { thisObj, prop }); 33144514f5e3Sopenharmony_ci} 33154514f5e3Sopenharmony_ci 33164514f5e3Sopenharmony_cibool SlowPathLowering::IsFastCallArgs(size_t index) 33174514f5e3Sopenharmony_ci{ 33184514f5e3Sopenharmony_ci return index != static_cast<size_t>(CommonArgIdx::ACTUAL_ARGC) && 33194514f5e3Sopenharmony_ci index != static_cast<size_t>(CommonArgIdx::ACTUAL_ARGV) && 33204514f5e3Sopenharmony_ci index != static_cast<size_t>(CommonArgIdx::NEW_TARGET); 33214514f5e3Sopenharmony_ci} 33224514f5e3Sopenharmony_ci 33234514f5e3Sopenharmony_civoid SlowPathLowering::LowerConstruct(GateRef gate) 33244514f5e3Sopenharmony_ci{ 33254514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 33264514f5e3Sopenharmony_ci size_t num = acc_.GetNumValueIn(gate); 33274514f5e3Sopenharmony_ci std::vector<GateRef> args(num); 33284514f5e3Sopenharmony_ci for (size_t i = 0; i < num; ++i) { 33294514f5e3Sopenharmony_ci args[i] = acc_.GetValueIn(gate, i); 33304514f5e3Sopenharmony_ci } 33314514f5e3Sopenharmony_ci ASSERT(num >= 3); // 3: skip argc argv newtarget 33324514f5e3Sopenharmony_ci std::vector<GateRef> argsFastCall(num - 3); // 3: skip argc argv newtarget 33334514f5e3Sopenharmony_ci size_t j = 0; 33344514f5e3Sopenharmony_ci for (size_t i = 0; i < num; ++i) { 33354514f5e3Sopenharmony_ci if (IsFastCallArgs(i)) { 33364514f5e3Sopenharmony_ci argsFastCall[j++] = acc_.GetValueIn(gate, i); 33374514f5e3Sopenharmony_ci } 33384514f5e3Sopenharmony_ci } 33394514f5e3Sopenharmony_ci GateRef ctor = acc_.GetValueIn(gate, static_cast<size_t>(CommonArgIdx::FUNC)); 33404514f5e3Sopenharmony_ci GateRef argc = acc_.GetValueIn(gate, static_cast<size_t>(CommonArgIdx::ACTUAL_ARGC)); 33414514f5e3Sopenharmony_ci Label exit(&builder_); 33424514f5e3Sopenharmony_ci DEFVALUE(res, (&builder_), VariableType::JS_ANY(), builder_.Undefined()); 33434514f5e3Sopenharmony_ci LowerFastCall(gate, glue_, ctor, argc, args, argsFastCall, &res, &exit, true); 33444514f5e3Sopenharmony_ci builder_.Bind(&exit); 33454514f5e3Sopenharmony_ci GateRef thisObj = acc_.GetValueIn(gate, static_cast<size_t>(CommonArgIdx::THIS_OBJECT)); 33464514f5e3Sopenharmony_ci GateRef result = builder_.CallStub( 33474514f5e3Sopenharmony_ci glue_, gate, CommonStubCSigns::ConstructorCheck, { glue_, ctor, *res, thisObj }); 33484514f5e3Sopenharmony_ci GateRef state = builder_.GetState(); 33494514f5e3Sopenharmony_ci ReplaceHirWithPendingException(gate, state, result, result); 33504514f5e3Sopenharmony_ci} 33514514f5e3Sopenharmony_ci 33524514f5e3Sopenharmony_civoid SlowPathLowering::LowerCallInternal(GateRef gate) 33534514f5e3Sopenharmony_ci{ 33544514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 33554514f5e3Sopenharmony_ci size_t num = acc_.GetNumValueIn(gate); 33564514f5e3Sopenharmony_ci std::vector<GateRef> args(num); 33574514f5e3Sopenharmony_ci for (size_t i = 0; i < num; ++i) { 33584514f5e3Sopenharmony_ci args[i] = acc_.GetValueIn(gate, i); 33594514f5e3Sopenharmony_ci } 33604514f5e3Sopenharmony_ci ASSERT(num >= 3); // 3: skip argc argv newtarget 33614514f5e3Sopenharmony_ci std::vector<GateRef> argsFastCall(num - 3); // 3:skip argc argv newtarget 33624514f5e3Sopenharmony_ci size_t j = 0; 33634514f5e3Sopenharmony_ci for (size_t i = 0; i < num; ++i) { 33644514f5e3Sopenharmony_ci if (IsFastCallArgs(i)) { // 1: argc index 3: newtarget index 2:ActualArgv 33654514f5e3Sopenharmony_ci argsFastCall[j++] = acc_.GetValueIn(gate, i); 33664514f5e3Sopenharmony_ci } 33674514f5e3Sopenharmony_ci } 33684514f5e3Sopenharmony_ci GateRef func = acc_.GetValueIn(gate, static_cast<size_t>(CommonArgIdx::FUNC)); 33694514f5e3Sopenharmony_ci GateRef argc = acc_.GetValueIn(gate, static_cast<size_t>(CommonArgIdx::ACTUAL_ARGC)); 33704514f5e3Sopenharmony_ci Label exit(&builder_); 33714514f5e3Sopenharmony_ci DEFVALUE(res, (&builder_), VariableType::JS_ANY(), builder_.Undefined()); 33724514f5e3Sopenharmony_ci LowerFastCall(gate, glue_, func, argc, args, argsFastCall, &res, &exit, false); 33734514f5e3Sopenharmony_ci builder_.Bind(&exit); 33744514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *res); 33754514f5e3Sopenharmony_ci} 33764514f5e3Sopenharmony_ci 33774514f5e3Sopenharmony_civoid SlowPathLowering::LowerCallNew(GateRef gate) 33784514f5e3Sopenharmony_ci{ 33794514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 33804514f5e3Sopenharmony_ci size_t num = acc_.GetNumValueIn(gate); 33814514f5e3Sopenharmony_ci bool needPushArgv = acc_.NeedPushArgv(gate); 33824514f5e3Sopenharmony_ci std::vector<GateRef> args(num); 33834514f5e3Sopenharmony_ci for (size_t i = 0; i < num; ++i) { 33844514f5e3Sopenharmony_ci args[i] = acc_.GetValueIn(gate, i); 33854514f5e3Sopenharmony_ci } 33864514f5e3Sopenharmony_ci ASSERT(num >= 3); // 3:skip argc argv newtarget 33874514f5e3Sopenharmony_ci std::vector<GateRef> argsFastCall(num - 3); // 3:skip argc argv newtarget 33884514f5e3Sopenharmony_ci size_t j = 0; 33894514f5e3Sopenharmony_ci for (size_t i = 0; i < num; ++i) { 33904514f5e3Sopenharmony_ci if (IsFastCallArgs(i)) { 33914514f5e3Sopenharmony_ci argsFastCall[j++] = acc_.GetValueIn(gate, i); 33924514f5e3Sopenharmony_ci } 33934514f5e3Sopenharmony_ci } 33944514f5e3Sopenharmony_ci GateRef ctor = acc_.GetValueIn(gate, static_cast<size_t>(CommonArgIdx::FUNC)); 33954514f5e3Sopenharmony_ci Label exit(&builder_); 33964514f5e3Sopenharmony_ci DEFVALUE(res, (&builder_), VariableType::JS_ANY(), builder_.Undefined()); 33974514f5e3Sopenharmony_ci LowerNewFastCall(gate, glue_, ctor, needPushArgv, args, argsFastCall, &res, &exit); 33984514f5e3Sopenharmony_ci builder_.Bind(&exit); 33994514f5e3Sopenharmony_ci GateRef thisObj = acc_.GetValueIn(gate, static_cast<size_t>(CommonArgIdx::THIS_OBJECT)); 34004514f5e3Sopenharmony_ci GateRef result = builder_.CallStub( 34014514f5e3Sopenharmony_ci glue_, gate, CommonStubCSigns::ConstructorCheck, { glue_, ctor, *res, thisObj }); 34024514f5e3Sopenharmony_ci GateRef state = builder_.GetState(); 34034514f5e3Sopenharmony_ci ReplaceHirWithPendingException(gate, state, result, result); 34044514f5e3Sopenharmony_ci} 34054514f5e3Sopenharmony_ci 34064514f5e3Sopenharmony_civoid SlowPathLowering::LowerNewFastCall(GateRef gate, GateRef glue, GateRef func, 34074514f5e3Sopenharmony_ci bool needPushArgv, const std::vector<GateRef> &args, 34084514f5e3Sopenharmony_ci const std::vector<GateRef> &argsFastCall, Variable *result, Label *exit) 34094514f5e3Sopenharmony_ci{ 34104514f5e3Sopenharmony_ci Label fastCall(&builder_); 34114514f5e3Sopenharmony_ci Label notFastCall(&builder_); 34124514f5e3Sopenharmony_ci Label slowCall(&builder_); 34134514f5e3Sopenharmony_ci Label slowPath(&builder_); 34144514f5e3Sopenharmony_ci BRANCH_CIR(builder_.JudgeAotAndFastCall(func, CircuitBuilder::JudgeMethodType::HAS_AOT_FASTCALL), 34154514f5e3Sopenharmony_ci &fastCall, ¬FastCall); 34164514f5e3Sopenharmony_ci builder_.Bind(&fastCall); 34174514f5e3Sopenharmony_ci { 34184514f5e3Sopenharmony_ci if (!needPushArgv) { 34194514f5e3Sopenharmony_ci builder_.StartCallTimer(glue_, gate, {glue_, func, builder_.True()}, true); 34204514f5e3Sopenharmony_ci GateRef code = builder_.GetCodeAddr(func); 34214514f5e3Sopenharmony_ci auto depend = builder_.GetDepend(); 34224514f5e3Sopenharmony_ci const CallSignature *cs = RuntimeStubCSigns::GetOptimizedFastCallSign(); 34234514f5e3Sopenharmony_ci result->WriteVariable(builder_.Call(cs, glue, code, depend, argsFastCall, gate, "callFastAOT")); 34244514f5e3Sopenharmony_ci builder_.EndCallTimer(glue_, gate, {glue_, func}, true); 34254514f5e3Sopenharmony_ci builder_.Jump(exit); 34264514f5e3Sopenharmony_ci } else { 34274514f5e3Sopenharmony_ci builder_.StartCallTimer(glue_, gate, {glue_, func, builder_.True()}, true); 34284514f5e3Sopenharmony_ci const CallSignature *cs = RuntimeStubCSigns::Get(RTSTUB_ID(OptimizedFastCallAndPushArgv)); 34294514f5e3Sopenharmony_ci GateRef target = builder_.IntPtr(RTSTUB_ID(OptimizedFastCallAndPushArgv)); 34304514f5e3Sopenharmony_ci auto depend = builder_.GetDepend(); 34314514f5e3Sopenharmony_ci result->WriteVariable(builder_.Call(cs, glue, target, depend, args, gate, "callFastBridge")); 34324514f5e3Sopenharmony_ci builder_.EndCallTimer(glue_, gate, {glue_, func}, true); 34334514f5e3Sopenharmony_ci builder_.Jump(exit); 34344514f5e3Sopenharmony_ci } 34354514f5e3Sopenharmony_ci } 34364514f5e3Sopenharmony_ci builder_.Bind(¬FastCall); 34374514f5e3Sopenharmony_ci BRANCH_CIR(builder_.JudgeAotAndFastCall(func, CircuitBuilder::JudgeMethodType::HAS_AOT), 34384514f5e3Sopenharmony_ci &slowCall, &slowPath); 34394514f5e3Sopenharmony_ci builder_.Bind(&slowCall); 34404514f5e3Sopenharmony_ci { 34414514f5e3Sopenharmony_ci if (!needPushArgv) { 34424514f5e3Sopenharmony_ci builder_.StartCallTimer(glue_, gate, {glue_, func, builder_.True()}, true); 34434514f5e3Sopenharmony_ci GateRef code = builder_.GetCodeAddr(func); 34444514f5e3Sopenharmony_ci auto depend = builder_.GetDepend(); 34454514f5e3Sopenharmony_ci const CallSignature *cs = RuntimeStubCSigns::GetOptimizedCallSign(); 34464514f5e3Sopenharmony_ci result->WriteVariable(builder_.Call(cs, glue, code, depend, args, gate, "callAOT")); 34474514f5e3Sopenharmony_ci builder_.EndCallTimer(glue_, gate, {glue_, func}, true); 34484514f5e3Sopenharmony_ci builder_.Jump(exit); 34494514f5e3Sopenharmony_ci } else { 34504514f5e3Sopenharmony_ci builder_.StartCallTimer(glue_, gate, {glue_, func, builder_.True()}, true); 34514514f5e3Sopenharmony_ci const CallSignature *cs = RuntimeStubCSigns::Get(RTSTUB_ID(OptimizedCallAndPushArgv)); 34524514f5e3Sopenharmony_ci GateRef target = builder_.IntPtr(RTSTUB_ID(OptimizedCallAndPushArgv)); 34534514f5e3Sopenharmony_ci auto depend = builder_.GetDepend(); 34544514f5e3Sopenharmony_ci result->WriteVariable(builder_.Call(cs, glue, target, depend, args, gate, "callBridge")); 34554514f5e3Sopenharmony_ci builder_.EndCallTimer(glue_, gate, {glue_, func}, true); 34564514f5e3Sopenharmony_ci builder_.Jump(exit); 34574514f5e3Sopenharmony_ci } 34584514f5e3Sopenharmony_ci } 34594514f5e3Sopenharmony_ci builder_.Bind(&slowPath); 34604514f5e3Sopenharmony_ci { 34614514f5e3Sopenharmony_ci builder_.StartCallTimer(glue_, gate, {glue_, func, builder_.True()}, true); 34624514f5e3Sopenharmony_ci const CallSignature *cs = RuntimeStubCSigns::Get(RTSTUB_ID(JSCallNew)); 34634514f5e3Sopenharmony_ci GateRef target = builder_.IntPtr(RTSTUB_ID(JSCallNew)); 34644514f5e3Sopenharmony_ci auto depend = builder_.GetDepend(); 34654514f5e3Sopenharmony_ci result->WriteVariable(builder_.Call(cs, glue, target, depend, args, gate, "slowNew")); 34664514f5e3Sopenharmony_ci builder_.EndCallTimer(glue_, gate, {glue_, func}, true); 34674514f5e3Sopenharmony_ci builder_.Jump(exit); 34684514f5e3Sopenharmony_ci } 34694514f5e3Sopenharmony_ci} 34704514f5e3Sopenharmony_ci 34714514f5e3Sopenharmony_civoid SlowPathLowering::LowerFastCall(GateRef gate, GateRef glue, GateRef func, GateRef argc, 34724514f5e3Sopenharmony_ci const std::vector<GateRef> &args, const std::vector<GateRef> &argsFastCall, 34734514f5e3Sopenharmony_ci Variable *result, Label *exit, bool isNew) 34744514f5e3Sopenharmony_ci{ 34754514f5e3Sopenharmony_ci Label isHeapObject(&builder_); 34764514f5e3Sopenharmony_ci Label isJsFcuntion(&builder_); 34774514f5e3Sopenharmony_ci Label fastCall(&builder_); 34784514f5e3Sopenharmony_ci Label notFastCall(&builder_); 34794514f5e3Sopenharmony_ci Label call(&builder_); 34804514f5e3Sopenharmony_ci Label call1(&builder_); 34814514f5e3Sopenharmony_ci Label slowCall(&builder_); 34824514f5e3Sopenharmony_ci Label callBridge(&builder_); 34834514f5e3Sopenharmony_ci Label callBridge1(&builder_); 34844514f5e3Sopenharmony_ci Label slowPath(&builder_); 34854514f5e3Sopenharmony_ci Label notCallConstructor(&builder_); 34864514f5e3Sopenharmony_ci Label isCallConstructor(&builder_); 34874514f5e3Sopenharmony_ci BRANCH_CIR(builder_.TaggedIsHeapObject(func), &isHeapObject, &slowPath); 34884514f5e3Sopenharmony_ci builder_.Bind(&isHeapObject); 34894514f5e3Sopenharmony_ci { 34904514f5e3Sopenharmony_ci BRANCH_CIR(builder_.IsJSFunction(func), &isJsFcuntion, &slowPath); 34914514f5e3Sopenharmony_ci builder_.Bind(&isJsFcuntion); 34924514f5e3Sopenharmony_ci { 34934514f5e3Sopenharmony_ci if (!isNew) { 34944514f5e3Sopenharmony_ci BRANCH_CIR(builder_.IsClassConstructor(func), &slowPath, ¬CallConstructor); 34954514f5e3Sopenharmony_ci builder_.Bind(¬CallConstructor); 34964514f5e3Sopenharmony_ci } 34974514f5e3Sopenharmony_ci GateRef method = builder_.GetMethodFromFunction(func); 34984514f5e3Sopenharmony_ci BRANCH_CIR(builder_.JudgeAotAndFastCall(func, 34994514f5e3Sopenharmony_ci CircuitBuilder::JudgeMethodType::HAS_AOT_FASTCALL), &fastCall, ¬FastCall); 35004514f5e3Sopenharmony_ci builder_.Bind(&fastCall); 35014514f5e3Sopenharmony_ci { 35024514f5e3Sopenharmony_ci GateRef expectedArgc = builder_.Int64Add(builder_.GetExpectedNumOfArgs(method), 35034514f5e3Sopenharmony_ci builder_.Int64(NUM_MANDATORY_JSFUNC_ARGS)); 35044514f5e3Sopenharmony_ci BRANCH_CIR(builder_.Equal(expectedArgc, argc), &call, &callBridge); 35054514f5e3Sopenharmony_ci builder_.Bind(&call); 35064514f5e3Sopenharmony_ci { 35074514f5e3Sopenharmony_ci builder_.StartCallTimer(glue_, gate, {glue_, func, builder_.True()}, true); 35084514f5e3Sopenharmony_ci GateRef code = builder_.GetCodeAddr(func); 35094514f5e3Sopenharmony_ci auto depend = builder_.GetDepend(); 35104514f5e3Sopenharmony_ci const CallSignature *cs = RuntimeStubCSigns::GetOptimizedFastCallSign(); 35114514f5e3Sopenharmony_ci result->WriteVariable(builder_.Call(cs, glue, code, depend, argsFastCall, gate, "callFastAOT")); 35124514f5e3Sopenharmony_ci builder_.EndCallTimer(glue_, gate, {glue_, func}, true); 35134514f5e3Sopenharmony_ci builder_.Jump(exit); 35144514f5e3Sopenharmony_ci } 35154514f5e3Sopenharmony_ci builder_.Bind(&callBridge); 35164514f5e3Sopenharmony_ci { 35174514f5e3Sopenharmony_ci builder_.StartCallTimer(glue_, gate, {glue_, func, builder_.True()}, true); 35184514f5e3Sopenharmony_ci const CallSignature *cs = RuntimeStubCSigns::Get(RTSTUB_ID(OptimizedFastCallAndPushArgv)); 35194514f5e3Sopenharmony_ci GateRef target = builder_.IntPtr(RTSTUB_ID(OptimizedFastCallAndPushArgv)); 35204514f5e3Sopenharmony_ci auto depend = builder_.GetDepend(); 35214514f5e3Sopenharmony_ci result->WriteVariable(builder_.Call(cs, glue, target, depend, args, gate, "callFastBridge")); 35224514f5e3Sopenharmony_ci builder_.EndCallTimer(glue_, gate, {glue_, func}, true); 35234514f5e3Sopenharmony_ci builder_.Jump(exit); 35244514f5e3Sopenharmony_ci } 35254514f5e3Sopenharmony_ci } 35264514f5e3Sopenharmony_ci builder_.Bind(¬FastCall); 35274514f5e3Sopenharmony_ci BRANCH_CIR(builder_.JudgeAotAndFastCall(func, CircuitBuilder::JudgeMethodType::HAS_AOT), 35284514f5e3Sopenharmony_ci &slowCall, &slowPath); 35294514f5e3Sopenharmony_ci builder_.Bind(&slowCall); 35304514f5e3Sopenharmony_ci { 35314514f5e3Sopenharmony_ci GateRef expectedArgc = builder_.Int64Add(builder_.GetExpectedNumOfArgs(method), 35324514f5e3Sopenharmony_ci builder_.Int64(NUM_MANDATORY_JSFUNC_ARGS)); 35334514f5e3Sopenharmony_ci BRANCH_CIR(builder_.Equal(expectedArgc, argc), &call1, &callBridge1); 35344514f5e3Sopenharmony_ci builder_.Bind(&call1); 35354514f5e3Sopenharmony_ci { 35364514f5e3Sopenharmony_ci builder_.StartCallTimer(glue_, gate, {glue_, func, builder_.True()}, true); 35374514f5e3Sopenharmony_ci GateRef code = builder_.GetCodeAddr(func); 35384514f5e3Sopenharmony_ci auto depend = builder_.GetDepend(); 35394514f5e3Sopenharmony_ci const CallSignature *cs = RuntimeStubCSigns::GetOptimizedCallSign(); 35404514f5e3Sopenharmony_ci result->WriteVariable(builder_.Call(cs, glue, code, depend, args, gate, "callAOT")); 35414514f5e3Sopenharmony_ci builder_.EndCallTimer(glue_, gate, {glue_, func}, true); 35424514f5e3Sopenharmony_ci builder_.Jump(exit); 35434514f5e3Sopenharmony_ci } 35444514f5e3Sopenharmony_ci builder_.Bind(&callBridge1); 35454514f5e3Sopenharmony_ci { 35464514f5e3Sopenharmony_ci builder_.StartCallTimer(glue_, gate, {glue_, func, builder_.True()}, true); 35474514f5e3Sopenharmony_ci const CallSignature *cs = RuntimeStubCSigns::Get(RTSTUB_ID(OptimizedCallAndPushArgv)); 35484514f5e3Sopenharmony_ci GateRef target = builder_.IntPtr(RTSTUB_ID(OptimizedCallAndPushArgv)); 35494514f5e3Sopenharmony_ci auto depend = builder_.GetDepend(); 35504514f5e3Sopenharmony_ci result->WriteVariable(builder_.Call(cs, glue, target, depend, args, gate, "callBridge")); 35514514f5e3Sopenharmony_ci builder_.EndCallTimer(glue_, gate, {glue_, func}, true); 35524514f5e3Sopenharmony_ci builder_.Jump(exit); 35534514f5e3Sopenharmony_ci } 35544514f5e3Sopenharmony_ci } 35554514f5e3Sopenharmony_ci } 35564514f5e3Sopenharmony_ci } 35574514f5e3Sopenharmony_ci builder_.Bind(&slowPath); 35584514f5e3Sopenharmony_ci { 35594514f5e3Sopenharmony_ci if (isNew) { 35604514f5e3Sopenharmony_ci builder_.StartCallTimer(glue_, gate, {glue_, func, builder_.True()}, true); 35614514f5e3Sopenharmony_ci const CallSignature *cs = RuntimeStubCSigns::Get(RTSTUB_ID(JSCallNew)); 35624514f5e3Sopenharmony_ci GateRef target = builder_.IntPtr(RTSTUB_ID(JSCallNew)); 35634514f5e3Sopenharmony_ci auto depend = builder_.GetDepend(); 35644514f5e3Sopenharmony_ci result->WriteVariable(builder_.Call(cs, glue, target, depend, args, gate, "slowNew")); 35654514f5e3Sopenharmony_ci builder_.EndCallTimer(glue_, gate, {glue_, func}, true); 35664514f5e3Sopenharmony_ci builder_.Jump(exit); 35674514f5e3Sopenharmony_ci } else { 35684514f5e3Sopenharmony_ci builder_.StartCallTimer(glue_, gate, {glue_, func, builder_.True()}, true); 35694514f5e3Sopenharmony_ci const CallSignature *cs = RuntimeStubCSigns::Get(RTSTUB_ID(JSCall)); 35704514f5e3Sopenharmony_ci GateRef target = builder_.IntPtr(RTSTUB_ID(JSCall)); 35714514f5e3Sopenharmony_ci auto depend = builder_.GetDepend(); 35724514f5e3Sopenharmony_ci result->WriteVariable(builder_.Call(cs, glue, target, depend, args, gate, "jscall")); 35734514f5e3Sopenharmony_ci builder_.EndCallTimer(glue_, gate, {glue_, func}, true); 35744514f5e3Sopenharmony_ci builder_.Jump(exit); 35754514f5e3Sopenharmony_ci } 35764514f5e3Sopenharmony_ci } 35774514f5e3Sopenharmony_ci} 35784514f5e3Sopenharmony_ci 35794514f5e3Sopenharmony_civoid SlowPathLowering::LowerTypedCall(GateRef gate) 35804514f5e3Sopenharmony_ci{ 35814514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 35824514f5e3Sopenharmony_ci GateRef func = acc_.GetValueIn(gate, static_cast<size_t>(CommonArgIdx::FUNC)); 35834514f5e3Sopenharmony_ci GateRef code = builder_.GetCodeAddr(func); 35844514f5e3Sopenharmony_ci size_t num = acc_.GetNumValueIn(gate); 35854514f5e3Sopenharmony_ci std::vector<GateRef> args(num); 35864514f5e3Sopenharmony_ci for (size_t i = 0; i < num; ++i) { 35874514f5e3Sopenharmony_ci args[i] = acc_.GetValueIn(gate, i); 35884514f5e3Sopenharmony_ci } 35894514f5e3Sopenharmony_ci GateRef state = builder_.GetState(); 35904514f5e3Sopenharmony_ci auto depend = builder_.GetDepend(); 35914514f5e3Sopenharmony_ci const CallSignature *cs = RuntimeStubCSigns::GetOptimizedCallSign(); 35924514f5e3Sopenharmony_ci GateRef result = builder_.Call(cs, glue_, code, depend, args, gate, "callAOT"); 35934514f5e3Sopenharmony_ci ReplaceHirWithPendingException(gate, state, result, result); 35944514f5e3Sopenharmony_ci} 35954514f5e3Sopenharmony_ci 35964514f5e3Sopenharmony_civoid SlowPathLowering::LowerTypedFastCall(GateRef gate) 35974514f5e3Sopenharmony_ci{ 35984514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 35994514f5e3Sopenharmony_ci GateRef func = acc_.GetValueIn(gate, static_cast<size_t>(FastCallArgIdx::FUNC)); 36004514f5e3Sopenharmony_ci GateRef code = builder_.GetCodeAddr(func); 36014514f5e3Sopenharmony_ci size_t num = acc_.GetNumValueIn(gate); 36024514f5e3Sopenharmony_ci std::vector<GateRef> args(num); 36034514f5e3Sopenharmony_ci for (size_t i = 0; i < num; ++i) { 36044514f5e3Sopenharmony_ci args[i] = acc_.GetValueIn(gate, i); 36054514f5e3Sopenharmony_ci } 36064514f5e3Sopenharmony_ci GateRef state = builder_.GetState(); 36074514f5e3Sopenharmony_ci auto depend = builder_.GetDepend(); 36084514f5e3Sopenharmony_ci const CallSignature *cs = RuntimeStubCSigns::GetOptimizedFastCallSign(); 36094514f5e3Sopenharmony_ci GateRef result = builder_.Call(cs, glue_, code, depend, args, gate, "callFastAOT"); 36104514f5e3Sopenharmony_ci ReplaceHirWithPendingException(gate, state, result, result); 36114514f5e3Sopenharmony_ci} 36124514f5e3Sopenharmony_ci 36134514f5e3Sopenharmony_civoid SlowPathLowering::LowerCheckSafePointAndStackOver(GateRef gate) 36144514f5e3Sopenharmony_ci{ 36154514f5e3Sopenharmony_ci Environment env(gate, circuit_, &builder_); 36164514f5e3Sopenharmony_ci Label slowPath(&builder_); 36174514f5e3Sopenharmony_ci Label dispatch(&builder_); 36184514f5e3Sopenharmony_ci Label checkStackOver(&builder_); 36194514f5e3Sopenharmony_ci Label stackOverflow(&builder_); 36204514f5e3Sopenharmony_ci GateRef stackLimit = builder_.Load(VariableType::INT64(), glue_, 36214514f5e3Sopenharmony_ci builder_.IntPtr(JSThread::GlueData::GetStackLimitOffset(builder_.GetCompilationConfig()->Is32Bit()))); 36224514f5e3Sopenharmony_ci GateRef interruptsFlag = builder_.Load(VariableType::INT8(), glue_, 36234514f5e3Sopenharmony_ci builder_.IntPtr(JSThread::GlueData::GetInterruptVectorOffset(builder_.GetCompilationConfig()->Is32Bit()))); 36244514f5e3Sopenharmony_ci GateRef spValue = builder_.ReadSp(); 36254514f5e3Sopenharmony_ci builder_.Branch(builder_.Int8Equal(interruptsFlag, builder_.Int8(VmThreadControl::VM_NEED_SUSPENSION)), 36264514f5e3Sopenharmony_ci &slowPath, &checkStackOver, BranchWeight::ONE_WEIGHT, BranchWeight::DEOPT_WEIGHT, "checkSafePoint"); 36274514f5e3Sopenharmony_ci builder_.Bind(&slowPath); 36284514f5e3Sopenharmony_ci { 36294514f5e3Sopenharmony_ci LowerCallRuntime(glue_, RTSTUB_ID(CheckSafePoint), {}, true); 36304514f5e3Sopenharmony_ci builder_.Jump(&checkStackOver); 36314514f5e3Sopenharmony_ci } 36324514f5e3Sopenharmony_ci builder_.Bind(&checkStackOver); 36334514f5e3Sopenharmony_ci { 36344514f5e3Sopenharmony_ci builder_.Branch(builder_.Int64LessThanOrEqual(spValue, stackLimit), &stackOverflow, &dispatch, 36354514f5e3Sopenharmony_ci BranchWeight::ONE_WEIGHT, BranchWeight::DEOPT_WEIGHT, "checkStackOverflow"); 36364514f5e3Sopenharmony_ci builder_.Bind(&stackOverflow); 36374514f5e3Sopenharmony_ci { 36384514f5e3Sopenharmony_ci GateRef res = LowerCallRuntime(glue_, RTSTUB_ID(ThrowStackOverflowException), {}, true); 36394514f5e3Sopenharmony_ci builder_.Return(res); 36404514f5e3Sopenharmony_ci } 36414514f5e3Sopenharmony_ci } 36424514f5e3Sopenharmony_ci builder_.Bind(&dispatch); 36434514f5e3Sopenharmony_ci acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate()); 36444514f5e3Sopenharmony_ci} 36454514f5e3Sopenharmony_ci 36464514f5e3Sopenharmony_civoid SlowPathLowering::LowerLdPrivateProperty(GateRef gate) 36474514f5e3Sopenharmony_ci{ 36484514f5e3Sopenharmony_ci const int id = RTSTUB_ID(LdPrivateProperty); 36494514f5e3Sopenharmony_ci // 5: number of value inputs + env + acc 36504514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 5); 36514514f5e3Sopenharmony_ci [[maybe_unused]] GateRef slotId = acc_.GetValueIn(gate, 0); 36524514f5e3Sopenharmony_ci GateRef levelIndex = acc_.GetValueIn(gate, 1); 36534514f5e3Sopenharmony_ci GateRef slotIndex = acc_.GetValueIn(gate, 2); 36544514f5e3Sopenharmony_ci GateRef lexicalEnv = acc_.GetValueIn(gate, 3); 36554514f5e3Sopenharmony_ci GateRef obj = acc_.GetValueIn(gate, 4); // acc 36564514f5e3Sopenharmony_ci 36574514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, {lexicalEnv, 36584514f5e3Sopenharmony_ci builder_.ToTaggedInt(levelIndex), builder_.ToTaggedInt(slotIndex), obj}); 36594514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 36604514f5e3Sopenharmony_ci} 36614514f5e3Sopenharmony_ci 36624514f5e3Sopenharmony_civoid SlowPathLowering::LowerStPrivateProperty(GateRef gate) 36634514f5e3Sopenharmony_ci{ 36644514f5e3Sopenharmony_ci const int id = RTSTUB_ID(StPrivateProperty); 36654514f5e3Sopenharmony_ci // 6: number of value inputs + env + acc 36664514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 6); 36674514f5e3Sopenharmony_ci [[maybe_unused]] GateRef slotId = acc_.GetValueIn(gate, 0); 36684514f5e3Sopenharmony_ci GateRef levelIndex = acc_.GetValueIn(gate, 1); 36694514f5e3Sopenharmony_ci GateRef slotIndex = acc_.GetValueIn(gate, 2); 36704514f5e3Sopenharmony_ci GateRef obj = acc_.GetValueIn(gate, 3); 36714514f5e3Sopenharmony_ci GateRef lexicalEnv = acc_.GetValueIn(gate, 4); 36724514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 5); // acc 36734514f5e3Sopenharmony_ci 36744514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, {lexicalEnv, 36754514f5e3Sopenharmony_ci builder_.ToTaggedInt(levelIndex), builder_.ToTaggedInt(slotIndex), obj, value}); 36764514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 36774514f5e3Sopenharmony_ci} 36784514f5e3Sopenharmony_ci 36794514f5e3Sopenharmony_civoid SlowPathLowering::LowerTestIn(GateRef gate) 36804514f5e3Sopenharmony_ci{ 36814514f5e3Sopenharmony_ci const int id = RTSTUB_ID(TestIn); 36824514f5e3Sopenharmony_ci // 5: number of value inputs + acc 36834514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 5); 36844514f5e3Sopenharmony_ci [[maybe_unused]] GateRef slotId = acc_.GetValueIn(gate, 0); 36854514f5e3Sopenharmony_ci GateRef levelIndex = acc_.GetValueIn(gate, 1); 36864514f5e3Sopenharmony_ci GateRef slotIndex = acc_.GetValueIn(gate, 2); 36874514f5e3Sopenharmony_ci GateRef lexicalEnv = acc_.GetValueIn(gate, 3); 36884514f5e3Sopenharmony_ci GateRef obj = acc_.GetValueIn(gate, 4); // acc 36894514f5e3Sopenharmony_ci 36904514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, {lexicalEnv, 36914514f5e3Sopenharmony_ci builder_.ToTaggedInt(levelIndex), builder_.ToTaggedInt(slotIndex), obj}); 36924514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 36934514f5e3Sopenharmony_ci} 36944514f5e3Sopenharmony_ci 36954514f5e3Sopenharmony_civoid SlowPathLowering::LowerNotifyConcurrentResult(GateRef gate) 36964514f5e3Sopenharmony_ci{ 36974514f5e3Sopenharmony_ci const int id = RTSTUB_ID(NotifyConcurrentResult); 36984514f5e3Sopenharmony_ci 36994514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, {acc_.GetValueIn(gate, 0), 37004514f5e3Sopenharmony_ci argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC)}); 37014514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 37024514f5e3Sopenharmony_ci} 37034514f5e3Sopenharmony_ci 37044514f5e3Sopenharmony_civoid SlowPathLowering::LowerDefineFieldByName(GateRef gate) 37054514f5e3Sopenharmony_ci{ 37064514f5e3Sopenharmony_ci // 4: number of value inputs + acc 37074514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 4); 37084514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 37094514f5e3Sopenharmony_ci GateRef sharedConstPool = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::SHARED_CONST_POOL); 37104514f5e3Sopenharmony_ci GateRef stringId = builder_.TruncInt64ToInt32(acc_.GetValueIn(gate, 1)); 37114514f5e3Sopenharmony_ci GateRef obj = acc_.GetValueIn(gate, 2); 37124514f5e3Sopenharmony_ci GateRef module = builder_.GetModuleFromFunction(jsFunc); 37134514f5e3Sopenharmony_ci GateRef propKey = builder_.GetObjectFromConstPool(glue_, gate, sharedConstPool, Circuit::NullGate(), module, 37144514f5e3Sopenharmony_ci stringId, ConstPoolType::STRING); 37154514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 3); // acc 37164514f5e3Sopenharmony_ci 37174514f5e3Sopenharmony_ci GateRef newGate = builder_.CallStub(glue_, gate, CommonStubCSigns::DefineField, 37184514f5e3Sopenharmony_ci {glue_, obj, propKey, value}); 37194514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 37204514f5e3Sopenharmony_ci} 37214514f5e3Sopenharmony_ci 37224514f5e3Sopenharmony_civoid SlowPathLowering::LowerDefineFieldByValue(GateRef gate) 37234514f5e3Sopenharmony_ci{ 37244514f5e3Sopenharmony_ci // 3: number of value inputs + acc 37254514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 3); 37264514f5e3Sopenharmony_ci GateRef obj = acc_.GetValueIn(gate, 1); 37274514f5e3Sopenharmony_ci GateRef propKey = acc_.GetValueIn(gate, 0); 37284514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 2); // acc 37294514f5e3Sopenharmony_ci 37304514f5e3Sopenharmony_ci GateRef newGate = builder_.CallStub(glue_, gate, CommonStubCSigns::DefineField, 37314514f5e3Sopenharmony_ci {glue_, obj, propKey, value}); 37324514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 37334514f5e3Sopenharmony_ci} 37344514f5e3Sopenharmony_ci 37354514f5e3Sopenharmony_civoid SlowPathLowering::LowerDefineFieldByIndex(GateRef gate) 37364514f5e3Sopenharmony_ci{ 37374514f5e3Sopenharmony_ci // 3: number of value inputs + acc 37384514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 3); 37394514f5e3Sopenharmony_ci GateRef obj = acc_.GetValueIn(gate, 1); 37404514f5e3Sopenharmony_ci GateRef propKey = builder_.ToTaggedInt(acc_.GetValueIn(gate, 0)); 37414514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 2); // acc 37424514f5e3Sopenharmony_ci 37434514f5e3Sopenharmony_ci GateRef newGate = builder_.CallStub(glue_, gate, CommonStubCSigns::DefineField, 37444514f5e3Sopenharmony_ci {glue_, obj, propKey, value}); 37454514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 37464514f5e3Sopenharmony_ci} 37474514f5e3Sopenharmony_ci 37484514f5e3Sopenharmony_civoid SlowPathLowering::LowerToPropertyKey(GateRef gate) 37494514f5e3Sopenharmony_ci{ 37504514f5e3Sopenharmony_ci const int id = RTSTUB_ID(ToPropertyKey); 37514514f5e3Sopenharmony_ci // 1: number of acc 37524514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 1); 37534514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 0); // acc 37544514f5e3Sopenharmony_ci 37554514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, {value}); 37564514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 37574514f5e3Sopenharmony_ci} 37584514f5e3Sopenharmony_ci 37594514f5e3Sopenharmony_civoid SlowPathLowering::LowerCreatePrivateProperty(GateRef gate) 37604514f5e3Sopenharmony_ci{ 37614514f5e3Sopenharmony_ci const int id = RTSTUB_ID(CreatePrivateProperty); 37624514f5e3Sopenharmony_ci // 3: number of value inputs 37634514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 3); 37644514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 37654514f5e3Sopenharmony_ci GateRef count = acc_.GetValueIn(gate, 0); 37664514f5e3Sopenharmony_ci GateRef literalId = acc_.GetValueIn(gate, 1); 37674514f5e3Sopenharmony_ci GateRef lexicalEnv = acc_.GetValueIn(gate, 2); 37684514f5e3Sopenharmony_ci GateRef constpool = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::SHARED_CONST_POOL); 37694514f5e3Sopenharmony_ci GateRef module = builder_.GetModuleFromFunction(jsFunc); 37704514f5e3Sopenharmony_ci 37714514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, {lexicalEnv, 37724514f5e3Sopenharmony_ci builder_.ToTaggedInt(count), constpool, builder_.ToTaggedInt(literalId), module}); 37734514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 37744514f5e3Sopenharmony_ci} 37754514f5e3Sopenharmony_ci 37764514f5e3Sopenharmony_civoid SlowPathLowering::LowerDefinePrivateProperty(GateRef gate) 37774514f5e3Sopenharmony_ci{ 37784514f5e3Sopenharmony_ci const int id = RTSTUB_ID(DefinePrivateProperty); 37794514f5e3Sopenharmony_ci // 5: number of value inputs + acc 37804514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 5); 37814514f5e3Sopenharmony_ci GateRef levelIndex = acc_.GetValueIn(gate, 0); 37824514f5e3Sopenharmony_ci GateRef slotIndex = acc_.GetValueIn(gate, 1); 37834514f5e3Sopenharmony_ci GateRef obj = acc_.GetValueIn(gate, 2); 37844514f5e3Sopenharmony_ci GateRef lexicalEnv = acc_.GetValueIn(gate, 3); 37854514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 4); // acc 37864514f5e3Sopenharmony_ci 37874514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, id, {lexicalEnv, 37884514f5e3Sopenharmony_ci builder_.ToTaggedInt(levelIndex), builder_.ToTaggedInt(slotIndex), obj, value}); 37894514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 37904514f5e3Sopenharmony_ci} 37914514f5e3Sopenharmony_ci 37924514f5e3Sopenharmony_civoid SlowPathLowering::LowerDefineSendableClass(GateRef gate) 37934514f5e3Sopenharmony_ci{ 37944514f5e3Sopenharmony_ci // 4: number of value inputs 37954514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 4); 37964514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 37974514f5e3Sopenharmony_ci GateRef methodId = acc_.GetValueIn(gate, 0); 37984514f5e3Sopenharmony_ci GateRef literalId = acc_.GetValueIn(gate, 1); 37994514f5e3Sopenharmony_ci GateRef length = acc_.GetValueIn(gate, 2); // 2: second arg 38004514f5e3Sopenharmony_ci GateRef proto = acc_.GetValueIn(gate, 3); 38014514f5e3Sopenharmony_ci GateRef constpool = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::SHARED_CONST_POOL); 38024514f5e3Sopenharmony_ci GateRef module = builder_.GetModuleFromFunction(jsFunc); 38034514f5e3Sopenharmony_ci auto args = { proto, constpool, builder_.ToTaggedInt(methodId), builder_.ToTaggedInt(literalId), 38044514f5e3Sopenharmony_ci builder_.ToTaggedInt(length), module }; 38054514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, RTSTUB_ID(CreateSharedClass), args); 38064514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 38074514f5e3Sopenharmony_ci} 38084514f5e3Sopenharmony_ci 38094514f5e3Sopenharmony_civoid SlowPathLowering::LowerLdSendableClass(GateRef gate) 38104514f5e3Sopenharmony_ci{ 38114514f5e3Sopenharmony_ci GateRef level = acc_.GetValueIn(gate, 0); 38124514f5e3Sopenharmony_ci GateRef lexicalEnv = acc_.GetValueIn(gate, 1); 38134514f5e3Sopenharmony_ci GateRef newGate = LowerCallRuntime(gate, RTSTUB_ID(LdSendableClass), { lexicalEnv, builder_.ToTaggedInt(level) }); 38144514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, newGate); 38154514f5e3Sopenharmony_ci} 38164514f5e3Sopenharmony_ci 38174514f5e3Sopenharmony_civoid SlowPathLowering::LowerSendableExternalModule(GateRef gate) 38184514f5e3Sopenharmony_ci{ 38194514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 1); 38204514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 38214514f5e3Sopenharmony_ci GateRef index = builder_.ToTaggedInt(acc_.GetValueIn(gate, 0)); 38224514f5e3Sopenharmony_ci GateRef result = LowerCallRuntime(gate, 38234514f5e3Sopenharmony_ci RTSTUB_ID(LdSendableExternalModuleVarByIndex), {index, jsFunc}, true); 38244514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 38254514f5e3Sopenharmony_ci} 38264514f5e3Sopenharmony_ci 38274514f5e3Sopenharmony_civoid SlowPathLowering::LowerCallInit(GateRef gate) 38284514f5e3Sopenharmony_ci{ 38294514f5e3Sopenharmony_ci // same as callthis0 38304514f5e3Sopenharmony_ci // 2: number of value inputs 38314514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); 38324514f5e3Sopenharmony_ci 38334514f5e3Sopenharmony_ci GateRef actualArgc = builder_.Int64(BytecodeCallArgc::ComputeCallArgc(acc_.GetNumValueIn(gate), 38344514f5e3Sopenharmony_ci EcmaOpcode::CALLTHIS0_IMM8_V8)); 38354514f5e3Sopenharmony_ci GateRef actualArgv = builder_.IntPtr(0); 38364514f5e3Sopenharmony_ci GateRef newTarget = builder_.Undefined(); 38374514f5e3Sopenharmony_ci GateRef thisObj = acc_.GetValueIn(gate, 0); 38384514f5e3Sopenharmony_ci GateRef func = acc_.GetValueIn(gate, 1); 38394514f5e3Sopenharmony_ci LowerToJSCall(gate, {glue_, actualArgc, actualArgv, func, newTarget, thisObj}, {glue_, func, thisObj}); 38404514f5e3Sopenharmony_ci} 38414514f5e3Sopenharmony_ci 38424514f5e3Sopenharmony_civoid SlowPathLowering::LowerLdStr(GateRef gate) 38434514f5e3Sopenharmony_ci{ 38444514f5e3Sopenharmony_ci GateRef stringId = builder_.TruncInt64ToInt32(acc_.GetValueIn(gate, 0)); 38454514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 38464514f5e3Sopenharmony_ci GateRef sharedConstPool = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::SHARED_CONST_POOL); 38474514f5e3Sopenharmony_ci GateRef module = builder_.GetModuleFromFunction(jsFunc); 38484514f5e3Sopenharmony_ci GateRef res = builder_.GetObjectFromConstPool(glue_, gate, sharedConstPool, Circuit::NullGate(), module, stringId, 38494514f5e3Sopenharmony_ci ConstPoolType::STRING); 38504514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, res); 38514514f5e3Sopenharmony_ci} 38524514f5e3Sopenharmony_ci 38534514f5e3Sopenharmony_civoid SlowPathLowering::LowerGetSharedConstPool(GateRef gate) 38544514f5e3Sopenharmony_ci{ 38554514f5e3Sopenharmony_ci bool useConstPool = false; 38564514f5e3Sopenharmony_ci auto uses = acc_.Uses(gate); 38574514f5e3Sopenharmony_ci for (auto useIt = uses.begin(); useIt != uses.end(); useIt++) { 38584514f5e3Sopenharmony_ci if (acc_.GetOpCode(*useIt) != OpCode::FRAME_ARGS) { 38594514f5e3Sopenharmony_ci useConstPool = true; 38604514f5e3Sopenharmony_ci break; 38614514f5e3Sopenharmony_ci } 38624514f5e3Sopenharmony_ci } 38634514f5e3Sopenharmony_ci if (!useConstPool) { 38644514f5e3Sopenharmony_ci acc_.UpdateAllUses(gate, builder_.Undefined()); 38654514f5e3Sopenharmony_ci acc_.DeleteGate(gate); 38664514f5e3Sopenharmony_ci return; 38674514f5e3Sopenharmony_ci } 38684514f5e3Sopenharmony_ci GateRef jsFunc = acc_.GetValueIn(gate, 0); 38694514f5e3Sopenharmony_ci GateRef methodOffset = builder_.IntPtr(JSFunctionBase::METHOD_OFFSET); 38704514f5e3Sopenharmony_ci GateRef method = builder_.Load(VariableType::JS_POINTER(), jsFunc, methodOffset, acc_.GetDependRoot()); 38714514f5e3Sopenharmony_ci GateRef sharedConstpool = 38724514f5e3Sopenharmony_ci builder_.Load(VariableType::JS_ANY(), method, builder_.IntPtr(Method::CONSTANT_POOL_OFFSET), method); 38734514f5e3Sopenharmony_ci acc_.UpdateAllUses(gate, sharedConstpool); 38744514f5e3Sopenharmony_ci acc_.DeleteGate(gate); 38754514f5e3Sopenharmony_ci} 38764514f5e3Sopenharmony_ci 38774514f5e3Sopenharmony_civoid SlowPathLowering::LowerGetUnsharedConstPool(GateRef gate) 38784514f5e3Sopenharmony_ci{ 38794514f5e3Sopenharmony_ci bool useConstPool = false; 38804514f5e3Sopenharmony_ci auto uses = acc_.Uses(gate); 38814514f5e3Sopenharmony_ci for (auto useIt = uses.begin(); useIt != uses.end(); useIt++) { 38824514f5e3Sopenharmony_ci if (acc_.GetOpCode(*useIt) != OpCode::FRAME_ARGS) { 38834514f5e3Sopenharmony_ci useConstPool = true; 38844514f5e3Sopenharmony_ci break; 38854514f5e3Sopenharmony_ci } 38864514f5e3Sopenharmony_ci } 38874514f5e3Sopenharmony_ci if (!useConstPool) { 38884514f5e3Sopenharmony_ci acc_.UpdateAllUses(gate, builder_.Undefined()); 38894514f5e3Sopenharmony_ci acc_.DeleteGate(gate); 38904514f5e3Sopenharmony_ci return; 38914514f5e3Sopenharmony_ci } 38924514f5e3Sopenharmony_ci GateRef sharedConstPool = acc_.GetValueIn(gate, 0); 38934514f5e3Sopenharmony_ci GateRef constPoolSize = builder_.Load(VariableType::INT32(), sharedConstPool, 38944514f5e3Sopenharmony_ci builder_.IntPtr(TaggedArray::LENGTH_OFFSET), sharedConstPool); 38954514f5e3Sopenharmony_ci GateRef unshareIdx = builder_.Int32Sub(constPoolSize, builder_.Int32(ConstantPool::UNSHARED_CONSTPOOL_INDEX)); 38964514f5e3Sopenharmony_ci GateRef offset = 38974514f5e3Sopenharmony_ci builder_.PtrMul(builder_.ZExtInt32ToPtr(unshareIdx), builder_.IntPtr(JSTaggedValue::TaggedTypeSize())); 38984514f5e3Sopenharmony_ci GateRef dataOffset = builder_.PtrAdd(offset, builder_.IntPtr(TaggedArray::DATA_OFFSET)); 38994514f5e3Sopenharmony_ci GateRef index = builder_.Load(VariableType::JS_ANY(), sharedConstPool, dataOffset, constPoolSize); 39004514f5e3Sopenharmony_ci GateRef unshareCpOffset = static_cast<int32_t>(JSThread::GlueData::GetUnSharedConstpoolsOffset(false)); 39014514f5e3Sopenharmony_ci GateRef unshareCpAddr = 39024514f5e3Sopenharmony_ci builder_.Load(VariableType::NATIVE_POINTER(), glue_, builder_.IntPtr(unshareCpOffset), index); 39034514f5e3Sopenharmony_ci GateRef unshareCpDataOffset = 39044514f5e3Sopenharmony_ci builder_.PtrAdd(unshareCpAddr, builder_.PtrMul(builder_.IntPtr(JSTaggedValue::TaggedTypeSize()), 39054514f5e3Sopenharmony_ci builder_.ZExtInt32ToPtr(builder_.TaggedGetInt(index)))); 39064514f5e3Sopenharmony_ci GateRef unsharedConstPool = 39074514f5e3Sopenharmony_ci builder_.Load(VariableType::JS_ANY(), unshareCpDataOffset, builder_.IntPtr(0), unshareCpAddr); 39084514f5e3Sopenharmony_ci 39094514f5e3Sopenharmony_ci acc_.UpdateAllUses(gate, unsharedConstPool); 39104514f5e3Sopenharmony_ci 39114514f5e3Sopenharmony_ci // delete old gate 39124514f5e3Sopenharmony_ci acc_.DeleteGate(gate); 39134514f5e3Sopenharmony_ci} 39144514f5e3Sopenharmony_ci 39154514f5e3Sopenharmony_civoid SlowPathLowering::LowerLdLazyExternalModuleVar(GateRef gate) 39164514f5e3Sopenharmony_ci{ 39174514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 1); 39184514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 39194514f5e3Sopenharmony_ci GateRef index = builder_.ToTaggedInt(acc_.GetValueIn(gate, 0)); 39204514f5e3Sopenharmony_ci GateRef result = LowerCallRuntime(gate, 39214514f5e3Sopenharmony_ci RTSTUB_ID(LdLazyExternalModuleVarByIndex), {index, jsFunc}, true); 39224514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 39234514f5e3Sopenharmony_ci} 39244514f5e3Sopenharmony_ci 39254514f5e3Sopenharmony_civoid SlowPathLowering::LowerLdLazySendableExternalModuleVar(GateRef gate) 39264514f5e3Sopenharmony_ci{ 39274514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 1); 39284514f5e3Sopenharmony_ci GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); 39294514f5e3Sopenharmony_ci GateRef index = builder_.ToTaggedInt(acc_.GetValueIn(gate, 0)); 39304514f5e3Sopenharmony_ci GateRef result = LowerCallRuntime(gate, 39314514f5e3Sopenharmony_ci RTSTUB_ID(LdLazySendableExternalModuleVarByIndex), {index, jsFunc}, true); 39324514f5e3Sopenharmony_ci ReplaceHirWithValue(gate, result); 39334514f5e3Sopenharmony_ci} 39344514f5e3Sopenharmony_ci} // namespace panda::ecmascript 3935