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