13af6ab5fSopenharmony_ci/*
23af6ab5fSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
33af6ab5fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43af6ab5fSopenharmony_ci * you may not use this file except in compliance with the License.
53af6ab5fSopenharmony_ci * You may obtain a copy of the License at
63af6ab5fSopenharmony_ci *
73af6ab5fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
83af6ab5fSopenharmony_ci *
93af6ab5fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103af6ab5fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113af6ab5fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123af6ab5fSopenharmony_ci * See the License for the specific language governing permissions and
133af6ab5fSopenharmony_ci * limitations under the License.
143af6ab5fSopenharmony_ci */
153af6ab5fSopenharmony_ci
163af6ab5fSopenharmony_ci#include "pandagen.h"
173af6ab5fSopenharmony_ci
183af6ab5fSopenharmony_ci#include <binder/binder.h>
193af6ab5fSopenharmony_ci#include <binder/scope.h>
203af6ab5fSopenharmony_ci#include <binder/variable.h>
213af6ab5fSopenharmony_ci#include <compiler/base/catchTable.h>
223af6ab5fSopenharmony_ci#include <compiler/base/lexenv.h>
233af6ab5fSopenharmony_ci#include <compiler/base/literals.h>
243af6ab5fSopenharmony_ci#include <compiler/core/compilerContext.h>
253af6ab5fSopenharmony_ci#include <compiler/core/labelTarget.h>
263af6ab5fSopenharmony_ci#include <compiler/core/regAllocator.h>
273af6ab5fSopenharmony_ci#include <compiler/function/asyncFunctionBuilder.h>
283af6ab5fSopenharmony_ci#include <compiler/function/asyncGeneratorFunctionBuilder.h>
293af6ab5fSopenharmony_ci#include <compiler/function/functionBuilder.h>
303af6ab5fSopenharmony_ci#include <compiler/function/generatorFunctionBuilder.h>
313af6ab5fSopenharmony_ci#include <es2panda.h>
323af6ab5fSopenharmony_ci#include <gen/isa.h>
333af6ab5fSopenharmony_ci#include <ir/base/classDefinition.h>
343af6ab5fSopenharmony_ci#include <ir/base/methodDefinition.h>
353af6ab5fSopenharmony_ci#include <ir/base/scriptFunction.h>
363af6ab5fSopenharmony_ci#include <ir/base/spreadElement.h>
373af6ab5fSopenharmony_ci#include <ir/expressions/callExpression.h>
383af6ab5fSopenharmony_ci#include <ir/expressions/functionExpression.h>
393af6ab5fSopenharmony_ci#include <ir/expressions/identifier.h>
403af6ab5fSopenharmony_ci#include <ir/expressions/literals/numberLiteral.h>
413af6ab5fSopenharmony_ci#include <ir/expressions/literals/stringLiteral.h>
423af6ab5fSopenharmony_ci#include <ir/expressions/newExpression.h>
433af6ab5fSopenharmony_ci#include <ir/module/importSpecifier.h>
443af6ab5fSopenharmony_ci#include <ir/statement.h>
453af6ab5fSopenharmony_ci#include <util/concurrent.h>
463af6ab5fSopenharmony_ci#include <util/helpers.h>
473af6ab5fSopenharmony_ci#include <util/patchFix.h>
483af6ab5fSopenharmony_ci
493af6ab5fSopenharmony_cinamespace panda::es2panda::compiler {
503af6ab5fSopenharmony_ci
513af6ab5fSopenharmony_ci// PandaGen
523af6ab5fSopenharmony_ci
533af6ab5fSopenharmony_civoid PandaGen::SetFunctionKind()
543af6ab5fSopenharmony_ci{
553af6ab5fSopenharmony_ci    int targetApiVersion = Binder()->Program()->TargetApiVersion();
563af6ab5fSopenharmony_ci    if (rootNode_->IsProgram()) {
573af6ab5fSopenharmony_ci        funcKind_ = panda::panda_file::FunctionKind::FUNCTION;
583af6ab5fSopenharmony_ci        return;
593af6ab5fSopenharmony_ci    }
603af6ab5fSopenharmony_ci
613af6ab5fSopenharmony_ci    auto *func = rootNode_->AsScriptFunction();
623af6ab5fSopenharmony_ci    if (func->IsConcurrent()) {
633af6ab5fSopenharmony_ci        funcKind_ = panda::panda_file::FunctionKind::CONCURRENT_FUNCTION;
643af6ab5fSopenharmony_ci        return;
653af6ab5fSopenharmony_ci    }
663af6ab5fSopenharmony_ci
673af6ab5fSopenharmony_ci    if (func->IsMethod()) {
683af6ab5fSopenharmony_ci        if (func->IsAsync()) {
693af6ab5fSopenharmony_ci            funcKind_ = panda::panda_file::FunctionKind::ASYNC_FUNCTION;
703af6ab5fSopenharmony_ci        }
713af6ab5fSopenharmony_ci        return;
723af6ab5fSopenharmony_ci    }
733af6ab5fSopenharmony_ci
743af6ab5fSopenharmony_ci    if (func->IsAsync()) {
753af6ab5fSopenharmony_ci        if (func->IsGenerator()) {
763af6ab5fSopenharmony_ci            funcKind_ = panda::panda_file::FunctionKind::ASYNC_GENERATOR_FUNCTION;
773af6ab5fSopenharmony_ci            return;
783af6ab5fSopenharmony_ci        }
793af6ab5fSopenharmony_ci
803af6ab5fSopenharmony_ci        if (func->IsArrow()) {
813af6ab5fSopenharmony_ci            funcKind_ = panda::panda_file::FunctionKind::ASYNC_NC_FUNCTION;
823af6ab5fSopenharmony_ci            return;
833af6ab5fSopenharmony_ci        }
843af6ab5fSopenharmony_ci
853af6ab5fSopenharmony_ci        funcKind_ = panda::panda_file::FunctionKind::ASYNC_FUNCTION;
863af6ab5fSopenharmony_ci
873af6ab5fSopenharmony_ci        if (func->IsSendable() && targetApiVersion >= util::Helpers::SENDABLE_FUNCTION_MIN_SUPPORTED_API_VERSION) {
883af6ab5fSopenharmony_ci            funcKind_ |= panda::panda_file::FunctionKind::SENDABLE_FUNCTION;
893af6ab5fSopenharmony_ci        }
903af6ab5fSopenharmony_ci        return;
913af6ab5fSopenharmony_ci    }
923af6ab5fSopenharmony_ci
933af6ab5fSopenharmony_ci    if (func->IsGenerator()) {
943af6ab5fSopenharmony_ci        funcKind_ = panda::panda_file::FunctionKind::GENERATOR_FUNCTION;
953af6ab5fSopenharmony_ci        return;
963af6ab5fSopenharmony_ci    }
973af6ab5fSopenharmony_ci
983af6ab5fSopenharmony_ci    if (func->IsArrow()) {
993af6ab5fSopenharmony_ci        funcKind_ = panda::panda_file::FunctionKind::NC_FUNCTION;
1003af6ab5fSopenharmony_ci        return;
1013af6ab5fSopenharmony_ci    }
1023af6ab5fSopenharmony_ci
1033af6ab5fSopenharmony_ci    funcKind_ = panda::panda_file::FunctionKind::FUNCTION;
1043af6ab5fSopenharmony_ci
1053af6ab5fSopenharmony_ci    if (func->IsSendable() && targetApiVersion >= util::Helpers::SENDABLE_FUNCTION_MIN_SUPPORTED_API_VERSION) {
1063af6ab5fSopenharmony_ci        funcKind_ |= panda::panda_file::FunctionKind::SENDABLE_FUNCTION;
1073af6ab5fSopenharmony_ci    }
1083af6ab5fSopenharmony_ci}
1093af6ab5fSopenharmony_ci
1103af6ab5fSopenharmony_civoid PandaGen::SetInSendable()
1113af6ab5fSopenharmony_ci{
1123af6ab5fSopenharmony_ci    if (rootNode_->IsProgram()) {
1133af6ab5fSopenharmony_ci        return;
1143af6ab5fSopenharmony_ci    }
1153af6ab5fSopenharmony_ci
1163af6ab5fSopenharmony_ci    auto *func = rootNode_->AsScriptFunction();
1173af6ab5fSopenharmony_ci    inSendable_ = func->InSendable();
1183af6ab5fSopenharmony_ci}
1193af6ab5fSopenharmony_ci
1203af6ab5fSopenharmony_ciLabel *PandaGen::AllocLabel()
1213af6ab5fSopenharmony_ci{
1223af6ab5fSopenharmony_ci    std::string id = std::string {Label::PREFIX} + std::to_string(labelId_++);
1233af6ab5fSopenharmony_ci    return ra_.AllocLabel(std::move(id));
1243af6ab5fSopenharmony_ci}
1253af6ab5fSopenharmony_ci
1263af6ab5fSopenharmony_cibool PandaGen::IsDebug() const
1273af6ab5fSopenharmony_ci{
1283af6ab5fSopenharmony_ci    return context_->IsDebug();
1293af6ab5fSopenharmony_ci}
1303af6ab5fSopenharmony_ci
1313af6ab5fSopenharmony_cibool PandaGen::isDebuggerEvaluateExpressionMode() const
1323af6ab5fSopenharmony_ci{
1333af6ab5fSopenharmony_ci    return context_->isDebuggerEvaluateExpressionMode();
1343af6ab5fSopenharmony_ci}
1353af6ab5fSopenharmony_ci
1363af6ab5fSopenharmony_cistd::string PandaGen::SourceFile() const
1373af6ab5fSopenharmony_ci{
1383af6ab5fSopenharmony_ci    return context_->SourceFile();
1393af6ab5fSopenharmony_ci}
1403af6ab5fSopenharmony_ci
1413af6ab5fSopenharmony_ciuint32_t PandaGen::ParamCount() const
1423af6ab5fSopenharmony_ci{
1433af6ab5fSopenharmony_ci    if (rootNode_->IsProgram()) {
1443af6ab5fSopenharmony_ci        return 0;
1453af6ab5fSopenharmony_ci    }
1463af6ab5fSopenharmony_ci
1473af6ab5fSopenharmony_ci    return rootNode_->AsScriptFunction()->Params().size();
1483af6ab5fSopenharmony_ci}
1493af6ab5fSopenharmony_ci
1503af6ab5fSopenharmony_ciuint32_t PandaGen::FormalParametersCount() const
1513af6ab5fSopenharmony_ci{
1523af6ab5fSopenharmony_ci    if (rootNode_->IsProgram()) {
1533af6ab5fSopenharmony_ci        return 0;
1543af6ab5fSopenharmony_ci    }
1553af6ab5fSopenharmony_ci
1563af6ab5fSopenharmony_ci    ASSERT(rootNode_->IsScriptFunction());
1573af6ab5fSopenharmony_ci
1583af6ab5fSopenharmony_ci    return rootNode_->AsScriptFunction()->FormalParamsLength();
1593af6ab5fSopenharmony_ci}
1603af6ab5fSopenharmony_ci
1613af6ab5fSopenharmony_ciuint32_t PandaGen::InternalParamCount() const
1623af6ab5fSopenharmony_ci{
1633af6ab5fSopenharmony_ci    if (rootNode_->IsProgram() && context_->Binder()->Program()->IsCommonjs()) {
1643af6ab5fSopenharmony_ci        return binder::Binder::CJS_MANDATORY_PARAMS_NUMBER;
1653af6ab5fSopenharmony_ci    }
1663af6ab5fSopenharmony_ci    return ParamCount() + binder::Binder::MANDATORY_PARAMS_NUMBER;
1673af6ab5fSopenharmony_ci}
1683af6ab5fSopenharmony_ci
1693af6ab5fSopenharmony_ciconst util::StringView &PandaGen::InternalName() const
1703af6ab5fSopenharmony_ci{
1713af6ab5fSopenharmony_ci    return topScope_->InternalName();
1723af6ab5fSopenharmony_ci}
1733af6ab5fSopenharmony_ci
1743af6ab5fSopenharmony_ciconst util::StringView &PandaGen::FunctionName() const
1753af6ab5fSopenharmony_ci{
1763af6ab5fSopenharmony_ci    return topScope_->Name();
1773af6ab5fSopenharmony_ci}
1783af6ab5fSopenharmony_ci
1793af6ab5fSopenharmony_cibinder::Binder *PandaGen::Binder() const
1803af6ab5fSopenharmony_ci{
1813af6ab5fSopenharmony_ci    return context_->Binder();
1823af6ab5fSopenharmony_ci}
1833af6ab5fSopenharmony_ci
1843af6ab5fSopenharmony_civoid PandaGen::FunctionInit(CatchTable *catchTable)
1853af6ab5fSopenharmony_ci{
1863af6ab5fSopenharmony_ci    if (rootNode_->IsProgram()) {
1873af6ab5fSopenharmony_ci        if (context_->Binder()->Program()->HasTLA()) {
1883af6ab5fSopenharmony_ci            builder_ = allocator_->New<AsyncFunctionBuilder>(this, catchTable);
1893af6ab5fSopenharmony_ci        } else {
1903af6ab5fSopenharmony_ci            builder_ = allocator_->New<FunctionBuilder>(this, catchTable);
1913af6ab5fSopenharmony_ci        }
1923af6ab5fSopenharmony_ci        return;
1933af6ab5fSopenharmony_ci    }
1943af6ab5fSopenharmony_ci
1953af6ab5fSopenharmony_ci    const ir::ScriptFunction *func = rootNode_->AsScriptFunction();
1963af6ab5fSopenharmony_ci
1973af6ab5fSopenharmony_ci    if (func->IsAsync()) {
1983af6ab5fSopenharmony_ci        if (func->IsGenerator()) {
1993af6ab5fSopenharmony_ci            builder_ = allocator_->New<AsyncGeneratorFunctionBuilder>(this, catchTable);
2003af6ab5fSopenharmony_ci            return;
2013af6ab5fSopenharmony_ci        }
2023af6ab5fSopenharmony_ci
2033af6ab5fSopenharmony_ci        builder_ = allocator_->New<AsyncFunctionBuilder>(this, catchTable);
2043af6ab5fSopenharmony_ci        return;
2053af6ab5fSopenharmony_ci    }
2063af6ab5fSopenharmony_ci
2073af6ab5fSopenharmony_ci    if (func->IsGenerator()) {
2083af6ab5fSopenharmony_ci        builder_ = allocator_->New<GeneratorFunctionBuilder>(this, catchTable);
2093af6ab5fSopenharmony_ci        return;
2103af6ab5fSopenharmony_ci    }
2113af6ab5fSopenharmony_ci
2123af6ab5fSopenharmony_ci    builder_ = allocator_->New<FunctionBuilder>(this, catchTable);
2133af6ab5fSopenharmony_ci}
2143af6ab5fSopenharmony_ci
2153af6ab5fSopenharmony_cibool PandaGen::FunctionHasFinalizer() const
2163af6ab5fSopenharmony_ci{
2173af6ab5fSopenharmony_ci    if (rootNode_->IsProgram()) {
2183af6ab5fSopenharmony_ci        return context_->Binder()->Program()->HasTLA();
2193af6ab5fSopenharmony_ci    }
2203af6ab5fSopenharmony_ci
2213af6ab5fSopenharmony_ci    const ir::ScriptFunction *func = rootNode_->AsScriptFunction();
2223af6ab5fSopenharmony_ci
2233af6ab5fSopenharmony_ci    return func->IsAsync() || func->IsGenerator();
2243af6ab5fSopenharmony_ci}
2253af6ab5fSopenharmony_ci
2263af6ab5fSopenharmony_cibool PandaGen::IsAsyncFunction() const
2273af6ab5fSopenharmony_ci{
2283af6ab5fSopenharmony_ci    if (rootNode_->IsProgram() && context_->Binder()->Program()->HasTLA()) {
2293af6ab5fSopenharmony_ci        return true;
2303af6ab5fSopenharmony_ci    }
2313af6ab5fSopenharmony_ci    const ir::ScriptFunction *func = rootNode_->AsScriptFunction();
2323af6ab5fSopenharmony_ci    return func->IsAsync() && !func->IsGenerator();
2333af6ab5fSopenharmony_ci}
2343af6ab5fSopenharmony_ci
2353af6ab5fSopenharmony_civoid PandaGen::FunctionEnter()
2363af6ab5fSopenharmony_ci{
2373af6ab5fSopenharmony_ci    if (rootNode_->IsProgram() && context_->Binder()->Program()->HasTLA()) {
2383af6ab5fSopenharmony_ci        builder_->Prepare(nullptr);
2393af6ab5fSopenharmony_ci        return;
2403af6ab5fSopenharmony_ci    }
2413af6ab5fSopenharmony_ci    builder_->Prepare(rootNode_->AsScriptFunction());
2423af6ab5fSopenharmony_ci}
2433af6ab5fSopenharmony_ci
2443af6ab5fSopenharmony_civoid PandaGen::FunctionExit()
2453af6ab5fSopenharmony_ci{
2463af6ab5fSopenharmony_ci    if (rootNode_->IsProgram() && context_->Binder()->Program()->HasTLA()) {
2473af6ab5fSopenharmony_ci        builder_->CleanUp(nullptr);
2483af6ab5fSopenharmony_ci        return;
2493af6ab5fSopenharmony_ci    }
2503af6ab5fSopenharmony_ci    builder_->CleanUp(rootNode_->AsScriptFunction());
2513af6ab5fSopenharmony_ci}
2523af6ab5fSopenharmony_ci
2533af6ab5fSopenharmony_civoid PandaGen::InitializeLexEnv(const ir::AstNode *node)
2543af6ab5fSopenharmony_ci{
2553af6ab5fSopenharmony_ci    FrontAllocator fa(this);
2563af6ab5fSopenharmony_ci
2573af6ab5fSopenharmony_ci    if (topScope_->NeedLexEnv()) {
2583af6ab5fSopenharmony_ci        NewLexicalEnv(node, topScope_->LexicalSlots(), topScope_);
2593af6ab5fSopenharmony_ci    }
2603af6ab5fSopenharmony_ci
2613af6ab5fSopenharmony_ci    if (topScope_->NeedSendableEnv()) {
2623af6ab5fSopenharmony_ci        NewSendableEnv(node, topScope_->SendableSlots());
2633af6ab5fSopenharmony_ci    }
2643af6ab5fSopenharmony_ci}
2653af6ab5fSopenharmony_ci
2663af6ab5fSopenharmony_civoid PandaGen::CopyFunctionArguments(const ir::AstNode *node)
2673af6ab5fSopenharmony_ci{
2683af6ab5fSopenharmony_ci    FrontAllocator fa(this);
2693af6ab5fSopenharmony_ci    VReg targetReg = totalRegs_;
2703af6ab5fSopenharmony_ci
2713af6ab5fSopenharmony_ci    for (const auto *param : topScope_->ParamScope()->Params()) {
2723af6ab5fSopenharmony_ci        if (param->LexicalBound()) {
2733af6ab5fSopenharmony_ci            StoreLexicalVar(node, 0, param->LexIdx(), targetReg++);
2743af6ab5fSopenharmony_ci            continue;
2753af6ab5fSopenharmony_ci        }
2763af6ab5fSopenharmony_ci        MoveVreg(node, param->Vreg(), targetReg++);
2773af6ab5fSopenharmony_ci    }
2783af6ab5fSopenharmony_ci}
2793af6ab5fSopenharmony_ci
2803af6ab5fSopenharmony_ciLiteralBuffer *PandaGen::NewLiteralBuffer()
2813af6ab5fSopenharmony_ci{
2823af6ab5fSopenharmony_ci    LiteralBuffer *buf = allocator_->New<LiteralBuffer>(allocator_);
2833af6ab5fSopenharmony_ci    CHECK_NOT_NULL(buf);
2843af6ab5fSopenharmony_ci    return buf;
2853af6ab5fSopenharmony_ci}
2863af6ab5fSopenharmony_ci
2873af6ab5fSopenharmony_ciint32_t PandaGen::AddLiteralBuffer(LiteralBuffer *buf)
2883af6ab5fSopenharmony_ci{
2893af6ab5fSopenharmony_ci    CHECK_NOT_NULL(buf);
2903af6ab5fSopenharmony_ci    buffStorage_.push_back(buf);
2913af6ab5fSopenharmony_ci    buf->SetIndex(context_->NewLiteralIndex());
2923af6ab5fSopenharmony_ci    return buf->Index();
2933af6ab5fSopenharmony_ci}
2943af6ab5fSopenharmony_ci
2953af6ab5fSopenharmony_ciint32_t PandaGen::AddLexicalVarNamesForDebugInfo(ArenaMap<uint32_t, std::pair<util::StringView, int>> &lexicalVars)
2963af6ab5fSopenharmony_ci{
2973af6ab5fSopenharmony_ci    auto *buf = NewLiteralBuffer();
2983af6ab5fSopenharmony_ci    buf->Add(Allocator()->New<ir::NumberLiteral>(lexicalVars.size()));
2993af6ab5fSopenharmony_ci    for (auto &iter : lexicalVars) {
3003af6ab5fSopenharmony_ci        // The slot is set to UINT32_MAX when the variable is a patchvar while its value is not stored in the slot
3013af6ab5fSopenharmony_ci        // The patchvar info should not be added to the DebugInfo since its value cannot be found in slot UINT32_MAX
3023af6ab5fSopenharmony_ci        if (iter.first != UINT32_MAX) {
3033af6ab5fSopenharmony_ci            buf->Add(Allocator()->New<ir::StringLiteral>(iter.second.first));
3043af6ab5fSopenharmony_ci            buf->Add(Allocator()->New<ir::NumberLiteral>(iter.first));
3053af6ab5fSopenharmony_ci        }
3063af6ab5fSopenharmony_ci    }
3073af6ab5fSopenharmony_ci    return AddLiteralBuffer(buf);
3083af6ab5fSopenharmony_ci}
3093af6ab5fSopenharmony_ci
3103af6ab5fSopenharmony_civoid PandaGen::GetFunctionObject(const ir::AstNode *node)
3113af6ab5fSopenharmony_ci{
3123af6ab5fSopenharmony_ci    LoadAccFromLexEnv(node, scope_->Find(binder::Binder::MANDATORY_PARAM_FUNC));
3133af6ab5fSopenharmony_ci}
3143af6ab5fSopenharmony_ci
3153af6ab5fSopenharmony_civoid PandaGen::GetNewTarget(const ir::AstNode *node)
3163af6ab5fSopenharmony_ci{
3173af6ab5fSopenharmony_ci    LoadAccFromLexEnv(node, scope_->Find(binder::Binder::MANDATORY_PARAM_NEW_TARGET));
3183af6ab5fSopenharmony_ci}
3193af6ab5fSopenharmony_ci
3203af6ab5fSopenharmony_civoid PandaGen::GetThis(const ir::AstNode *node)
3213af6ab5fSopenharmony_ci{
3223af6ab5fSopenharmony_ci    LoadAccFromLexEnv(node, scope_->Find(binder::Binder::MANDATORY_PARAM_THIS));
3233af6ab5fSopenharmony_ci}
3243af6ab5fSopenharmony_ci
3253af6ab5fSopenharmony_civoid PandaGen::SetThis(const ir::AstNode *node)
3263af6ab5fSopenharmony_ci{
3273af6ab5fSopenharmony_ci    StoreAccToLexEnv(node, scope_->Find(binder::Binder::MANDATORY_PARAM_THIS), true);
3283af6ab5fSopenharmony_ci}
3293af6ab5fSopenharmony_ci
3303af6ab5fSopenharmony_civoid PandaGen::LoadVar(const ir::Identifier *node, const binder::ScopeFindResult &result)
3313af6ab5fSopenharmony_ci{
3323af6ab5fSopenharmony_ci    auto *var = result.variable;
3333af6ab5fSopenharmony_ci
3343af6ab5fSopenharmony_ci    if (!var || var->Declaration()->IsDeclare()) {
3353af6ab5fSopenharmony_ci        TryLoadGlobalByName(node, result.name);
3363af6ab5fSopenharmony_ci        return;
3373af6ab5fSopenharmony_ci    }
3383af6ab5fSopenharmony_ci
3393af6ab5fSopenharmony_ci    if (var->IsGlobalVariable()) {
3403af6ab5fSopenharmony_ci        LoadGlobalVar(node, var->Name());
3413af6ab5fSopenharmony_ci        return;
3423af6ab5fSopenharmony_ci    }
3433af6ab5fSopenharmony_ci
3443af6ab5fSopenharmony_ci    if (var->IsModuleVariable()) {
3453af6ab5fSopenharmony_ci        var->HasFlag(binder::VariableFlags::LOCAL_EXPORT) ? LoadLocalModuleVariable(node, var->AsModuleVariable()) :
3463af6ab5fSopenharmony_ci                                                            LoadExternalModuleVariable(node, var->AsModuleVariable());
3473af6ab5fSopenharmony_ci        if (var->Declaration()->IsLetOrConstOrClassDecl()) {
3483af6ab5fSopenharmony_ci            ThrowUndefinedIfHole(node, var->Name());
3493af6ab5fSopenharmony_ci        }
3503af6ab5fSopenharmony_ci        return;
3513af6ab5fSopenharmony_ci    }
3523af6ab5fSopenharmony_ci
3533af6ab5fSopenharmony_ci    ASSERT(var->IsLocalVariable());
3543af6ab5fSopenharmony_ci
3553af6ab5fSopenharmony_ci    if (var->Declaration()->IsLetOrConstOrClassDecl() && result.scope->IsGlobalScope()) {
3563af6ab5fSopenharmony_ci        TryLoadGlobalByName(node, result.name);
3573af6ab5fSopenharmony_ci        return;
3583af6ab5fSopenharmony_ci    }
3593af6ab5fSopenharmony_ci
3603af6ab5fSopenharmony_ci    LoadAccFromLexEnv(node, result);
3613af6ab5fSopenharmony_ci}
3623af6ab5fSopenharmony_ci
3633af6ab5fSopenharmony_civoid PandaGen::StoreVar(const ir::AstNode *node, const binder::ScopeFindResult &result, bool isDeclaration)
3643af6ab5fSopenharmony_ci{
3653af6ab5fSopenharmony_ci    binder::Variable *var = result.variable;
3663af6ab5fSopenharmony_ci
3673af6ab5fSopenharmony_ci    if (!var) {
3683af6ab5fSopenharmony_ci        TryStoreGlobalByName(node, result.name);
3693af6ab5fSopenharmony_ci        return;
3703af6ab5fSopenharmony_ci    }
3713af6ab5fSopenharmony_ci
3723af6ab5fSopenharmony_ci    if (var->IsGlobalVariable()) {
3733af6ab5fSopenharmony_ci        StoreGlobalVar(node, var->Name());
3743af6ab5fSopenharmony_ci        return;
3753af6ab5fSopenharmony_ci    }
3763af6ab5fSopenharmony_ci
3773af6ab5fSopenharmony_ci    if (var->IsModuleVariable()) {
3783af6ab5fSopenharmony_ci        if (!isDeclaration && var->Declaration()->IsConstDecl()) {
3793af6ab5fSopenharmony_ci            ThrowConstAssignment(node, var->Name());
3803af6ab5fSopenharmony_ci            return;
3813af6ab5fSopenharmony_ci        }
3823af6ab5fSopenharmony_ci
3833af6ab5fSopenharmony_ci        if (!isDeclaration &&
3843af6ab5fSopenharmony_ci            (var->Declaration()->IsLetDecl() || var->Declaration()->IsClassDecl())) {
3853af6ab5fSopenharmony_ci            RegScope rs(this);
3863af6ab5fSopenharmony_ci            VReg valueReg = AllocReg();
3873af6ab5fSopenharmony_ci            StoreAccumulator(node, valueReg);
3883af6ab5fSopenharmony_ci            LoadLocalModuleVariable(node, var->AsModuleVariable());
3893af6ab5fSopenharmony_ci            ThrowUndefinedIfHole(node, var->Name());
3903af6ab5fSopenharmony_ci            LoadAccumulator(node, valueReg);
3913af6ab5fSopenharmony_ci        }
3923af6ab5fSopenharmony_ci
3933af6ab5fSopenharmony_ci        StoreModuleVariable(node, var->AsModuleVariable());
3943af6ab5fSopenharmony_ci        return;
3953af6ab5fSopenharmony_ci    }
3963af6ab5fSopenharmony_ci
3973af6ab5fSopenharmony_ci    ASSERT(var->IsLocalVariable());
3983af6ab5fSopenharmony_ci
3993af6ab5fSopenharmony_ci    if (var->Declaration()->IsLetOrConstOrClassDecl() && result.scope->IsGlobalScope()) {
4003af6ab5fSopenharmony_ci        if (!isDeclaration) {
4013af6ab5fSopenharmony_ci            TryStoreGlobalByName(node, var->Name());
4023af6ab5fSopenharmony_ci        } else if (var->Declaration()->IsLetDecl() || var->Declaration()->IsClassDecl()) {
4033af6ab5fSopenharmony_ci            StLetOrClassToGlobalRecord(node, var->Name());
4043af6ab5fSopenharmony_ci        } else if (var->Declaration()->IsConstDecl()) {
4053af6ab5fSopenharmony_ci            StConstToGlobalRecord(node, var->Name());
4063af6ab5fSopenharmony_ci        }
4073af6ab5fSopenharmony_ci
4083af6ab5fSopenharmony_ci        return;
4093af6ab5fSopenharmony_ci    }
4103af6ab5fSopenharmony_ci
4113af6ab5fSopenharmony_ci    StoreAccToLexEnv(node, result, isDeclaration);
4123af6ab5fSopenharmony_ci}
4133af6ab5fSopenharmony_ci
4143af6ab5fSopenharmony_civoid PandaGen::StoreAccumulator(const ir::AstNode *node, VReg vreg)
4153af6ab5fSopenharmony_ci{
4163af6ab5fSopenharmony_ci    ra_.Emit<Sta>(node, vreg);
4173af6ab5fSopenharmony_ci}
4183af6ab5fSopenharmony_ci
4193af6ab5fSopenharmony_civoid PandaGen::LoadAccFromArgs(const ir::AstNode *node)
4203af6ab5fSopenharmony_ci{
4213af6ab5fSopenharmony_ci    const auto *varScope = scope_->AsVariableScope();
4223af6ab5fSopenharmony_ci
4233af6ab5fSopenharmony_ci    if (!varScope->HasFlag(binder::VariableScopeFlags::USE_ARGS)) {
4243af6ab5fSopenharmony_ci        return;
4253af6ab5fSopenharmony_ci    }
4263af6ab5fSopenharmony_ci
4273af6ab5fSopenharmony_ci    binder::ScopeFindResult res = scope_->Find(binder::Binder::FUNCTION_ARGUMENTS);
4283af6ab5fSopenharmony_ci    ASSERT(res.scope);
4293af6ab5fSopenharmony_ci
4303af6ab5fSopenharmony_ci    GetUnmappedArgs(node);
4313af6ab5fSopenharmony_ci    StoreAccToLexEnv(node, res, true);
4323af6ab5fSopenharmony_ci}
4333af6ab5fSopenharmony_ci
4343af6ab5fSopenharmony_civoid PandaGen::LoadObjProperty(const ir::AstNode *node, VReg obj, const Operand &prop)
4353af6ab5fSopenharmony_ci{
4363af6ab5fSopenharmony_ci    if (std::holds_alternative<VReg>(prop)) {
4373af6ab5fSopenharmony_ci        LoadAccumulator(node, std::get<VReg>(prop));
4383af6ab5fSopenharmony_ci        LoadObjByValue(node, obj);
4393af6ab5fSopenharmony_ci        return;
4403af6ab5fSopenharmony_ci    }
4413af6ab5fSopenharmony_ci
4423af6ab5fSopenharmony_ci    if (std::holds_alternative<int64_t>(prop)) {
4433af6ab5fSopenharmony_ci        LoadObjByIndex(node, obj, std::get<int64_t>(prop));
4443af6ab5fSopenharmony_ci        return;
4453af6ab5fSopenharmony_ci    }
4463af6ab5fSopenharmony_ci
4473af6ab5fSopenharmony_ci    ASSERT(std::holds_alternative<util::StringView>(prop));
4483af6ab5fSopenharmony_ci    LoadObjByName(node, obj, std::get<util::StringView>(prop));
4493af6ab5fSopenharmony_ci}
4503af6ab5fSopenharmony_ci
4513af6ab5fSopenharmony_civoid PandaGen::StoreObjProperty(const ir::AstNode *node, VReg obj, const Operand &prop)
4523af6ab5fSopenharmony_ci{
4533af6ab5fSopenharmony_ci    if (std::holds_alternative<VReg>(prop)) {
4543af6ab5fSopenharmony_ci        StoreObjByValue(node, obj, std::get<VReg>(prop));
4553af6ab5fSopenharmony_ci        return;
4563af6ab5fSopenharmony_ci    }
4573af6ab5fSopenharmony_ci
4583af6ab5fSopenharmony_ci    if (std::holds_alternative<int64_t>(prop)) {
4593af6ab5fSopenharmony_ci        StoreObjByIndex(node, obj, std::get<int64_t>(prop));
4603af6ab5fSopenharmony_ci        return;
4613af6ab5fSopenharmony_ci    }
4623af6ab5fSopenharmony_ci
4633af6ab5fSopenharmony_ci    ASSERT(std::holds_alternative<util::StringView>(prop));
4643af6ab5fSopenharmony_ci    StoreObjByName(node, obj, std::get<util::StringView>(prop));
4653af6ab5fSopenharmony_ci}
4663af6ab5fSopenharmony_ci
4673af6ab5fSopenharmony_civoid PandaGen::DefineOwnProperty(const ir::AstNode *node, VReg obj, const Operand &prop)
4683af6ab5fSopenharmony_ci{
4693af6ab5fSopenharmony_ci    if (std::holds_alternative<VReg>(prop)) {
4703af6ab5fSopenharmony_ci        DefineFieldByValue(node, obj, std::get<VReg>(prop));
4713af6ab5fSopenharmony_ci        return;
4723af6ab5fSopenharmony_ci    }
4733af6ab5fSopenharmony_ci
4743af6ab5fSopenharmony_ci    if (std::holds_alternative<int64_t>(prop)) {
4753af6ab5fSopenharmony_ci        DefineFieldByIndex(node, obj, std::get<int64_t>(prop));
4763af6ab5fSopenharmony_ci        return;
4773af6ab5fSopenharmony_ci    }
4783af6ab5fSopenharmony_ci
4793af6ab5fSopenharmony_ci    ASSERT(std::holds_alternative<util::StringView>(prop));
4803af6ab5fSopenharmony_ci    DefineFieldByName(node, obj, std::get<util::StringView>(prop));
4813af6ab5fSopenharmony_ci}
4823af6ab5fSopenharmony_ci
4833af6ab5fSopenharmony_civoid PandaGen::DefineClassPrivateField(const ir::AstNode *node, uint32_t level, uint32_t slot, VReg obj)
4843af6ab5fSopenharmony_ci{
4853af6ab5fSopenharmony_ci    ra_.Emit<CallruntimeDefineprivateproperty>(node, 0, level, slot, obj);
4863af6ab5fSopenharmony_ci}
4873af6ab5fSopenharmony_ci
4883af6ab5fSopenharmony_civoid PandaGen::StoreOwnProperty(const ir::AstNode *node, VReg obj, const Operand &prop, bool nameSetting)
4893af6ab5fSopenharmony_ci{
4903af6ab5fSopenharmony_ci    if (std::holds_alternative<VReg>(prop)) {
4913af6ab5fSopenharmony_ci        StOwnByValue(node, obj, std::get<VReg>(prop), nameSetting);
4923af6ab5fSopenharmony_ci        return;
4933af6ab5fSopenharmony_ci    }
4943af6ab5fSopenharmony_ci
4953af6ab5fSopenharmony_ci    if (std::holds_alternative<int64_t>(prop)) {
4963af6ab5fSopenharmony_ci        StOwnByIndex(node, obj, std::get<int64_t>(prop));
4973af6ab5fSopenharmony_ci        return;
4983af6ab5fSopenharmony_ci    }
4993af6ab5fSopenharmony_ci
5003af6ab5fSopenharmony_ci    ASSERT(std::holds_alternative<util::StringView>(prop));
5013af6ab5fSopenharmony_ci    StOwnByName(node, obj, std::get<util::StringView>(prop), nameSetting);
5023af6ab5fSopenharmony_ci}
5033af6ab5fSopenharmony_ci
5043af6ab5fSopenharmony_ciconstexpr size_t DEBUGGER_GET_SET_ARGS_NUM = 2;
5053af6ab5fSopenharmony_ci
5063af6ab5fSopenharmony_civoid PandaGen::LoadObjByNameViaDebugger(const ir::AstNode *node, const util::StringView &name,
5073af6ab5fSopenharmony_ci                                        bool throwUndefinedIfHole)
5083af6ab5fSopenharmony_ci{
5093af6ab5fSopenharmony_ci    RegScope rs(this);
5103af6ab5fSopenharmony_ci    VReg global = AllocReg();
5113af6ab5fSopenharmony_ci    LoadConst(node, compiler::Constant::JS_GLOBAL);
5123af6ab5fSopenharmony_ci    StoreAccumulator(node, global);
5133af6ab5fSopenharmony_ci    LoadObjByName(node, global, "debuggerGetValue");
5143af6ab5fSopenharmony_ci    VReg debuggerGetValueReg = AllocReg();
5153af6ab5fSopenharmony_ci    StoreAccumulator(node, debuggerGetValueReg);
5163af6ab5fSopenharmony_ci    VReg variableReg = AllocReg();
5173af6ab5fSopenharmony_ci    LoadAccumulatorString(node, name);
5183af6ab5fSopenharmony_ci    StoreAccumulator(node, variableReg);
5193af6ab5fSopenharmony_ci    VReg boolFlag = AllocReg();
5203af6ab5fSopenharmony_ci    if (throwUndefinedIfHole) {
5213af6ab5fSopenharmony_ci        LoadConst(node, compiler::Constant::JS_TRUE);
5223af6ab5fSopenharmony_ci    } else {
5233af6ab5fSopenharmony_ci        LoadConst(node, compiler::Constant::JS_FALSE);
5243af6ab5fSopenharmony_ci    }
5253af6ab5fSopenharmony_ci    StoreAccumulator(node, boolFlag);
5263af6ab5fSopenharmony_ci    Call(node, debuggerGetValueReg, DEBUGGER_GET_SET_ARGS_NUM);
5273af6ab5fSopenharmony_ci}
5283af6ab5fSopenharmony_ci
5293af6ab5fSopenharmony_civoid PandaGen::TryLoadGlobalByName(const ir::AstNode *node, const util::StringView &name)
5303af6ab5fSopenharmony_ci{
5313af6ab5fSopenharmony_ci    if (isDebuggerEvaluateExpressionMode()) {
5323af6ab5fSopenharmony_ci        LoadObjByNameViaDebugger(node, name, true);
5333af6ab5fSopenharmony_ci    } else {
5343af6ab5fSopenharmony_ci        ra_.Emit<Tryldglobalbyname>(node, 0, name);
5353af6ab5fSopenharmony_ci    }
5363af6ab5fSopenharmony_ci    strings_.insert(name);
5373af6ab5fSopenharmony_ci}
5383af6ab5fSopenharmony_ci
5393af6ab5fSopenharmony_civoid PandaGen::StoreObjByNameViaDebugger(const ir::AstNode *node, const util::StringView &name)
5403af6ab5fSopenharmony_ci{
5413af6ab5fSopenharmony_ci    RegScope rs(this);
5423af6ab5fSopenharmony_ci    VReg valueReg = AllocReg();
5433af6ab5fSopenharmony_ci    StoreAccumulator(node, valueReg);
5443af6ab5fSopenharmony_ci    VReg global = AllocReg();
5453af6ab5fSopenharmony_ci    LoadConst(node, compiler::Constant::JS_GLOBAL);
5463af6ab5fSopenharmony_ci    StoreAccumulator(node, global);
5473af6ab5fSopenharmony_ci    LoadObjByName(node, global, "debuggerSetValue");
5483af6ab5fSopenharmony_ci    VReg debuggerSetValueReg = AllocReg();
5493af6ab5fSopenharmony_ci    StoreAccumulator(node, debuggerSetValueReg);
5503af6ab5fSopenharmony_ci    VReg variableReg = AllocReg();
5513af6ab5fSopenharmony_ci    LoadAccumulatorString(node, name);
5523af6ab5fSopenharmony_ci    StoreAccumulator(node, variableReg);
5533af6ab5fSopenharmony_ci    MoveVreg(node, AllocReg(), valueReg);
5543af6ab5fSopenharmony_ci    Call(node, debuggerSetValueReg, DEBUGGER_GET_SET_ARGS_NUM);
5553af6ab5fSopenharmony_ci}
5563af6ab5fSopenharmony_ci
5573af6ab5fSopenharmony_civoid PandaGen::TryStoreGlobalByName(const ir::AstNode *node, const util::StringView &name)
5583af6ab5fSopenharmony_ci{
5593af6ab5fSopenharmony_ci    if (isDebuggerEvaluateExpressionMode()) {
5603af6ab5fSopenharmony_ci        StoreObjByNameViaDebugger(node, name);
5613af6ab5fSopenharmony_ci    } else {
5623af6ab5fSopenharmony_ci        ra_.Emit<Trystglobalbyname>(node, 0, name);
5633af6ab5fSopenharmony_ci    }
5643af6ab5fSopenharmony_ci    strings_.insert(name);
5653af6ab5fSopenharmony_ci}
5663af6ab5fSopenharmony_ci
5673af6ab5fSopenharmony_civoid PandaGen::LoadObjByName(const ir::AstNode *node, VReg obj, const util::StringView &prop)
5683af6ab5fSopenharmony_ci{
5693af6ab5fSopenharmony_ci    LoadAccumulator(node, obj); // object is load to acc
5703af6ab5fSopenharmony_ci    ra_.Emit<Ldobjbyname>(node, 0, prop);
5713af6ab5fSopenharmony_ci    strings_.insert(prop);
5723af6ab5fSopenharmony_ci}
5733af6ab5fSopenharmony_ci
5743af6ab5fSopenharmony_civoid PandaGen::StoreObjByName(const ir::AstNode *node, VReg obj, const util::StringView &prop)
5753af6ab5fSopenharmony_ci{
5763af6ab5fSopenharmony_ci    ra_.Emit<Stobjbyname>(node, 0, prop, obj);
5773af6ab5fSopenharmony_ci    strings_.insert(prop);
5783af6ab5fSopenharmony_ci}
5793af6ab5fSopenharmony_ci
5803af6ab5fSopenharmony_civoid PandaGen::DefineFieldByName(const ir::AstNode *node, VReg obj, const util::StringView &prop)
5813af6ab5fSopenharmony_ci{
5823af6ab5fSopenharmony_ci    if (util::Helpers::IsDefaultApiVersion(Binder()->Program()->TargetApiVersion(),
5833af6ab5fSopenharmony_ci        Binder()->Program()->GetTargetApiSubVersion())) {
5843af6ab5fSopenharmony_ci        ra_.Emit<Definefieldbyname>(node, 0, prop, obj);
5853af6ab5fSopenharmony_ci        strings_.insert(prop);
5863af6ab5fSopenharmony_ci        return;
5873af6ab5fSopenharmony_ci    }
5883af6ab5fSopenharmony_ci
5893af6ab5fSopenharmony_ci    ra_.Emit<Definepropertybyname>(node, 0, prop, obj);
5903af6ab5fSopenharmony_ci    strings_.insert(prop);
5913af6ab5fSopenharmony_ci}
5923af6ab5fSopenharmony_ci
5933af6ab5fSopenharmony_civoid PandaGen::LoadObjByIndex(const ir::AstNode *node, VReg obj, int64_t index)
5943af6ab5fSopenharmony_ci{
5953af6ab5fSopenharmony_ci    LoadAccumulator(node, obj); // object is load to acc
5963af6ab5fSopenharmony_ci    if (index <= util::Helpers::MAX_INT16) {
5973af6ab5fSopenharmony_ci        ra_.Emit<Ldobjbyindex>(node, 0, index);
5983af6ab5fSopenharmony_ci        return;
5993af6ab5fSopenharmony_ci    }
6003af6ab5fSopenharmony_ci
6013af6ab5fSopenharmony_ci    ra_.Emit<WideLdobjbyindex>(node, index);
6023af6ab5fSopenharmony_ci}
6033af6ab5fSopenharmony_ci
6043af6ab5fSopenharmony_civoid PandaGen::LoadObjByValue(const ir::AstNode *node, VReg obj)
6053af6ab5fSopenharmony_ci{
6063af6ab5fSopenharmony_ci    ra_.Emit<Ldobjbyvalue>(node, 0, obj); // prop is in acc
6073af6ab5fSopenharmony_ci}
6083af6ab5fSopenharmony_ci
6093af6ab5fSopenharmony_civoid PandaGen::StoreObjByValue(const ir::AstNode *node, VReg obj, VReg prop)
6103af6ab5fSopenharmony_ci{
6113af6ab5fSopenharmony_ci    ra_.Emit<Stobjbyvalue>(node, 0, obj, prop);
6123af6ab5fSopenharmony_ci}
6133af6ab5fSopenharmony_ci
6143af6ab5fSopenharmony_civoid PandaGen::StoreObjByIndex(const ir::AstNode *node, VReg obj, int64_t index)
6153af6ab5fSopenharmony_ci{
6163af6ab5fSopenharmony_ci    if (index <= util::Helpers::MAX_INT16) {
6173af6ab5fSopenharmony_ci        ra_.Emit<Stobjbyindex>(node, 0, obj, index);
6183af6ab5fSopenharmony_ci        return;
6193af6ab5fSopenharmony_ci    }
6203af6ab5fSopenharmony_ci
6213af6ab5fSopenharmony_ci    ra_.Emit<WideStobjbyindex>(node, obj, index);
6223af6ab5fSopenharmony_ci}
6233af6ab5fSopenharmony_ci
6243af6ab5fSopenharmony_civoid PandaGen::DefineFieldByValue(const ir::AstNode *node, VReg obj, VReg prop)
6253af6ab5fSopenharmony_ci{
6263af6ab5fSopenharmony_ci    ra_.Emit<CallruntimeDefinefieldbyvalue>(node, 0, prop, obj);
6273af6ab5fSopenharmony_ci}
6283af6ab5fSopenharmony_ci
6293af6ab5fSopenharmony_civoid PandaGen::DefineFieldByIndex(const ir::AstNode *node, VReg obj, int64_t index)
6303af6ab5fSopenharmony_ci{
6313af6ab5fSopenharmony_ci    ra_.Emit<CallruntimeDefinefieldbyindex>(node, 0, index, obj);
6323af6ab5fSopenharmony_ci}
6333af6ab5fSopenharmony_ci
6343af6ab5fSopenharmony_civoid PandaGen::StOwnByName(const ir::AstNode *node, VReg obj, const util::StringView &prop, bool nameSetting)
6353af6ab5fSopenharmony_ci{
6363af6ab5fSopenharmony_ci    nameSetting ? ra_.Emit<Stownbynamewithnameset>(node, 0, prop, obj) :
6373af6ab5fSopenharmony_ci                  ra_.Emit<Stownbyname>(node, 0, prop, obj);
6383af6ab5fSopenharmony_ci    strings_.insert(prop);
6393af6ab5fSopenharmony_ci}
6403af6ab5fSopenharmony_ci
6413af6ab5fSopenharmony_civoid PandaGen::StOwnByValue(const ir::AstNode *node, VReg obj, VReg prop, bool nameSetting)
6423af6ab5fSopenharmony_ci{
6433af6ab5fSopenharmony_ci    nameSetting ? ra_.Emit<Stownbyvaluewithnameset>(node, 0, obj, prop) :
6443af6ab5fSopenharmony_ci                  ra_.Emit<Stownbyvalue>(node, 0, obj, prop);
6453af6ab5fSopenharmony_ci}
6463af6ab5fSopenharmony_ci
6473af6ab5fSopenharmony_civoid PandaGen::StOwnByIndex(const ir::AstNode *node, VReg obj, int64_t index)
6483af6ab5fSopenharmony_ci{
6493af6ab5fSopenharmony_ci    if (index <= util::Helpers::MAX_INT16) {
6503af6ab5fSopenharmony_ci        ra_.Emit<Stownbyindex>(node, 0, obj, index);
6513af6ab5fSopenharmony_ci        return;
6523af6ab5fSopenharmony_ci    }
6533af6ab5fSopenharmony_ci
6543af6ab5fSopenharmony_ci    ra_.Emit<WideStownbyindex>(node, obj, index);
6553af6ab5fSopenharmony_ci}
6563af6ab5fSopenharmony_ci
6573af6ab5fSopenharmony_civoid PandaGen::DeleteObjProperty(const ir::AstNode *node, VReg obj, const Operand &prop)
6583af6ab5fSopenharmony_ci{
6593af6ab5fSopenharmony_ci    if (std::holds_alternative<VReg>(prop)) {
6603af6ab5fSopenharmony_ci        LoadAccumulator(node, std::get<VReg>(prop));
6613af6ab5fSopenharmony_ci    } else if (std::holds_alternative<int64_t>(prop)) {
6623af6ab5fSopenharmony_ci        LoadAccumulatorInt(node, static_cast<size_t>(std::get<int64_t>(prop)));
6633af6ab5fSopenharmony_ci    } else {
6643af6ab5fSopenharmony_ci        ASSERT(std::holds_alternative<util::StringView>(prop));
6653af6ab5fSopenharmony_ci        LoadAccumulatorString(node, std::get<util::StringView>(prop));
6663af6ab5fSopenharmony_ci    }
6673af6ab5fSopenharmony_ci
6683af6ab5fSopenharmony_ci    ra_.Emit<Delobjprop>(node, obj); // property is load to acc
6693af6ab5fSopenharmony_ci}
6703af6ab5fSopenharmony_ci
6713af6ab5fSopenharmony_civoid PandaGen::LoadAccumulator(const ir::AstNode *node, VReg reg)
6723af6ab5fSopenharmony_ci{
6733af6ab5fSopenharmony_ci    ra_.Emit<Lda>(node, reg);
6743af6ab5fSopenharmony_ci}
6753af6ab5fSopenharmony_ci
6763af6ab5fSopenharmony_civoid PandaGen::LoadGlobalVar(const ir::AstNode *node, const util::StringView &name)
6773af6ab5fSopenharmony_ci{
6783af6ab5fSopenharmony_ci    ra_.Emit<Ldglobalvar>(node, 0, name);
6793af6ab5fSopenharmony_ci    strings_.insert(name);
6803af6ab5fSopenharmony_ci}
6813af6ab5fSopenharmony_ci
6823af6ab5fSopenharmony_civoid PandaGen::StoreGlobalVar(const ir::AstNode *node, const util::StringView &name)
6833af6ab5fSopenharmony_ci{
6843af6ab5fSopenharmony_ci    ra_.Emit<Stglobalvar>(node, 0, name);
6853af6ab5fSopenharmony_ci    strings_.insert(name);
6863af6ab5fSopenharmony_ci}
6873af6ab5fSopenharmony_ci
6883af6ab5fSopenharmony_civoid PandaGen::LoadAccFromLexEnv(const ir::AstNode *node, const binder::ScopeFindResult &result)
6893af6ab5fSopenharmony_ci{
6903af6ab5fSopenharmony_ci    VirtualLoadVar::Expand(this, node, result);
6913af6ab5fSopenharmony_ci}
6923af6ab5fSopenharmony_ci
6933af6ab5fSopenharmony_civoid PandaGen::StoreAccToLexEnv(const ir::AstNode *node, const binder::ScopeFindResult &result, bool isDeclaration)
6943af6ab5fSopenharmony_ci{
6953af6ab5fSopenharmony_ci    VirtualStoreVar::Expand(this, node, result, isDeclaration);
6963af6ab5fSopenharmony_ci}
6973af6ab5fSopenharmony_ci
6983af6ab5fSopenharmony_civoid PandaGen::LoadAccumulatorString(const ir::AstNode *node, const util::StringView &str)
6993af6ab5fSopenharmony_ci{
7003af6ab5fSopenharmony_ci    ra_.Emit<LdaStr>(node, str);
7013af6ab5fSopenharmony_ci    strings_.insert(str);
7023af6ab5fSopenharmony_ci}
7033af6ab5fSopenharmony_ci
7043af6ab5fSopenharmony_civoid PandaGen::LoadAccumulatorFloat(const ir::AstNode *node, double num)
7053af6ab5fSopenharmony_ci{
7063af6ab5fSopenharmony_ci    ra_.Emit<Fldai>(node, num);
7073af6ab5fSopenharmony_ci}
7083af6ab5fSopenharmony_ci
7093af6ab5fSopenharmony_civoid PandaGen::LoadAccumulatorInt(const ir::AstNode *node, int32_t num)
7103af6ab5fSopenharmony_ci{
7113af6ab5fSopenharmony_ci    ra_.Emit<Ldai>(node, num);
7123af6ab5fSopenharmony_ci}
7133af6ab5fSopenharmony_ci
7143af6ab5fSopenharmony_civoid PandaGen::LoadAccumulatorInt(const ir::AstNode *node, size_t num)
7153af6ab5fSopenharmony_ci{
7163af6ab5fSopenharmony_ci    ra_.Emit<Ldai>(node, static_cast<int64_t>(num));
7173af6ab5fSopenharmony_ci}
7183af6ab5fSopenharmony_ci
7193af6ab5fSopenharmony_civoid PandaGen::LoadAccumulatorBigInt(const ir::AstNode *node, const util::StringView &num)
7203af6ab5fSopenharmony_ci{
7213af6ab5fSopenharmony_ci    ra_.Emit<Ldbigint>(node, num);
7223af6ab5fSopenharmony_ci    strings_.insert(num);
7233af6ab5fSopenharmony_ci}
7243af6ab5fSopenharmony_ci
7253af6ab5fSopenharmony_civoid PandaGen::StoreConst(const ir::AstNode *node, VReg reg, Constant id)
7263af6ab5fSopenharmony_ci{
7273af6ab5fSopenharmony_ci    LoadConst(node, id);
7283af6ab5fSopenharmony_ci    StoreAccumulator(node, reg);
7293af6ab5fSopenharmony_ci}
7303af6ab5fSopenharmony_ci
7313af6ab5fSopenharmony_civoid PandaGen::LoadConst(const ir::AstNode *node, Constant id)
7323af6ab5fSopenharmony_ci{
7333af6ab5fSopenharmony_ci    switch (id) {
7343af6ab5fSopenharmony_ci        case Constant::JS_HOLE: {
7353af6ab5fSopenharmony_ci            ra_.Emit<Ldhole>(node);
7363af6ab5fSopenharmony_ci            break;
7373af6ab5fSopenharmony_ci        }
7383af6ab5fSopenharmony_ci        case Constant::JS_NAN: {
7393af6ab5fSopenharmony_ci            ra_.Emit<Ldnan>(node);
7403af6ab5fSopenharmony_ci            break;
7413af6ab5fSopenharmony_ci        }
7423af6ab5fSopenharmony_ci        case Constant::JS_INFINITY: {
7433af6ab5fSopenharmony_ci            ra_.Emit<Ldinfinity>(node);
7443af6ab5fSopenharmony_ci            break;
7453af6ab5fSopenharmony_ci        }
7463af6ab5fSopenharmony_ci        case Constant::JS_GLOBAL: {
7473af6ab5fSopenharmony_ci            ra_.Emit<Ldglobal>(node);
7483af6ab5fSopenharmony_ci            break;
7493af6ab5fSopenharmony_ci        }
7503af6ab5fSopenharmony_ci        case Constant::JS_UNDEFINED: {
7513af6ab5fSopenharmony_ci            ra_.Emit<Ldundefined>(node);
7523af6ab5fSopenharmony_ci            break;
7533af6ab5fSopenharmony_ci        }
7543af6ab5fSopenharmony_ci        case Constant::JS_SYMBOL: {
7553af6ab5fSopenharmony_ci            ra_.Emit<Ldsymbol>(node);
7563af6ab5fSopenharmony_ci            break;
7573af6ab5fSopenharmony_ci        }
7583af6ab5fSopenharmony_ci        case Constant::JS_NULL: {
7593af6ab5fSopenharmony_ci            ra_.Emit<Ldnull>(node);
7603af6ab5fSopenharmony_ci            break;
7613af6ab5fSopenharmony_ci        }
7623af6ab5fSopenharmony_ci        case Constant::JS_TRUE: {
7633af6ab5fSopenharmony_ci            ra_.Emit<Ldtrue>(node);
7643af6ab5fSopenharmony_ci            break;
7653af6ab5fSopenharmony_ci        }
7663af6ab5fSopenharmony_ci        case Constant::JS_FALSE: {
7673af6ab5fSopenharmony_ci            ra_.Emit<Ldfalse>(node);
7683af6ab5fSopenharmony_ci            break;
7693af6ab5fSopenharmony_ci        }
7703af6ab5fSopenharmony_ci        default: {
7713af6ab5fSopenharmony_ci            UNREACHABLE();
7723af6ab5fSopenharmony_ci        }
7733af6ab5fSopenharmony_ci    }
7743af6ab5fSopenharmony_ci}
7753af6ab5fSopenharmony_ci
7763af6ab5fSopenharmony_civoid PandaGen::MoveVreg(const ir::AstNode *node, VReg vd, VReg vs)
7773af6ab5fSopenharmony_ci{
7783af6ab5fSopenharmony_ci    ra_.Emit<Mov>(node, vd, vs);
7793af6ab5fSopenharmony_ci}
7803af6ab5fSopenharmony_ci
7813af6ab5fSopenharmony_civoid PandaGen::SetLabel([[maybe_unused]] const ir::AstNode *node, Label *label)
7823af6ab5fSopenharmony_ci{
7833af6ab5fSopenharmony_ci    ra_.AddLabel(label);
7843af6ab5fSopenharmony_ci}
7853af6ab5fSopenharmony_ci
7863af6ab5fSopenharmony_civoid PandaGen::Branch(const ir::AstNode *node, Label *label)
7873af6ab5fSopenharmony_ci{
7883af6ab5fSopenharmony_ci    ra_.Emit<Jmp>(node, label);
7893af6ab5fSopenharmony_ci}
7903af6ab5fSopenharmony_ci
7913af6ab5fSopenharmony_cibool PandaGen::CheckControlFlowChange() const
7923af6ab5fSopenharmony_ci{
7933af6ab5fSopenharmony_ci    const auto *iter = dynamicContext_;
7943af6ab5fSopenharmony_ci
7953af6ab5fSopenharmony_ci    while (iter) {
7963af6ab5fSopenharmony_ci        if (iter->HasFinalizer()) {
7973af6ab5fSopenharmony_ci            return true;
7983af6ab5fSopenharmony_ci        }
7993af6ab5fSopenharmony_ci
8003af6ab5fSopenharmony_ci        iter = iter->Prev();
8013af6ab5fSopenharmony_ci    }
8023af6ab5fSopenharmony_ci
8033af6ab5fSopenharmony_ci    return false;
8043af6ab5fSopenharmony_ci}
8053af6ab5fSopenharmony_ci
8063af6ab5fSopenharmony_ciLabel *PandaGen::ControlFlowChangeBreak(const ir::Identifier *label)
8073af6ab5fSopenharmony_ci{
8083af6ab5fSopenharmony_ci    auto *iter = dynamicContext_;
8093af6ab5fSopenharmony_ci
8103af6ab5fSopenharmony_ci    util::StringView labelName = label ? label->Name() : LabelTarget::BREAK_LABEL;
8113af6ab5fSopenharmony_ci    Label *breakTarget = nullptr;
8123af6ab5fSopenharmony_ci
8133af6ab5fSopenharmony_ci    while (iter) {
8143af6ab5fSopenharmony_ci        iter->AbortContext(ControlFlowChange::BREAK, labelName);
8153af6ab5fSopenharmony_ci
8163af6ab5fSopenharmony_ci        const auto &labelTargetName = iter->Target().BreakLabel();
8173af6ab5fSopenharmony_ci
8183af6ab5fSopenharmony_ci        if (iter->Target().BreakTarget()) {
8193af6ab5fSopenharmony_ci            breakTarget = iter->Target().BreakTarget();
8203af6ab5fSopenharmony_ci        }
8213af6ab5fSopenharmony_ci
8223af6ab5fSopenharmony_ci        if (labelTargetName == labelName) {
8233af6ab5fSopenharmony_ci            break;
8243af6ab5fSopenharmony_ci        }
8253af6ab5fSopenharmony_ci
8263af6ab5fSopenharmony_ci        iter = iter->Prev();
8273af6ab5fSopenharmony_ci    }
8283af6ab5fSopenharmony_ci
8293af6ab5fSopenharmony_ci    return breakTarget;
8303af6ab5fSopenharmony_ci}
8313af6ab5fSopenharmony_ci
8323af6ab5fSopenharmony_ciLabel *PandaGen::ControlFlowChangeContinue(const ir::Identifier *label)
8333af6ab5fSopenharmony_ci{
8343af6ab5fSopenharmony_ci    auto *iter = dynamicContext_;
8353af6ab5fSopenharmony_ci    util::StringView labelName = label ? label->Name() : LabelTarget::CONTINUE_LABEL;
8363af6ab5fSopenharmony_ci    Label *continueTarget = nullptr;
8373af6ab5fSopenharmony_ci
8383af6ab5fSopenharmony_ci    while (iter) {
8393af6ab5fSopenharmony_ci        iter->AbortContext(ControlFlowChange::CONTINUE, labelName);
8403af6ab5fSopenharmony_ci
8413af6ab5fSopenharmony_ci        const auto &labelTargetName = iter->Target().ContinueLabel();
8423af6ab5fSopenharmony_ci
8433af6ab5fSopenharmony_ci        if (iter->Target().ContinueTarget()) {
8443af6ab5fSopenharmony_ci            continueTarget = iter->Target().ContinueTarget();
8453af6ab5fSopenharmony_ci        }
8463af6ab5fSopenharmony_ci
8473af6ab5fSopenharmony_ci        if (labelTargetName == labelName) {
8483af6ab5fSopenharmony_ci            break;
8493af6ab5fSopenharmony_ci        }
8503af6ab5fSopenharmony_ci
8513af6ab5fSopenharmony_ci        iter = iter->Prev();
8523af6ab5fSopenharmony_ci    }
8533af6ab5fSopenharmony_ci
8543af6ab5fSopenharmony_ci    return continueTarget;
8553af6ab5fSopenharmony_ci}
8563af6ab5fSopenharmony_ci
8573af6ab5fSopenharmony_civoid PandaGen::ControlFlowChangeReturn()
8583af6ab5fSopenharmony_ci{
8593af6ab5fSopenharmony_ci    auto *iter = dynamicContext_;
8603af6ab5fSopenharmony_ci    while (iter) {
8613af6ab5fSopenharmony_ci        iter->AbortContext(ControlFlowChange::BREAK, LabelTarget::RETURN_LABEL);
8623af6ab5fSopenharmony_ci        iter = iter->Prev();
8633af6ab5fSopenharmony_ci    }
8643af6ab5fSopenharmony_ci}
8653af6ab5fSopenharmony_ci
8663af6ab5fSopenharmony_civoid PandaGen::Condition(const ir::AstNode *node, lexer::TokenType op, VReg lhs, Label *ifFalse)
8673af6ab5fSopenharmony_ci{
8683af6ab5fSopenharmony_ci    switch (op) {
8693af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_EQUAL: {
8703af6ab5fSopenharmony_ci            Equal(node, lhs);
8713af6ab5fSopenharmony_ci            break;
8723af6ab5fSopenharmony_ci        }
8733af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: {
8743af6ab5fSopenharmony_ci            NotEqual(node, lhs);
8753af6ab5fSopenharmony_ci            break;
8763af6ab5fSopenharmony_ci        }
8773af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL: {
8783af6ab5fSopenharmony_ci            StrictEqual(node, lhs);
8793af6ab5fSopenharmony_ci            break;
8803af6ab5fSopenharmony_ci        }
8813af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL: {
8823af6ab5fSopenharmony_ci            StrictNotEqual(node, lhs);
8833af6ab5fSopenharmony_ci            break;
8843af6ab5fSopenharmony_ci        }
8853af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_LESS_THAN: {
8863af6ab5fSopenharmony_ci            LessThan(node, lhs);
8873af6ab5fSopenharmony_ci            break;
8883af6ab5fSopenharmony_ci        }
8893af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL: {
8903af6ab5fSopenharmony_ci            LessEqual(node, lhs);
8913af6ab5fSopenharmony_ci            break;
8923af6ab5fSopenharmony_ci        }
8933af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_GREATER_THAN: {
8943af6ab5fSopenharmony_ci            GreaterThan(node, lhs);
8953af6ab5fSopenharmony_ci            break;
8963af6ab5fSopenharmony_ci        }
8973af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL: {
8983af6ab5fSopenharmony_ci            GreaterEqual(node, lhs);
8993af6ab5fSopenharmony_ci            break;
9003af6ab5fSopenharmony_ci        }
9013af6ab5fSopenharmony_ci        default: {
9023af6ab5fSopenharmony_ci            UNREACHABLE();
9033af6ab5fSopenharmony_ci        }
9043af6ab5fSopenharmony_ci    }
9053af6ab5fSopenharmony_ci
9063af6ab5fSopenharmony_ci    ra_.Emit<Jeqz>(node, ifFalse);
9073af6ab5fSopenharmony_ci}
9083af6ab5fSopenharmony_ci
9093af6ab5fSopenharmony_civoid PandaGen::Unary(const ir::AstNode *node, lexer::TokenType op, VReg operand)
9103af6ab5fSopenharmony_ci{
9113af6ab5fSopenharmony_ci    switch (op) {
9123af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_PLUS: {
9133af6ab5fSopenharmony_ci            ToNumber(node, operand);
9143af6ab5fSopenharmony_ci            break;
9153af6ab5fSopenharmony_ci        }
9163af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_MINUS: {
9173af6ab5fSopenharmony_ci            LoadAccumulator(node, operand);
9183af6ab5fSopenharmony_ci            ra_.Emit<Neg>(node, 0);
9193af6ab5fSopenharmony_ci            break;
9203af6ab5fSopenharmony_ci        }
9213af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_TILDE: {
9223af6ab5fSopenharmony_ci            LoadAccumulator(node, operand);
9233af6ab5fSopenharmony_ci            ra_.Emit<Not>(node, 0);
9243af6ab5fSopenharmony_ci            break;
9253af6ab5fSopenharmony_ci        }
9263af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK: {
9273af6ab5fSopenharmony_ci            Negate(node);
9283af6ab5fSopenharmony_ci            break;
9293af6ab5fSopenharmony_ci        }
9303af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_PLUS_PLUS: {
9313af6ab5fSopenharmony_ci            LoadAccumulator(node, operand);
9323af6ab5fSopenharmony_ci            ra_.Emit<Inc>(node, 0);
9333af6ab5fSopenharmony_ci            break;
9343af6ab5fSopenharmony_ci        }
9353af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_MINUS_MINUS: {
9363af6ab5fSopenharmony_ci            LoadAccumulator(node, operand);
9373af6ab5fSopenharmony_ci            ra_.Emit<Dec>(node, 0);
9383af6ab5fSopenharmony_ci            break;
9393af6ab5fSopenharmony_ci        }
9403af6ab5fSopenharmony_ci        case lexer::TokenType::KEYW_VOID:
9413af6ab5fSopenharmony_ci        case lexer::TokenType::KEYW_DELETE: {
9423af6ab5fSopenharmony_ci            LoadConst(node, Constant::JS_UNDEFINED);
9433af6ab5fSopenharmony_ci            break;
9443af6ab5fSopenharmony_ci        }
9453af6ab5fSopenharmony_ci        default: {
9463af6ab5fSopenharmony_ci            UNREACHABLE();
9473af6ab5fSopenharmony_ci        }
9483af6ab5fSopenharmony_ci    }
9493af6ab5fSopenharmony_ci}
9503af6ab5fSopenharmony_ci
9513af6ab5fSopenharmony_civoid PandaGen::Binary(const ir::AstNode *node, lexer::TokenType op, VReg lhs)
9523af6ab5fSopenharmony_ci{
9533af6ab5fSopenharmony_ci    switch (op) {
9543af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_EQUAL: {
9553af6ab5fSopenharmony_ci            Equal(node, lhs);
9563af6ab5fSopenharmony_ci            break;
9573af6ab5fSopenharmony_ci        }
9583af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: {
9593af6ab5fSopenharmony_ci            NotEqual(node, lhs);
9603af6ab5fSopenharmony_ci            break;
9613af6ab5fSopenharmony_ci        }
9623af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL: {
9633af6ab5fSopenharmony_ci            StrictEqual(node, lhs);
9643af6ab5fSopenharmony_ci            break;
9653af6ab5fSopenharmony_ci        }
9663af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL: {
9673af6ab5fSopenharmony_ci            StrictNotEqual(node, lhs);
9683af6ab5fSopenharmony_ci            break;
9693af6ab5fSopenharmony_ci        }
9703af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_LESS_THAN: {
9713af6ab5fSopenharmony_ci            LessThan(node, lhs);
9723af6ab5fSopenharmony_ci            break;
9733af6ab5fSopenharmony_ci        }
9743af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL: {
9753af6ab5fSopenharmony_ci            LessEqual(node, lhs);
9763af6ab5fSopenharmony_ci            break;
9773af6ab5fSopenharmony_ci        }
9783af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_GREATER_THAN: {
9793af6ab5fSopenharmony_ci            GreaterThan(node, lhs);
9803af6ab5fSopenharmony_ci            break;
9813af6ab5fSopenharmony_ci        }
9823af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL: {
9833af6ab5fSopenharmony_ci            GreaterEqual(node, lhs);
9843af6ab5fSopenharmony_ci            break;
9853af6ab5fSopenharmony_ci        }
9863af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_PLUS:
9873af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_PLUS_EQUAL: {
9883af6ab5fSopenharmony_ci            ra_.Emit<Add2>(node, 0, lhs);
9893af6ab5fSopenharmony_ci            break;
9903af6ab5fSopenharmony_ci        }
9913af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_MINUS:
9923af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_MINUS_EQUAL: {
9933af6ab5fSopenharmony_ci            ra_.Emit<Sub2>(node, 0, lhs);
9943af6ab5fSopenharmony_ci            break;
9953af6ab5fSopenharmony_ci        }
9963af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_MULTIPLY:
9973af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_MULTIPLY_EQUAL: {
9983af6ab5fSopenharmony_ci            ra_.Emit<Mul2>(node, 0, lhs);
9993af6ab5fSopenharmony_ci            break;
10003af6ab5fSopenharmony_ci        }
10013af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_DIVIDE:
10023af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_DIVIDE_EQUAL: {
10033af6ab5fSopenharmony_ci            ra_.Emit<Div2>(node, 0, lhs);
10043af6ab5fSopenharmony_ci            break;
10053af6ab5fSopenharmony_ci        }
10063af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_MOD:
10073af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_MOD_EQUAL: {
10083af6ab5fSopenharmony_ci            ra_.Emit<Mod2>(node, 0, lhs);
10093af6ab5fSopenharmony_ci            break;
10103af6ab5fSopenharmony_ci        }
10113af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_EXPONENTIATION_EQUAL:
10123af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_EXPONENTIATION: {
10133af6ab5fSopenharmony_ci            ra_.Emit<Exp>(node, 0, lhs);
10143af6ab5fSopenharmony_ci            break;
10153af6ab5fSopenharmony_ci        }
10163af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT:
10173af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT_EQUAL: {
10183af6ab5fSopenharmony_ci            ra_.Emit<Shl2>(node, 0, lhs);
10193af6ab5fSopenharmony_ci            break;
10203af6ab5fSopenharmony_ci        }
10213af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT:
10223af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT_EQUAL: {
10233af6ab5fSopenharmony_ci            ra_.Emit<Ashr2>(node, 0, lhs);
10243af6ab5fSopenharmony_ci            break;
10253af6ab5fSopenharmony_ci        }
10263af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT:
10273af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT_EQUAL: {
10283af6ab5fSopenharmony_ci            ra_.Emit<Shr2>(node, 0, lhs);
10293af6ab5fSopenharmony_ci            break;
10303af6ab5fSopenharmony_ci        }
10313af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_BITWISE_AND:
10323af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_BITWISE_AND_EQUAL: {
10333af6ab5fSopenharmony_ci            ra_.Emit<And2>(node, 0, lhs);
10343af6ab5fSopenharmony_ci            break;
10353af6ab5fSopenharmony_ci        }
10363af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_BITWISE_OR:
10373af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_BITWISE_OR_EQUAL: {
10383af6ab5fSopenharmony_ci            ra_.Emit<Or2>(node, 0, lhs);
10393af6ab5fSopenharmony_ci            break;
10403af6ab5fSopenharmony_ci        }
10413af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_BITWISE_XOR:
10423af6ab5fSopenharmony_ci        case lexer::TokenType::PUNCTUATOR_BITWISE_XOR_EQUAL: {
10433af6ab5fSopenharmony_ci            ra_.Emit<Xor2>(node, 0, lhs);
10443af6ab5fSopenharmony_ci            break;
10453af6ab5fSopenharmony_ci        }
10463af6ab5fSopenharmony_ci        case lexer::TokenType::KEYW_IN: {
10473af6ab5fSopenharmony_ci            ra_.Emit<Isin>(node, 0, lhs);
10483af6ab5fSopenharmony_ci            break;
10493af6ab5fSopenharmony_ci        }
10503af6ab5fSopenharmony_ci        case lexer::TokenType::KEYW_INSTANCEOF: {
10513af6ab5fSopenharmony_ci            ra_.Emit<Instanceof>(node, 0, lhs);
10523af6ab5fSopenharmony_ci            break;
10533af6ab5fSopenharmony_ci        }
10543af6ab5fSopenharmony_ci        default: {
10553af6ab5fSopenharmony_ci            UNREACHABLE();
10563af6ab5fSopenharmony_ci        }
10573af6ab5fSopenharmony_ci    }
10583af6ab5fSopenharmony_ci}
10593af6ab5fSopenharmony_ci
10603af6ab5fSopenharmony_civoid PandaGen::Equal(const ir::AstNode *node, VReg lhs)
10613af6ab5fSopenharmony_ci{
10623af6ab5fSopenharmony_ci    ra_.Emit<Eq>(node, 0, lhs);
10633af6ab5fSopenharmony_ci}
10643af6ab5fSopenharmony_ci
10653af6ab5fSopenharmony_civoid PandaGen::NotEqual(const ir::AstNode *node, VReg lhs)
10663af6ab5fSopenharmony_ci{
10673af6ab5fSopenharmony_ci    ra_.Emit<Noteq>(node, 0, lhs);
10683af6ab5fSopenharmony_ci}
10693af6ab5fSopenharmony_ci
10703af6ab5fSopenharmony_civoid PandaGen::StrictEqual(const ir::AstNode *node, VReg lhs)
10713af6ab5fSopenharmony_ci{
10723af6ab5fSopenharmony_ci    ra_.Emit<Stricteq>(node, 0, lhs);
10733af6ab5fSopenharmony_ci}
10743af6ab5fSopenharmony_ci
10753af6ab5fSopenharmony_civoid PandaGen::StrictNotEqual(const ir::AstNode *node, VReg lhs)
10763af6ab5fSopenharmony_ci{
10773af6ab5fSopenharmony_ci    ra_.Emit<Strictnoteq>(node, 0, lhs);
10783af6ab5fSopenharmony_ci}
10793af6ab5fSopenharmony_ci
10803af6ab5fSopenharmony_civoid PandaGen::LessThan(const ir::AstNode *node, VReg lhs)
10813af6ab5fSopenharmony_ci{
10823af6ab5fSopenharmony_ci    ra_.Emit<Less>(node, 0, lhs);
10833af6ab5fSopenharmony_ci}
10843af6ab5fSopenharmony_ci
10853af6ab5fSopenharmony_civoid PandaGen::LessEqual(const ir::AstNode *node, VReg lhs)
10863af6ab5fSopenharmony_ci{
10873af6ab5fSopenharmony_ci    ra_.Emit<Lesseq>(node, 0, lhs);
10883af6ab5fSopenharmony_ci}
10893af6ab5fSopenharmony_ci
10903af6ab5fSopenharmony_civoid PandaGen::GreaterThan(const ir::AstNode *node, VReg lhs)
10913af6ab5fSopenharmony_ci{
10923af6ab5fSopenharmony_ci    ra_.Emit<Greater>(node, 0, lhs);
10933af6ab5fSopenharmony_ci}
10943af6ab5fSopenharmony_ci
10953af6ab5fSopenharmony_civoid PandaGen::GreaterEqual(const ir::AstNode *node, VReg lhs)
10963af6ab5fSopenharmony_ci{
10973af6ab5fSopenharmony_ci    ra_.Emit<Greatereq>(node, 0, lhs);
10983af6ab5fSopenharmony_ci}
10993af6ab5fSopenharmony_ci
11003af6ab5fSopenharmony_civoid PandaGen::IsTrue(const ir::AstNode *node)
11013af6ab5fSopenharmony_ci{
11023af6ab5fSopenharmony_ci    if (util::Helpers::IsDefaultApiVersion(Binder()->Program()->TargetApiVersion(),
11033af6ab5fSopenharmony_ci        Binder()->Program()->GetTargetApiSubVersion())) {
11043af6ab5fSopenharmony_ci        ra_.Emit<Istrue>(node);
11053af6ab5fSopenharmony_ci        return;
11063af6ab5fSopenharmony_ci    }
11073af6ab5fSopenharmony_ci
11083af6ab5fSopenharmony_ci    ra_.Emit<CallruntimeIstrue>(node, 0);
11093af6ab5fSopenharmony_ci}
11103af6ab5fSopenharmony_ci
11113af6ab5fSopenharmony_civoid PandaGen::BranchIfUndefined(const ir::AstNode *node, Label *target)
11123af6ab5fSopenharmony_ci{
11133af6ab5fSopenharmony_ci    RegScope rs(this);
11143af6ab5fSopenharmony_ci    VReg tmp = AllocReg();
11153af6ab5fSopenharmony_ci    StoreAccumulator(node, tmp);
11163af6ab5fSopenharmony_ci    LoadConst(node, Constant::JS_UNDEFINED);
11173af6ab5fSopenharmony_ci    Equal(node, tmp);
11183af6ab5fSopenharmony_ci    ra_.Emit<Jnez>(node, target);
11193af6ab5fSopenharmony_ci}
11203af6ab5fSopenharmony_ci
11213af6ab5fSopenharmony_civoid PandaGen::BranchIfStrictUndefined(const ir::AstNode *node, class Label *target)
11223af6ab5fSopenharmony_ci{
11233af6ab5fSopenharmony_ci    RegScope rs(this);
11243af6ab5fSopenharmony_ci    VReg tmp = AllocReg();
11253af6ab5fSopenharmony_ci    StoreAccumulator(node, tmp);
11263af6ab5fSopenharmony_ci    LoadConst(node, Constant::JS_UNDEFINED);
11273af6ab5fSopenharmony_ci    StrictEqual(node, tmp);
11283af6ab5fSopenharmony_ci    ra_.Emit<Jnez>(node, target);
11293af6ab5fSopenharmony_ci}
11303af6ab5fSopenharmony_ci
11313af6ab5fSopenharmony_civoid PandaGen::BranchIfNotUndefined(const ir::AstNode *node, Label *target)
11323af6ab5fSopenharmony_ci{
11333af6ab5fSopenharmony_ci    RegScope rs(this);
11343af6ab5fSopenharmony_ci    VReg tmp = AllocReg();
11353af6ab5fSopenharmony_ci    StoreAccumulator(node, tmp);
11363af6ab5fSopenharmony_ci    LoadConst(node, Constant::JS_UNDEFINED);
11373af6ab5fSopenharmony_ci    Equal(node, tmp);
11383af6ab5fSopenharmony_ci    ra_.Emit<Jeqz>(node, target);
11393af6ab5fSopenharmony_ci}
11403af6ab5fSopenharmony_ci
11413af6ab5fSopenharmony_civoid PandaGen::BranchIfStrictNotUndefined(const ir::AstNode *node, class Label *target)
11423af6ab5fSopenharmony_ci{
11433af6ab5fSopenharmony_ci    RegScope rs(this);
11443af6ab5fSopenharmony_ci    VReg tmp = AllocReg();
11453af6ab5fSopenharmony_ci    StoreAccumulator(node, tmp);
11463af6ab5fSopenharmony_ci    LoadConst(node, Constant::JS_UNDEFINED);
11473af6ab5fSopenharmony_ci    StrictEqual(node, tmp);
11483af6ab5fSopenharmony_ci    ra_.Emit<Jeqz>(node, target);
11493af6ab5fSopenharmony_ci}
11503af6ab5fSopenharmony_ci
11513af6ab5fSopenharmony_civoid PandaGen::BranchIfTrue(const ir::AstNode *node, Label *target)
11523af6ab5fSopenharmony_ci{
11533af6ab5fSopenharmony_ci    IsTrue(node);
11543af6ab5fSopenharmony_ci    ra_.Emit<Jnez>(node, target);
11553af6ab5fSopenharmony_ci}
11563af6ab5fSopenharmony_ci
11573af6ab5fSopenharmony_civoid PandaGen::BranchIfNotTrue(const ir::AstNode *node, Label *target)
11583af6ab5fSopenharmony_ci{
11593af6ab5fSopenharmony_ci    IsTrue(node);
11603af6ab5fSopenharmony_ci    BranchIfFalse(node, target);
11613af6ab5fSopenharmony_ci}
11623af6ab5fSopenharmony_ci
11633af6ab5fSopenharmony_civoid PandaGen::BranchIfFalse(const ir::AstNode *node, Label *target)
11643af6ab5fSopenharmony_ci{
11653af6ab5fSopenharmony_ci    if (util::Helpers::IsDefaultApiVersion(Binder()->Program()->TargetApiVersion(),
11663af6ab5fSopenharmony_ci        Binder()->Program()->GetTargetApiSubVersion())) {
11673af6ab5fSopenharmony_ci        ra_.Emit<Isfalse>(node);
11683af6ab5fSopenharmony_ci        ra_.Emit<Jnez>(node, target);
11693af6ab5fSopenharmony_ci        return;
11703af6ab5fSopenharmony_ci    }
11713af6ab5fSopenharmony_ci
11723af6ab5fSopenharmony_ci    ra_.Emit<CallruntimeIsfalse>(node, 0);
11733af6ab5fSopenharmony_ci    ra_.Emit<Jnez>(node, target);
11743af6ab5fSopenharmony_ci}
11753af6ab5fSopenharmony_ci
11763af6ab5fSopenharmony_civoid PandaGen::BranchIfStrictNull(const ir::AstNode *node, class Label *target)
11773af6ab5fSopenharmony_ci{
11783af6ab5fSopenharmony_ci    RegScope rs(this);
11793af6ab5fSopenharmony_ci    VReg tmp = AllocReg();
11803af6ab5fSopenharmony_ci    StoreAccumulator(node, tmp);
11813af6ab5fSopenharmony_ci    LoadConst(node, Constant::JS_NULL);
11823af6ab5fSopenharmony_ci    ra_.Emit<Stricteq>(node, 0, tmp);
11833af6ab5fSopenharmony_ci    ra_.Emit<Jnez>(node, target);
11843af6ab5fSopenharmony_ci}
11853af6ab5fSopenharmony_ci
11863af6ab5fSopenharmony_civoid PandaGen::EmitThrow(const ir::AstNode *node)
11873af6ab5fSopenharmony_ci{
11883af6ab5fSopenharmony_ci    ra_.Emit<Throw>(node);
11893af6ab5fSopenharmony_ci}
11903af6ab5fSopenharmony_ci
11913af6ab5fSopenharmony_civoid PandaGen::EmitRethrow(const ir::AstNode *node)
11923af6ab5fSopenharmony_ci{
11933af6ab5fSopenharmony_ci    RegScope rs(this);
11943af6ab5fSopenharmony_ci    auto *skipThrow = AllocLabel();
11953af6ab5fSopenharmony_ci    auto *doThrow = AllocLabel();
11963af6ab5fSopenharmony_ci
11973af6ab5fSopenharmony_ci    VReg exception = AllocReg();
11983af6ab5fSopenharmony_ci    StoreAccumulator(node, exception);
11993af6ab5fSopenharmony_ci
12003af6ab5fSopenharmony_ci    VReg hole = AllocReg();
12013af6ab5fSopenharmony_ci    StoreConst(node, hole, Constant::JS_HOLE);
12023af6ab5fSopenharmony_ci
12033af6ab5fSopenharmony_ci    LoadAccumulator(node, exception);
12043af6ab5fSopenharmony_ci    NotEqual(node, hole);
12053af6ab5fSopenharmony_ci    ra_.Emit<Jeqz>(node, skipThrow);
12063af6ab5fSopenharmony_ci
12073af6ab5fSopenharmony_ci    SetLabel(node, doThrow);
12083af6ab5fSopenharmony_ci    LoadAccumulator(node, exception);
12093af6ab5fSopenharmony_ci    EmitThrow(node);
12103af6ab5fSopenharmony_ci
12113af6ab5fSopenharmony_ci    SetLabel(node, skipThrow);
12123af6ab5fSopenharmony_ci}
12133af6ab5fSopenharmony_ci
12143af6ab5fSopenharmony_civoid PandaGen::EmitReturn(const ir::AstNode *node)
12153af6ab5fSopenharmony_ci{
12163af6ab5fSopenharmony_ci    ra_.Emit<Return>(node);
12173af6ab5fSopenharmony_ci}
12183af6ab5fSopenharmony_ci
12193af6ab5fSopenharmony_civoid PandaGen::EmitReturnUndefined(const ir::AstNode *node)
12203af6ab5fSopenharmony_ci{
12213af6ab5fSopenharmony_ci    ra_.Emit<Returnundefined>(node);
12223af6ab5fSopenharmony_ci}
12233af6ab5fSopenharmony_ci
12243af6ab5fSopenharmony_civoid PandaGen::ImplicitReturn(const ir::AstNode *node)
12253af6ab5fSopenharmony_ci{
12263af6ab5fSopenharmony_ci    builder_->ImplicitReturn(node);
12273af6ab5fSopenharmony_ci}
12283af6ab5fSopenharmony_ci
12293af6ab5fSopenharmony_civoid PandaGen::DirectReturn(const ir::AstNode *node)
12303af6ab5fSopenharmony_ci{
12313af6ab5fSopenharmony_ci    builder_->DirectReturn(node);
12323af6ab5fSopenharmony_ci}
12333af6ab5fSopenharmony_ci
12343af6ab5fSopenharmony_civoid PandaGen::ExplicitReturn(const ir::AstNode *node)
12353af6ab5fSopenharmony_ci{
12363af6ab5fSopenharmony_ci    builder_->ExplicitReturn(node);
12373af6ab5fSopenharmony_ci}
12383af6ab5fSopenharmony_ci
12393af6ab5fSopenharmony_civoid PandaGen::ValidateClassDirectReturn(const ir::AstNode *node)
12403af6ab5fSopenharmony_ci{
12413af6ab5fSopenharmony_ci    const ir::ScriptFunction *func = util::Helpers::GetContainingFunction(node);
12423af6ab5fSopenharmony_ci
12433af6ab5fSopenharmony_ci    if (!func || !func->IsConstructor()) {
12443af6ab5fSopenharmony_ci        return;
12453af6ab5fSopenharmony_ci    }
12463af6ab5fSopenharmony_ci
12473af6ab5fSopenharmony_ci    RegScope rs(this);
12483af6ab5fSopenharmony_ci    VReg value = AllocReg();
12493af6ab5fSopenharmony_ci    StoreAccumulator(node, value);
12503af6ab5fSopenharmony_ci
12513af6ab5fSopenharmony_ci    auto *notUndefined = AllocLabel();
12523af6ab5fSopenharmony_ci    auto *condEnd = AllocLabel();
12533af6ab5fSopenharmony_ci
12543af6ab5fSopenharmony_ci    BranchIfStrictNotUndefined(node, notUndefined);
12553af6ab5fSopenharmony_ci    GetThis(func);
12563af6ab5fSopenharmony_ci    ThrowIfSuperNotCorrectCall(func, 0);
12573af6ab5fSopenharmony_ci    Branch(node, condEnd);
12583af6ab5fSopenharmony_ci
12593af6ab5fSopenharmony_ci    SetLabel(node, notUndefined);
12603af6ab5fSopenharmony_ci    LoadAccumulator(node, value);
12613af6ab5fSopenharmony_ci
12623af6ab5fSopenharmony_ci    SetLabel(node, condEnd);
12633af6ab5fSopenharmony_ci}
12643af6ab5fSopenharmony_ci
12653af6ab5fSopenharmony_civoid PandaGen::EmitAwait(const ir::AstNode *node)
12663af6ab5fSopenharmony_ci{
12673af6ab5fSopenharmony_ci    builder_->Await(node);
12683af6ab5fSopenharmony_ci}
12693af6ab5fSopenharmony_ci
12703af6ab5fSopenharmony_civoid PandaGen::CallThis(const ir::AstNode *node, VReg startReg, size_t argCount)
12713af6ab5fSopenharmony_ci{
12723af6ab5fSopenharmony_ci    LoadAccumulator(node, startReg); // callee is load to acc
12733af6ab5fSopenharmony_ci    VReg thisReg = startReg + 1; // This dependency is used in other places, do not modify.
12743af6ab5fSopenharmony_ci    switch (argCount) {
12753af6ab5fSopenharmony_ci        case 1: { // no args
12763af6ab5fSopenharmony_ci            ra_.Emit<Callthis0>(node, 0, thisReg);
12773af6ab5fSopenharmony_ci            break;
12783af6ab5fSopenharmony_ci        }
12793af6ab5fSopenharmony_ci        case 2: { // 1 arg
12803af6ab5fSopenharmony_ci            VReg arg0 = thisReg + 1;
12813af6ab5fSopenharmony_ci            ra_.Emit<Callthis1>(node, 0, thisReg, arg0);
12823af6ab5fSopenharmony_ci            break;
12833af6ab5fSopenharmony_ci        }
12843af6ab5fSopenharmony_ci        case 3: { // 2 args
12853af6ab5fSopenharmony_ci            VReg arg0 = thisReg + 1;
12863af6ab5fSopenharmony_ci            VReg arg1 = arg0 + 1;
12873af6ab5fSopenharmony_ci            ra_.Emit<Callthis2>(node, 0, thisReg, arg0, arg1);
12883af6ab5fSopenharmony_ci            break;
12893af6ab5fSopenharmony_ci        }
12903af6ab5fSopenharmony_ci        case 4: { // 3 args
12913af6ab5fSopenharmony_ci            VReg arg0 = thisReg + 1;
12923af6ab5fSopenharmony_ci            VReg arg1 = arg0 + 1;
12933af6ab5fSopenharmony_ci            VReg arg2 = arg1 + 1;
12943af6ab5fSopenharmony_ci            ra_.Emit<Callthis3>(node, 0, thisReg, arg0, arg1, arg2);
12953af6ab5fSopenharmony_ci            break;
12963af6ab5fSopenharmony_ci        }
12973af6ab5fSopenharmony_ci        default: {
12983af6ab5fSopenharmony_ci            int64_t actualArgs = static_cast<int64_t>(argCount) - 1;
12993af6ab5fSopenharmony_ci            if (actualArgs <= util::Helpers::MAX_INT8) {
13003af6ab5fSopenharmony_ci                ra_.EmitRange<Callthisrange>(node, argCount, 0, actualArgs, thisReg);
13013af6ab5fSopenharmony_ci                break;
13023af6ab5fSopenharmony_ci            }
13033af6ab5fSopenharmony_ci
13043af6ab5fSopenharmony_ci            ra_.EmitRange<WideCallthisrange>(node, argCount, actualArgs, thisReg);
13053af6ab5fSopenharmony_ci            break;
13063af6ab5fSopenharmony_ci        }
13073af6ab5fSopenharmony_ci    }
13083af6ab5fSopenharmony_ci}
13093af6ab5fSopenharmony_ci
13103af6ab5fSopenharmony_civoid PandaGen::Call(const ir::AstNode *node, VReg startReg, size_t argCount)
13113af6ab5fSopenharmony_ci{
13123af6ab5fSopenharmony_ci    LoadAccumulator(node, startReg); // callee is load to acc
13133af6ab5fSopenharmony_ci    switch (argCount) {
13143af6ab5fSopenharmony_ci        case 0: { // 0 args
13153af6ab5fSopenharmony_ci            ra_.Emit<Callarg0>(node, 0);
13163af6ab5fSopenharmony_ci            break;
13173af6ab5fSopenharmony_ci        }
13183af6ab5fSopenharmony_ci        case 1: { // 1 arg
13193af6ab5fSopenharmony_ci            VReg arg0 = startReg + 1;
13203af6ab5fSopenharmony_ci            ra_.Emit<Callarg1>(node, 0, arg0);
13213af6ab5fSopenharmony_ci            break;
13223af6ab5fSopenharmony_ci        }
13233af6ab5fSopenharmony_ci        case 2: { // 2 args
13243af6ab5fSopenharmony_ci            VReg arg0 = startReg + 1;
13253af6ab5fSopenharmony_ci            VReg arg1 = arg0 + 1;
13263af6ab5fSopenharmony_ci            ra_.Emit<Callargs2>(node, 0, arg0, arg1);
13273af6ab5fSopenharmony_ci            break;
13283af6ab5fSopenharmony_ci        }
13293af6ab5fSopenharmony_ci        case 3: { // 3 args
13303af6ab5fSopenharmony_ci            VReg arg0 = startReg + 1;
13313af6ab5fSopenharmony_ci            VReg arg1 = arg0 + 1;
13323af6ab5fSopenharmony_ci            VReg arg2 = arg1 + 1;
13333af6ab5fSopenharmony_ci            ra_.Emit<Callargs3>(node, 0, arg0, arg1, arg2);
13343af6ab5fSopenharmony_ci            break;
13353af6ab5fSopenharmony_ci        }
13363af6ab5fSopenharmony_ci        default: {
13373af6ab5fSopenharmony_ci            VReg arg0 = startReg + 1;
13383af6ab5fSopenharmony_ci            if (argCount <= util::Helpers::MAX_INT8) {
13393af6ab5fSopenharmony_ci                ra_.EmitRange<Callrange>(node, argCount, 0, argCount, arg0);
13403af6ab5fSopenharmony_ci                break;
13413af6ab5fSopenharmony_ci            }
13423af6ab5fSopenharmony_ci
13433af6ab5fSopenharmony_ci            ra_.EmitRange<WideCallrange>(node, argCount, argCount, arg0);
13443af6ab5fSopenharmony_ci            break;
13453af6ab5fSopenharmony_ci        }
13463af6ab5fSopenharmony_ci    }
13473af6ab5fSopenharmony_ci}
13483af6ab5fSopenharmony_ci
13493af6ab5fSopenharmony_civoid PandaGen::SuperCall(const ir::AstNode *node, VReg startReg, size_t argCount)
13503af6ab5fSopenharmony_ci{
13513af6ab5fSopenharmony_ci    if (RootNode()->AsScriptFunction()->IsArrow()) {
13523af6ab5fSopenharmony_ci        GetFunctionObject(node); // load funcobj to acc for super call in arrow function
13533af6ab5fSopenharmony_ci        if (argCount <= util::Helpers::MAX_INT8) {
13543af6ab5fSopenharmony_ci            ra_.EmitRange<Supercallarrowrange>(node, argCount, 0, static_cast<int64_t>(argCount), startReg);
13553af6ab5fSopenharmony_ci        } else {
13563af6ab5fSopenharmony_ci            ra_.EmitRange<WideSupercallarrowrange>(node, argCount, static_cast<int64_t>(argCount), startReg);
13573af6ab5fSopenharmony_ci        }
13583af6ab5fSopenharmony_ci        return;
13593af6ab5fSopenharmony_ci    }
13603af6ab5fSopenharmony_ci
13613af6ab5fSopenharmony_ci    if (argCount <= util::Helpers::MAX_INT8) {
13623af6ab5fSopenharmony_ci        // no need to load funcobj to acc for super call in other kinds of functions
13633af6ab5fSopenharmony_ci        ra_.EmitRange<Supercallthisrange>(node, argCount, 0, static_cast<int64_t>(argCount), startReg);
13643af6ab5fSopenharmony_ci        return;
13653af6ab5fSopenharmony_ci    }
13663af6ab5fSopenharmony_ci
13673af6ab5fSopenharmony_ci    ra_.EmitRange<WideSupercallthisrange>(node, argCount, static_cast<int64_t>(argCount), startReg);
13683af6ab5fSopenharmony_ci}
13693af6ab5fSopenharmony_ci
13703af6ab5fSopenharmony_civoid PandaGen::SuperCallSpread(const ir::AstNode *node, VReg vs)
13713af6ab5fSopenharmony_ci{
13723af6ab5fSopenharmony_ci    ra_.Emit<Supercallspread>(node, 0, vs);
13733af6ab5fSopenharmony_ci}
13743af6ab5fSopenharmony_ci
13753af6ab5fSopenharmony_civoid PandaGen::SuperCallForwardAllArgs(const ir::AstNode *node, VReg funcObj)
13763af6ab5fSopenharmony_ci{
13773af6ab5fSopenharmony_ci    ra_.Emit<CallruntimeSupercallforwardallargs>(node, funcObj);
13783af6ab5fSopenharmony_ci}
13793af6ab5fSopenharmony_ci
13803af6ab5fSopenharmony_civoid PandaGen::NotifyConcurrentResult(const ir::AstNode *node)
13813af6ab5fSopenharmony_ci{
13823af6ab5fSopenharmony_ci    if (IsConcurrent()) {
13833af6ab5fSopenharmony_ci        ra_.Emit<CallruntimeNotifyconcurrentresult>(node);
13843af6ab5fSopenharmony_ci    }
13853af6ab5fSopenharmony_ci}
13863af6ab5fSopenharmony_ci
13873af6ab5fSopenharmony_civoid PandaGen::CallInit(const ir::AstNode *node, VReg thisReg)
13883af6ab5fSopenharmony_ci{
13893af6ab5fSopenharmony_ci    // callee is in acc
13903af6ab5fSopenharmony_ci    ra_.Emit<CallruntimeCallinit>(node, 0, thisReg);
13913af6ab5fSopenharmony_ci}
13923af6ab5fSopenharmony_ci
13933af6ab5fSopenharmony_civoid PandaGen::NewObject(const ir::AstNode *node, VReg startReg, size_t argCount)
13943af6ab5fSopenharmony_ci{
13953af6ab5fSopenharmony_ci    if (argCount <= util::Helpers::MAX_INT8) {
13963af6ab5fSopenharmony_ci        ra_.EmitRange<Newobjrange>(node, argCount, 0, static_cast<int64_t>(argCount), startReg);
13973af6ab5fSopenharmony_ci        return;
13983af6ab5fSopenharmony_ci    }
13993af6ab5fSopenharmony_ci
14003af6ab5fSopenharmony_ci    ra_.EmitRange<WideNewobjrange>(node, argCount, static_cast<int64_t>(argCount), startReg);
14013af6ab5fSopenharmony_ci}
14023af6ab5fSopenharmony_ci
14033af6ab5fSopenharmony_civoid PandaGen::DefineFunction(const ir::AstNode *node, const ir::ScriptFunction *realNode, const util::StringView &name)
14043af6ab5fSopenharmony_ci{
14053af6ab5fSopenharmony_ci    if (realNode->IsOverload() || realNode->Declare()) {
14063af6ab5fSopenharmony_ci        return;
14073af6ab5fSopenharmony_ci    }
14083af6ab5fSopenharmony_ci
14093af6ab5fSopenharmony_ci    auto formalParamCnt = realNode->FormalParamsLength();
14103af6ab5fSopenharmony_ci    if (realNode->IsMethod()) {
14113af6ab5fSopenharmony_ci        ra_.Emit<Definemethod>(node, 0, name, static_cast<int64_t>(formalParamCnt));
14123af6ab5fSopenharmony_ci    } else  {
14133af6ab5fSopenharmony_ci        ra_.Emit<Definefunc>(node, 0, name, static_cast<int64_t>(formalParamCnt));
14143af6ab5fSopenharmony_ci    }
14153af6ab5fSopenharmony_ci
14163af6ab5fSopenharmony_ci    strings_.insert(name);
14173af6ab5fSopenharmony_ci}
14183af6ab5fSopenharmony_ci
14193af6ab5fSopenharmony_civoid PandaGen::TypeOf(const ir::AstNode *node)
14203af6ab5fSopenharmony_ci{
14213af6ab5fSopenharmony_ci    ra_.Emit<Typeof>(node, 0);
14223af6ab5fSopenharmony_ci}
14233af6ab5fSopenharmony_ci
14243af6ab5fSopenharmony_civoid PandaGen::CallSpread(const ir::AstNode *node, VReg func, VReg thisReg, VReg args)
14253af6ab5fSopenharmony_ci{
14263af6ab5fSopenharmony_ci    LoadAccumulator(node, func); // callee is load to acc
14273af6ab5fSopenharmony_ci    ra_.Emit<Apply>(node, 0, thisReg, args);
14283af6ab5fSopenharmony_ci}
14293af6ab5fSopenharmony_ci
14303af6ab5fSopenharmony_civoid PandaGen::NewObjSpread(const ir::AstNode *node, VReg obj)
14313af6ab5fSopenharmony_ci{
14323af6ab5fSopenharmony_ci    ra_.Emit<Newobjapply>(node, 0, obj);
14333af6ab5fSopenharmony_ci}
14343af6ab5fSopenharmony_ci
14353af6ab5fSopenharmony_civoid PandaGen::GetUnmappedArgs(const ir::AstNode *node)
14363af6ab5fSopenharmony_ci{
14373af6ab5fSopenharmony_ci    ra_.Emit<Getunmappedargs>(node);
14383af6ab5fSopenharmony_ci}
14393af6ab5fSopenharmony_ci
14403af6ab5fSopenharmony_civoid PandaGen::Negate(const ir::AstNode *node)
14413af6ab5fSopenharmony_ci{
14423af6ab5fSopenharmony_ci    auto *falseLabel = AllocLabel();
14433af6ab5fSopenharmony_ci    auto *endLabel = AllocLabel();
14443af6ab5fSopenharmony_ci    BranchIfTrue(node, falseLabel);
14453af6ab5fSopenharmony_ci    LoadConst(node, Constant::JS_TRUE);
14463af6ab5fSopenharmony_ci    Branch(node, endLabel);
14473af6ab5fSopenharmony_ci    SetLabel(node, falseLabel);
14483af6ab5fSopenharmony_ci    LoadConst(node, Constant::JS_FALSE);
14493af6ab5fSopenharmony_ci    SetLabel(node, endLabel);
14503af6ab5fSopenharmony_ci}
14513af6ab5fSopenharmony_ci
14523af6ab5fSopenharmony_civoid PandaGen::ToNumber(const ir::AstNode *node, VReg arg)
14533af6ab5fSopenharmony_ci{
14543af6ab5fSopenharmony_ci    LoadAccumulator(node, arg);
14553af6ab5fSopenharmony_ci    ra_.Emit<Tonumber>(node, 0);
14563af6ab5fSopenharmony_ci}
14573af6ab5fSopenharmony_ci
14583af6ab5fSopenharmony_civoid PandaGen::ToNumeric(const ir::AstNode *node, VReg arg)
14593af6ab5fSopenharmony_ci{
14603af6ab5fSopenharmony_ci    LoadAccumulator(node, arg);
14613af6ab5fSopenharmony_ci    ra_.Emit<Tonumeric>(node, 0);
14623af6ab5fSopenharmony_ci}
14633af6ab5fSopenharmony_ci
14643af6ab5fSopenharmony_civoid PandaGen::CreateGeneratorObj(const ir::AstNode *node, VReg funcObj)
14653af6ab5fSopenharmony_ci{
14663af6ab5fSopenharmony_ci    ra_.Emit<Creategeneratorobj>(node, funcObj);
14673af6ab5fSopenharmony_ci}
14683af6ab5fSopenharmony_ci
14693af6ab5fSopenharmony_civoid PandaGen::CreateAsyncGeneratorObj(const ir::AstNode *node, VReg funcObj)
14703af6ab5fSopenharmony_ci{
14713af6ab5fSopenharmony_ci    ra_.Emit<Createasyncgeneratorobj>(node, funcObj);
14723af6ab5fSopenharmony_ci}
14733af6ab5fSopenharmony_ci
14743af6ab5fSopenharmony_civoid PandaGen::CreateIterResultObject(const ir::AstNode *node, VReg value, VReg done)
14753af6ab5fSopenharmony_ci{
14763af6ab5fSopenharmony_ci    ra_.Emit<Createiterresultobj>(node, value, done);
14773af6ab5fSopenharmony_ci}
14783af6ab5fSopenharmony_ci
14793af6ab5fSopenharmony_civoid PandaGen::SuspendGenerator(const ir::AstNode *node, VReg genObj)
14803af6ab5fSopenharmony_ci{
14813af6ab5fSopenharmony_ci    ra_.Emit<Suspendgenerator>(node, genObj); // iterResult is in acc
14823af6ab5fSopenharmony_ci}
14833af6ab5fSopenharmony_ci
14843af6ab5fSopenharmony_civoid PandaGen::GeneratorYield(const ir::AstNode *node, VReg genObj)
14853af6ab5fSopenharmony_ci{
14863af6ab5fSopenharmony_ci    LoadAccumulator(node, genObj);
14873af6ab5fSopenharmony_ci    ra_.Emit<Setgeneratorstate>(node, static_cast<int32_t>(GeneratorState::SUSPENDED_YIELD));
14883af6ab5fSopenharmony_ci}
14893af6ab5fSopenharmony_ci
14903af6ab5fSopenharmony_civoid PandaGen::GeneratorComplete(const ir::AstNode *node, VReg genObj)
14913af6ab5fSopenharmony_ci{
14923af6ab5fSopenharmony_ci    LoadAccumulator(node, genObj);
14933af6ab5fSopenharmony_ci    ra_.Emit<Setgeneratorstate>(node, static_cast<int32_t>(GeneratorState::COMPLETED));
14943af6ab5fSopenharmony_ci}
14953af6ab5fSopenharmony_ci
14963af6ab5fSopenharmony_civoid PandaGen::ResumeGenerator(const ir::AstNode *node, VReg genObj)
14973af6ab5fSopenharmony_ci{
14983af6ab5fSopenharmony_ci    LoadAccumulator(node, genObj);
14993af6ab5fSopenharmony_ci    ra_.Emit<Resumegenerator>(node);
15003af6ab5fSopenharmony_ci}
15013af6ab5fSopenharmony_ci
15023af6ab5fSopenharmony_civoid PandaGen::GetResumeMode(const ir::AstNode *node, VReg genObj)
15033af6ab5fSopenharmony_ci{
15043af6ab5fSopenharmony_ci    LoadAccumulator(node, genObj);
15053af6ab5fSopenharmony_ci    ra_.Emit<Getresumemode>(node);
15063af6ab5fSopenharmony_ci}
15073af6ab5fSopenharmony_ci
15083af6ab5fSopenharmony_civoid PandaGen::AsyncFunctionEnter(const ir::AstNode *node)
15093af6ab5fSopenharmony_ci{
15103af6ab5fSopenharmony_ci    ra_.Emit<Asyncfunctionenter>(node);
15113af6ab5fSopenharmony_ci}
15123af6ab5fSopenharmony_ci
15133af6ab5fSopenharmony_civoid PandaGen::AsyncFunctionAwait(const ir::AstNode *node, VReg asyncFuncObj)
15143af6ab5fSopenharmony_ci{
15153af6ab5fSopenharmony_ci    ra_.Emit<Asyncfunctionawaituncaught>(node, asyncFuncObj); // receivedValue is in acc
15163af6ab5fSopenharmony_ci}
15173af6ab5fSopenharmony_ci
15183af6ab5fSopenharmony_civoid PandaGen::AsyncFunctionResolve(const ir::AstNode *node, VReg asyncFuncObj)
15193af6ab5fSopenharmony_ci{
15203af6ab5fSopenharmony_ci    ra_.Emit<Asyncfunctionresolve>(node, asyncFuncObj); // use retVal in acc
15213af6ab5fSopenharmony_ci}
15223af6ab5fSopenharmony_ci
15233af6ab5fSopenharmony_civoid PandaGen::AsyncFunctionReject(const ir::AstNode *node, VReg asyncFuncObj)
15243af6ab5fSopenharmony_ci{
15253af6ab5fSopenharmony_ci    ra_.Emit<Asyncfunctionreject>(node, asyncFuncObj); // exception is in acc
15263af6ab5fSopenharmony_ci}
15273af6ab5fSopenharmony_ci
15283af6ab5fSopenharmony_civoid PandaGen::AsyncGeneratorResolve(const ir::AstNode *node, VReg asyncGenObj, VReg value, VReg canSuspend)
15293af6ab5fSopenharmony_ci{
15303af6ab5fSopenharmony_ci    ra_.Emit<Asyncgeneratorresolve>(node, asyncGenObj, value, canSuspend);
15313af6ab5fSopenharmony_ci}
15323af6ab5fSopenharmony_ci
15333af6ab5fSopenharmony_civoid PandaGen::AsyncGeneratorReject(const ir::AstNode *node, VReg asyncGenObj)
15343af6ab5fSopenharmony_ci{
15353af6ab5fSopenharmony_ci    ra_.Emit<Asyncgeneratorreject>(node, asyncGenObj); // value is in acc
15363af6ab5fSopenharmony_ci}
15373af6ab5fSopenharmony_ci
15383af6ab5fSopenharmony_civoid PandaGen::GetTemplateObject(const ir::AstNode *node, VReg value)
15393af6ab5fSopenharmony_ci{
15403af6ab5fSopenharmony_ci    LoadAccumulator(node, value);
15413af6ab5fSopenharmony_ci    ra_.Emit<Gettemplateobject>(node, 0);
15423af6ab5fSopenharmony_ci}
15433af6ab5fSopenharmony_ci
15443af6ab5fSopenharmony_civoid PandaGen::CopyRestArgs(const ir::AstNode *node, uint32_t index)
15453af6ab5fSopenharmony_ci{
15463af6ab5fSopenharmony_ci    index <= util::Helpers::MAX_INT8 ? ra_.Emit<Copyrestargs>(node, index) : ra_.Emit<WideCopyrestargs>(node, index);
15473af6ab5fSopenharmony_ci}
15483af6ab5fSopenharmony_ci
15493af6ab5fSopenharmony_civoid PandaGen::GetPropIterator(const ir::AstNode *node)
15503af6ab5fSopenharmony_ci{
15513af6ab5fSopenharmony_ci    ra_.Emit<Getpropiterator>(node);
15523af6ab5fSopenharmony_ci}
15533af6ab5fSopenharmony_ci
15543af6ab5fSopenharmony_civoid PandaGen::GetNextPropName(const ir::AstNode *node, VReg iter)
15553af6ab5fSopenharmony_ci{
15563af6ab5fSopenharmony_ci    ra_.Emit<Getnextpropname>(node, iter);
15573af6ab5fSopenharmony_ci}
15583af6ab5fSopenharmony_ci
15593af6ab5fSopenharmony_civoid PandaGen::CreateEmptyObject(const ir::AstNode *node)
15603af6ab5fSopenharmony_ci{
15613af6ab5fSopenharmony_ci    ra_.Emit<Createemptyobject>(node);
15623af6ab5fSopenharmony_ci}
15633af6ab5fSopenharmony_ci
15643af6ab5fSopenharmony_civoid PandaGen::CreateObjectWithBuffer(const ir::AstNode *node, uint32_t idx)
15653af6ab5fSopenharmony_ci{
15663af6ab5fSopenharmony_ci    ASSERT(util::Helpers::IsInteger<uint32_t>(idx));
15673af6ab5fSopenharmony_ci    std::string idxStr = std::string(context_->Binder()->Program()->RecordName()) + "_" + std::to_string(idx);
15683af6ab5fSopenharmony_ci    util::UString litId(idxStr, allocator_);
15693af6ab5fSopenharmony_ci    ra_.Emit<Createobjectwithbuffer>(node, 0, litId.View());
15703af6ab5fSopenharmony_ci}
15713af6ab5fSopenharmony_ci
15723af6ab5fSopenharmony_civoid PandaGen::SetObjectWithProto(const ir::AstNode *node, VReg proto, VReg obj)
15733af6ab5fSopenharmony_ci{
15743af6ab5fSopenharmony_ci    LoadAccumulator(node, obj);
15753af6ab5fSopenharmony_ci    ra_.Emit<Setobjectwithproto>(node, 0, proto);
15763af6ab5fSopenharmony_ci}
15773af6ab5fSopenharmony_ci
15783af6ab5fSopenharmony_civoid PandaGen::CopyDataProperties(const ir::AstNode *node, VReg dst)
15793af6ab5fSopenharmony_ci{
15803af6ab5fSopenharmony_ci    ra_.Emit<Copydataproperties>(node, dst); // use acc as srcObj
15813af6ab5fSopenharmony_ci}
15823af6ab5fSopenharmony_ci
15833af6ab5fSopenharmony_civoid PandaGen::DefineGetterSetterByValue(const ir::AstNode *node, VReg obj, VReg name, VReg getter, VReg setter,
15843af6ab5fSopenharmony_ci                                         bool setName)
15853af6ab5fSopenharmony_ci{
15863af6ab5fSopenharmony_ci    LoadConst(node, setName ? Constant::JS_TRUE : Constant::JS_FALSE);
15873af6ab5fSopenharmony_ci    ra_.Emit<Definegettersetterbyvalue>(node, obj, name, getter, setter);
15883af6ab5fSopenharmony_ci}
15893af6ab5fSopenharmony_ci
15903af6ab5fSopenharmony_civoid PandaGen::CreateEmptyArray(const ir::AstNode *node)
15913af6ab5fSopenharmony_ci{
15923af6ab5fSopenharmony_ci    ra_.Emit<Createemptyarray>(node, 0);
15933af6ab5fSopenharmony_ci}
15943af6ab5fSopenharmony_ci
15953af6ab5fSopenharmony_civoid PandaGen::CreateArrayWithBuffer(const ir::AstNode *node, uint32_t idx)
15963af6ab5fSopenharmony_ci{
15973af6ab5fSopenharmony_ci    ASSERT(util::Helpers::IsInteger<uint32_t>(idx));
15983af6ab5fSopenharmony_ci    std::string idxStr = std::string(context_->Binder()->Program()->RecordName()) + "_" + std::to_string(idx);
15993af6ab5fSopenharmony_ci    util::UString litId(idxStr, allocator_);
16003af6ab5fSopenharmony_ci    ra_.Emit<Createarraywithbuffer>(node, 0, litId.View());
16013af6ab5fSopenharmony_ci}
16023af6ab5fSopenharmony_ci
16033af6ab5fSopenharmony_civoid PandaGen::CreateArray(const ir::AstNode *node, const ArenaVector<ir::Expression *> &elements, VReg obj)
16043af6ab5fSopenharmony_ci{
16053af6ab5fSopenharmony_ci    if (elements.empty()) {
16063af6ab5fSopenharmony_ci        CreateEmptyArray(node);
16073af6ab5fSopenharmony_ci        StoreAccumulator(node, obj);
16083af6ab5fSopenharmony_ci        return;
16093af6ab5fSopenharmony_ci    }
16103af6ab5fSopenharmony_ci
16113af6ab5fSopenharmony_ci    auto *buf = NewLiteralBuffer();
16123af6ab5fSopenharmony_ci
16133af6ab5fSopenharmony_ci    size_t i = 0;
16143af6ab5fSopenharmony_ci    // This loop handles constant literal data by collecting it into a literal buffer
16153af6ab5fSopenharmony_ci    // until a non-constant element is encountered.
16163af6ab5fSopenharmony_ci    while (i < elements.size() && util::Helpers::IsConstantExpr(elements[i])) {
16173af6ab5fSopenharmony_ci        buf->Add(elements[i]->AsLiteral());
16183af6ab5fSopenharmony_ci        i++;
16193af6ab5fSopenharmony_ci    }
16203af6ab5fSopenharmony_ci
16213af6ab5fSopenharmony_ci    if (buf->IsEmpty()) {
16223af6ab5fSopenharmony_ci        CreateEmptyArray(node);
16233af6ab5fSopenharmony_ci    } else {
16243af6ab5fSopenharmony_ci        uint32_t bufIdx = static_cast<uint32_t>(AddLiteralBuffer(buf));
16253af6ab5fSopenharmony_ci        CreateArrayWithBuffer(node, bufIdx);
16263af6ab5fSopenharmony_ci    }
16273af6ab5fSopenharmony_ci
16283af6ab5fSopenharmony_ci    StoreAccumulator(node, obj);
16293af6ab5fSopenharmony_ci
16303af6ab5fSopenharmony_ci    if (i == elements.size()) {
16313af6ab5fSopenharmony_ci        return;
16323af6ab5fSopenharmony_ci    }
16333af6ab5fSopenharmony_ci
16343af6ab5fSopenharmony_ci    bool hasSpread = false;
16353af6ab5fSopenharmony_ci
16363af6ab5fSopenharmony_ci    // This loop handles array elements until a spread element is encountered
16373af6ab5fSopenharmony_ci    for (; i < elements.size(); i++) {
16383af6ab5fSopenharmony_ci        const ir::Expression *elem = elements[i];
16393af6ab5fSopenharmony_ci
16403af6ab5fSopenharmony_ci        if (elem->IsOmittedExpression()) {
16413af6ab5fSopenharmony_ci            continue;
16423af6ab5fSopenharmony_ci        }
16433af6ab5fSopenharmony_ci
16443af6ab5fSopenharmony_ci        if (elem->IsSpreadElement()) {
16453af6ab5fSopenharmony_ci            // The next loop will handle arrays that have a spread element
16463af6ab5fSopenharmony_ci            hasSpread = true;
16473af6ab5fSopenharmony_ci            break;
16483af6ab5fSopenharmony_ci        }
16493af6ab5fSopenharmony_ci
16503af6ab5fSopenharmony_ci        elem->Compile(this);
16513af6ab5fSopenharmony_ci        StOwnByIndex(elem, obj, i);
16523af6ab5fSopenharmony_ci    }
16533af6ab5fSopenharmony_ci
16543af6ab5fSopenharmony_ci    RegScope rs(this);
16553af6ab5fSopenharmony_ci    VReg idxReg {};
16563af6ab5fSopenharmony_ci
16573af6ab5fSopenharmony_ci    if (hasSpread) {
16583af6ab5fSopenharmony_ci        idxReg = AllocReg();
16593af6ab5fSopenharmony_ci        LoadAccumulatorInt(node, i);
16603af6ab5fSopenharmony_ci        StoreAccumulator(node, idxReg);
16613af6ab5fSopenharmony_ci    }
16623af6ab5fSopenharmony_ci
16633af6ab5fSopenharmony_ci    // This loop handles arrays that contain spread elements
16643af6ab5fSopenharmony_ci    for (; i < elements.size(); i++) {
16653af6ab5fSopenharmony_ci        const ir::Expression *elem = elements[i];
16663af6ab5fSopenharmony_ci
16673af6ab5fSopenharmony_ci        if (elem->IsSpreadElement()) {
16683af6ab5fSopenharmony_ci            elem->AsSpreadElement()->Argument()->Compile(this);
16693af6ab5fSopenharmony_ci
16703af6ab5fSopenharmony_ci            StoreArraySpread(elem, obj, idxReg);
16713af6ab5fSopenharmony_ci
16723af6ab5fSopenharmony_ci            LoadObjByName(node, obj, "length");
16733af6ab5fSopenharmony_ci            StoreAccumulator(elem, idxReg);
16743af6ab5fSopenharmony_ci            continue;
16753af6ab5fSopenharmony_ci        }
16763af6ab5fSopenharmony_ci
16773af6ab5fSopenharmony_ci        if (!elem->IsOmittedExpression()) {
16783af6ab5fSopenharmony_ci            elem->Compile(this);
16793af6ab5fSopenharmony_ci            StOwnByValue(elem, obj, idxReg);
16803af6ab5fSopenharmony_ci        }
16813af6ab5fSopenharmony_ci
16823af6ab5fSopenharmony_ci        Unary(elem, lexer::TokenType::PUNCTUATOR_PLUS_PLUS, idxReg);
16833af6ab5fSopenharmony_ci        StoreAccumulator(elem, idxReg);
16843af6ab5fSopenharmony_ci    }
16853af6ab5fSopenharmony_ci
16863af6ab5fSopenharmony_ci    // If the last element is omitted, we also have to update the length property
16873af6ab5fSopenharmony_ci    if (elements.back()->IsOmittedExpression()) {
16883af6ab5fSopenharmony_ci        // if there was a spread value then acc already contains the length
16893af6ab5fSopenharmony_ci        if (!hasSpread) {
16903af6ab5fSopenharmony_ci            LoadAccumulatorInt(node, i);
16913af6ab5fSopenharmony_ci        }
16923af6ab5fSopenharmony_ci
16933af6ab5fSopenharmony_ci        StOwnByName(node, obj, "length");
16943af6ab5fSopenharmony_ci    }
16953af6ab5fSopenharmony_ci
16963af6ab5fSopenharmony_ci    LoadAccumulator(node, obj);
16973af6ab5fSopenharmony_ci}
16983af6ab5fSopenharmony_ci
16993af6ab5fSopenharmony_civoid PandaGen::StoreArraySpread(const ir::AstNode *node, VReg array, VReg index)
17003af6ab5fSopenharmony_ci{
17013af6ab5fSopenharmony_ci    ra_.Emit<Starrayspread>(node, array, index);
17023af6ab5fSopenharmony_ci}
17033af6ab5fSopenharmony_ci
17043af6ab5fSopenharmony_civoid PandaGen::ThrowIfNotObject(const ir::AstNode *node, VReg obj)
17053af6ab5fSopenharmony_ci{
17063af6ab5fSopenharmony_ci    ra_.Emit<ThrowIfnotobject>(node, obj);
17073af6ab5fSopenharmony_ci}
17083af6ab5fSopenharmony_ci
17093af6ab5fSopenharmony_civoid PandaGen::ThrowThrowNotExist(const ir::AstNode *node)
17103af6ab5fSopenharmony_ci{
17113af6ab5fSopenharmony_ci    ra_.Emit<ThrowNotexists>(node);
17123af6ab5fSopenharmony_ci}
17133af6ab5fSopenharmony_ci
17143af6ab5fSopenharmony_civoid PandaGen::GetIterator(const ir::AstNode *node)
17153af6ab5fSopenharmony_ci{
17163af6ab5fSopenharmony_ci    ra_.Emit<Getiterator>(node, 0);
17173af6ab5fSopenharmony_ci}
17183af6ab5fSopenharmony_ci
17193af6ab5fSopenharmony_civoid PandaGen::GetAsyncIterator(const ir::AstNode *node)
17203af6ab5fSopenharmony_ci{
17213af6ab5fSopenharmony_ci    ra_.Emit<Getasynciterator>(node, 0);
17223af6ab5fSopenharmony_ci}
17233af6ab5fSopenharmony_ci
17243af6ab5fSopenharmony_civoid PandaGen::CreateObjectWithExcludedKeys(const ir::AstNode *node, VReg obj, VReg argStart, size_t argCount)
17253af6ab5fSopenharmony_ci{
17263af6ab5fSopenharmony_ci    ASSERT(argStart == obj + 1);
17273af6ab5fSopenharmony_ci    if (argCount == 0) {
17283af6ab5fSopenharmony_ci        LoadConst(node, Constant::JS_UNDEFINED);
17293af6ab5fSopenharmony_ci        StoreAccumulator(node, argStart);
17303af6ab5fSopenharmony_ci    }
17313af6ab5fSopenharmony_ci
17323af6ab5fSopenharmony_ci    size_t argRegCnt = (argCount == 0 ? argCount : argCount - 1);
17333af6ab5fSopenharmony_ci
17343af6ab5fSopenharmony_ci    if (argRegCnt <= util::Helpers::MAX_INT8) {
17353af6ab5fSopenharmony_ci        ra_.EmitRange<Createobjectwithexcludedkeys>(node, argCount, static_cast<int64_t>(argRegCnt), obj, argStart);
17363af6ab5fSopenharmony_ci        return;
17373af6ab5fSopenharmony_ci    }
17383af6ab5fSopenharmony_ci
17393af6ab5fSopenharmony_ci    ra_.EmitRange<WideCreateobjectwithexcludedkeys>(node, argCount, static_cast<int64_t>(argRegCnt), obj, argStart);
17403af6ab5fSopenharmony_ci}
17413af6ab5fSopenharmony_ci
17423af6ab5fSopenharmony_civoid PandaGen::ThrowObjectNonCoercible(const ir::AstNode *node)
17433af6ab5fSopenharmony_ci{
17443af6ab5fSopenharmony_ci    ra_.Emit<ThrowPatternnoncoercible>(node);
17453af6ab5fSopenharmony_ci}
17463af6ab5fSopenharmony_ci
17473af6ab5fSopenharmony_civoid PandaGen::CloseIterator(const ir::AstNode *node, VReg iter)
17483af6ab5fSopenharmony_ci{
17493af6ab5fSopenharmony_ci    ra_.Emit<Closeiterator>(node, 0, iter);
17503af6ab5fSopenharmony_ci}
17513af6ab5fSopenharmony_ci
17523af6ab5fSopenharmony_civoid PandaGen::DefineClassWithBuffer(const ir::AstNode *node, const util::StringView &ctorId, int32_t litIdx, VReg base)
17533af6ab5fSopenharmony_ci{
17543af6ab5fSopenharmony_ci    auto formalParamCnt = node->AsClassDefinition()->Ctor()->Function()->FormalParamsLength();
17553af6ab5fSopenharmony_ci    std::string idxStr = std::string(context_->Binder()->Program()->RecordName()) + "_" + std::to_string(litIdx);
17563af6ab5fSopenharmony_ci    util::UString litId(idxStr, allocator_);
17573af6ab5fSopenharmony_ci    ra_.Emit<Defineclasswithbuffer>(node, 0, ctorId, litId.View(), static_cast<int64_t>(formalParamCnt), base);
17583af6ab5fSopenharmony_ci    strings_.insert(ctorId);
17593af6ab5fSopenharmony_ci}
17603af6ab5fSopenharmony_ci
17613af6ab5fSopenharmony_civoid PandaGen::DefineSendableClass(const ir::AstNode *node, const util::StringView &ctorId, int32_t litIdx, VReg base)
17623af6ab5fSopenharmony_ci{
17633af6ab5fSopenharmony_ci    auto formalParamCnt = node->AsClassDefinition()->Ctor()->Function()->FormalParamsLength();
17643af6ab5fSopenharmony_ci    std::string idxStr = std::string(context_->Binder()->Program()->RecordName()) + "_" + std::to_string(litIdx);
17653af6ab5fSopenharmony_ci    util::UString litId(idxStr, allocator_);
17663af6ab5fSopenharmony_ci    ra_.Emit<CallruntimeDefinesendableclass>(node, 0, ctorId, litId.View(), static_cast<int64_t>(formalParamCnt), base);
17673af6ab5fSopenharmony_ci    strings_.insert(ctorId);
17683af6ab5fSopenharmony_ci}
17693af6ab5fSopenharmony_ci
17703af6ab5fSopenharmony_civoid PandaGen::LoadSendableClass(const ir::AstNode *node, int32_t level)
17713af6ab5fSopenharmony_ci{
17723af6ab5fSopenharmony_ci    ra_.Emit<CallruntimeLdsendableclass>(node, level);
17733af6ab5fSopenharmony_ci}
17743af6ab5fSopenharmony_ci
17753af6ab5fSopenharmony_civoid PandaGen::LoadLocalModuleVariable(const ir::AstNode *node, const binder::ModuleVariable *variable)
17763af6ab5fSopenharmony_ci{
17773af6ab5fSopenharmony_ci    auto index = variable->Index();
17783af6ab5fSopenharmony_ci    index <= util::Helpers::MAX_INT8 ? ra_.Emit<Ldlocalmodulevar>(node, index) :
17793af6ab5fSopenharmony_ci                                       ra_.Emit<WideLdlocalmodulevar>(node, index);
17803af6ab5fSopenharmony_ci}
17813af6ab5fSopenharmony_ci
17823af6ab5fSopenharmony_civoid PandaGen::LoadExternalModuleVariable(const ir::AstNode *node, const binder::ModuleVariable *variable)
17833af6ab5fSopenharmony_ci{
17843af6ab5fSopenharmony_ci    auto index = variable->Index();
17853af6ab5fSopenharmony_ci
17863af6ab5fSopenharmony_ci    auto targetApiVersion = Binder()->Program()->TargetApiVersion();
17873af6ab5fSopenharmony_ci    bool isLazy = variable->Declaration()->Node()->IsImportSpecifier() ?
17883af6ab5fSopenharmony_ci        variable->Declaration()->Node()->AsImportSpecifier()->IsLazy() : false;
17893af6ab5fSopenharmony_ci    if (isLazy) {
17903af6ab5fSopenharmony_ci        // Change the behavior of using imported object in sendable class since api12
17913af6ab5fSopenharmony_ci        if (inSendable_ && targetApiVersion >= util::Helpers::SENDABLE_LAZY_LOADING_MIN_SUPPORTED_API_VERSION) {
17923af6ab5fSopenharmony_ci            index <= util::Helpers::MAX_INT8 ? ra_.Emit<CallruntimeLdlazysendablemodulevar>(node, index) :
17933af6ab5fSopenharmony_ci                                               ra_.Emit<CallruntimeWideldlazysendablemodulevar>(node, index);
17943af6ab5fSopenharmony_ci            return;
17953af6ab5fSopenharmony_ci        }
17963af6ab5fSopenharmony_ci
17973af6ab5fSopenharmony_ci        index <= util::Helpers::MAX_INT8 ? ra_.Emit<CallruntimeLdlazymodulevar>(node, index) :
17983af6ab5fSopenharmony_ci                                           ra_.Emit<CallruntimeWideldlazymodulevar>(node, index);
17993af6ab5fSopenharmony_ci        return;
18003af6ab5fSopenharmony_ci    }
18013af6ab5fSopenharmony_ci
18023af6ab5fSopenharmony_ci    // Change the behavior of using imported object in sendable class since api12
18033af6ab5fSopenharmony_ci    if (inSendable_ && targetApiVersion >= util::Helpers::SENDABLE_LAZY_LOADING_MIN_SUPPORTED_API_VERSION) {
18043af6ab5fSopenharmony_ci        index <= util::Helpers::MAX_INT8 ? ra_.Emit<CallruntimeLdsendableexternalmodulevar>(node, index) :
18053af6ab5fSopenharmony_ci                                           ra_.Emit<CallruntimeWideldsendableexternalmodulevar>(node, index);
18063af6ab5fSopenharmony_ci        return;
18073af6ab5fSopenharmony_ci    }
18083af6ab5fSopenharmony_ci
18093af6ab5fSopenharmony_ci    index <= util::Helpers::MAX_INT8 ? ra_.Emit<Ldexternalmodulevar>(node, index) :
18103af6ab5fSopenharmony_ci                                       ra_.Emit<WideLdexternalmodulevar>(node, index);
18113af6ab5fSopenharmony_ci}
18123af6ab5fSopenharmony_ci
18133af6ab5fSopenharmony_civoid PandaGen::StoreModuleVariable(const ir::AstNode *node, const binder::ModuleVariable *variable)
18143af6ab5fSopenharmony_ci{
18153af6ab5fSopenharmony_ci    auto index = variable->Index();
18163af6ab5fSopenharmony_ci    index <= util::Helpers::MAX_INT8 ? ra_.Emit<Stmodulevar>(node, index) :
18173af6ab5fSopenharmony_ci                                       ra_.Emit<WideStmodulevar>(node, index);
18183af6ab5fSopenharmony_ci}
18193af6ab5fSopenharmony_ci
18203af6ab5fSopenharmony_civoid PandaGen::GetModuleNamespace(const ir::AstNode *node, uint32_t index)
18213af6ab5fSopenharmony_ci{
18223af6ab5fSopenharmony_ci    index <= util::Helpers::MAX_INT8 ? ra_.Emit<Getmodulenamespace>(node, index) :
18233af6ab5fSopenharmony_ci                                       ra_.Emit<WideGetmodulenamespace>(node, index);
18243af6ab5fSopenharmony_ci}
18253af6ab5fSopenharmony_ci
18263af6ab5fSopenharmony_civoid PandaGen::DynamicImportCall(const ir::AstNode *node)
18273af6ab5fSopenharmony_ci{
18283af6ab5fSopenharmony_ci    ra_.Emit<Dynamicimport>(node);
18293af6ab5fSopenharmony_ci}
18303af6ab5fSopenharmony_ci
18313af6ab5fSopenharmony_civoid PandaGen::StSuperByName(const ir::AstNode *node, VReg obj, const util::StringView &key)
18323af6ab5fSopenharmony_ci{
18333af6ab5fSopenharmony_ci    ra_.Emit<Stsuperbyname>(node, 0, key, obj);
18343af6ab5fSopenharmony_ci    strings_.insert(key);
18353af6ab5fSopenharmony_ci}
18363af6ab5fSopenharmony_ci
18373af6ab5fSopenharmony_civoid PandaGen::LdSuperByName(const ir::AstNode *node, VReg obj, const util::StringView &key)
18383af6ab5fSopenharmony_ci{
18393af6ab5fSopenharmony_ci    LoadAccumulator(node, obj); // object is load to acc
18403af6ab5fSopenharmony_ci    ra_.Emit<Ldsuperbyname>(node, 0, key);
18413af6ab5fSopenharmony_ci    strings_.insert(key);
18423af6ab5fSopenharmony_ci}
18433af6ab5fSopenharmony_ci
18443af6ab5fSopenharmony_civoid PandaGen::StSuperByValue(const ir::AstNode *node, VReg obj, VReg prop)
18453af6ab5fSopenharmony_ci{
18463af6ab5fSopenharmony_ci    ra_.Emit<Stsuperbyvalue>(node, 0, obj, prop);
18473af6ab5fSopenharmony_ci}
18483af6ab5fSopenharmony_ci
18493af6ab5fSopenharmony_civoid PandaGen::LdSuperByValue(const ir::AstNode *node, VReg obj)
18503af6ab5fSopenharmony_ci{
18513af6ab5fSopenharmony_ci    ra_.Emit<Ldsuperbyvalue>(node, 0, obj); // prop is in acc
18523af6ab5fSopenharmony_ci}
18533af6ab5fSopenharmony_ci
18543af6ab5fSopenharmony_civoid PandaGen::StoreSuperProperty(const ir::AstNode *node, VReg obj, const Operand &prop)
18553af6ab5fSopenharmony_ci{
18563af6ab5fSopenharmony_ci    if (std::holds_alternative<util::StringView>(prop)) {
18573af6ab5fSopenharmony_ci        StSuperByName(node, obj, std::get<util::StringView>(prop));
18583af6ab5fSopenharmony_ci        return;
18593af6ab5fSopenharmony_ci    }
18603af6ab5fSopenharmony_ci
18613af6ab5fSopenharmony_ci    if (std::holds_alternative<VReg>(prop)) {
18623af6ab5fSopenharmony_ci        StSuperByValue(node, obj, std::get<VReg>(prop));
18633af6ab5fSopenharmony_ci        return;
18643af6ab5fSopenharmony_ci    }
18653af6ab5fSopenharmony_ci
18663af6ab5fSopenharmony_ci    ASSERT(std::holds_alternative<int64_t>(prop));
18673af6ab5fSopenharmony_ci    RegScope rs(this);
18683af6ab5fSopenharmony_ci    VReg property = AllocReg();
18693af6ab5fSopenharmony_ci    VReg value = AllocReg();
18703af6ab5fSopenharmony_ci
18713af6ab5fSopenharmony_ci    StoreAccumulator(node, value);
18723af6ab5fSopenharmony_ci    LoadAccumulatorInt(node, static_cast<size_t>(std::get<int64_t>(prop)));
18733af6ab5fSopenharmony_ci    StoreAccumulator(node, property);
18743af6ab5fSopenharmony_ci    LoadAccumulator(node, value);
18753af6ab5fSopenharmony_ci    StSuperByValue(node, obj, property);
18763af6ab5fSopenharmony_ci}
18773af6ab5fSopenharmony_ci
18783af6ab5fSopenharmony_civoid PandaGen::LoadSuperProperty(const ir::AstNode *node, VReg obj, const Operand &prop)
18793af6ab5fSopenharmony_ci{
18803af6ab5fSopenharmony_ci    if (std::holds_alternative<util::StringView>(prop)) {
18813af6ab5fSopenharmony_ci        LdSuperByName(node, obj, std::get<util::StringView>(prop));
18823af6ab5fSopenharmony_ci        return;
18833af6ab5fSopenharmony_ci    }
18843af6ab5fSopenharmony_ci
18853af6ab5fSopenharmony_ci    if (std::holds_alternative<VReg>(prop)) {
18863af6ab5fSopenharmony_ci        LoadAccumulator(node, std::get<VReg>(prop));
18873af6ab5fSopenharmony_ci        LdSuperByValue(node, obj);
18883af6ab5fSopenharmony_ci        return;
18893af6ab5fSopenharmony_ci    }
18903af6ab5fSopenharmony_ci
18913af6ab5fSopenharmony_ci    ASSERT(std::holds_alternative<int64_t>(prop));
18923af6ab5fSopenharmony_ci
18933af6ab5fSopenharmony_ci    LoadAccumulatorInt(node, static_cast<size_t>(std::get<int64_t>(prop)));
18943af6ab5fSopenharmony_ci    LdSuperByValue(node, obj);
18953af6ab5fSopenharmony_ci}
18963af6ab5fSopenharmony_ci
18973af6ab5fSopenharmony_civoid PandaGen::LoadLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot)
18983af6ab5fSopenharmony_ci{
18993af6ab5fSopenharmony_ci    if ((level > util::Helpers::MAX_INT8) || (slot > util::Helpers::MAX_INT8)) {
19003af6ab5fSopenharmony_ci        ra_.Emit<WideLdlexvar>(node, level, slot);
19013af6ab5fSopenharmony_ci        return;
19023af6ab5fSopenharmony_ci    }
19033af6ab5fSopenharmony_ci
19043af6ab5fSopenharmony_ci    ra_.Emit<Ldlexvar>(node, level, slot);
19053af6ab5fSopenharmony_ci}
19063af6ab5fSopenharmony_ci
19073af6ab5fSopenharmony_civoid PandaGen::LoadSendableVar(const ir::AstNode *node, uint32_t level, uint32_t slot)
19083af6ab5fSopenharmony_ci{
19093af6ab5fSopenharmony_ci    if ((level > util::Helpers::MAX_INT8) || (slot > util::Helpers::MAX_INT8)) {
19103af6ab5fSopenharmony_ci        ra_.Emit<CallruntimeWideldsendablevar>(node, level, slot);
19113af6ab5fSopenharmony_ci        return;
19123af6ab5fSopenharmony_ci    }
19133af6ab5fSopenharmony_ci
19143af6ab5fSopenharmony_ci    ra_.Emit<CallruntimeLdsendablevar>(node, level, slot);
19153af6ab5fSopenharmony_ci}
19163af6ab5fSopenharmony_ci
19173af6ab5fSopenharmony_civoid PandaGen::LoadLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot, const util::StringView &name)
19183af6ab5fSopenharmony_ci{
19193af6ab5fSopenharmony_ci    if (context_->PatchFixHelper() && context_->PatchFixHelper()->IsAdditionalVarInPatch(slot)) {
19203af6ab5fSopenharmony_ci        uint32_t patchSlot = context_->PatchFixHelper()->GetPatchLexicalIdx(std::string(name));
19213af6ab5fSopenharmony_ci        ra_.Emit<WideLdpatchvar>(node, patchSlot);
19223af6ab5fSopenharmony_ci        return;
19233af6ab5fSopenharmony_ci    }
19243af6ab5fSopenharmony_ci
19253af6ab5fSopenharmony_ci    if ((level > util::Helpers::MAX_INT8) || (slot > util::Helpers::MAX_INT8)) {
19263af6ab5fSopenharmony_ci        ra_.Emit<WideLdlexvar>(node, level, slot);
19273af6ab5fSopenharmony_ci        return;
19283af6ab5fSopenharmony_ci    }
19293af6ab5fSopenharmony_ci
19303af6ab5fSopenharmony_ci    ra_.Emit<Ldlexvar>(node, level, slot);
19313af6ab5fSopenharmony_ci}
19323af6ab5fSopenharmony_ci
19333af6ab5fSopenharmony_civoid PandaGen::StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot)
19343af6ab5fSopenharmony_ci{
19353af6ab5fSopenharmony_ci    if ((level > util::Helpers::MAX_INT8) || (slot > util::Helpers::MAX_INT8)) {
19363af6ab5fSopenharmony_ci        ra_.Emit<WideStlexvar>(node, level, slot);
19373af6ab5fSopenharmony_ci        return;
19383af6ab5fSopenharmony_ci    }
19393af6ab5fSopenharmony_ci
19403af6ab5fSopenharmony_ci    ra_.Emit<Stlexvar>(node, level, slot);
19413af6ab5fSopenharmony_ci}
19423af6ab5fSopenharmony_ci
19433af6ab5fSopenharmony_civoid PandaGen::StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot, VReg value)
19443af6ab5fSopenharmony_ci{
19453af6ab5fSopenharmony_ci    LoadAccumulator(node, value);
19463af6ab5fSopenharmony_ci    if ((level > util::Helpers::MAX_INT8) || (slot > util::Helpers::MAX_INT8)) {
19473af6ab5fSopenharmony_ci        ra_.Emit<WideStlexvar>(node, level, slot);
19483af6ab5fSopenharmony_ci        return;
19493af6ab5fSopenharmony_ci    }
19503af6ab5fSopenharmony_ci
19513af6ab5fSopenharmony_ci    ra_.Emit<Stlexvar>(node, level, slot);
19523af6ab5fSopenharmony_ci}
19533af6ab5fSopenharmony_ci
19543af6ab5fSopenharmony_civoid PandaGen::StoreSendableVar(const ir::AstNode *node, uint32_t level, uint32_t slot)
19553af6ab5fSopenharmony_ci{
19563af6ab5fSopenharmony_ci    if ((level > util::Helpers::MAX_INT8) || (slot > util::Helpers::MAX_INT8)) {
19573af6ab5fSopenharmony_ci        ra_.Emit<CallruntimeWidestsendablevar>(node, level, slot);
19583af6ab5fSopenharmony_ci        return;
19593af6ab5fSopenharmony_ci    }
19603af6ab5fSopenharmony_ci
19613af6ab5fSopenharmony_ci    ra_.Emit<CallruntimeStsendablevar>(node, level, slot);
19623af6ab5fSopenharmony_ci}
19633af6ab5fSopenharmony_ci
19643af6ab5fSopenharmony_civoid PandaGen::StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot,
19653af6ab5fSopenharmony_ci    const binder::LocalVariable *local)
19663af6ab5fSopenharmony_ci{
19673af6ab5fSopenharmony_ci    if (context_->PatchFixHelper() && context_->PatchFixHelper()->IsAdditionalVarInPatch(slot)) {
19683af6ab5fSopenharmony_ci        uint32_t patchSlot = context_->PatchFixHelper()->GetPatchLexicalIdx(std::string(local->Name()));
19693af6ab5fSopenharmony_ci        ra_.Emit<WideStpatchvar>(node, patchSlot);
19703af6ab5fSopenharmony_ci        return;
19713af6ab5fSopenharmony_ci    }
19723af6ab5fSopenharmony_ci    RegScope rs(this);
19733af6ab5fSopenharmony_ci    VReg value = AllocReg();
19743af6ab5fSopenharmony_ci    StoreAccumulator(node, value);
19753af6ab5fSopenharmony_ci    StoreLexicalVar(node, level, slot, value);
19763af6ab5fSopenharmony_ci}
19773af6ab5fSopenharmony_ci
19783af6ab5fSopenharmony_civoid PandaGen::ThrowIfSuperNotCorrectCall(const ir::AstNode *node, int64_t num)
19793af6ab5fSopenharmony_ci{
19803af6ab5fSopenharmony_ci    ra_.Emit<ThrowIfsupernotcorrectcall>(node, num);
19813af6ab5fSopenharmony_ci}
19823af6ab5fSopenharmony_ci
19833af6ab5fSopenharmony_civoid PandaGen::ThrowUndefinedIfHole(const ir::AstNode *node, const util::StringView &name)
19843af6ab5fSopenharmony_ci{
19853af6ab5fSopenharmony_ci    ra_.Emit<ThrowUndefinedifholewithname>(node, name);
19863af6ab5fSopenharmony_ci    strings_.insert(name);
19873af6ab5fSopenharmony_ci}
19883af6ab5fSopenharmony_ci
19893af6ab5fSopenharmony_civoid PandaGen::ThrowConstAssignment(const ir::AstNode *node, const util::StringView &name)
19903af6ab5fSopenharmony_ci{
19913af6ab5fSopenharmony_ci    RegScope rs(this);
19923af6ab5fSopenharmony_ci    LoadAccumulatorString(node, name);
19933af6ab5fSopenharmony_ci    VReg nameReg = AllocReg();
19943af6ab5fSopenharmony_ci    StoreAccumulator(node, nameReg);
19953af6ab5fSopenharmony_ci    ra_.Emit<ThrowConstassignment>(node, nameReg);
19963af6ab5fSopenharmony_ci    strings_.insert(name);
19973af6ab5fSopenharmony_ci}
19983af6ab5fSopenharmony_ci
19993af6ab5fSopenharmony_civoid PandaGen::PopLexEnv(const ir::AstNode *node)
20003af6ab5fSopenharmony_ci{
20013af6ab5fSopenharmony_ci    ra_.Emit<Poplexenv>(node);
20023af6ab5fSopenharmony_ci}
20033af6ab5fSopenharmony_ci
20043af6ab5fSopenharmony_civoid PandaGen::GenDebugger(const ir::AstNode *node)
20053af6ab5fSopenharmony_ci{
20063af6ab5fSopenharmony_ci    if (IsDebug()) {
20073af6ab5fSopenharmony_ci        ra_.Emit<Debugger>(node);
20083af6ab5fSopenharmony_ci    }
20093af6ab5fSopenharmony_ci}
20103af6ab5fSopenharmony_ci
20113af6ab5fSopenharmony_civoid PandaGen::NewLexicalEnv(const ir::AstNode *node, uint32_t num, binder::VariableScope *scope)
20123af6ab5fSopenharmony_ci{
20133af6ab5fSopenharmony_ci    if (IsDebug()) {
20143af6ab5fSopenharmony_ci        int32_t scopeInfoIdx = AddLexicalVarNamesForDebugInfo(scope->GetLexicalVarNameAndTypes());
20153af6ab5fSopenharmony_ci        NewLexEnvWithScopeInfo(node, num, scopeInfoIdx);
20163af6ab5fSopenharmony_ci        return;
20173af6ab5fSopenharmony_ci    }
20183af6ab5fSopenharmony_ci
20193af6ab5fSopenharmony_ci    NewLexEnv(node, num);
20203af6ab5fSopenharmony_ci}
20213af6ab5fSopenharmony_ci
20223af6ab5fSopenharmony_civoid PandaGen::NewLexEnv(const ir::AstNode *node, uint32_t num)
20233af6ab5fSopenharmony_ci{
20243af6ab5fSopenharmony_ci    num <= util::Helpers::MAX_INT8 ? ra_.Emit<Newlexenv>(node, num) : ra_.Emit<WideNewlexenv>(node, num);
20253af6ab5fSopenharmony_ci}
20263af6ab5fSopenharmony_ci
20273af6ab5fSopenharmony_civoid PandaGen::NewSendableEnv(const ir::AstNode * node, uint32_t num)
20283af6ab5fSopenharmony_ci{
20293af6ab5fSopenharmony_ci    num <= util::Helpers::MAX_INT8 ? ra_.Emit<CallruntimeNewsendableenv>(node, num) :
20303af6ab5fSopenharmony_ci        ra_.Emit<CallruntimeWidenewsendableenv>(node, num);
20313af6ab5fSopenharmony_ci}
20323af6ab5fSopenharmony_ci
20333af6ab5fSopenharmony_civoid PandaGen::NewLexEnvWithScopeInfo(const ir::AstNode *node, uint32_t num, int32_t scopeInfoIdx)
20343af6ab5fSopenharmony_ci{
20353af6ab5fSopenharmony_ci    std::string idxStr = std::string(context_->Binder()->Program()->RecordName()) + "_" + std::to_string(scopeInfoIdx);
20363af6ab5fSopenharmony_ci    util::UString litId(idxStr, allocator_);
20373af6ab5fSopenharmony_ci    num <= util::Helpers::MAX_INT8 ? ra_.Emit<Newlexenvwithname>(node, num, litId.View()) :
20383af6ab5fSopenharmony_ci                                     ra_.Emit<WideNewlexenvwithname>(node, num, litId.View());
20393af6ab5fSopenharmony_ci}
20403af6ab5fSopenharmony_ci
20413af6ab5fSopenharmony_ciuint32_t PandaGen::TryDepth() const
20423af6ab5fSopenharmony_ci{
20433af6ab5fSopenharmony_ci    const auto *iter = dynamicContext_;
20443af6ab5fSopenharmony_ci    uint32_t depth = 0;
20453af6ab5fSopenharmony_ci
20463af6ab5fSopenharmony_ci    while (iter) {
20473af6ab5fSopenharmony_ci        if (iter->HasTryCatch()) {
20483af6ab5fSopenharmony_ci            depth++;
20493af6ab5fSopenharmony_ci        }
20503af6ab5fSopenharmony_ci
20513af6ab5fSopenharmony_ci        iter = iter->Prev();
20523af6ab5fSopenharmony_ci    }
20533af6ab5fSopenharmony_ci
20543af6ab5fSopenharmony_ci    return depth;
20553af6ab5fSopenharmony_ci}
20563af6ab5fSopenharmony_ci
20573af6ab5fSopenharmony_ciCatchTable *PandaGen::CreateCatchTable()
20583af6ab5fSopenharmony_ci{
20593af6ab5fSopenharmony_ci    auto *catchTable = allocator_->New<CatchTable>(this, TryDepth());
20603af6ab5fSopenharmony_ci    CHECK_NOT_NULL(catchTable);
20613af6ab5fSopenharmony_ci    catchList_.push_back(catchTable);
20623af6ab5fSopenharmony_ci    return catchTable;
20633af6ab5fSopenharmony_ci}
20643af6ab5fSopenharmony_ci
20653af6ab5fSopenharmony_civoid PandaGen::SortCatchTables()
20663af6ab5fSopenharmony_ci{
20673af6ab5fSopenharmony_ci    std::sort(catchList_.begin(), catchList_.end(),
20683af6ab5fSopenharmony_ci              [](const CatchTable *a, const CatchTable *b) { return b->Depth() < a->Depth(); });
20693af6ab5fSopenharmony_ci}
20703af6ab5fSopenharmony_ci
20713af6ab5fSopenharmony_ciOperand PandaGen::ToNamedPropertyKey(const ir::Expression *prop, bool isComputed)
20723af6ab5fSopenharmony_ci{
20733af6ab5fSopenharmony_ci    VReg res {0};
20743af6ab5fSopenharmony_ci
20753af6ab5fSopenharmony_ci    if (isComputed) {
20763af6ab5fSopenharmony_ci        return res;
20773af6ab5fSopenharmony_ci    }
20783af6ab5fSopenharmony_ci
20793af6ab5fSopenharmony_ci    if (prop->IsIdentifier()) {
20803af6ab5fSopenharmony_ci        return prop->AsIdentifier()->Name();
20813af6ab5fSopenharmony_ci    }
20823af6ab5fSopenharmony_ci
20833af6ab5fSopenharmony_ci    if (prop->IsStringLiteral()) {
20843af6ab5fSopenharmony_ci        const util::StringView &str = prop->AsStringLiteral()->Str();
20853af6ab5fSopenharmony_ci
20863af6ab5fSopenharmony_ci        // remove this when runtime handles __proto__ as property name correctly
20873af6ab5fSopenharmony_ci        if (str.Is("__proto__")) {
20883af6ab5fSopenharmony_ci            return res;
20893af6ab5fSopenharmony_ci        }
20903af6ab5fSopenharmony_ci
20913af6ab5fSopenharmony_ci        int64_t index = util::Helpers::GetIndex(str);
20923af6ab5fSopenharmony_ci        if (index != util::Helpers::INVALID_INDEX) {
20933af6ab5fSopenharmony_ci            return index;
20943af6ab5fSopenharmony_ci        }
20953af6ab5fSopenharmony_ci
20963af6ab5fSopenharmony_ci        return str;
20973af6ab5fSopenharmony_ci    }
20983af6ab5fSopenharmony_ci
20993af6ab5fSopenharmony_ci    if (prop->IsNumberLiteral()) {
21003af6ab5fSopenharmony_ci        auto num = prop->AsNumberLiteral()->Number<double>();
21013af6ab5fSopenharmony_ci        if (util::Helpers::IsIndex(num)) {
21023af6ab5fSopenharmony_ci            return static_cast<int64_t>(num);
21033af6ab5fSopenharmony_ci        }
21043af6ab5fSopenharmony_ci
21053af6ab5fSopenharmony_ci        return util::Helpers::ToStringView(allocator_, num);
21063af6ab5fSopenharmony_ci    }
21073af6ab5fSopenharmony_ci
21083af6ab5fSopenharmony_ci    return res;
21093af6ab5fSopenharmony_ci}
21103af6ab5fSopenharmony_ci
21113af6ab5fSopenharmony_ciOperand PandaGen::ToPropertyKey(const ir::Expression *prop, bool isComputed)
21123af6ab5fSopenharmony_ci{
21133af6ab5fSopenharmony_ci    Operand op = ToNamedPropertyKey(prop, isComputed);
21143af6ab5fSopenharmony_ci    if (std::holds_alternative<util::StringView>(op) || (std::holds_alternative<int64_t>(op) &&
21153af6ab5fSopenharmony_ci        (std::get<int64_t>(op) <= util::Helpers::MAX_INT32))) {
21163af6ab5fSopenharmony_ci        return op;
21173af6ab5fSopenharmony_ci    }
21183af6ab5fSopenharmony_ci
21193af6ab5fSopenharmony_ci    VReg propReg = AllocReg();
21203af6ab5fSopenharmony_ci
21213af6ab5fSopenharmony_ci    /**
21223af6ab5fSopenharmony_ci     * Store index to vreg when index > MAX_INT32 to simplify ASM interpreter If byindex-related instructions support
21233af6ab5fSopenharmony_ci     * index > MAX_INT32, ASM interpreter will have to add a judgment whether index needs more than 32 bits which will
21243af6ab5fSopenharmony_ci     * cause inefficiency of it since cases when index > MAX_INT32 can be quite rare
21253af6ab5fSopenharmony_ci     **/
21263af6ab5fSopenharmony_ci    if (std::holds_alternative<int64_t>(op) && (std::get<int64_t>(op) > util::Helpers::MAX_INT32)) {
21273af6ab5fSopenharmony_ci        LoadAccumulatorFloat(prop, std::get<int64_t>(op));
21283af6ab5fSopenharmony_ci        StoreAccumulator(prop, propReg);
21293af6ab5fSopenharmony_ci        return propReg;
21303af6ab5fSopenharmony_ci    }
21313af6ab5fSopenharmony_ci
21323af6ab5fSopenharmony_ci    ASSERT(std::holds_alternative<VReg>(op));
21333af6ab5fSopenharmony_ci    prop->Compile(this);
21343af6ab5fSopenharmony_ci    StoreAccumulator(prop, propReg);
21353af6ab5fSopenharmony_ci
21363af6ab5fSopenharmony_ci    return propReg;
21373af6ab5fSopenharmony_ci}
21383af6ab5fSopenharmony_ci
21393af6ab5fSopenharmony_ciVReg PandaGen::LoadPropertyKey(const ir::Expression *prop, bool isComputed)
21403af6ab5fSopenharmony_ci{
21413af6ab5fSopenharmony_ci    Operand op = ToNamedPropertyKey(prop, isComputed);
21423af6ab5fSopenharmony_ci    if (std::holds_alternative<util::StringView>(op)) {
21433af6ab5fSopenharmony_ci        LoadAccumulatorString(prop, std::get<util::StringView>(op));
21443af6ab5fSopenharmony_ci    } else if (std::holds_alternative<int64_t>(op)) {
21453af6ab5fSopenharmony_ci        LoadAccumulatorInt(prop, static_cast<size_t>(std::get<int64_t>(op)));
21463af6ab5fSopenharmony_ci    } else {
21473af6ab5fSopenharmony_ci        prop->Compile(this);
21483af6ab5fSopenharmony_ci    }
21493af6ab5fSopenharmony_ci
21503af6ab5fSopenharmony_ci    VReg propReg = AllocReg();
21513af6ab5fSopenharmony_ci    StoreAccumulator(prop, propReg);
21523af6ab5fSopenharmony_ci
21533af6ab5fSopenharmony_ci    return propReg;
21543af6ab5fSopenharmony_ci}
21553af6ab5fSopenharmony_ci
21563af6ab5fSopenharmony_civoid PandaGen::ToComputedPropertyKey(const ir::AstNode *node)
21573af6ab5fSopenharmony_ci{
21583af6ab5fSopenharmony_ci    ra_.Emit<CallruntimeTopropertykey>(node);
21593af6ab5fSopenharmony_ci}
21603af6ab5fSopenharmony_ci
21613af6ab5fSopenharmony_civoid PandaGen::StLetOrClassToGlobalRecord(const ir::AstNode *node, const util::StringView &name)
21623af6ab5fSopenharmony_ci{
21633af6ab5fSopenharmony_ci    ra_.Emit<Sttoglobalrecord>(node, 0, name);
21643af6ab5fSopenharmony_ci    strings_.insert(name);
21653af6ab5fSopenharmony_ci}
21663af6ab5fSopenharmony_ci
21673af6ab5fSopenharmony_civoid PandaGen::StConstToGlobalRecord(const ir::AstNode *node, const util::StringView &name)
21683af6ab5fSopenharmony_ci{
21693af6ab5fSopenharmony_ci    ra_.Emit<Stconsttoglobalrecord>(node, 0, name);
21703af6ab5fSopenharmony_ci    strings_.insert(name);
21713af6ab5fSopenharmony_ci}
21723af6ab5fSopenharmony_ci
21733af6ab5fSopenharmony_cibool PandaGen::TryCompileFunctionCallOrNewExpression(const ir::Expression *expr)
21743af6ab5fSopenharmony_ci{
21753af6ab5fSopenharmony_ci    ASSERT(expr->IsCallExpression() || expr->IsNewExpression());
21763af6ab5fSopenharmony_ci    const auto *callee = expr->IsCallExpression() ? expr->AsCallExpression()->Callee() :
21773af6ab5fSopenharmony_ci                         expr->AsNewExpression()->Callee();
21783af6ab5fSopenharmony_ci
21793af6ab5fSopenharmony_ci    if (!callee->IsIdentifier()) {
21803af6ab5fSopenharmony_ci        return false;
21813af6ab5fSopenharmony_ci    }
21823af6ab5fSopenharmony_ci
21833af6ab5fSopenharmony_ci    if (callee->AsIdentifier()->Name().Is("Function")) {
21843af6ab5fSopenharmony_ci        auto arguments = expr->IsCallExpression() ? expr->AsCallExpression()->Arguments() :
21853af6ab5fSopenharmony_ci                         expr->AsNewExpression()->Arguments();
21863af6ab5fSopenharmony_ci        if (arguments.empty()) {
21873af6ab5fSopenharmony_ci            return false;
21883af6ab5fSopenharmony_ci        }
21893af6ab5fSopenharmony_ci
21903af6ab5fSopenharmony_ci        auto *arg = arguments[arguments.size() - 1];
21913af6ab5fSopenharmony_ci        if (!arg->IsStringLiteral()) {
21923af6ab5fSopenharmony_ci            return false;
21933af6ab5fSopenharmony_ci        }
21943af6ab5fSopenharmony_ci
21953af6ab5fSopenharmony_ci        if (std::regex_match(arg->AsStringLiteral()->Str().Mutf8(), std::regex(" *return +this[;]? *$"))) {
21963af6ab5fSopenharmony_ci            LoadConst(arg, Constant::JS_GLOBAL);
21973af6ab5fSopenharmony_ci            return true;
21983af6ab5fSopenharmony_ci        }
21993af6ab5fSopenharmony_ci    }
22003af6ab5fSopenharmony_ci
22013af6ab5fSopenharmony_ci    return false;
22023af6ab5fSopenharmony_ci}
22033af6ab5fSopenharmony_ci
22043af6ab5fSopenharmony_civoid PandaGen::ReArrangeIc()
22053af6ab5fSopenharmony_ci{
22063af6ab5fSopenharmony_ci    if (!IsIcOverFlow()) {
22073af6ab5fSopenharmony_ci        return;
22083af6ab5fSopenharmony_ci    }
22093af6ab5fSopenharmony_ci
22103af6ab5fSopenharmony_ci    ResetCurrentSlot(0);
22113af6ab5fSopenharmony_ci
22123af6ab5fSopenharmony_ci    for (auto *ins: Insns()) {
22133af6ab5fSopenharmony_ci        if (!ins->InlineCacheEnabled()) {
22143af6ab5fSopenharmony_ci            continue;
22153af6ab5fSopenharmony_ci        }
22163af6ab5fSopenharmony_ci
22173af6ab5fSopenharmony_ci        if (ins->oneByteSlotOnly()) {
22183af6ab5fSopenharmony_ci            auto inc = ins->SetIcSlot(GetCurrentSlot());
22193af6ab5fSopenharmony_ci            IncreaseCurrentSlot(inc);
22203af6ab5fSopenharmony_ci        }
22213af6ab5fSopenharmony_ci    }
22223af6ab5fSopenharmony_ci
22233af6ab5fSopenharmony_ci    for (auto *ins: Insns()) {
22243af6ab5fSopenharmony_ci        if (!ins->InlineCacheEnabled()) {
22253af6ab5fSopenharmony_ci            continue;
22263af6ab5fSopenharmony_ci        }
22273af6ab5fSopenharmony_ci
22283af6ab5fSopenharmony_ci        if (ins->oneByteSlotOnly()) {
22293af6ab5fSopenharmony_ci            continue;
22303af6ab5fSopenharmony_ci        }
22313af6ab5fSopenharmony_ci
22323af6ab5fSopenharmony_ci        auto inc = ins->SetIcSlot(GetCurrentSlot());
22333af6ab5fSopenharmony_ci        IncreaseCurrentSlot(inc);
22343af6ab5fSopenharmony_ci    }
22353af6ab5fSopenharmony_ci}
22363af6ab5fSopenharmony_ci
22373af6ab5fSopenharmony_civoid PandaGen::CreatePrivateProperty(const ir::AstNode *node, uint32_t num, int32_t bufIdx)
22383af6ab5fSopenharmony_ci{
22393af6ab5fSopenharmony_ci    std::string idxStr = std::string(context_->Binder()->Program()->RecordName()) + "_" + std::to_string(bufIdx);
22403af6ab5fSopenharmony_ci    util::UString litId(idxStr, allocator_);
22413af6ab5fSopenharmony_ci    ra_.Emit<CallruntimeCreateprivateproperty>(node, num, litId.View());
22423af6ab5fSopenharmony_ci}
22433af6ab5fSopenharmony_ci
22443af6ab5fSopenharmony_civoid PandaGen::TestIn(const ir::AstNode *node, uint32_t level, uint32_t slot)
22453af6ab5fSopenharmony_ci{
22463af6ab5fSopenharmony_ci    ra_.Emit<Testin>(node, 0, level, slot);
22473af6ab5fSopenharmony_ci}
22483af6ab5fSopenharmony_ci
22493af6ab5fSopenharmony_civoid PandaGen::LoadPrivateProperty(const ir::AstNode *node, uint32_t level, uint32_t slot)
22503af6ab5fSopenharmony_ci{
22513af6ab5fSopenharmony_ci    ra_.Emit<Ldprivateproperty>(node, 0, level, slot);
22523af6ab5fSopenharmony_ci}
22533af6ab5fSopenharmony_ci
22543af6ab5fSopenharmony_civoid PandaGen::StorePrivateProperty(const ir::AstNode *node, uint32_t level, uint32_t slot, VReg obj)
22553af6ab5fSopenharmony_ci{
22563af6ab5fSopenharmony_ci    ra_.Emit<Stprivateproperty>(node, 0, level, slot, obj);
22573af6ab5fSopenharmony_ci}
22583af6ab5fSopenharmony_civoid PandaGen::ThrowTypeErrorIfFalse(const ir::AstNode *node, util::StringView str)
22593af6ab5fSopenharmony_ci{
22603af6ab5fSopenharmony_ci    auto *trueLabel = AllocLabel();
22613af6ab5fSopenharmony_ci    BranchIfTrue(node, trueLabel);
22623af6ab5fSopenharmony_ci    ThrowTypeError(node, str);
22633af6ab5fSopenharmony_ci    SetLabel(node, trueLabel);
22643af6ab5fSopenharmony_ci}
22653af6ab5fSopenharmony_ci
22663af6ab5fSopenharmony_civoid PandaGen::ThrowTypeError(const ir::AstNode *node, util::StringView str)
22673af6ab5fSopenharmony_ci{
22683af6ab5fSopenharmony_ci    LoadAccumulatorString(node, str);
22693af6ab5fSopenharmony_ci    VReg reg = AllocReg();
22703af6ab5fSopenharmony_ci    StoreAccumulator(node, reg);
22713af6ab5fSopenharmony_ci    TryLoadGlobalByName(node, "TypeError");
22723af6ab5fSopenharmony_ci    ra_.Emit<Callarg1>(node, 0, reg);
22733af6ab5fSopenharmony_ci    EmitThrow(node);
22743af6ab5fSopenharmony_ci}
22753af6ab5fSopenharmony_ci
22763af6ab5fSopenharmony_ci}  // namespace panda::es2panda::compiler
2277