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