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