14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2023-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/hcr_circuit_builder.h" 174514f5e3Sopenharmony_ci#include "ecmascript/compiler/common_stub_csigns.h" 184514f5e3Sopenharmony_ci#include "ecmascript/js_thread.h" 194514f5e3Sopenharmony_ci#include "ecmascript/compiler/circuit_builder-inl.h" 204514f5e3Sopenharmony_ci 214514f5e3Sopenharmony_cinamespace panda::ecmascript::kungfu { 224514f5e3Sopenharmony_ci 234514f5e3Sopenharmony_ciGateRef CircuitBuilder::NoLabelCallRuntime(GateRef glue, GateRef depend, size_t index, std::vector<GateRef> &args, 244514f5e3Sopenharmony_ci GateRef hirGate) 254514f5e3Sopenharmony_ci{ 264514f5e3Sopenharmony_ci const std::string name = RuntimeStubCSigns::GetRTName(RTSTUB_ID(CallRuntime)); 274514f5e3Sopenharmony_ci const CallSignature *cs = RuntimeStubCSigns::Get(RTSTUB_ID(CallRuntime)); 284514f5e3Sopenharmony_ci GateRef target = IntPtr(index); 294514f5e3Sopenharmony_ci std::vector<GateRef> inputs { depend, target, glue }; 304514f5e3Sopenharmony_ci inputs.insert(inputs.end(), args.begin(), args.end()); 314514f5e3Sopenharmony_ci auto numValuesIn = args.size() + 2; // 2: target & glue 324514f5e3Sopenharmony_ci inputs.emplace_back(IntPtr(0)); // framestate slot 334514f5e3Sopenharmony_ci numValuesIn += 1; 344514f5e3Sopenharmony_ci GateRef pcOffset = Int64(acc_.TryGetPcOffset(hirGate)); 354514f5e3Sopenharmony_ci inputs.emplace_back(pcOffset); 364514f5e3Sopenharmony_ci numValuesIn += 1; 374514f5e3Sopenharmony_ci 384514f5e3Sopenharmony_ci const GateMetaData* meta = circuit_->RuntimeCall(numValuesIn); 394514f5e3Sopenharmony_ci MachineType machineType = cs->GetReturnType().GetMachineType(); 404514f5e3Sopenharmony_ci GateType type = cs->GetReturnType().GetGateType(); 414514f5e3Sopenharmony_ci GateRef result = circuit_->NewGate(meta, machineType, inputs.size(), inputs.data(), type, name.c_str()); 424514f5e3Sopenharmony_ci return result; 434514f5e3Sopenharmony_ci} 444514f5e3Sopenharmony_ci 454514f5e3Sopenharmony_ciGateRef CircuitBuilder::ToLength(GateRef receiver) 464514f5e3Sopenharmony_ci{ 474514f5e3Sopenharmony_ci auto currentLabel = env_->GetCurrentLabel(); 484514f5e3Sopenharmony_ci auto currentControl = currentLabel->GetControl(); 494514f5e3Sopenharmony_ci auto currentDepend = currentLabel->GetDepend(); 504514f5e3Sopenharmony_ci auto ret = GetCircuit()->NewGate(circuit_->ToLength(), MachineType::I64, 514514f5e3Sopenharmony_ci { currentControl, currentDepend, receiver }, GateType::NumberType()); 524514f5e3Sopenharmony_ci currentLabel->SetControl(ret); 534514f5e3Sopenharmony_ci currentLabel->SetDepend(ret); 544514f5e3Sopenharmony_ci return ret; 554514f5e3Sopenharmony_ci} 564514f5e3Sopenharmony_ci 574514f5e3Sopenharmony_ciGateRef CircuitBuilder::CallStub(GateRef glue, GateRef hirGate, int index, const std::vector<GateRef> &args, 584514f5e3Sopenharmony_ci const char* comment) 594514f5e3Sopenharmony_ci{ 604514f5e3Sopenharmony_ci const CallSignature *cs = env_->IsBaselineBuiltin() ? BaselineStubCSigns::Get(index) : 614514f5e3Sopenharmony_ci CommonStubCSigns::Get(index); 624514f5e3Sopenharmony_ci ASSERT(cs->IsCommonStub() || cs->IsBaselineStub()); 634514f5e3Sopenharmony_ci GateRef target = IntPtr(index); 644514f5e3Sopenharmony_ci auto label = GetCurrentLabel(); 654514f5e3Sopenharmony_ci auto depend = label->GetDepend(); 664514f5e3Sopenharmony_ci GateRef result; 674514f5e3Sopenharmony_ci if (GetCircuit()->IsOptimizedOrFastJit()) { 684514f5e3Sopenharmony_ci ASSERT(hirGate != Circuit::NullGate()); 694514f5e3Sopenharmony_ci result = Call(cs, glue, target, depend, args, hirGate, comment); 704514f5e3Sopenharmony_ci } else { 714514f5e3Sopenharmony_ci result = Call(cs, glue, target, depend, args, Circuit::NullGate(), comment); 724514f5e3Sopenharmony_ci } 734514f5e3Sopenharmony_ci return result; 744514f5e3Sopenharmony_ci} 754514f5e3Sopenharmony_ci 764514f5e3Sopenharmony_ciGateRef CircuitBuilder::CallBuiltinRuntime(GateRef glue, GateRef depend, const std::vector<GateRef> &args, bool isNew) 774514f5e3Sopenharmony_ci{ 784514f5e3Sopenharmony_ci ASSERT(!GetCircuit()->IsOptimizedOrFastJit()); 794514f5e3Sopenharmony_ci int index = 0; 804514f5e3Sopenharmony_ci if (!isNew) { 814514f5e3Sopenharmony_ci index = static_cast<int>(RTSTUB_ID(PushCallArgsAndDispatchNative)); 824514f5e3Sopenharmony_ci } else { 834514f5e3Sopenharmony_ci index = static_cast<int>(RTSTUB_ID(PushCallNewAndDispatchNative)); 844514f5e3Sopenharmony_ci } 854514f5e3Sopenharmony_ci const std::string name = RuntimeStubCSigns::GetRTName(index); 864514f5e3Sopenharmony_ci 874514f5e3Sopenharmony_ci const CallSignature *cs = RuntimeStubCSigns::Get(index); 884514f5e3Sopenharmony_ci GateRef target = IntPtr(index); 894514f5e3Sopenharmony_ci auto label = GetCurrentLabel(); 904514f5e3Sopenharmony_ci if (depend == Gate::InvalidGateRef) { 914514f5e3Sopenharmony_ci depend = label->GetDepend(); 924514f5e3Sopenharmony_ci } 934514f5e3Sopenharmony_ci GateRef result = Call(cs, glue, target, depend, args, Circuit::NullGate(), name.c_str()); 944514f5e3Sopenharmony_ci return result; 954514f5e3Sopenharmony_ci} 964514f5e3Sopenharmony_ci 974514f5e3Sopenharmony_ciGateRef CircuitBuilder::CallBuiltinRuntimeWithNewTarget(GateRef glue, GateRef depend, const std::vector<GateRef> &args) 984514f5e3Sopenharmony_ci{ 994514f5e3Sopenharmony_ci ASSERT(!GetCircuit()->IsOptimizedOrFastJit()); 1004514f5e3Sopenharmony_ci int index = 0; 1014514f5e3Sopenharmony_ci 1024514f5e3Sopenharmony_ci index = static_cast<int>(RTSTUB_ID(PushNewTargetAndDispatchNative)); 1034514f5e3Sopenharmony_ci const std::string name = RuntimeStubCSigns::GetRTName(index); 1044514f5e3Sopenharmony_ci 1054514f5e3Sopenharmony_ci const CallSignature *cs = RuntimeStubCSigns::Get(index); 1064514f5e3Sopenharmony_ci GateRef target = IntPtr(index); 1074514f5e3Sopenharmony_ci auto label = GetCurrentLabel(); 1084514f5e3Sopenharmony_ci if (depend == Gate::InvalidGateRef) { 1094514f5e3Sopenharmony_ci depend = label->GetDepend(); 1104514f5e3Sopenharmony_ci } 1114514f5e3Sopenharmony_ci GateRef result = Call(cs, glue, target, depend, args, Circuit::NullGate(), name.c_str()); 1124514f5e3Sopenharmony_ci return result; 1134514f5e3Sopenharmony_ci} 1144514f5e3Sopenharmony_ci 1154514f5e3Sopenharmony_ciGateRef CircuitBuilder::Call(const CallSignature* cs, GateRef glue, GateRef target, GateRef depend, 1164514f5e3Sopenharmony_ci const std::vector<GateRef> &args, GateRef hirGate, const char* comment) 1174514f5e3Sopenharmony_ci{ 1184514f5e3Sopenharmony_ci std::vector<GateRef> inputs { depend, target, glue }; 1194514f5e3Sopenharmony_ci inputs.insert(inputs.end(), args.begin(), args.end()); 1204514f5e3Sopenharmony_ci auto numValuesIn = args.size() + 2; // 2: target & glue 1214514f5e3Sopenharmony_ci if (GetCircuit()->IsOptimizedOrFastJit() && hirGate != Circuit::NullGate()) { 1224514f5e3Sopenharmony_ci AppendFrameArgs(inputs, hirGate); 1234514f5e3Sopenharmony_ci numValuesIn += 1; 1244514f5e3Sopenharmony_ci 1254514f5e3Sopenharmony_ci GateRef pcOffset = Int64(acc_.TryGetPcOffset(hirGate)); 1264514f5e3Sopenharmony_ci inputs.emplace_back(pcOffset); 1274514f5e3Sopenharmony_ci numValuesIn += 1; 1284514f5e3Sopenharmony_ci } 1294514f5e3Sopenharmony_ci 1304514f5e3Sopenharmony_ci const GateMetaData* meta = nullptr; 1314514f5e3Sopenharmony_ci if (cs->IsCommonStub()) { 1324514f5e3Sopenharmony_ci meta = circuit_->Call(numValuesIn); 1334514f5e3Sopenharmony_ci } else if (cs->IsRuntimeVAStub()) { 1344514f5e3Sopenharmony_ci meta = circuit_->RuntimeCallWithArgv(numValuesIn); 1354514f5e3Sopenharmony_ci } else if (cs->IsRuntimeStub()) { 1364514f5e3Sopenharmony_ci meta = circuit_->RuntimeCall(numValuesIn); 1374514f5e3Sopenharmony_ci } else if (cs->IsBCDebuggerStub()) { 1384514f5e3Sopenharmony_ci meta = circuit_->DebuggerBytecodeCall(numValuesIn); 1394514f5e3Sopenharmony_ci } else if (cs->IsBCHandlerStub()) { 1404514f5e3Sopenharmony_ci meta = circuit_->BytecodeCall(numValuesIn); 1414514f5e3Sopenharmony_ci } else if (cs->IsBuiltinsStub()) { 1424514f5e3Sopenharmony_ci meta = circuit_->BuiltinsCall(numValuesIn); 1434514f5e3Sopenharmony_ci } else if (cs->IsBuiltinsWithArgvStub()) { 1444514f5e3Sopenharmony_ci meta = circuit_->BuiltinsCallWithArgv(numValuesIn); 1454514f5e3Sopenharmony_ci } else if (cs->IsRuntimeNGCStub()) { 1464514f5e3Sopenharmony_ci meta = circuit_->NoGcRuntimeCall(numValuesIn); 1474514f5e3Sopenharmony_ci } else if (cs->IsOptimizedStub()) { 1484514f5e3Sopenharmony_ci bool isNoGC = acc_.GetNoGCFlag(hirGate); 1494514f5e3Sopenharmony_ci meta = circuit_->CallOptimized(numValuesIn, isNoGC); 1504514f5e3Sopenharmony_ci } else if (cs->IsOptimizedFastCallStub()) { 1514514f5e3Sopenharmony_ci bool isNoGC = acc_.GetNoGCFlag(hirGate); 1524514f5e3Sopenharmony_ci meta = circuit_->FastCallOptimized(numValuesIn, isNoGC); 1534514f5e3Sopenharmony_ci } else if (cs->IsBaselineStub()) { 1544514f5e3Sopenharmony_ci meta = circuit_->BaselineCall(numValuesIn); 1554514f5e3Sopenharmony_ci } else if (cs->IsASMCallBarrierStub()) { 1564514f5e3Sopenharmony_ci meta = circuit_->ASMCallBarrier(numValuesIn); 1574514f5e3Sopenharmony_ci } else { 1584514f5e3Sopenharmony_ci LOG_ECMA(FATAL) << "unknown call operator"; 1594514f5e3Sopenharmony_ci UNREACHABLE(); 1604514f5e3Sopenharmony_ci } 1614514f5e3Sopenharmony_ci MachineType machineType = cs->GetReturnType().GetMachineType(); 1624514f5e3Sopenharmony_ci GateType type = cs->GetReturnType().GetGateType(); 1634514f5e3Sopenharmony_ci GateRef result = GetCircuit()->NewGate(meta, machineType, inputs.size(), inputs.data(), type, comment); 1644514f5e3Sopenharmony_ci auto label = GetCurrentLabel(); 1654514f5e3Sopenharmony_ci label->SetDepend(result); 1664514f5e3Sopenharmony_ci return result; 1674514f5e3Sopenharmony_ci} 1684514f5e3Sopenharmony_ci 1694514f5e3Sopenharmony_ciGateRef CircuitBuilder::CallBCHandler(GateRef glue, GateRef target, const std::vector<GateRef> &args, 1704514f5e3Sopenharmony_ci const char* comment) 1714514f5e3Sopenharmony_ci{ 1724514f5e3Sopenharmony_ci ASSERT(!GetCircuit()->IsOptimizedOrFastJit()); 1734514f5e3Sopenharmony_ci const CallSignature *cs = BytecodeStubCSigns::BCHandler(); 1744514f5e3Sopenharmony_ci ASSERT(cs->IsBCStub()); 1754514f5e3Sopenharmony_ci auto label = GetCurrentLabel(); 1764514f5e3Sopenharmony_ci auto depend = label->GetDepend(); 1774514f5e3Sopenharmony_ci GateRef result = Call(cs, glue, target, depend, args, Circuit::NullGate(), comment); 1784514f5e3Sopenharmony_ci return result; 1794514f5e3Sopenharmony_ci} 1804514f5e3Sopenharmony_ci 1814514f5e3Sopenharmony_ciGateRef CircuitBuilder::CallBuiltin(GateRef glue, GateRef target, const std::vector<GateRef> &args, 1824514f5e3Sopenharmony_ci const char* comment) 1834514f5e3Sopenharmony_ci{ 1844514f5e3Sopenharmony_ci ASSERT(!GetCircuit()->IsOptimizedOrFastJit()); 1854514f5e3Sopenharmony_ci const CallSignature *cs = BuiltinsStubCSigns::BuiltinsCSign(); 1864514f5e3Sopenharmony_ci ASSERT(cs->IsBuiltinsStub()); 1874514f5e3Sopenharmony_ci auto label = GetCurrentLabel(); 1884514f5e3Sopenharmony_ci auto depend = label->GetDepend(); 1894514f5e3Sopenharmony_ci GateRef result = Call(cs, glue, target, depend, args, Circuit::NullGate(), comment); 1904514f5e3Sopenharmony_ci return result; 1914514f5e3Sopenharmony_ci} 1924514f5e3Sopenharmony_ci 1934514f5e3Sopenharmony_ciGateRef CircuitBuilder::CallBuiltinWithArgv(GateRef glue, GateRef target, const std::vector<GateRef> &args, 1944514f5e3Sopenharmony_ci const char* comment) 1954514f5e3Sopenharmony_ci{ 1964514f5e3Sopenharmony_ci ASSERT(!GetCircuit()->IsOptimizedOrFastJit()); 1974514f5e3Sopenharmony_ci const CallSignature *cs = BuiltinsStubCSigns::BuiltinsWithArgvCSign(); 1984514f5e3Sopenharmony_ci ASSERT(cs->IsBuiltinsWithArgvStub()); 1994514f5e3Sopenharmony_ci auto label = GetCurrentLabel(); 2004514f5e3Sopenharmony_ci auto depend = label->GetDepend(); 2014514f5e3Sopenharmony_ci GateRef result = Call(cs, glue, target, depend, args, Circuit::NullGate(), comment); 2024514f5e3Sopenharmony_ci return result; 2034514f5e3Sopenharmony_ci} 2044514f5e3Sopenharmony_ci 2054514f5e3Sopenharmony_ciGateRef CircuitBuilder::CallBCDebugger(GateRef glue, GateRef target, const std::vector<GateRef> &args, 2064514f5e3Sopenharmony_ci const char* comment) 2074514f5e3Sopenharmony_ci{ 2084514f5e3Sopenharmony_ci ASSERT(!GetCircuit()->IsOptimizedOrFastJit()); 2094514f5e3Sopenharmony_ci const CallSignature *cs = BytecodeStubCSigns::BCDebuggerHandler(); 2104514f5e3Sopenharmony_ci ASSERT(cs->IsBCDebuggerStub()); 2114514f5e3Sopenharmony_ci auto label = GetCurrentLabel(); 2124514f5e3Sopenharmony_ci auto depend = label->GetDepend(); 2134514f5e3Sopenharmony_ci GateRef result = Call(cs, glue, target, depend, args, Circuit::NullGate(), comment); 2144514f5e3Sopenharmony_ci return result; 2154514f5e3Sopenharmony_ci} 2164514f5e3Sopenharmony_ci 2174514f5e3Sopenharmony_ciGateRef CircuitBuilder::CallRuntime(GateRef glue, int index, GateRef depend, const std::vector<GateRef> &args, 2184514f5e3Sopenharmony_ci GateRef hirGate, const char* comment) 2194514f5e3Sopenharmony_ci{ 2204514f5e3Sopenharmony_ci GateRef target = IntPtr(index); 2214514f5e3Sopenharmony_ci const CallSignature *cs = RuntimeStubCSigns::Get(RTSTUB_ID(CallRuntime)); 2224514f5e3Sopenharmony_ci ASSERT(cs->IsRuntimeStub()); 2234514f5e3Sopenharmony_ci auto label = GetCurrentLabel(); 2244514f5e3Sopenharmony_ci if (depend == Gate::InvalidGateRef) { 2254514f5e3Sopenharmony_ci depend = label->GetDepend(); 2264514f5e3Sopenharmony_ci } 2274514f5e3Sopenharmony_ci GateRef filteredHirGate = Circuit::NullGate(); 2284514f5e3Sopenharmony_ci if (GetCircuit()->IsOptimizedOrFastJit()) { 2294514f5e3Sopenharmony_ci ASSERT(hirGate != Circuit::NullGate()); 2304514f5e3Sopenharmony_ci filteredHirGate = hirGate; 2314514f5e3Sopenharmony_ci } 2324514f5e3Sopenharmony_ci GateRef result = Call(cs, glue, target, depend, args, filteredHirGate, comment); 2334514f5e3Sopenharmony_ci return result; 2344514f5e3Sopenharmony_ci} 2354514f5e3Sopenharmony_ci 2364514f5e3Sopenharmony_ciGateRef CircuitBuilder::CallRuntimeVarargs(GateRef glue, int index, GateRef argc, GateRef argv, const char* comment) 2374514f5e3Sopenharmony_ci{ 2384514f5e3Sopenharmony_ci ASSERT(!GetCircuit()->IsOptimizedOrFastJit()); 2394514f5e3Sopenharmony_ci const CallSignature *cs = RuntimeStubCSigns::Get(RTSTUB_ID(CallRuntimeWithArgv)); 2404514f5e3Sopenharmony_ci GateRef target = IntPtr(index); 2414514f5e3Sopenharmony_ci auto label = GetCurrentLabel(); 2424514f5e3Sopenharmony_ci auto depend = label->GetDepend(); 2434514f5e3Sopenharmony_ci ASSERT(cs->IsRuntimeVAStub()); 2444514f5e3Sopenharmony_ci GateRef result = Call(cs, glue, target, depend, {argc, argv}, Circuit::NullGate(), comment); 2454514f5e3Sopenharmony_ci return result; 2464514f5e3Sopenharmony_ci} 2474514f5e3Sopenharmony_ci 2484514f5e3Sopenharmony_ciGateRef CircuitBuilder::CallNGCRuntime(GateRef glue, int index, GateRef depend, const std::vector<GateRef> &args, 2494514f5e3Sopenharmony_ci GateRef hirGate, const char* comment) 2504514f5e3Sopenharmony_ci{ 2514514f5e3Sopenharmony_ci const CallSignature *cs = RuntimeStubCSigns::Get(index); 2524514f5e3Sopenharmony_ci ASSERT(cs->IsRuntimeNGCStub()); 2534514f5e3Sopenharmony_ci GateRef target = IntPtr(index); 2544514f5e3Sopenharmony_ci auto label = GetCurrentLabel(); 2554514f5e3Sopenharmony_ci if (depend == Gate::InvalidGateRef) { 2564514f5e3Sopenharmony_ci depend = label->GetDepend(); 2574514f5e3Sopenharmony_ci } 2584514f5e3Sopenharmony_ci GateRef filteredHirGate = Circuit::NullGate(); 2594514f5e3Sopenharmony_ci if (GetCircuit()->IsOptimizedOrFastJit() && RuntimeStubCSigns::IsAsmStub(index)) { 2604514f5e3Sopenharmony_ci ASSERT(hirGate != Circuit::NullGate()); 2614514f5e3Sopenharmony_ci filteredHirGate = hirGate; 2624514f5e3Sopenharmony_ci } 2634514f5e3Sopenharmony_ci GateRef result = Call(cs, glue, target, depend, args, filteredHirGate, comment); 2644514f5e3Sopenharmony_ci return result; 2654514f5e3Sopenharmony_ci} 2664514f5e3Sopenharmony_ci 2674514f5e3Sopenharmony_ciGateRef CircuitBuilder::CallNGCRuntime(GateRef glue, GateRef gate, int index, const std::vector<GateRef> &args, 2684514f5e3Sopenharmony_ci bool useLabel) 2694514f5e3Sopenharmony_ci{ 2704514f5e3Sopenharmony_ci const std::string name = RuntimeStubCSigns::GetRTName(index); 2714514f5e3Sopenharmony_ci if (useLabel) { 2724514f5e3Sopenharmony_ci GateRef result = CallNGCRuntime(glue, index, Gate::InvalidGateRef, args, gate, name.c_str()); 2734514f5e3Sopenharmony_ci return result; 2744514f5e3Sopenharmony_ci } else { 2754514f5e3Sopenharmony_ci const CallSignature *cs = RuntimeStubCSigns::Get(index); 2764514f5e3Sopenharmony_ci GateRef target = IntPtr(index); 2774514f5e3Sopenharmony_ci GateRef result = Call(cs, glue, target, GetDepend(), args, gate, name.c_str()); 2784514f5e3Sopenharmony_ci return result; 2794514f5e3Sopenharmony_ci } 2804514f5e3Sopenharmony_ci} 2814514f5e3Sopenharmony_ci 2824514f5e3Sopenharmony_civoid CircuitBuilder::StartCallTimer(GateRef glue, GateRef gate, const std::vector<GateRef> &args, bool useLabel) 2834514f5e3Sopenharmony_ci{ 2844514f5e3Sopenharmony_ci (void)glue; 2854514f5e3Sopenharmony_ci (void)gate; 2864514f5e3Sopenharmony_ci (void)args; 2874514f5e3Sopenharmony_ci (void)useLabel; 2884514f5e3Sopenharmony_ci#if ECMASCRIPT_ENABLE_FUNCTION_CALL_TIMER 2894514f5e3Sopenharmony_ci CallNGCRuntime(glue, gate, RTSTUB_ID(StartCallTimer), args, useLabel); 2904514f5e3Sopenharmony_ci#endif 2914514f5e3Sopenharmony_ci} 2924514f5e3Sopenharmony_ci 2934514f5e3Sopenharmony_civoid CircuitBuilder::EndCallTimer(GateRef glue, GateRef gate, const std::vector<GateRef> &args, bool useLabel) 2944514f5e3Sopenharmony_ci{ 2954514f5e3Sopenharmony_ci (void)glue; 2964514f5e3Sopenharmony_ci (void)gate; 2974514f5e3Sopenharmony_ci (void)args; 2984514f5e3Sopenharmony_ci (void)useLabel; 2994514f5e3Sopenharmony_ci#if ECMASCRIPT_ENABLE_FUNCTION_CALL_TIMER 3004514f5e3Sopenharmony_ci CallNGCRuntime(glue, gate, RTSTUB_ID(EndCallTimer), args, useLabel); 3014514f5e3Sopenharmony_ci#endif 3024514f5e3Sopenharmony_ci} 3034514f5e3Sopenharmony_ci 3044514f5e3Sopenharmony_ciGateRef CircuitBuilder::FastCallOptimized(GateRef glue, GateRef code, GateRef depend, const std::vector<GateRef> &args, 3054514f5e3Sopenharmony_ci GateRef hirGate) 3064514f5e3Sopenharmony_ci{ 3074514f5e3Sopenharmony_ci const CallSignature *cs = RuntimeStubCSigns::GetOptimizedFastCallSign(); 3084514f5e3Sopenharmony_ci ASSERT(cs->IsOptimizedFastCallStub()); 3094514f5e3Sopenharmony_ci auto label = GetCurrentLabel(); 3104514f5e3Sopenharmony_ci if (depend == Gate::InvalidGateRef) { 3114514f5e3Sopenharmony_ci depend = label->GetDepend(); 3124514f5e3Sopenharmony_ci } 3134514f5e3Sopenharmony_ci GateRef filteredHirGate = Circuit::NullGate(); 3144514f5e3Sopenharmony_ci if (GetCircuit()->IsOptimizedOrFastJit()) { 3154514f5e3Sopenharmony_ci ASSERT(hirGate != Circuit::NullGate()); 3164514f5e3Sopenharmony_ci filteredHirGate = hirGate; 3174514f5e3Sopenharmony_ci } 3184514f5e3Sopenharmony_ci GateRef result = Call(cs, glue, code, depend, args, filteredHirGate, "fastCallOptimized"); 3194514f5e3Sopenharmony_ci return result; 3204514f5e3Sopenharmony_ci} 3214514f5e3Sopenharmony_ci 3224514f5e3Sopenharmony_ciGateRef CircuitBuilder::CallOptimized(GateRef glue, GateRef code, GateRef depend, const std::vector<GateRef> &args, 3234514f5e3Sopenharmony_ci GateRef hirGate) 3244514f5e3Sopenharmony_ci{ 3254514f5e3Sopenharmony_ci const CallSignature *cs = RuntimeStubCSigns::GetOptimizedCallSign(); 3264514f5e3Sopenharmony_ci ASSERT(cs->IsOptimizedStub()); 3274514f5e3Sopenharmony_ci auto label = GetCurrentLabel(); 3284514f5e3Sopenharmony_ci if (depend == Gate::InvalidGateRef) { 3294514f5e3Sopenharmony_ci depend = label->GetDepend(); 3304514f5e3Sopenharmony_ci } 3314514f5e3Sopenharmony_ci GateRef filteredHirGate = Circuit::NullGate(); 3324514f5e3Sopenharmony_ci if (GetCircuit()->IsOptimizedOrFastJit()) { 3334514f5e3Sopenharmony_ci ASSERT(hirGate != Circuit::NullGate()); 3344514f5e3Sopenharmony_ci filteredHirGate = hirGate; 3354514f5e3Sopenharmony_ci } 3364514f5e3Sopenharmony_ci GateRef result = Call(cs, glue, code, depend, args, filteredHirGate, "callOptimized"); 3374514f5e3Sopenharmony_ci return result; 3384514f5e3Sopenharmony_ci} 3394514f5e3Sopenharmony_ci 3404514f5e3Sopenharmony_ciGateRef CircuitBuilder::GetCallBuiltinId(GateRef method) 3414514f5e3Sopenharmony_ci{ 3424514f5e3Sopenharmony_ci GateRef extraLiteralInfoOffset = IntPtr(Method::EXTRA_LITERAL_INFO_OFFSET); 3434514f5e3Sopenharmony_ci GateRef extraLiteralInfo = Load(VariableType::INT64(), method, extraLiteralInfoOffset); 3444514f5e3Sopenharmony_ci return Int64And( 3454514f5e3Sopenharmony_ci Int64LSR(extraLiteralInfo, Int64(MethodLiteral::BuiltinIdBits::START_BIT)), 3464514f5e3Sopenharmony_ci Int64((1LU << MethodLiteral::BuiltinIdBits::SIZE) - 1)); 3474514f5e3Sopenharmony_ci} 3484514f5e3Sopenharmony_ci 3494514f5e3Sopenharmony_ciGateRef CircuitBuilder::CallPrivateGetter(GateRef hirGate, GateRef receiver, GateRef accessor, const char* comment) 3504514f5e3Sopenharmony_ci{ 3514514f5e3Sopenharmony_ci ASSERT(acc_.GetOpCode(hirGate) == OpCode::JS_BYTECODE); 3524514f5e3Sopenharmony_ci uint64_t pcOffset = acc_.TryGetPcOffset(hirGate); 3534514f5e3Sopenharmony_ci ASSERT(pcOffset != 0); 3544514f5e3Sopenharmony_ci 3554514f5e3Sopenharmony_ci auto currentLabel = env_->GetCurrentLabel(); 3564514f5e3Sopenharmony_ci auto currentControl = currentLabel->GetControl(); 3574514f5e3Sopenharmony_ci auto currentDepend = currentLabel->GetDepend(); 3584514f5e3Sopenharmony_ci std::vector<GateRef> args = {currentControl, currentDepend, receiver, accessor}; 3594514f5e3Sopenharmony_ci AppendFrameArgs(args, hirGate); 3604514f5e3Sopenharmony_ci auto callGate = GetCircuit()->NewGate(circuit_->CallPrivateGetter(pcOffset), 3614514f5e3Sopenharmony_ci MachineType::I64, 3624514f5e3Sopenharmony_ci args.size(), 3634514f5e3Sopenharmony_ci args.data(), 3644514f5e3Sopenharmony_ci GateType::AnyType(), 3654514f5e3Sopenharmony_ci comment); 3664514f5e3Sopenharmony_ci currentLabel->SetControl(callGate); 3674514f5e3Sopenharmony_ci currentLabel->SetDepend(callGate); 3684514f5e3Sopenharmony_ci return callGate; 3694514f5e3Sopenharmony_ci} 3704514f5e3Sopenharmony_ci 3714514f5e3Sopenharmony_ciGateRef CircuitBuilder::CallPrivateSetter( 3724514f5e3Sopenharmony_ci GateRef hirGate, GateRef receiver, GateRef accessor, GateRef value, const char* comment) 3734514f5e3Sopenharmony_ci{ 3744514f5e3Sopenharmony_ci ASSERT(acc_.GetOpCode(hirGate) == OpCode::JS_BYTECODE); 3754514f5e3Sopenharmony_ci uint64_t pcOffset = acc_.TryGetPcOffset(hirGate); 3764514f5e3Sopenharmony_ci ASSERT(pcOffset != 0); 3774514f5e3Sopenharmony_ci 3784514f5e3Sopenharmony_ci auto currentLabel = env_->GetCurrentLabel(); 3794514f5e3Sopenharmony_ci auto currentControl = currentLabel->GetControl(); 3804514f5e3Sopenharmony_ci auto currentDepend = currentLabel->GetDepend(); 3814514f5e3Sopenharmony_ci std::vector<GateRef> args = {currentControl, currentDepend, receiver, accessor, value}; 3824514f5e3Sopenharmony_ci AppendFrameArgs(args, hirGate); 3834514f5e3Sopenharmony_ci auto callGate = GetCircuit()->NewGate(circuit_->CallPrivateSetter(pcOffset), 3844514f5e3Sopenharmony_ci MachineType::I64, 3854514f5e3Sopenharmony_ci args.size(), 3864514f5e3Sopenharmony_ci args.data(), 3874514f5e3Sopenharmony_ci GateType::AnyType(), 3884514f5e3Sopenharmony_ci comment); 3894514f5e3Sopenharmony_ci currentLabel->SetControl(callGate); 3904514f5e3Sopenharmony_ci currentLabel->SetDepend(callGate); 3914514f5e3Sopenharmony_ci return callGate; 3924514f5e3Sopenharmony_ci} 3934514f5e3Sopenharmony_ci 3944514f5e3Sopenharmony_ciGateRef CircuitBuilder::CallGetter(GateRef hirGate, GateRef receiver, GateRef holder, GateRef propertyLookupResult, 3954514f5e3Sopenharmony_ci const char* comment) 3964514f5e3Sopenharmony_ci{ 3974514f5e3Sopenharmony_ci ASSERT(acc_.GetOpCode(hirGate) == OpCode::JS_BYTECODE); 3984514f5e3Sopenharmony_ci uint64_t pcOffset = acc_.TryGetPcOffset(hirGate); 3994514f5e3Sopenharmony_ci ASSERT(pcOffset != 0); 4004514f5e3Sopenharmony_ci 4014514f5e3Sopenharmony_ci auto currentLabel = env_->GetCurrentLabel(); 4024514f5e3Sopenharmony_ci auto currentControl = currentLabel->GetControl(); 4034514f5e3Sopenharmony_ci auto currentDepend = currentLabel->GetDepend(); 4044514f5e3Sopenharmony_ci std::vector<GateRef> args = { currentControl, currentDepend, receiver, propertyLookupResult, holder }; 4054514f5e3Sopenharmony_ci AppendFrameArgs(args, hirGate); 4064514f5e3Sopenharmony_ci auto callGate = GetCircuit()->NewGate(circuit_->CallGetter(pcOffset), 4074514f5e3Sopenharmony_ci MachineType::I64, 4084514f5e3Sopenharmony_ci args.size(), 4094514f5e3Sopenharmony_ci args.data(), 4104514f5e3Sopenharmony_ci GateType::AnyType(), 4114514f5e3Sopenharmony_ci comment); 4124514f5e3Sopenharmony_ci currentLabel->SetControl(callGate); 4134514f5e3Sopenharmony_ci currentLabel->SetDepend(callGate); 4144514f5e3Sopenharmony_ci return callGate; 4154514f5e3Sopenharmony_ci} 4164514f5e3Sopenharmony_ci 4174514f5e3Sopenharmony_ciGateRef CircuitBuilder::CallSetter(GateRef hirGate, GateRef receiver, GateRef holder, GateRef propertyLookupResult, 4184514f5e3Sopenharmony_ci GateRef value, const char* comment) 4194514f5e3Sopenharmony_ci{ 4204514f5e3Sopenharmony_ci ASSERT(acc_.GetOpCode(hirGate) == OpCode::JS_BYTECODE); 4214514f5e3Sopenharmony_ci uint64_t pcOffset = acc_.TryGetPcOffset(hirGate); 4224514f5e3Sopenharmony_ci ASSERT(pcOffset != 0); 4234514f5e3Sopenharmony_ci 4244514f5e3Sopenharmony_ci auto currentLabel = env_->GetCurrentLabel(); 4254514f5e3Sopenharmony_ci auto currentControl = currentLabel->GetControl(); 4264514f5e3Sopenharmony_ci auto currentDepend = currentLabel->GetDepend(); 4274514f5e3Sopenharmony_ci std::vector<GateRef> args = { currentControl, currentDepend, receiver, propertyLookupResult, holder, value }; 4284514f5e3Sopenharmony_ci AppendFrameArgs(args, hirGate); 4294514f5e3Sopenharmony_ci auto callGate = GetCircuit()->NewGate(circuit_->CallSetter(pcOffset), 4304514f5e3Sopenharmony_ci MachineType::I64, 4314514f5e3Sopenharmony_ci args.size(), 4324514f5e3Sopenharmony_ci args.data(), 4334514f5e3Sopenharmony_ci GateType::AnyType(), 4344514f5e3Sopenharmony_ci comment); 4354514f5e3Sopenharmony_ci currentLabel->SetControl(callGate); 4364514f5e3Sopenharmony_ci currentLabel->SetDepend(callGate); 4374514f5e3Sopenharmony_ci return callGate; 4384514f5e3Sopenharmony_ci} 4394514f5e3Sopenharmony_ci 4404514f5e3Sopenharmony_ciGateRef CircuitBuilder::Float32ArrayConstructor(GateRef hirGate, std::vector<GateRef> args) 4414514f5e3Sopenharmony_ci{ 4424514f5e3Sopenharmony_ci ASSERT(acc_.GetOpCode(hirGate) == OpCode::JS_BYTECODE); 4434514f5e3Sopenharmony_ci auto currentLabel = env_->GetCurrentLabel(); 4444514f5e3Sopenharmony_ci auto currentControl = currentLabel->GetControl(); 4454514f5e3Sopenharmony_ci auto currentDepend = currentLabel->GetDepend(); 4464514f5e3Sopenharmony_ci uint64_t bitfield = args.size(); 4474514f5e3Sopenharmony_ci uint64_t pcOffset = acc_.TryGetPcOffset(hirGate); 4484514f5e3Sopenharmony_ci ASSERT(pcOffset != 0); 4494514f5e3Sopenharmony_ci args.insert(args.begin(), currentDepend); 4504514f5e3Sopenharmony_ci args.insert(args.begin(), currentControl); 4514514f5e3Sopenharmony_ci AppendFrameArgs(args, hirGate); 4524514f5e3Sopenharmony_ci auto callGate = GetCircuit()->NewGate(circuit_->Float32ArrayConstructor(bitfield, pcOffset), 4534514f5e3Sopenharmony_ci MachineType::I64, args.size(), args.data(), GateType::AnyType()); 4544514f5e3Sopenharmony_ci currentLabel->SetControl(callGate); 4554514f5e3Sopenharmony_ci currentLabel->SetDepend(callGate); 4564514f5e3Sopenharmony_ci return callGate; 4574514f5e3Sopenharmony_ci} 4584514f5e3Sopenharmony_ci 4594514f5e3Sopenharmony_ciGateRef CircuitBuilder::Construct(GateRef hirGate, std::vector<GateRef> args) 4604514f5e3Sopenharmony_ci{ 4614514f5e3Sopenharmony_ci ASSERT(acc_.GetOpCode(hirGate) == OpCode::JS_BYTECODE || acc_.GetOpCode(hirGate) == OpCode::REFLECT_CONSTRUCT); 4624514f5e3Sopenharmony_ci auto currentLabel = env_->GetCurrentLabel(); 4634514f5e3Sopenharmony_ci auto currentControl = currentLabel->GetControl(); 4644514f5e3Sopenharmony_ci auto currentDepend = currentLabel->GetDepend(); 4654514f5e3Sopenharmony_ci uint64_t bitfield = args.size(); 4664514f5e3Sopenharmony_ci uint64_t pcOffset = acc_.TryGetPcOffset(hirGate); 4674514f5e3Sopenharmony_ci args.insert(args.begin(), currentDepend); 4684514f5e3Sopenharmony_ci args.insert(args.begin(), currentControl); 4694514f5e3Sopenharmony_ci AppendFrameArgs(args, hirGate); 4704514f5e3Sopenharmony_ci auto callGate = GetCircuit()->NewGate(circuit_->Construct(bitfield, pcOffset), MachineType::I64, 4714514f5e3Sopenharmony_ci args.size(), args.data(), GateType::AnyType()); 4724514f5e3Sopenharmony_ci currentLabel->SetControl(callGate); 4734514f5e3Sopenharmony_ci currentLabel->SetDepend(callGate); 4744514f5e3Sopenharmony_ci return callGate; 4754514f5e3Sopenharmony_ci} 4764514f5e3Sopenharmony_ci 4774514f5e3Sopenharmony_ciGateRef CircuitBuilder::CallInternal(GateRef hirGate, std::vector<GateRef> args, uint64_t pcOffset) 4784514f5e3Sopenharmony_ci{ 4794514f5e3Sopenharmony_ci auto currentLabel = env_->GetCurrentLabel(); 4804514f5e3Sopenharmony_ci auto currentControl = currentLabel->GetControl(); 4814514f5e3Sopenharmony_ci auto currentDepend = currentLabel->GetDepend(); 4824514f5e3Sopenharmony_ci uint64_t bitfield = args.size(); 4834514f5e3Sopenharmony_ci ASSERT(pcOffset != 0); 4844514f5e3Sopenharmony_ci args.insert(args.begin(), currentDepend); 4854514f5e3Sopenharmony_ci args.insert(args.begin(), currentControl); 4864514f5e3Sopenharmony_ci AppendFrameArgs(args, hirGate); 4874514f5e3Sopenharmony_ci auto callGate = GetCircuit()->NewGate( 4884514f5e3Sopenharmony_ci circuit_->CallInternal(bitfield, pcOffset), MachineType::I64, args.size(), args.data(), GateType::AnyType()); 4894514f5e3Sopenharmony_ci currentLabel->SetControl(callGate); 4904514f5e3Sopenharmony_ci currentLabel->SetDepend(callGate); 4914514f5e3Sopenharmony_ci return callGate; 4924514f5e3Sopenharmony_ci} 4934514f5e3Sopenharmony_ci 4944514f5e3Sopenharmony_ciGateRef CircuitBuilder::CallNew(GateRef hirGate, std::vector<GateRef> args, 4954514f5e3Sopenharmony_ci bool needPushArgv) 4964514f5e3Sopenharmony_ci{ 4974514f5e3Sopenharmony_ci ASSERT(acc_.GetOpCode(hirGate) == OpCode::JS_BYTECODE || 4984514f5e3Sopenharmony_ci acc_.GetOpCode(hirGate) == OpCode::FLOAT32_ARRAY_CONSTRUCTOR); 4994514f5e3Sopenharmony_ci auto currentLabel = env_->GetCurrentLabel(); 5004514f5e3Sopenharmony_ci auto currentControl = currentLabel->GetControl(); 5014514f5e3Sopenharmony_ci auto currentDepend = currentLabel->GetDepend(); 5024514f5e3Sopenharmony_ci uint64_t bitfield = args.size(); 5034514f5e3Sopenharmony_ci uint64_t pcOffset = acc_.TryGetPcOffset(hirGate); 5044514f5e3Sopenharmony_ci ASSERT(pcOffset != 0); 5054514f5e3Sopenharmony_ci args.insert(args.begin(), currentDepend); 5064514f5e3Sopenharmony_ci args.insert(args.begin(), currentControl); 5074514f5e3Sopenharmony_ci AppendFrameArgs(args, hirGate); 5084514f5e3Sopenharmony_ci auto callGate = GetCircuit()->NewGate(circuit_->CallNew(bitfield, pcOffset, needPushArgv), 5094514f5e3Sopenharmony_ci MachineType::I64, args.size(), args.data(), GateType::AnyType()); 5104514f5e3Sopenharmony_ci currentLabel->SetControl(callGate); 5114514f5e3Sopenharmony_ci currentLabel->SetDepend(callGate); 5124514f5e3Sopenharmony_ci return callGate; 5134514f5e3Sopenharmony_ci} 5144514f5e3Sopenharmony_ci 5154514f5e3Sopenharmony_ciGateRef CircuitBuilder::CreateArray(ElementsKind kind, uint32_t arraySize, 5164514f5e3Sopenharmony_ci GateRef elementsLength, RegionSpaceFlag flag) 5174514f5e3Sopenharmony_ci{ 5184514f5e3Sopenharmony_ci auto currentLabel = env_->GetCurrentLabel(); 5194514f5e3Sopenharmony_ci auto currentControl = currentLabel->GetControl(); 5204514f5e3Sopenharmony_ci auto currentDepend = currentLabel->GetDepend(); 5214514f5e3Sopenharmony_ci ArrayMetaDataAccessor accessor(kind, ArrayMetaDataAccessor::Mode::CREATE, arraySize, flag); 5224514f5e3Sopenharmony_ci GateRef newGate = GetCircuit()->NewGate(circuit_->CreateArray(accessor.ToValue()), MachineType::I64, 5234514f5e3Sopenharmony_ci { currentControl, currentDepend, elementsLength }, 5244514f5e3Sopenharmony_ci GateType::TaggedValue()); 5254514f5e3Sopenharmony_ci currentLabel->SetControl(newGate); 5264514f5e3Sopenharmony_ci currentLabel->SetDepend(newGate); 5274514f5e3Sopenharmony_ci return newGate; 5284514f5e3Sopenharmony_ci} 5294514f5e3Sopenharmony_ci 5304514f5e3Sopenharmony_ciGateRef CircuitBuilder::CreateArrayWithBuffer(ElementsKind kind, ArrayMetaDataAccessor::Mode mode, GateRef cpId, 5314514f5e3Sopenharmony_ci GateRef constPoolIndex, RegionSpaceFlag flag) 5324514f5e3Sopenharmony_ci{ 5334514f5e3Sopenharmony_ci auto currentLabel = env_->GetCurrentLabel(); 5344514f5e3Sopenharmony_ci auto currentControl = currentLabel->GetControl(); 5354514f5e3Sopenharmony_ci auto currentDepend = currentLabel->GetDepend(); 5364514f5e3Sopenharmony_ci auto frameState = acc_.FindNearestFrameState(currentDepend); 5374514f5e3Sopenharmony_ci ArrayMetaDataAccessor accessor(kind, mode, 0, flag); 5384514f5e3Sopenharmony_ci GateRef newGate = GetCircuit()->NewGate(circuit_->CreateArrayWithBuffer(accessor.ToValue()), 5394514f5e3Sopenharmony_ci MachineType::I64, 5404514f5e3Sopenharmony_ci { currentControl, currentDepend, cpId, constPoolIndex, frameState }, 5414514f5e3Sopenharmony_ci GateType::NJSValue()); 5424514f5e3Sopenharmony_ci currentLabel->SetControl(newGate); 5434514f5e3Sopenharmony_ci currentLabel->SetDepend(newGate); 5444514f5e3Sopenharmony_ci return newGate; 5454514f5e3Sopenharmony_ci} 5464514f5e3Sopenharmony_ci 5474514f5e3Sopenharmony_ciGateRef CircuitBuilder::CreateArguments(ElementsKind kind, CreateArgumentsAccessor::Mode mode, GateRef restIdx) 5484514f5e3Sopenharmony_ci{ 5494514f5e3Sopenharmony_ci auto currentLabel = env_->GetCurrentLabel(); 5504514f5e3Sopenharmony_ci auto currentControl = currentLabel->GetControl(); 5514514f5e3Sopenharmony_ci auto currentDepend = currentLabel->GetDepend(); 5524514f5e3Sopenharmony_ci auto frameState = acc_.FindNearestFrameState(currentDepend); 5534514f5e3Sopenharmony_ci CreateArgumentsAccessor accessor(kind, mode); 5544514f5e3Sopenharmony_ci GateRef newGate = GetCircuit()->NewGate(circuit_->CreateArguments(accessor.ToValue()), 5554514f5e3Sopenharmony_ci MachineType::I64, 5564514f5e3Sopenharmony_ci { currentControl, currentDepend, restIdx, frameState }, 5574514f5e3Sopenharmony_ci GateType::NJSValue()); 5584514f5e3Sopenharmony_ci currentLabel->SetControl(newGate); 5594514f5e3Sopenharmony_ci currentLabel->SetDepend(newGate); 5604514f5e3Sopenharmony_ci return newGate; 5614514f5e3Sopenharmony_ci} 5624514f5e3Sopenharmony_ci 5634514f5e3Sopenharmony_civoid CircuitBuilder::SetPropertyInlinedProps(GateRef glue, GateRef obj, GateRef hClass, 5644514f5e3Sopenharmony_ci GateRef value, GateRef attrOffset, VariableType type) 5654514f5e3Sopenharmony_ci{ 5664514f5e3Sopenharmony_ci GateRef bitfield = Load(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD1_OFFSET)); 5674514f5e3Sopenharmony_ci GateRef inlinedPropsStart = Int32And(Int32LSR(bitfield, 5684514f5e3Sopenharmony_ci Int32(JSHClass::InlinedPropsStartBits::START_BIT)), 5694514f5e3Sopenharmony_ci Int32((1LU << JSHClass::InlinedPropsStartBits::SIZE) - 1)); 5704514f5e3Sopenharmony_ci GateRef propOffset = Int32Mul(Int32Add(inlinedPropsStart, attrOffset), 5714514f5e3Sopenharmony_ci Int32(JSTaggedValue::TaggedTypeSize())); 5724514f5e3Sopenharmony_ci Store(type, glue, obj, ZExtInt32ToPtr(propOffset), value); 5734514f5e3Sopenharmony_ci} 5744514f5e3Sopenharmony_ci 5754514f5e3Sopenharmony_ciGateRef CircuitBuilder::IsStabelArray(GateRef glue, GateRef obj) 5764514f5e3Sopenharmony_ci{ 5774514f5e3Sopenharmony_ci Label subentry(env_); 5784514f5e3Sopenharmony_ci env_->SubCfgEntry(&subentry); 5794514f5e3Sopenharmony_ci DEFVALUE(result, env_, VariableType::BOOL(), False()); 5804514f5e3Sopenharmony_ci Label exit(env_); 5814514f5e3Sopenharmony_ci Label targetIsHeapObject(env_); 5824514f5e3Sopenharmony_ci Label targetIsStableArray(env_); 5834514f5e3Sopenharmony_ci 5844514f5e3Sopenharmony_ci BRANCH_CIR2(TaggedIsHeapObject(obj), &targetIsHeapObject, &exit); 5854514f5e3Sopenharmony_ci Bind(&targetIsHeapObject); 5864514f5e3Sopenharmony_ci { 5874514f5e3Sopenharmony_ci GateRef jsHclass = LoadHClass(obj); 5884514f5e3Sopenharmony_ci BRANCH_CIR2(IsStableArray(jsHclass), &targetIsStableArray, &exit); 5894514f5e3Sopenharmony_ci Bind(&targetIsStableArray); 5904514f5e3Sopenharmony_ci { 5914514f5e3Sopenharmony_ci GateRef guardiansOffset = 5924514f5e3Sopenharmony_ci IntPtr(JSThread::GlueData::GetStableArrayElementsGuardiansOffset(false)); 5934514f5e3Sopenharmony_ci result = Load(VariableType::BOOL(), glue, guardiansOffset); 5944514f5e3Sopenharmony_ci Jump(&exit); 5954514f5e3Sopenharmony_ci } 5964514f5e3Sopenharmony_ci } 5974514f5e3Sopenharmony_ci Bind(&exit); 5984514f5e3Sopenharmony_ci auto res = *result; 5994514f5e3Sopenharmony_ci env_->SubCfgExit(); 6004514f5e3Sopenharmony_ci return res; 6014514f5e3Sopenharmony_ci} 6024514f5e3Sopenharmony_ci 6034514f5e3Sopenharmony_ciGateRef CircuitBuilder::StoreModuleVar(GateRef jsFunc, GateRef index, GateRef value) 6044514f5e3Sopenharmony_ci{ 6054514f5e3Sopenharmony_ci auto currentLabel = env_->GetCurrentLabel(); 6064514f5e3Sopenharmony_ci auto currentControl = currentLabel->GetControl(); 6074514f5e3Sopenharmony_ci auto currentDepend = currentLabel->GetDepend(); 6084514f5e3Sopenharmony_ci GateRef newGate = GetCircuit()->NewGate(circuit_->StoreModuleVar(), MachineType::I64, 6094514f5e3Sopenharmony_ci { currentControl, currentDepend, jsFunc, index, value }, GateType::TaggedValue()); 6104514f5e3Sopenharmony_ci currentLabel->SetControl(newGate); 6114514f5e3Sopenharmony_ci currentLabel->SetDepend(newGate); 6124514f5e3Sopenharmony_ci return newGate; 6134514f5e3Sopenharmony_ci} 6144514f5e3Sopenharmony_ci 6154514f5e3Sopenharmony_ciGateRef CircuitBuilder::LdLocalModuleVar(GateRef jsFunc, GateRef index) 6164514f5e3Sopenharmony_ci{ 6174514f5e3Sopenharmony_ci auto currentLabel = env_->GetCurrentLabel(); 6184514f5e3Sopenharmony_ci auto currentControl = currentLabel->GetControl(); 6194514f5e3Sopenharmony_ci auto currentDepend = currentLabel->GetDepend(); 6204514f5e3Sopenharmony_ci GateRef newGate = GetCircuit()->NewGate(circuit_->LdLocalModuleVar(), MachineType::I64, 6214514f5e3Sopenharmony_ci { currentControl, currentDepend, jsFunc, index}, GateType::TaggedValue()); 6224514f5e3Sopenharmony_ci currentLabel->SetControl(newGate); 6234514f5e3Sopenharmony_ci currentLabel->SetDepend(newGate); 6244514f5e3Sopenharmony_ci return newGate; 6254514f5e3Sopenharmony_ci} 6264514f5e3Sopenharmony_ci 6274514f5e3Sopenharmony_ciGateRef CircuitBuilder::BuiltinConstructor(BuiltinsStubCSigns::ID id, GateRef gate) 6284514f5e3Sopenharmony_ci{ 6294514f5e3Sopenharmony_ci auto currentLabel = env_->GetCurrentLabel(); 6304514f5e3Sopenharmony_ci auto currentControl = currentLabel->GetControl(); 6314514f5e3Sopenharmony_ci auto currentDepend = currentLabel->GetDepend(); 6324514f5e3Sopenharmony_ci GateRef newGate = Circuit::NullGate(); 6334514f5e3Sopenharmony_ci switch (id) { 6344514f5e3Sopenharmony_ci case BuiltinsStubCSigns::ID::ArrayConstructor: { 6354514f5e3Sopenharmony_ci if (acc_.GetNumValueIn(gate) == 1) { 6364514f5e3Sopenharmony_ci newGate = GetCircuit()->NewGate(circuit_->ArrayConstructor(1), MachineType::I64, 6374514f5e3Sopenharmony_ci { currentControl, currentDepend, acc_.GetValueIn(gate, 0)}, 6384514f5e3Sopenharmony_ci GateType::TaggedValue()); 6394514f5e3Sopenharmony_ci } else { 6404514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); // 2: num value in 6414514f5e3Sopenharmony_ci newGate = GetCircuit()->NewGate(circuit_->ArrayConstructor(2), MachineType::I64, 6424514f5e3Sopenharmony_ci { currentControl, currentDepend, acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1)}, 6434514f5e3Sopenharmony_ci GateType::TaggedValue()); 6444514f5e3Sopenharmony_ci } 6454514f5e3Sopenharmony_ci break; 6464514f5e3Sopenharmony_ci } 6474514f5e3Sopenharmony_ci case BuiltinsStubCSigns::ID::ObjectConstructor: { 6484514f5e3Sopenharmony_ci if (acc_.GetNumValueIn(gate) == 1) { 6494514f5e3Sopenharmony_ci newGate = GetCircuit()->NewGate(circuit_->ObjectConstructor(1), MachineType::I64, 6504514f5e3Sopenharmony_ci { currentControl, currentDepend, acc_.GetValueIn(gate, 0)}, 6514514f5e3Sopenharmony_ci GateType::TaggedValue()); 6524514f5e3Sopenharmony_ci } else { 6534514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) >= 2); // 2: num value in 6544514f5e3Sopenharmony_ci newGate = GetCircuit()->NewGate(circuit_->ObjectConstructor(2), MachineType::I64, 6554514f5e3Sopenharmony_ci { currentControl, currentDepend, acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1)}, 6564514f5e3Sopenharmony_ci GateType::TaggedValue()); 6574514f5e3Sopenharmony_ci } 6584514f5e3Sopenharmony_ci break; 6594514f5e3Sopenharmony_ci } 6604514f5e3Sopenharmony_ci case BuiltinsStubCSigns::ID::BooleanConstructor: { 6614514f5e3Sopenharmony_ci if (acc_.GetNumValueIn(gate) == 1) { 6624514f5e3Sopenharmony_ci newGate = GetCircuit()->NewGate(circuit_->BooleanConstructor(1), MachineType::I64, 6634514f5e3Sopenharmony_ci { currentControl, currentDepend, acc_.GetValueIn(gate, 0)}, 6644514f5e3Sopenharmony_ci GateType::TaggedValue()); 6654514f5e3Sopenharmony_ci } else { 6664514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); // 2: num value in 6674514f5e3Sopenharmony_ci newGate = GetCircuit()->NewGate(circuit_->BooleanConstructor(2), MachineType::I64, 6684514f5e3Sopenharmony_ci { currentControl, currentDepend, acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1)}, 6694514f5e3Sopenharmony_ci GateType::TaggedValue()); 6704514f5e3Sopenharmony_ci } 6714514f5e3Sopenharmony_ci break; 6724514f5e3Sopenharmony_ci } 6734514f5e3Sopenharmony_ci case BuiltinsStubCSigns::ID::Float32ArrayConstructor: { 6744514f5e3Sopenharmony_ci if (acc_.GetNumValueIn(gate) == 1) { 6754514f5e3Sopenharmony_ci newGate = Float32ArrayConstructor(gate, { acc_.GetValueIn(gate, 0)}); 6764514f5e3Sopenharmony_ci } else { 6774514f5e3Sopenharmony_ci ASSERT(acc_.GetNumValueIn(gate) == 2); // 2: num value in 6784514f5e3Sopenharmony_ci newGate = Float32ArrayConstructor(gate, { acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1)}); 6794514f5e3Sopenharmony_ci } 6804514f5e3Sopenharmony_ci break; 6814514f5e3Sopenharmony_ci } 6824514f5e3Sopenharmony_ci default: 6834514f5e3Sopenharmony_ci LOG_ECMA(FATAL) << "this branch is unreachable"; 6844514f5e3Sopenharmony_ci UNREACHABLE(); 6854514f5e3Sopenharmony_ci break; 6864514f5e3Sopenharmony_ci } 6874514f5e3Sopenharmony_ci currentLabel->SetControl(newGate); 6884514f5e3Sopenharmony_ci currentLabel->SetDepend(newGate); 6894514f5e3Sopenharmony_ci return newGate; 6904514f5e3Sopenharmony_ci} 6914514f5e3Sopenharmony_ci 6924514f5e3Sopenharmony_civoid CircuitBuilder::SetExtensibleToBitfield(GateRef glue, GateRef obj, bool isExtensible) 6934514f5e3Sopenharmony_ci{ 6944514f5e3Sopenharmony_ci GateRef jsHclass = LoadHClass(obj); 6954514f5e3Sopenharmony_ci GateRef bitfield = Load(VariableType::INT32(), jsHclass, IntPtr(JSHClass::BIT_FIELD_OFFSET)); 6964514f5e3Sopenharmony_ci GateRef boolVal = Boolean(isExtensible); 6974514f5e3Sopenharmony_ci GateRef boolToInt32 = ZExtInt1ToInt32(boolVal); 6984514f5e3Sopenharmony_ci GateRef encodeValue = Int32LSL(boolToInt32, Int32(JSHClass::ExtensibleBit::START_BIT)); 6994514f5e3Sopenharmony_ci GateRef mask = Int32(((1LU << JSHClass::ExtensibleBit::SIZE) - 1) << JSHClass::ExtensibleBit::START_BIT); 7004514f5e3Sopenharmony_ci bitfield = Int32Or(Int32And(bitfield, Int32Not(mask)), encodeValue); 7014514f5e3Sopenharmony_ci Store(VariableType::INT32(), glue, jsHclass, IntPtr(JSHClass::BIT_FIELD_OFFSET), bitfield); 7024514f5e3Sopenharmony_ci} 7034514f5e3Sopenharmony_ci 7044514f5e3Sopenharmony_ciGateRef CircuitBuilder::OrdinaryHasInstance(GateRef obj, GateRef target) 7054514f5e3Sopenharmony_ci{ 7064514f5e3Sopenharmony_ci auto currentLabel = env_->GetCurrentLabel(); 7074514f5e3Sopenharmony_ci auto currentControl = currentLabel->GetControl(); 7084514f5e3Sopenharmony_ci auto currentDepend = currentLabel->GetDepend(); 7094514f5e3Sopenharmony_ci GateRef frameState = acc_.FindNearestFrameState(currentDepend); 7104514f5e3Sopenharmony_ci auto ret = GetCircuit()->NewGate(circuit_->OrdinaryHasInstance(), 7114514f5e3Sopenharmony_ci MachineType::I64, 7124514f5e3Sopenharmony_ci {currentControl, currentDepend, obj, target, frameState}, 7134514f5e3Sopenharmony_ci GateType::TaggedNPointer()); 7144514f5e3Sopenharmony_ci acc_.ReplaceInAfterInsert(currentControl, currentDepend, ret); 7154514f5e3Sopenharmony_ci currentLabel->SetControl(ret); 7164514f5e3Sopenharmony_ci currentLabel->SetDepend(ret); 7174514f5e3Sopenharmony_ci return ret; 7184514f5e3Sopenharmony_ci} 7194514f5e3Sopenharmony_ci 7204514f5e3Sopenharmony_ciGateRef CircuitBuilder::MigrateArrayWithKind(GateRef receiver, GateRef oldElementsKind, 7214514f5e3Sopenharmony_ci GateRef newElementsKind) 7224514f5e3Sopenharmony_ci{ 7234514f5e3Sopenharmony_ci auto currentLabel = env_->GetCurrentLabel(); 7244514f5e3Sopenharmony_ci auto currentControl = currentLabel->GetControl(); 7254514f5e3Sopenharmony_ci auto currentDepend = currentLabel->GetDepend(); 7264514f5e3Sopenharmony_ci GateRef newGate = GetCircuit()->NewGate(circuit_->MigrateArrayWithKind(), MachineType::I64, 7274514f5e3Sopenharmony_ci { currentControl, currentDepend, receiver, oldElementsKind, 7284514f5e3Sopenharmony_ci newElementsKind }, 7294514f5e3Sopenharmony_ci GateType::TaggedValue()); 7304514f5e3Sopenharmony_ci currentLabel->SetControl(newGate); 7314514f5e3Sopenharmony_ci currentLabel->SetDepend(newGate); 7324514f5e3Sopenharmony_ci return newGate; 7334514f5e3Sopenharmony_ci} 7344514f5e3Sopenharmony_ci 7354514f5e3Sopenharmony_ciGateRef CircuitBuilder::IsLiteralString(GateRef string) 7364514f5e3Sopenharmony_ci{ 7374514f5e3Sopenharmony_ci GateRef objectType = GetObjectType(LoadHClass(string)); 7384514f5e3Sopenharmony_ci return BitOr(Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::LINE_STRING))), 7394514f5e3Sopenharmony_ci Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::CONSTANT_STRING)))); 7404514f5e3Sopenharmony_ci} 7414514f5e3Sopenharmony_ci 7424514f5e3Sopenharmony_ci// left and right both utf-8 or utf-16 and both linestring or constantstring can be concat. 7434514f5e3Sopenharmony_ciGateRef CircuitBuilder::CanBeConcat(GateRef leftString, GateRef rightString, GateRef isValidOpt) 7444514f5e3Sopenharmony_ci{ 7454514f5e3Sopenharmony_ci return LogicAndBuilder(env_).And(isValidOpt).And(IsLiteralString(leftString)) 7464514f5e3Sopenharmony_ci .And(IsLiteralString(rightString)).Done(); 7474514f5e3Sopenharmony_ci} 7484514f5e3Sopenharmony_ci 7494514f5e3Sopenharmony_ci// left and right both utf-8 or utf-16 and right is linestring or constantstring can back store. 7504514f5e3Sopenharmony_ciGateRef CircuitBuilder::CanBackStore(GateRef rightString, GateRef isValidOpt) 7514514f5e3Sopenharmony_ci{ 7524514f5e3Sopenharmony_ci return LogicAndBuilder(env_).And(isValidOpt).And(IsLiteralString(rightString)).Done(); 7534514f5e3Sopenharmony_ci} 7544514f5e3Sopenharmony_ci 7554514f5e3Sopenharmony_ciGateRef CircuitBuilder::NumberToString(GateRef number) 7564514f5e3Sopenharmony_ci{ 7574514f5e3Sopenharmony_ci auto currentLabel = env_->GetCurrentLabel(); 7584514f5e3Sopenharmony_ci auto currentControl = currentLabel->GetControl(); 7594514f5e3Sopenharmony_ci auto currentDepend = currentLabel->GetDepend(); 7604514f5e3Sopenharmony_ci GateRef newGate = GetCircuit()->NewGate(circuit_->NumberToString(), MachineType::I64, 7614514f5e3Sopenharmony_ci { currentControl, currentDepend, number }, GateType::StringType()); 7624514f5e3Sopenharmony_ci currentLabel->SetControl(newGate); 7634514f5e3Sopenharmony_ci currentLabel->SetDepend(newGate); 7644514f5e3Sopenharmony_ci return newGate; 7654514f5e3Sopenharmony_ci} 7664514f5e3Sopenharmony_ci} 767