13af6ab5fSopenharmony_ci/**
23af6ab5fSopenharmony_ci * Copyright (c) 2021-2024 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#ifndef ES2PANDA_COMPILER_CORE_PANDAGEN_H
173af6ab5fSopenharmony_ci#define ES2PANDA_COMPILER_CORE_PANDAGEN_H
183af6ab5fSopenharmony_ci
193af6ab5fSopenharmony_ci#include <compiler/base/optionalChain.h>
203af6ab5fSopenharmony_ci#include <compiler/core/envScope.h>
213af6ab5fSopenharmony_ci#include <compiler/core/inlineCache.h>
223af6ab5fSopenharmony_ci#include <compiler/core/regAllocator.h>
233af6ab5fSopenharmony_ci#include <compiler/core/regScope.h>
243af6ab5fSopenharmony_ci#include <ir/irnode.h>
253af6ab5fSopenharmony_ci#include <lexer/token/tokenType.h>
263af6ab5fSopenharmony_ci#include <libpandafile/file_items.h>
273af6ab5fSopenharmony_ci#include <macros.h>
283af6ab5fSopenharmony_ci#include <util/enumbitops.h>
293af6ab5fSopenharmony_ci
303af6ab5fSopenharmony_ci#include <regex>
313af6ab5fSopenharmony_ci
323af6ab5fSopenharmony_cinamespace panda::es2panda::binder {
333af6ab5fSopenharmony_ciclass FunctionScope;
343af6ab5fSopenharmony_ciclass ModuleVaribale;
353af6ab5fSopenharmony_ciclass ScopeFindResult;
363af6ab5fSopenharmony_ciclass Scope;
373af6ab5fSopenharmony_ci}  // namespace panda::es2panda::binder
383af6ab5fSopenharmony_ci
393af6ab5fSopenharmony_cinamespace panda::es2panda::ir {
403af6ab5fSopenharmony_ciclass AstNode;
413af6ab5fSopenharmony_ciclass ScriptFunction;
423af6ab5fSopenharmony_ciclass Statement;
433af6ab5fSopenharmony_ciclass Expression;
443af6ab5fSopenharmony_ciclass Identifier;
453af6ab5fSopenharmony_ci}  // namespace panda::es2panda::ir
463af6ab5fSopenharmony_ci
473af6ab5fSopenharmony_ciDEFINE_BITOPS(panda::panda_file::FunctionKind);
483af6ab5fSopenharmony_ci
493af6ab5fSopenharmony_cinamespace panda::es2panda::compiler {
503af6ab5fSopenharmony_ciclass FunctionBuilder;
513af6ab5fSopenharmony_ciclass CompilerContext;
523af6ab5fSopenharmony_ciclass LiteralBuffer;
533af6ab5fSopenharmony_ciclass DynamicContext;
543af6ab5fSopenharmony_ciclass CatchTable;
553af6ab5fSopenharmony_ci
563af6ab5fSopenharmony_cienum class Constant {
573af6ab5fSopenharmony_ci    JS_NAN,
583af6ab5fSopenharmony_ci    JS_HOLE,
593af6ab5fSopenharmony_ci    JS_INFINITY,
603af6ab5fSopenharmony_ci    JS_UNDEFINED,
613af6ab5fSopenharmony_ci    JS_NULL,
623af6ab5fSopenharmony_ci    JS_TRUE,
633af6ab5fSopenharmony_ci    JS_FALSE,
643af6ab5fSopenharmony_ci    JS_SYMBOL,
653af6ab5fSopenharmony_ci    JS_GLOBAL,
663af6ab5fSopenharmony_ci};
673af6ab5fSopenharmony_ci
683af6ab5fSopenharmony_ciclass DebugInfo {
693af6ab5fSopenharmony_cipublic:
703af6ab5fSopenharmony_ci    explicit DebugInfo(ArenaAllocator *allocator) : variableDebugInfo(allocator->Adapter()) {};
713af6ab5fSopenharmony_ci    DEFAULT_COPY_SEMANTIC(DebugInfo);
723af6ab5fSopenharmony_ci    DEFAULT_MOVE_SEMANTIC(DebugInfo);
733af6ab5fSopenharmony_ci    ~DebugInfo() = default;
743af6ab5fSopenharmony_ci
753af6ab5fSopenharmony_ci    ArenaVector<const binder::Scope *> variableDebugInfo;
763af6ab5fSopenharmony_ci    const ir::Statement *firstStmt {};
773af6ab5fSopenharmony_ci};
783af6ab5fSopenharmony_ci
793af6ab5fSopenharmony_ciclass PandaGen {
803af6ab5fSopenharmony_cipublic:
813af6ab5fSopenharmony_ci    explicit PandaGen(ArenaAllocator *allocator, CompilerContext *context, binder::FunctionScope *scope)
823af6ab5fSopenharmony_ci        : allocator_(allocator),
833af6ab5fSopenharmony_ci          context_(context),
843af6ab5fSopenharmony_ci          builder_(nullptr),
853af6ab5fSopenharmony_ci          debugInfo_(allocator_),
863af6ab5fSopenharmony_ci          topScope_(scope),
873af6ab5fSopenharmony_ci          scope_(topScope_),
883af6ab5fSopenharmony_ci          rootNode_(scope->Node()),
893af6ab5fSopenharmony_ci          insns_(allocator_->Adapter()),
903af6ab5fSopenharmony_ci          catchList_(allocator_->Adapter()),
913af6ab5fSopenharmony_ci          strings_(allocator_->Adapter()),
923af6ab5fSopenharmony_ci          buffStorage_(allocator_->Adapter()),
933af6ab5fSopenharmony_ci          ra_(this)
943af6ab5fSopenharmony_ci    {
953af6ab5fSopenharmony_ci    }
963af6ab5fSopenharmony_ci    ~PandaGen() = default;
973af6ab5fSopenharmony_ci    NO_COPY_SEMANTIC(PandaGen);
983af6ab5fSopenharmony_ci    NO_MOVE_SEMANTIC(PandaGen);
993af6ab5fSopenharmony_ci
1003af6ab5fSopenharmony_ci    inline ArenaAllocator *Allocator() const
1013af6ab5fSopenharmony_ci    {
1023af6ab5fSopenharmony_ci        return allocator_;
1033af6ab5fSopenharmony_ci    }
1043af6ab5fSopenharmony_ci
1053af6ab5fSopenharmony_ci    inline CompilerContext *Context() const
1063af6ab5fSopenharmony_ci    {
1073af6ab5fSopenharmony_ci        return context_;
1083af6ab5fSopenharmony_ci    }
1093af6ab5fSopenharmony_ci
1103af6ab5fSopenharmony_ci    const ArenaSet<util::StringView> &Strings() const
1113af6ab5fSopenharmony_ci    {
1123af6ab5fSopenharmony_ci        return strings_;
1133af6ab5fSopenharmony_ci    }
1143af6ab5fSopenharmony_ci
1153af6ab5fSopenharmony_ci    const ArenaVector<CatchTable *> &CatchList() const
1163af6ab5fSopenharmony_ci    {
1173af6ab5fSopenharmony_ci        return catchList_;
1183af6ab5fSopenharmony_ci    }
1193af6ab5fSopenharmony_ci
1203af6ab5fSopenharmony_ci    binder::FunctionScope *TopScope() const
1213af6ab5fSopenharmony_ci    {
1223af6ab5fSopenharmony_ci        return topScope_;
1233af6ab5fSopenharmony_ci    }
1243af6ab5fSopenharmony_ci
1253af6ab5fSopenharmony_ci    binder::Scope *Scope() const
1263af6ab5fSopenharmony_ci    {
1273af6ab5fSopenharmony_ci        return scope_;
1283af6ab5fSopenharmony_ci    }
1293af6ab5fSopenharmony_ci
1303af6ab5fSopenharmony_ci    const ir::AstNode *RootNode() const
1313af6ab5fSopenharmony_ci    {
1323af6ab5fSopenharmony_ci        return rootNode_;
1333af6ab5fSopenharmony_ci    }
1343af6ab5fSopenharmony_ci
1353af6ab5fSopenharmony_ci    ArenaList<IRNode *> &Insns()
1363af6ab5fSopenharmony_ci    {
1373af6ab5fSopenharmony_ci        return insns_;
1383af6ab5fSopenharmony_ci    }
1393af6ab5fSopenharmony_ci
1403af6ab5fSopenharmony_ci    const ArenaList<IRNode *> &Insns() const
1413af6ab5fSopenharmony_ci    {
1423af6ab5fSopenharmony_ci        return insns_;
1433af6ab5fSopenharmony_ci    }
1443af6ab5fSopenharmony_ci
1453af6ab5fSopenharmony_ci    void SetInsns(ArenaList<IRNode *> &newInsns)
1463af6ab5fSopenharmony_ci    {
1473af6ab5fSopenharmony_ci        insns_.assign(newInsns.begin(), newInsns.end());
1483af6ab5fSopenharmony_ci    }
1493af6ab5fSopenharmony_ci
1503af6ab5fSopenharmony_ci    VReg AllocReg()
1513af6ab5fSopenharmony_ci    {
1523af6ab5fSopenharmony_ci        if (usedRegs_ > UINT16_MAX) {
1533af6ab5fSopenharmony_ci            throw Error(ErrorType::GENERIC, "Can't alloc new reg because all regs ran out");
1543af6ab5fSopenharmony_ci        }
1553af6ab5fSopenharmony_ci        return usedRegs_++;
1563af6ab5fSopenharmony_ci    }
1573af6ab5fSopenharmony_ci
1583af6ab5fSopenharmony_ci    VReg NextReg() const
1593af6ab5fSopenharmony_ci    {
1603af6ab5fSopenharmony_ci        return usedRegs_;
1613af6ab5fSopenharmony_ci    }
1623af6ab5fSopenharmony_ci
1633af6ab5fSopenharmony_ci    uint32_t TotalRegsNum() const
1643af6ab5fSopenharmony_ci    {
1653af6ab5fSopenharmony_ci        return totalRegs_;
1663af6ab5fSopenharmony_ci    }
1673af6ab5fSopenharmony_ci
1683af6ab5fSopenharmony_ci    size_t LabelCount() const
1693af6ab5fSopenharmony_ci    {
1703af6ab5fSopenharmony_ci        return labelId_;
1713af6ab5fSopenharmony_ci    }
1723af6ab5fSopenharmony_ci
1733af6ab5fSopenharmony_ci    const DebugInfo &Debuginfo() const
1743af6ab5fSopenharmony_ci    {
1753af6ab5fSopenharmony_ci        return debugInfo_;
1763af6ab5fSopenharmony_ci    }
1773af6ab5fSopenharmony_ci
1783af6ab5fSopenharmony_ci    FunctionBuilder *FuncBuilder() const
1793af6ab5fSopenharmony_ci    {
1803af6ab5fSopenharmony_ci        return builder_;
1813af6ab5fSopenharmony_ci    }
1823af6ab5fSopenharmony_ci
1833af6ab5fSopenharmony_ci    EnvScope *GetEnvScope() const
1843af6ab5fSopenharmony_ci    {
1853af6ab5fSopenharmony_ci        return envScope_;
1863af6ab5fSopenharmony_ci    }
1873af6ab5fSopenharmony_ci
1883af6ab5fSopenharmony_ci    const ArenaVector<compiler::LiteralBuffer *> &BuffStorage() const
1893af6ab5fSopenharmony_ci    {
1903af6ab5fSopenharmony_ci        return buffStorage_;
1913af6ab5fSopenharmony_ci    }
1923af6ab5fSopenharmony_ci
1933af6ab5fSopenharmony_ci    OptionalChain *GetOptionalChain() const
1943af6ab5fSopenharmony_ci    {
1953af6ab5fSopenharmony_ci        return optionalChain_;
1963af6ab5fSopenharmony_ci    }
1973af6ab5fSopenharmony_ci
1983af6ab5fSopenharmony_ci    uint32_t IcSize() const
1993af6ab5fSopenharmony_ci    {
2003af6ab5fSopenharmony_ci        return ic_.Size();
2013af6ab5fSopenharmony_ci    }
2023af6ab5fSopenharmony_ci
2033af6ab5fSopenharmony_ci    void SetSourceLocationFlag(lexer::SourceLocationFlag flag)
2043af6ab5fSopenharmony_ci    {
2053af6ab5fSopenharmony_ci        ra_.SetSourceLocationFlag(flag);
2063af6ab5fSopenharmony_ci    }
2073af6ab5fSopenharmony_ci
2083af6ab5fSopenharmony_ci    void AdjustSpillInsns()
2093af6ab5fSopenharmony_ci    {
2103af6ab5fSopenharmony_ci        ra_.AdjustInsRegWhenHasSpill();
2113af6ab5fSopenharmony_ci        totalRegs_ += ra_.GetSpillRegsCount();
2123af6ab5fSopenharmony_ci    }
2133af6ab5fSopenharmony_ci
2143af6ab5fSopenharmony_ci    uint16_t GetSpillRegsCount() const
2153af6ab5fSopenharmony_ci    {
2163af6ab5fSopenharmony_ci        if (ra_.HasSpill()) {
2173af6ab5fSopenharmony_ci            return ra_.GetSpillRegsCount();
2183af6ab5fSopenharmony_ci        }
2193af6ab5fSopenharmony_ci        return 0;
2203af6ab5fSopenharmony_ci    }
2213af6ab5fSopenharmony_ci
2223af6ab5fSopenharmony_ci    panda::panda_file::FunctionKind GetFunctionKind() const
2233af6ab5fSopenharmony_ci    {
2243af6ab5fSopenharmony_ci        return funcKind_;
2253af6ab5fSopenharmony_ci    }
2263af6ab5fSopenharmony_ci
2273af6ab5fSopenharmony_ci    bool IsConcurrent() const
2283af6ab5fSopenharmony_ci    {
2293af6ab5fSopenharmony_ci        return funcKind_ == panda::panda_file::FunctionKind::CONCURRENT_FUNCTION;
2303af6ab5fSopenharmony_ci    }
2313af6ab5fSopenharmony_ci
2323af6ab5fSopenharmony_ci    bool IsSendable() const
2333af6ab5fSopenharmony_ci    {
2343af6ab5fSopenharmony_ci        return (funcKind_ & panda::panda_file::FunctionKind::SENDABLE_FUNCTION) != 0;
2353af6ab5fSopenharmony_ci    }
2363af6ab5fSopenharmony_ci
2373af6ab5fSopenharmony_ci    void SetFunctionKind();
2383af6ab5fSopenharmony_ci    void SetInSendable();
2393af6ab5fSopenharmony_ci
2403af6ab5fSopenharmony_ci    bool IsDebug() const;
2413af6ab5fSopenharmony_ci    bool isDebuggerEvaluateExpressionMode() const;
2423af6ab5fSopenharmony_ci    std::string SourceFile() const;
2433af6ab5fSopenharmony_ci    uint32_t ParamCount() const;
2443af6ab5fSopenharmony_ci    uint32_t FormalParametersCount() const;
2453af6ab5fSopenharmony_ci    uint32_t InternalParamCount() const;
2463af6ab5fSopenharmony_ci    const util::StringView &InternalName() const;
2473af6ab5fSopenharmony_ci    const util::StringView &FunctionName() const;
2483af6ab5fSopenharmony_ci    binder::Binder *Binder() const;
2493af6ab5fSopenharmony_ci
2503af6ab5fSopenharmony_ci    Label *AllocLabel();
2513af6ab5fSopenharmony_ci
2523af6ab5fSopenharmony_ci    bool FunctionHasFinalizer() const;
2533af6ab5fSopenharmony_ci    bool IsAsyncFunction() const;
2543af6ab5fSopenharmony_ci    void FunctionInit(CatchTable* catchTable);
2553af6ab5fSopenharmony_ci    void FunctionEnter();
2563af6ab5fSopenharmony_ci    void FunctionExit();
2573af6ab5fSopenharmony_ci
2583af6ab5fSopenharmony_ci    LiteralBuffer *NewLiteralBuffer();
2593af6ab5fSopenharmony_ci    int32_t AddLiteralBuffer(LiteralBuffer *buf);
2603af6ab5fSopenharmony_ci    int32_t AddLexicalVarNamesForDebugInfo(ArenaMap<uint32_t, std::pair<util::StringView, int>> &lexicalVars);
2613af6ab5fSopenharmony_ci
2623af6ab5fSopenharmony_ci    void InitializeLexEnv(const ir::AstNode *node);
2633af6ab5fSopenharmony_ci    void CopyFunctionArguments(const ir::AstNode *node);
2643af6ab5fSopenharmony_ci    void GetFunctionObject(const ir::AstNode *node);
2653af6ab5fSopenharmony_ci    void GetNewTarget(const ir::AstNode *node);
2663af6ab5fSopenharmony_ci    void GetThis(const ir::AstNode *node);
2673af6ab5fSopenharmony_ci    void SetThis(const ir::AstNode *node);
2683af6ab5fSopenharmony_ci    void LoadVar(const ir::Identifier *node, const binder::ScopeFindResult &result);
2693af6ab5fSopenharmony_ci    void StoreVar(const ir::AstNode *node, const binder::ScopeFindResult &result, bool isDeclaration);
2703af6ab5fSopenharmony_ci
2713af6ab5fSopenharmony_ci    void StLetOrClassToGlobalRecord(const ir::AstNode *node, const util::StringView &name);
2723af6ab5fSopenharmony_ci    void StConstToGlobalRecord(const ir::AstNode *node, const util::StringView &name);
2733af6ab5fSopenharmony_ci
2743af6ab5fSopenharmony_ci    void StoreAccumulator(const ir::AstNode *node, VReg vreg);
2753af6ab5fSopenharmony_ci    void LoadAccFromArgs(const ir::AstNode *node);
2763af6ab5fSopenharmony_ci    void LoadObjProperty(const ir::AstNode *node, VReg obj, const Operand &prop);
2773af6ab5fSopenharmony_ci
2783af6ab5fSopenharmony_ci    void LoadObjByName(const ir::AstNode *node, VReg obj, const util::StringView &prop);
2793af6ab5fSopenharmony_ci
2803af6ab5fSopenharmony_ci    void StoreObjProperty(const ir::AstNode *node, VReg obj, const Operand &prop);
2813af6ab5fSopenharmony_ci    void DefineOwnProperty(const ir::AstNode *node, VReg obj, const Operand &prop);
2823af6ab5fSopenharmony_ci    void DefineClassPrivateField(const ir::AstNode *node, uint32_t level, uint32_t slot, VReg obj);
2833af6ab5fSopenharmony_ci    void StoreOwnProperty(const ir::AstNode *node, VReg obj, const Operand &prop, bool nameSetting = false);
2843af6ab5fSopenharmony_ci    void DeleteObjProperty(const ir::AstNode *node, VReg obj, const Operand &prop);
2853af6ab5fSopenharmony_ci    void LoadAccumulator(const ir::AstNode *node, VReg reg);
2863af6ab5fSopenharmony_ci    void LoadGlobalVar(const ir::AstNode *node, const util::StringView &name);
2873af6ab5fSopenharmony_ci    void StoreGlobalVar(const ir::AstNode *node, const util::StringView &name);
2883af6ab5fSopenharmony_ci
2893af6ab5fSopenharmony_ci    void LoadObjByNameViaDebugger(const ir::AstNode *node, const util::StringView &name, bool throwUndefinedIfHole);
2903af6ab5fSopenharmony_ci    void TryLoadGlobalByName(const ir::AstNode *node, const util::StringView &name);
2913af6ab5fSopenharmony_ci    void StoreObjByNameViaDebugger(const ir::AstNode *node, const util::StringView &name);
2923af6ab5fSopenharmony_ci    void TryStoreGlobalByName(const ir::AstNode *node, const util::StringView &name);
2933af6ab5fSopenharmony_ci
2943af6ab5fSopenharmony_ci    void LoadAccFromLexEnv(const ir::AstNode *node, const binder::ScopeFindResult &result);
2953af6ab5fSopenharmony_ci    void StoreAccToLexEnv(const ir::AstNode *node, const binder::ScopeFindResult &result, bool isDeclaration);
2963af6ab5fSopenharmony_ci
2973af6ab5fSopenharmony_ci    void LoadAccumulatorString(const ir::AstNode *node, const util::StringView &str);
2983af6ab5fSopenharmony_ci    void LoadAccumulatorFloat(const ir::AstNode *node, double num);
2993af6ab5fSopenharmony_ci    void LoadAccumulatorInt(const ir::AstNode *node, int32_t num);
3003af6ab5fSopenharmony_ci    void LoadAccumulatorInt(const ir::AstNode *node, size_t num);
3013af6ab5fSopenharmony_ci    void LoadAccumulatorBigInt(const ir::AstNode *node, const util::StringView &num);
3023af6ab5fSopenharmony_ci
3033af6ab5fSopenharmony_ci    void LoadConst(const ir::AstNode *node, Constant id);
3043af6ab5fSopenharmony_ci    void StoreConst(const ir::AstNode *node, VReg reg, Constant id);
3053af6ab5fSopenharmony_ci    void MoveVreg(const ir::AstNode *node, VReg vd, VReg vs);
3063af6ab5fSopenharmony_ci
3073af6ab5fSopenharmony_ci    void SetLabel(const ir::AstNode *node, Label *label);
3083af6ab5fSopenharmony_ci    void Branch(const ir::AstNode *node, class Label *label);
3093af6ab5fSopenharmony_ci    bool CheckControlFlowChange() const;
3103af6ab5fSopenharmony_ci    Label *ControlFlowChangeBreak(const ir::Identifier *label = nullptr);
3113af6ab5fSopenharmony_ci    Label *ControlFlowChangeContinue(const ir::Identifier *label);
3123af6ab5fSopenharmony_ci    void ControlFlowChangeReturn();
3133af6ab5fSopenharmony_ci
3143af6ab5fSopenharmony_ci    void Condition(const ir::AstNode *node, lexer::TokenType op, VReg lhs, class Label *ifFalse);
3153af6ab5fSopenharmony_ci    void Unary(const ir::AstNode *node, lexer::TokenType op, VReg operand);
3163af6ab5fSopenharmony_ci    void Binary(const ir::AstNode *node, lexer::TokenType op, VReg lhs);
3173af6ab5fSopenharmony_ci    void Equal(const ir::AstNode *node, VReg lhs);
3183af6ab5fSopenharmony_ci    void NotEqual(const ir::AstNode *node, VReg lhs);
3193af6ab5fSopenharmony_ci    void StrictEqual(const ir::AstNode *node, VReg lhs);
3203af6ab5fSopenharmony_ci    void StrictNotEqual(const ir::AstNode *node, VReg lhs);
3213af6ab5fSopenharmony_ci    void LessThan(const ir::AstNode *node, VReg lhs);
3223af6ab5fSopenharmony_ci    void LessEqual(const ir::AstNode *node, VReg lhs);
3233af6ab5fSopenharmony_ci    void GreaterThan(const ir::AstNode *node, VReg lhs);
3243af6ab5fSopenharmony_ci    void GreaterEqual(const ir::AstNode *node, VReg lhs);
3253af6ab5fSopenharmony_ci    void IsTrue(const ir::AstNode *node);
3263af6ab5fSopenharmony_ci
3273af6ab5fSopenharmony_ci    void BranchIfUndefined(const ir::AstNode *node, class Label *target);
3283af6ab5fSopenharmony_ci    void BranchIfStrictUndefined(const ir::AstNode *node, class Label *target);
3293af6ab5fSopenharmony_ci    void BranchIfStrictNotUndefined(const ir::AstNode *node, class Label *target);
3303af6ab5fSopenharmony_ci    void BranchIfNotUndefined(const ir::AstNode *node, class Label *target);
3313af6ab5fSopenharmony_ci    void BranchIfHole(const ir::AstNode *node, class Label *target);
3323af6ab5fSopenharmony_ci    void BranchIfTrue(const ir::AstNode *node, class Label *target);
3333af6ab5fSopenharmony_ci    void BranchIfNotTrue(const ir::AstNode *node, class Label *target);
3343af6ab5fSopenharmony_ci    void BranchIfFalse(const ir::AstNode *node, class Label *target);
3353af6ab5fSopenharmony_ci    void BranchIfNotFalse(const ir::AstNode *node, class Label *target);
3363af6ab5fSopenharmony_ci    void BranchIfStrictNull(const ir::AstNode *node, class Label *target);
3373af6ab5fSopenharmony_ci
3383af6ab5fSopenharmony_ci    void EmitThrow(const ir::AstNode *node);
3393af6ab5fSopenharmony_ci    void EmitRethrow(const ir::AstNode *node);
3403af6ab5fSopenharmony_ci    void EmitReturn(const ir::AstNode *node);
3413af6ab5fSopenharmony_ci    void EmitReturnUndefined(const ir::AstNode *node);
3423af6ab5fSopenharmony_ci    void ValidateClassDirectReturn(const ir::AstNode *node);
3433af6ab5fSopenharmony_ci    void DirectReturn(const ir::AstNode *node);
3443af6ab5fSopenharmony_ci    void ExplicitReturn(const ir::AstNode *node);
3453af6ab5fSopenharmony_ci    void ImplicitReturn(const ir::AstNode *node);
3463af6ab5fSopenharmony_ci    void EmitAwait(const ir::AstNode *node);
3473af6ab5fSopenharmony_ci
3483af6ab5fSopenharmony_ci    void CallThis(const ir::AstNode *node, VReg startReg, size_t argCount);
3493af6ab5fSopenharmony_ci    void Call(const ir::AstNode *node, VReg startReg, size_t argCount);
3503af6ab5fSopenharmony_ci    void CallSpread(const ir::AstNode *node, VReg func, VReg thisReg, VReg args);
3513af6ab5fSopenharmony_ci    void SuperCall(const ir::AstNode *node, VReg startReg, size_t argCount);
3523af6ab5fSopenharmony_ci    void SuperCallSpread(const ir::AstNode *node, VReg vs);
3533af6ab5fSopenharmony_ci    void SuperCallForwardAllArgs(const ir::AstNode *node, VReg funcObj);
3543af6ab5fSopenharmony_ci    void NotifyConcurrentResult(const ir::AstNode *node);
3553af6ab5fSopenharmony_ci    void CallInit(const ir::AstNode *node, VReg thisReg);
3563af6ab5fSopenharmony_ci
3573af6ab5fSopenharmony_ci    void NewObject(const ir::AstNode *node, VReg startReg, size_t argCount);
3583af6ab5fSopenharmony_ci    void DefineFunction(const ir::AstNode *node, const ir::ScriptFunction *realNode, const util::StringView &name);
3593af6ab5fSopenharmony_ci
3603af6ab5fSopenharmony_ci    void TypeOf(const ir::AstNode *node);
3613af6ab5fSopenharmony_ci    void NewObjSpread(const ir::AstNode *node, VReg obj);
3623af6ab5fSopenharmony_ci    void GetUnmappedArgs(const ir::AstNode *node);
3633af6ab5fSopenharmony_ci
3643af6ab5fSopenharmony_ci    void Negate(const ir::AstNode *node);
3653af6ab5fSopenharmony_ci    void ToNumber(const ir::AstNode *node, VReg arg);
3663af6ab5fSopenharmony_ci    void ToNumeric(const ir::AstNode *node, VReg arg);
3673af6ab5fSopenharmony_ci
3683af6ab5fSopenharmony_ci    void CreateGeneratorObj(const ir::AstNode *node, VReg funcObj);
3693af6ab5fSopenharmony_ci    void ResumeGenerator(const ir::AstNode *node, VReg genObj);
3703af6ab5fSopenharmony_ci    void GetResumeMode(const ir::AstNode *node, VReg genObj);
3713af6ab5fSopenharmony_ci
3723af6ab5fSopenharmony_ci    void AsyncFunctionEnter(const ir::AstNode *node);
3733af6ab5fSopenharmony_ci    void AsyncFunctionAwait(const ir::AstNode *node, VReg asyncFuncObj);
3743af6ab5fSopenharmony_ci    void AsyncFunctionResolve(const ir::AstNode *node, VReg asyncFuncObj);
3753af6ab5fSopenharmony_ci    void AsyncFunctionReject(const ir::AstNode *node, VReg asyncFuncObj);
3763af6ab5fSopenharmony_ci
3773af6ab5fSopenharmony_ci    void GeneratorYield(const ir::AstNode *node, VReg genObj);
3783af6ab5fSopenharmony_ci    void GeneratorComplete(const ir::AstNode *node, VReg genObj);
3793af6ab5fSopenharmony_ci    void CreateAsyncGeneratorObj(const ir::AstNode *node, VReg funcObj);
3803af6ab5fSopenharmony_ci    void CreateIterResultObject(const ir::AstNode *node, VReg value, VReg done);
3813af6ab5fSopenharmony_ci    void SuspendGenerator(const ir::AstNode *node, VReg genObj);
3823af6ab5fSopenharmony_ci
3833af6ab5fSopenharmony_ci    void AsyncGeneratorResolve(const ir::AstNode *node, VReg asyncGenObj, VReg value, VReg canSuspend);
3843af6ab5fSopenharmony_ci    void AsyncGeneratorReject(const ir::AstNode *node, VReg asyncGenObj);
3853af6ab5fSopenharmony_ci
3863af6ab5fSopenharmony_ci    void GetTemplateObject(const ir::AstNode *node, VReg value);
3873af6ab5fSopenharmony_ci    void CopyRestArgs(const ir::AstNode *node, uint32_t index);
3883af6ab5fSopenharmony_ci
3893af6ab5fSopenharmony_ci    void GetPropIterator(const ir::AstNode *node);
3903af6ab5fSopenharmony_ci    void GetNextPropName(const ir::AstNode *node, VReg iter);
3913af6ab5fSopenharmony_ci    void CreateEmptyObject(const ir::AstNode *node);
3923af6ab5fSopenharmony_ci    void CreateObjectWithBuffer(const ir::AstNode *node, uint32_t idx);
3933af6ab5fSopenharmony_ci    void SetObjectWithProto(const ir::AstNode *node, VReg proto, VReg obj);
3943af6ab5fSopenharmony_ci    void CopyDataProperties(const ir::AstNode *node, VReg dst);
3953af6ab5fSopenharmony_ci    void DefineGetterSetterByValue(const ir::AstNode *node, VReg obj, VReg name, VReg getter, VReg setter,
3963af6ab5fSopenharmony_ci                                   bool setName);
3973af6ab5fSopenharmony_ci    void CreateEmptyArray(const ir::AstNode *node);
3983af6ab5fSopenharmony_ci    void CreateArray(const ir::AstNode *node, const ArenaVector<ir::Expression *> &elements, VReg obj);
3993af6ab5fSopenharmony_ci    void CreateArrayWithBuffer(const ir::AstNode *node, uint32_t idx);
4003af6ab5fSopenharmony_ci    void StoreArraySpread(const ir::AstNode *node, VReg array, VReg index);
4013af6ab5fSopenharmony_ci
4023af6ab5fSopenharmony_ci    void ThrowIfNotObject(const ir::AstNode *node, VReg obj);
4033af6ab5fSopenharmony_ci    void ThrowThrowNotExist(const ir::AstNode *node);
4043af6ab5fSopenharmony_ci    void GetIterator(const ir::AstNode *node);
4053af6ab5fSopenharmony_ci    void GetAsyncIterator(const ir::AstNode *node);
4063af6ab5fSopenharmony_ci
4073af6ab5fSopenharmony_ci    void CreateObjectWithExcludedKeys(const ir::AstNode *node, VReg obj, VReg argStart, size_t argCount);
4083af6ab5fSopenharmony_ci    void ThrowObjectNonCoercible(const ir::AstNode *node);
4093af6ab5fSopenharmony_ci    void CloseIterator(const ir::AstNode *node, VReg iter);
4103af6ab5fSopenharmony_ci    void DefineClassWithBuffer(const ir::AstNode *node, const util::StringView &ctorId, int32_t litIdx, VReg base);
4113af6ab5fSopenharmony_ci    void DefineSendableClass(const ir::AstNode *node, const util::StringView &ctorId,
4123af6ab5fSopenharmony_ci                             int32_t litIdx, VReg base);
4133af6ab5fSopenharmony_ci    void LoadSendableClass(const ir::AstNode *node, int32_t level);
4143af6ab5fSopenharmony_ci
4153af6ab5fSopenharmony_ci    void LoadLocalModuleVariable(const ir::AstNode *node, const binder::ModuleVariable *variable);
4163af6ab5fSopenharmony_ci    void LoadExternalModuleVariable(const ir::AstNode *node, const binder::ModuleVariable *variable);
4173af6ab5fSopenharmony_ci    void StoreModuleVariable(const ir::AstNode *node, const binder::ModuleVariable *variable);
4183af6ab5fSopenharmony_ci    void GetModuleNamespace(const ir::AstNode *node, uint32_t index);
4193af6ab5fSopenharmony_ci    void DynamicImportCall(const ir::AstNode *node);
4203af6ab5fSopenharmony_ci
4213af6ab5fSopenharmony_ci    void StSuperByName(const ir::AstNode *node, VReg obj, const util::StringView &key);
4223af6ab5fSopenharmony_ci    void LdSuperByName(const ir::AstNode *node, VReg obj, const util::StringView &key);
4233af6ab5fSopenharmony_ci    void StSuperByValue(const ir::AstNode *node, VReg obj, VReg prop);
4243af6ab5fSopenharmony_ci    void LdSuperByValue(const ir::AstNode *node, VReg obj);
4253af6ab5fSopenharmony_ci    void StoreSuperProperty(const ir::AstNode *node, VReg obj, const Operand &prop);
4263af6ab5fSopenharmony_ci    void LoadSuperProperty(const ir::AstNode *node, VReg obj, const Operand &prop);
4273af6ab5fSopenharmony_ci
4283af6ab5fSopenharmony_ci    void PopLexEnv(const ir::AstNode *node);
4293af6ab5fSopenharmony_ci    void GenDebugger(const ir::AstNode *node);
4303af6ab5fSopenharmony_ci    void NewLexicalEnv(const ir::AstNode *node, uint32_t num, binder::VariableScope *scope);
4313af6ab5fSopenharmony_ci    void NewLexEnv(const ir::AstNode *node, uint32_t num);
4323af6ab5fSopenharmony_ci    void NewSendableEnv(const ir::AstNode *node, uint32_t num);
4333af6ab5fSopenharmony_ci    void NewLexEnvWithScopeInfo(const ir::AstNode *node, uint32_t num, int32_t scopeInfoIdx);
4343af6ab5fSopenharmony_ci    void LoadLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot);
4353af6ab5fSopenharmony_ci    void LoadSendableVar(const ir::AstNode *node, uint32_t level, uint32_t slot);
4363af6ab5fSopenharmony_ci    void LoadLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot, const util::StringView &name);
4373af6ab5fSopenharmony_ci    void StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot);
4383af6ab5fSopenharmony_ci    void StoreSendableVar(const ir::AstNode *node, uint32_t level, uint32_t slot);
4393af6ab5fSopenharmony_ci    void StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot, const binder::LocalVariable *local);
4403af6ab5fSopenharmony_ci    void StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot, VReg value);
4413af6ab5fSopenharmony_ci
4423af6ab5fSopenharmony_ci    void ThrowIfSuperNotCorrectCall(const ir::AstNode *node, int64_t num);
4433af6ab5fSopenharmony_ci    void ThrowUndefinedIfHole(const ir::AstNode *node, const util::StringView &name);
4443af6ab5fSopenharmony_ci    void ThrowConstAssignment(const ir::AstNode *node, const util::StringView &name);
4453af6ab5fSopenharmony_ci
4463af6ab5fSopenharmony_ci    uint32_t TryDepth() const;
4473af6ab5fSopenharmony_ci    CatchTable *CreateCatchTable();
4483af6ab5fSopenharmony_ci    void SortCatchTables();
4493af6ab5fSopenharmony_ci
4503af6ab5fSopenharmony_ci    void LoadObjByIndex(const ir::AstNode *node, VReg obj, int64_t index);
4513af6ab5fSopenharmony_ci    void LoadObjByValue(const ir::AstNode *node, VReg obj);
4523af6ab5fSopenharmony_ci
4533af6ab5fSopenharmony_ci    void StoreObjByName(const ir::AstNode *node, VReg obj, const util::StringView &prop);
4543af6ab5fSopenharmony_ci    void StoreObjByIndex(const ir::AstNode *node, VReg obj, int64_t index);
4553af6ab5fSopenharmony_ci    void StoreObjByValue(const ir::AstNode *node, VReg obj, VReg prop);
4563af6ab5fSopenharmony_ci
4573af6ab5fSopenharmony_ci    void DefineFieldByName(const ir::AstNode *node, VReg obj, const util::StringView &prop);
4583af6ab5fSopenharmony_ci    void DefineFieldByIndex(const ir::AstNode *node, VReg obj, int64_t index);
4593af6ab5fSopenharmony_ci    void DefineFieldByValue(const ir::AstNode *node, VReg obj, VReg prop);
4603af6ab5fSopenharmony_ci
4613af6ab5fSopenharmony_ci    void StOwnByName(const ir::AstNode *node, VReg obj, const util::StringView &prop, bool nameSetting = false);
4623af6ab5fSopenharmony_ci    void StOwnByValue(const ir::AstNode *node, VReg obj, VReg prop, bool nameSetting = false);
4633af6ab5fSopenharmony_ci    void StOwnByIndex(const ir::AstNode *node, VReg obj, int64_t index);
4643af6ab5fSopenharmony_ci
4653af6ab5fSopenharmony_ci    Operand ToNamedPropertyKey(const ir::Expression *prop, bool isComputed);
4663af6ab5fSopenharmony_ci    Operand ToPropertyKey(const ir::Expression *prop, bool isComputed);
4673af6ab5fSopenharmony_ci    VReg LoadPropertyKey(const ir::Expression *prop, bool isComputed);
4683af6ab5fSopenharmony_ci    void ToComputedPropertyKey(const ir::AstNode *node);
4693af6ab5fSopenharmony_ci
4703af6ab5fSopenharmony_ci    void ReArrangeIc();
4713af6ab5fSopenharmony_ci
4723af6ab5fSopenharmony_ci    void CreatePrivateProperty(const ir::AstNode *node, uint32_t num, int32_t bufIdx);
4733af6ab5fSopenharmony_ci    void TestIn(const ir::AstNode *node, uint32_t level, uint32_t slot);
4743af6ab5fSopenharmony_ci    void LoadPrivateProperty(const ir::AstNode *node, uint32_t level, uint32_t slot);
4753af6ab5fSopenharmony_ci    void StorePrivateProperty(const ir::AstNode *node, uint32_t level, uint32_t slot, VReg obj);
4763af6ab5fSopenharmony_ci    void ThrowTypeErrorIfFalse(const ir::AstNode *node, util::StringView str);
4773af6ab5fSopenharmony_ci    void ThrowTypeError(const ir::AstNode *node, util::StringView str);
4783af6ab5fSopenharmony_ci
4793af6ab5fSopenharmony_ci    /*
4803af6ab5fSopenharmony_ci     * Since the [Function] is not implemented yet, We compile the test262's framework code
4813af6ab5fSopenharmony_ci     * which obtains the [global] Object as following into [LoadConst.Global] directly.
4823af6ab5fSopenharmony_ci     * ```
4833af6ab5fSopenharmony_ci     *    var __globalObject = Function("return this;")();
4843af6ab5fSopenharmony_ci     *    var __globalObject = new Function("return this;")();
4853af6ab5fSopenharmony_ci     * ```
4863af6ab5fSopenharmony_ci     */
4873af6ab5fSopenharmony_ci    bool TryCompileFunctionCallOrNewExpression(const ir::Expression *expr);
4883af6ab5fSopenharmony_ci
4893af6ab5fSopenharmony_ci    void SetFirstStmt(const ir::Statement *stmt)
4903af6ab5fSopenharmony_ci    {
4913af6ab5fSopenharmony_ci        debugInfo_.firstStmt = stmt;
4923af6ab5fSopenharmony_ci    }
4933af6ab5fSopenharmony_ci
4943af6ab5fSopenharmony_ci    [[noreturn]] static void Unimplemented()
4953af6ab5fSopenharmony_ci    {
4963af6ab5fSopenharmony_ci        throw Error(ErrorType::GENERIC, "Unimplemented code path");
4973af6ab5fSopenharmony_ci    }
4983af6ab5fSopenharmony_ci
4993af6ab5fSopenharmony_ci    IcSizeType GetCurrentSlot() const
5003af6ab5fSopenharmony_ci    {
5013af6ab5fSopenharmony_ci        return currentSlot_;
5023af6ab5fSopenharmony_ci    }
5033af6ab5fSopenharmony_ci
5043af6ab5fSopenharmony_ci    void IncreaseCurrentSlot(ICSlot inc)
5053af6ab5fSopenharmony_ci    {
5063af6ab5fSopenharmony_ci        currentSlot_ += inc;
5073af6ab5fSopenharmony_ci    }
5083af6ab5fSopenharmony_ci
5093af6ab5fSopenharmony_ci    void ResetCurrentSlot(IcSizeType slotSize)
5103af6ab5fSopenharmony_ci    {
5113af6ab5fSopenharmony_ci        currentSlot_ = slotSize;
5123af6ab5fSopenharmony_ci    }
5133af6ab5fSopenharmony_ci
5143af6ab5fSopenharmony_ci    void SetIcOverFlow()
5153af6ab5fSopenharmony_ci    {
5163af6ab5fSopenharmony_ci        icOverFlow_ = true;
5173af6ab5fSopenharmony_ci    }
5183af6ab5fSopenharmony_ci
5193af6ab5fSopenharmony_ci    bool IsIcOverFlow() const
5203af6ab5fSopenharmony_ci    {
5213af6ab5fSopenharmony_ci        return icOverFlow_;
5223af6ab5fSopenharmony_ci    }
5233af6ab5fSopenharmony_ci
5243af6ab5fSopenharmony_ciprivate:
5253af6ab5fSopenharmony_ci    ArenaAllocator *allocator_;
5263af6ab5fSopenharmony_ci    CompilerContext *context_;
5273af6ab5fSopenharmony_ci    FunctionBuilder *builder_;
5283af6ab5fSopenharmony_ci    DebugInfo debugInfo_;
5293af6ab5fSopenharmony_ci    binder::FunctionScope *topScope_;
5303af6ab5fSopenharmony_ci    binder::Scope *scope_;
5313af6ab5fSopenharmony_ci    const ir::AstNode *rootNode_;
5323af6ab5fSopenharmony_ci    ArenaList<IRNode *> insns_;
5333af6ab5fSopenharmony_ci    ArenaVector<CatchTable *> catchList_;
5343af6ab5fSopenharmony_ci    ArenaSet<util::StringView> strings_;
5353af6ab5fSopenharmony_ci    ArenaVector<LiteralBuffer *> buffStorage_;
5363af6ab5fSopenharmony_ci    EnvScope *envScope_ {};
5373af6ab5fSopenharmony_ci    DynamicContext *dynamicContext_ {};
5383af6ab5fSopenharmony_ci    OptionalChain *optionalChain_ {};
5393af6ab5fSopenharmony_ci    InlineCache ic_;
5403af6ab5fSopenharmony_ci    RegAllocator ra_;
5413af6ab5fSopenharmony_ci    IcSizeType currentSlot_ {0};
5423af6ab5fSopenharmony_ci
5433af6ab5fSopenharmony_ci    uint32_t usedRegs_ {0};
5443af6ab5fSopenharmony_ci    uint32_t totalRegs_ {0};
5453af6ab5fSopenharmony_ci    friend class ScopeContext;
5463af6ab5fSopenharmony_ci    friend class RegScope;
5473af6ab5fSopenharmony_ci    friend class LocalRegScope;
5483af6ab5fSopenharmony_ci    friend class LoopRegScope;
5493af6ab5fSopenharmony_ci    friend class ParamRegScope;
5503af6ab5fSopenharmony_ci    friend class FunctionRegScope;
5513af6ab5fSopenharmony_ci    friend class EnvScope;
5523af6ab5fSopenharmony_ci    friend class LoopEnvScope;
5533af6ab5fSopenharmony_ci    friend class DynamicContext;
5543af6ab5fSopenharmony_ci    friend class OptionalChain;
5553af6ab5fSopenharmony_ci    size_t labelId_ {0};
5563af6ab5fSopenharmony_ci    panda::panda_file::FunctionKind funcKind_ {panda::panda_file::FunctionKind::NONE};
5573af6ab5fSopenharmony_ci    bool icOverFlow_ {false};
5583af6ab5fSopenharmony_ci    bool inSendable_ {false};
5593af6ab5fSopenharmony_ci};
5603af6ab5fSopenharmony_ci}  // namespace panda::es2panda::compiler
5613af6ab5fSopenharmony_ci
5623af6ab5fSopenharmony_ci#endif
563