1/* 2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "pandagen.h" 17 18#include "varbinder/varbinder.h" 19#include "checker/checker.h" 20#include "checker/types/globalTypesHolder.h" 21#include "util/helpers.h" 22#include "varbinder/scope.h" 23#include "varbinder/variable.h" 24#include "compiler/base/catchTable.h" 25#include "compiler/base/lexenv.h" 26#include "compiler/base/literals.h" 27#include "public/public.h" 28#include "compiler/core/labelTarget.h" 29#include "compiler/core/regAllocator.h" 30#include "compiler/function/asyncFunctionBuilder.h" 31#include "compiler/function/asyncGeneratorFunctionBuilder.h" 32#include "compiler/function/functionBuilder.h" 33#include "compiler/function/generatorFunctionBuilder.h" 34#include "es2panda.h" 35#include "generated/isa.h" 36#include "ir/base/scriptFunction.h" 37#include "ir/base/spreadElement.h" 38#include "ir/statement.h" 39#include "ir/expressions/identifier.h" 40#include "ir/expressions/literals/numberLiteral.h" 41#include "ir/expressions/literals/stringLiteral.h" 42 43namespace ark::es2panda::compiler { 44 45#ifndef PANDA_WITH_ECMASCRIPT 46class EcmaDisabled : public IRNode { 47public: 48 template <typename... Args> 49 explicit EcmaDisabled(const ir::AstNode *node, [[maybe_unused]] Args &&...args) : IRNode(node) 50 { 51 UNREACHABLE(); 52 } 53 54 Formats GetFormats() const override 55 { 56 UNREACHABLE(); 57 } 58 59 size_t Registers([[maybe_unused]] std::array<VReg *, MAX_REG_OPERAND> *regs) override 60 { 61 UNREACHABLE(); 62 } 63 64 size_t Registers([[maybe_unused]] std::array<const VReg *, MAX_REG_OPERAND> *regs) const override 65 { 66 UNREACHABLE(); 67 } 68 69 size_t OutRegisters([[maybe_unused]] std::array<OutVReg, MAX_REG_OPERAND> *regs) const override 70 { 71 UNREACHABLE(); 72 } 73 74 void Transform([[maybe_unused]] pandasm::Ins *ins, [[maybe_unused]] ProgramElement *programElement, 75 [[maybe_unused]] uint32_t totalRegs) const override 76 { 77 UNREACHABLE(); 78 } 79}; 80 81using EcmaLdhole = EcmaDisabled; 82using EcmaLdnan = EcmaDisabled; 83using EcmaLdinfinity = EcmaDisabled; 84using EcmaLdglobal = EcmaDisabled; 85using EcmaLdundefined = EcmaDisabled; 86using EcmaLdsymbol = EcmaDisabled; 87using EcmaLdnull = EcmaDisabled; 88using EcmaLdtrue = EcmaDisabled; 89using EcmaLdfalse = EcmaDisabled; 90using EcmaTryldglobalbyname = EcmaDisabled; 91using EcmaTrystglobalbyname = EcmaDisabled; 92using EcmaLdobjbyname = EcmaDisabled; 93using EcmaStobjbyname = EcmaDisabled; 94using EcmaLdobjbyindex = EcmaDisabled; 95using EcmaLdobjbyvalue = EcmaDisabled; 96using EcmaStobjbyvalue = EcmaDisabled; 97using EcmaStobjbyindex = EcmaDisabled; 98using EcmaStownbyname = EcmaDisabled; 99using EcmaStownbyvalue = EcmaDisabled; 100using EcmaStownbyindex = EcmaDisabled; 101using EcmaDelobjprop = EcmaDisabled; 102using EcmaLdglobalvar = EcmaDisabled; 103using EcmaStglobalvar = EcmaDisabled; 104using EcmaLdbigint = EcmaDisabled; 105using EcmaEqdyn = EcmaDisabled; 106using EcmaNoteqdyn = EcmaDisabled; 107using EcmaStricteqdyn = EcmaDisabled; 108using EcmaStrictnoteqdyn = EcmaDisabled; 109using EcmaLessdyn = EcmaDisabled; 110using EcmaLesseqdyn = EcmaDisabled; 111using EcmaGreaterdyn = EcmaDisabled; 112using EcmaGreatereqdyn = EcmaDisabled; 113using EcmaTonumber = EcmaDisabled; 114using EcmaNegdyn = EcmaDisabled; 115using EcmaNotdyn = EcmaDisabled; 116using EcmaNegate = EcmaDisabled; 117using EcmaIncdyn = EcmaDisabled; 118using EcmaDecdyn = EcmaDisabled; 119using EcmaEqdyn = EcmaDisabled; 120using EcmaNoteqdyn = EcmaDisabled; 121using EcmaStricteqdyn = EcmaDisabled; 122using EcmaStrictnoteqdyn = EcmaDisabled; 123using EcmaLessdyn = EcmaDisabled; 124using EcmaLesseqdyn = EcmaDisabled; 125using EcmaGreaterdyn = EcmaDisabled; 126using EcmaGreatereqdyn = EcmaDisabled; 127using EcmaAdd2dyn = EcmaDisabled; 128using EcmaSub2dyn = EcmaDisabled; 129using EcmaMul2dyn = EcmaDisabled; 130using EcmaDiv2dyn = EcmaDisabled; 131using EcmaMod2dyn = EcmaDisabled; 132using EcmaExpdyn = EcmaDisabled; 133using EcmaShl2dyn = EcmaDisabled; 134using EcmaShr2dyn = EcmaDisabled; 135using EcmaAshr2dyn = EcmaDisabled; 136using EcmaAnd2dyn = EcmaDisabled; 137using EcmaOr2dyn = EcmaDisabled; 138using EcmaXor2dyn = EcmaDisabled; 139using EcmaIsindyn = EcmaDisabled; 140using EcmaInstanceofdyn = EcmaDisabled; 141using EcmaIsundefined = EcmaDisabled; 142using EcmaIsundefined = EcmaDisabled; 143using EcmaJtrue = EcmaDisabled; 144using EcmaIstrue = EcmaDisabled; 145using EcmaJfalse = EcmaDisabled; 146using EcmaIscoercible = EcmaDisabled; 147using EcmaThrowdyn = EcmaDisabled; 148using EcmaRethrowdyn = EcmaDisabled; 149using EcmaReturnDyn = EcmaDisabled; 150using EcmaReturnundefined = EcmaDisabled; 151using EcmaCall0thisdyn = EcmaDisabled; 152using EcmaCall1thisdyn = EcmaDisabled; 153using EcmaCall0dyn = EcmaDisabled; 154using EcmaCall1thisdyn = EcmaDisabled; 155using EcmaCall1dyn = EcmaDisabled; 156using EcmaCall2thisdyn = EcmaDisabled; 157using EcmaCall2dyn = EcmaDisabled; 158using EcmaCall3thisdyn = EcmaDisabled; 159using EcmaCall3dyn = EcmaDisabled; 160using EcmaCallithisrangedyn = EcmaDisabled; 161using EcmaCallirangedyn = EcmaDisabled; 162using EcmaCall1thisdyn = EcmaDisabled; 163using EcmaCall1dyn = EcmaDisabled; 164using EcmaCall2thisdyn = EcmaDisabled; 165using EcmaCall2dyn = EcmaDisabled; 166using EcmaCall3thisdyn = EcmaDisabled; 167using EcmaCall3dyn = EcmaDisabled; 168using EcmaCallithisrangedyn = EcmaDisabled; 169using EcmaCallirangedyn = EcmaDisabled; 170using EcmaSupercall = EcmaDisabled; 171using EcmaSupercallspread = EcmaDisabled; 172using EcmaNewobjdynrange = EcmaDisabled; 173using EcmaLdhomeobject = EcmaDisabled; 174using EcmaDefinemethod = EcmaDisabled; 175using EcmaDefineasyncgeneratorfunc = EcmaDisabled; 176using EcmaDefineasyncfunc = EcmaDisabled; 177using EcmaDefinegeneratorfunc = EcmaDisabled; 178using EcmaDefinencfuncdyn = EcmaDisabled; 179using EcmaDefinefuncdyn = EcmaDisabled; 180using EcmaTypeofdyn = EcmaDisabled; 181using EcmaCallspreaddyn = EcmaDisabled; 182using EcmaNewobjspreaddyn = EcmaDisabled; 183using EcmaGetunmappedargs = EcmaDisabled; 184using EcmaNegate = EcmaDisabled; 185using EcmaToboolean = EcmaDisabled; 186using EcmaTonumber = EcmaDisabled; 187using EcmaGetmethod = EcmaDisabled; 188using EcmaCreategeneratorobj = EcmaDisabled; 189using EcmaCreateasyncgeneratorobj = EcmaDisabled; 190using EcmaCreateiterresultobj = EcmaDisabled; 191using EcmaSuspendgenerator = EcmaDisabled; 192using EcmaSuspendasyncgenerator = EcmaDisabled; 193using EcmaSetgeneratorstate = EcmaDisabled; 194using EcmaSetgeneratorstate = EcmaDisabled; 195using EcmaResumegenerator = EcmaDisabled; 196using EcmaGetresumemode = EcmaDisabled; 197using EcmaAsyncfunctionenter = EcmaDisabled; 198using EcmaAsyncfunctionawait = EcmaDisabled; 199using EcmaAsyncfunctionresolve = EcmaDisabled; 200using EcmaAsyncfunctionreject = EcmaDisabled; 201using EcmaAsyncgeneratorresolve = EcmaDisabled; 202using EcmaAsyncgeneratorreject = EcmaDisabled; 203using EcmaGettemplateobject = EcmaDisabled; 204using EcmaCopyrestargs = EcmaDisabled; 205using EcmaGetpropiterator = EcmaDisabled; 206using EcmaGetnextpropname = EcmaDisabled; 207using EcmaCreateemptyobject = EcmaDisabled; 208using EcmaCreateobjectwithbuffer = EcmaDisabled; 209using EcmaCreateobjecthavingmethod = EcmaDisabled; 210using EcmaSetobjectwithproto = EcmaDisabled; 211using EcmaCopydataproperties = EcmaDisabled; 212using EcmaDefinegettersetterbyvalue = EcmaDisabled; 213using EcmaCreateemptyarray = EcmaDisabled; 214using EcmaCreatearraywithbuffer = EcmaDisabled; 215using EcmaStarrayspread = EcmaDisabled; 216using EcmaCreateregexpwithliteral = EcmaDisabled; 217using EcmaThrowifnotobject = EcmaDisabled; 218using EcmaThrowthrownotexists = EcmaDisabled; 219using EcmaGetiterator = EcmaDisabled; 220using EcmaGetasynciterator = EcmaDisabled; 221using EcmaCreateobjectwithexcludedkeys = EcmaDisabled; 222using EcmaThrowpatternnoncoercible = EcmaDisabled; 223using EcmaCloseiterator = EcmaDisabled; 224using EcmaImportmodule = EcmaDisabled; 225using EcmaSetclasscomputedfields = EcmaDisabled; 226using EcmaDefineclasswithbuffer = EcmaDisabled; 227using EcmaLoadclasscomputedinstancefields = EcmaDisabled; 228using EcmaDefineclassprivatefields = EcmaDisabled; 229using EcmaClassfieldadd = EcmaDisabled; 230using EcmaClassprivatefieldadd = EcmaDisabled; 231using EcmaClassprivatemethodoraccessoradd = EcmaDisabled; 232using EcmaClassprivatefieldget = EcmaDisabled; 233using EcmaClassprivatefieldset = EcmaDisabled; 234using EcmaClassprivatefieldin = EcmaDisabled; 235using EcmaLdmodvarbyname = EcmaDisabled; 236using EcmaStmodulevar = EcmaDisabled; 237using EcmaCopymodule = EcmaDisabled; 238using EcmaStsuperbyname = EcmaDisabled; 239using EcmaLdsuperbyname = EcmaDisabled; 240using EcmaStsuperbyvalue = EcmaDisabled; 241using EcmaLdsuperbyvalue = EcmaDisabled; 242using EcmaLdlexvardyn = EcmaDisabled; 243using EcmaLdlexdyn = EcmaDisabled; 244using EcmaStlexvardyn = EcmaDisabled; 245using EcmaStlexdyn = EcmaDisabled; 246using EcmaThrowifsupernotcorrectcall = EcmaDisabled; 247using EcmaThrowtdz = EcmaDisabled; 248using EcmaThrowconstassignment = EcmaDisabled; 249using EcmaPoplexenvdyn = EcmaDisabled; 250using EcmaCopylexenvdyn = EcmaDisabled; 251using EcmaNewlexenvdyn = EcmaDisabled; 252using EcmaLdlexenvdyn = EcmaDisabled; 253using EcmaLdevalvar = EcmaDisabled; 254using EcmaStevalvar = EcmaDisabled; 255using EcmaLdevalbindings = EcmaDisabled; 256using EcmaDirecteval = EcmaDisabled; 257#endif 258 259PandaGen::PandaGen(ArenaAllocator *const allocator, RegSpiller *const spiller, public_lib::Context *const context, 260 std::tuple<varbinder::FunctionScope *, ProgramElement *, AstCompiler *> toCompile) 261 : CodeGen(allocator, spiller, context, toCompile) 262{ 263 Function::Compile(this); 264} 265 266FunctionBuilder *PandaGen::FuncBuilder() const noexcept 267{ 268 return builder_; 269} 270 271EnvScope *PandaGen::GetEnvScope() const noexcept 272{ 273 return envScope_; 274} 275 276void PandaGen::OptionalChainCheck(const bool optional, const VReg obj) const 277{ 278 if (optional && optionalChain_ != nullptr) { 279 optionalChain_->Check(obj); 280 } 281} 282 283void PandaGen::FunctionInit(CatchTable *catchTable) 284{ 285 if (RootNode()->IsProgram()) { 286 builder_ = Allocator()->New<FunctionBuilder>(this, catchTable); 287 return; 288 } 289 290 const ir::ScriptFunction *func = RootNode()->AsScriptFunction(); 291 292 if (func->IsAsyncFunc()) { 293 if (func->IsGenerator()) { 294 builder_ = Allocator()->New<AsyncGeneratorFunctionBuilder>(this, catchTable); 295 return; 296 } 297 298 builder_ = Allocator()->New<AsyncFunctionBuilder>(this, catchTable); 299 return; 300 } 301 302 if (func->IsGenerator()) { 303 builder_ = Allocator()->New<GeneratorFunctionBuilder>(this, catchTable); 304 return; 305 } 306 307 builder_ = Allocator()->New<FunctionBuilder>(this, catchTable); 308} 309 310bool PandaGen::FunctionHasFinalizer() const 311{ 312 if (RootNode()->IsProgram()) { 313 return false; 314 } 315 316 const ir::ScriptFunction *func = RootNode()->AsScriptFunction(); 317 318 return func->IsAsyncFunc() || func->IsGenerator(); 319} 320 321void PandaGen::FunctionEnter() 322{ 323 builder_->Prepare(RootNode()->AsScriptFunction()); 324} 325 326void PandaGen::FunctionExit() 327{ 328 builder_->CleanUp(RootNode()->AsScriptFunction()); 329} 330 331void PandaGen::StoreAccumulator(const ir::AstNode *node, VReg vreg) 332{ 333 Ra().Emit<StaDyn>(node, vreg); 334} 335 336void PandaGen::LoadAccumulator(const ir::AstNode *node, VReg reg) 337{ 338 Ra().Emit<LdaDyn>(node, reg); 339} 340 341IRNode *PandaGen::AllocMov(const ir::AstNode *node, const VReg vd, const VReg vs) 342{ 343 return Allocator()->New<MovDyn>(node, vd, vs); 344} 345 346IRNode *PandaGen::AllocMov(const ir::AstNode *node, OutVReg vd, const VReg vs) 347{ 348 ASSERT(vd.type == OperandType::ANY); 349 return Allocator()->New<MovDyn>(node, *vd.reg, vs); 350} 351 352void PandaGen::MoveVreg(const ir::AstNode *node, VReg vd, VReg vs) 353{ 354 Ra().Emit<MovDyn>(node, vd, vs); 355} 356 357void PandaGen::LoadAccumulatorDouble(const ir::AstNode *node, double num) 358{ 359 Sa().Emit<FldaiDyn>(node, num); 360} 361 362void PandaGen::LoadAccumulatorInt(const ir::AstNode *node, size_t num) 363{ 364 Sa().Emit<LdaiDyn>(node, static_cast<int64_t>(num)); 365} 366 367void PandaGen::StoreConst(const ir::AstNode *node, VReg reg, Constant id) 368{ 369 LoadConst(node, id); 370 StoreAccumulator(node, reg); 371} 372 373void PandaGen::LoadConst(const ir::AstNode *node, Constant id) 374{ 375 switch (id) { 376 case Constant::JS_HOLE: { 377 Sa().Emit<EcmaLdhole>(node); 378 break; 379 } 380 case Constant::JS_NAN: { 381 Sa().Emit<EcmaLdnan>(node); 382 break; 383 } 384 case Constant::JS_INFINITY: { 385 Sa().Emit<EcmaLdinfinity>(node); 386 break; 387 } 388 case Constant::JS_GLOBAL: { 389 Sa().Emit<EcmaLdglobal>(node); 390 break; 391 } 392 case Constant::JS_UNDEFINED: { 393 Sa().Emit<EcmaLdundefined>(node); 394 break; 395 } 396 case Constant::JS_SYMBOL: { 397 Sa().Emit<EcmaLdsymbol>(node); 398 break; 399 } 400 case Constant::JS_NULL: { 401 Sa().Emit<EcmaLdnull>(node); 402 break; 403 } 404 case Constant::JS_TRUE: { 405 Sa().Emit<EcmaLdtrue>(node); 406 break; 407 } 408 case Constant::JS_FALSE: { 409 Sa().Emit<EcmaLdfalse>(node); 410 break; 411 } 412 default: { 413 UNREACHABLE(); 414 } 415 } 416} 417 418void PandaGen::GetFunctionObject(const ir::AstNode *node) 419{ 420 LoadAccFromLexEnv(node, Scope()->Find(varbinder::VarBinder::MANDATORY_PARAM_FUNC)); 421} 422 423void PandaGen::GetNewTarget(const ir::AstNode *node) 424{ 425 LoadAccFromLexEnv(node, Scope()->Find(varbinder::VarBinder::MANDATORY_PARAM_NEW_TARGET)); 426} 427 428void PandaGen::GetThis(const ir::AstNode *node) 429{ 430 LoadAccFromLexEnv(node, Scope()->Find(varbinder::VarBinder::MANDATORY_PARAM_THIS)); 431} 432 433void PandaGen::SetThis(const ir::AstNode *node) 434{ 435 StoreAccToLexEnv(node, Scope()->Find(varbinder::VarBinder::MANDATORY_PARAM_THIS), true); 436} 437 438void PandaGen::LoadVar(const ir::Identifier *node, const varbinder::ConstScopeFindResult &result) 439{ 440 auto *var = result.variable; 441 442 if (var == nullptr) { 443 TryLoadGlobalByName(node, result.name); 444 return; 445 } 446 447 if (var->IsGlobalVariable()) { 448 LoadGlobalVar(node, var->Name()); 449 return; 450 } 451 452 if (var->IsModuleVariable()) { 453 LoadModuleVariable(node, var->AsModuleVariable()->ModuleReg(), var->AsModuleVariable()->ExoticName()); 454 return; 455 } 456 457 ASSERT(var->IsLocalVariable()); 458 LoadAccFromLexEnv(node, result); 459} 460 461void PandaGen::StoreVar(const ir::AstNode *node, const varbinder::ConstScopeFindResult &result, bool isDeclaration) 462{ 463 varbinder::Variable *var = result.variable; 464 465 if (var == nullptr) { 466 if (IsDirectEval()) { 467 StoreEvalVariable(node, result.name); 468 } else { 469 TryStoreGlobalByName(node, result.name); 470 } 471 return; 472 } 473 474 if (var->IsGlobalVariable()) { 475 StoreGlobalVar(node, var->Name()); 476 return; 477 } 478 479 if (var->IsModuleVariable()) { 480 ThrowConstAssignment(node, var->Name()); 481 return; 482 } 483 484 ASSERT(var->IsLocalVariable()); 485 StoreAccToLexEnv(node, result, isDeclaration); 486} 487 488void PandaGen::LoadAccFromArgs(const ir::AstNode *node) 489{ 490 if (!Scope()->HasFlag(varbinder::ScopeFlags::USE_ARGS)) { 491 return; 492 } 493 494 auto res = Scope()->Find(varbinder::VarBinder::FUNCTION_ARGUMENTS); 495 ASSERT(res.scope); 496 497 GetUnmappedArgs(node); 498 StoreAccToLexEnv(node, res, true); 499} 500 501void PandaGen::LoadObjProperty(const ir::AstNode *node, const Operand &prop) 502{ 503 if (std::holds_alternative<VReg>(prop)) { 504 LoadObjByValue(node, std::get<VReg>(prop)); 505 return; 506 } 507 508 if (std::holds_alternative<int64_t>(prop)) { 509 LoadObjByIndex(node, std::get<int64_t>(prop)); 510 return; 511 } 512 513 ASSERT(std::holds_alternative<util::StringView>(prop)); 514 LoadObjByName(node, std::get<util::StringView>(prop)); 515} 516 517void PandaGen::StoreObjProperty(const ir::AstNode *node, VReg obj, const Operand &prop) 518{ 519 if (std::holds_alternative<VReg>(prop)) { 520 StoreObjByValue(node, obj, std::get<VReg>(prop)); 521 return; 522 } 523 524 if (std::holds_alternative<int64_t>(prop)) { 525 StoreObjByIndex(node, obj, std::get<int64_t>(prop)); 526 return; 527 } 528 529 ASSERT(std::holds_alternative<util::StringView>(prop)); 530 StoreObjByName(node, obj, std::get<util::StringView>(prop)); 531} 532 533void PandaGen::StoreOwnProperty(const ir::AstNode *node, VReg obj, const Operand &prop) 534{ 535 if (std::holds_alternative<VReg>(prop)) { 536 StOwnByValue(node, obj, std::get<VReg>(prop)); 537 return; 538 } 539 540 if (std::holds_alternative<int64_t>(prop)) { 541 StOwnByIndex(node, obj, std::get<int64_t>(prop)); 542 return; 543 } 544 545 ASSERT(std::holds_alternative<util::StringView>(prop)); 546 StOwnByName(node, obj, std::get<util::StringView>(prop)); 547} 548 549void PandaGen::TryLoadGlobalByName(const ir::AstNode *node, const util::StringView &name) 550{ 551 Sa().Emit<EcmaTryldglobalbyname>(node, name); 552} 553 554void PandaGen::TryStoreGlobalByName(const ir::AstNode *node, const util::StringView &name) 555{ 556 Sa().Emit<EcmaTrystglobalbyname>(node, name); 557} 558 559void PandaGen::LoadObjByName(const ir::AstNode *node, const util::StringView &prop) 560{ 561 Ra().Emit<EcmaLdobjbyname>(node, prop); 562} 563 564void PandaGen::StoreObjByName(const ir::AstNode *node, VReg obj, const util::StringView &prop) 565{ 566 Ra().Emit<EcmaStobjbyname>(node, prop, obj); 567} 568 569void PandaGen::LoadObjByIndex(const ir::AstNode *node, int64_t index) 570{ 571 Ra().Emit<EcmaLdobjbyindex>(node, index); 572} 573 574void PandaGen::LoadObjByValue(const ir::AstNode *node, VReg obj) 575{ 576 Ra().Emit<EcmaLdobjbyvalue>(node, obj); 577} 578 579void PandaGen::StoreObjByValue(const ir::AstNode *node, VReg obj, VReg prop) 580{ 581 Ra().Emit<EcmaStobjbyvalue>(node, obj, prop); 582} 583 584void PandaGen::StoreObjByIndex(const ir::AstNode *node, VReg obj, int64_t index) 585{ 586 Ra().Emit<EcmaStobjbyindex>(node, index, obj); 587} 588 589void PandaGen::StOwnByName(const ir::AstNode *node, VReg obj, const util::StringView &prop) 590{ 591 Ra().Emit<EcmaStownbyname>(node, prop, obj); 592} 593 594void PandaGen::StOwnByValue(const ir::AstNode *node, VReg obj, VReg prop) 595{ 596 Ra().Emit<EcmaStownbyvalue>(node, obj, prop); 597} 598 599void PandaGen::StOwnByIndex(const ir::AstNode *node, VReg obj, int64_t index) 600{ 601 Ra().Emit<EcmaStownbyindex>(node, index, obj); 602} 603 604void PandaGen::DeleteObjProperty(const ir::AstNode *node, VReg obj, VReg prop) 605{ 606 Ra().Emit<EcmaDelobjprop>(node, obj, prop); 607} 608 609void PandaGen::LoadGlobalVar(const ir::AstNode *node, const util::StringView &name) 610{ 611 Sa().Emit<EcmaLdglobalvar>(node, name); 612} 613 614void PandaGen::StoreGlobalVar(const ir::AstNode *node, const util::StringView &name) 615{ 616 Sa().Emit<EcmaStglobalvar>(node, name); 617} 618 619VReg PandaGen::LexEnv() const noexcept 620{ 621 return envScope_->LexEnv(); 622} 623 624void PandaGen::LoadAccFromLexEnv(const ir::AstNode *node, const varbinder::ConstScopeFindResult &result) 625{ 626 VirtualLoadVar::Expand(this, node, result); 627} 628 629void PandaGen::StoreAccToLexEnv(const ir::AstNode *node, const varbinder::ConstScopeFindResult &result, 630 bool isDeclaration) 631{ 632 VirtualStoreVar::Expand(this, node, result, isDeclaration); 633} 634 635void PandaGen::LoadAccumulatorBigInt(const ir::AstNode *node, const util::StringView &bigInt) 636{ 637 Sa().Emit<EcmaLdbigint>(node, bigInt); 638} 639 640void PandaGen::Condition(const ir::AstNode *node, lexer::TokenType op, VReg lhs, Label *ifFalse) 641{ 642 switch (op) { 643 case lexer::TokenType::PUNCTUATOR_EQUAL: { 644 Ra().Emit<EcmaEqdyn>(node, lhs); 645 break; 646 } 647 case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: { 648 Ra().Emit<EcmaNoteqdyn>(node, lhs); 649 break; 650 } 651 case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL: { 652 Ra().Emit<EcmaStricteqdyn>(node, lhs); 653 break; 654 } 655 case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL: { 656 Ra().Emit<EcmaStrictnoteqdyn>(node, lhs); 657 break; 658 } 659 case lexer::TokenType::PUNCTUATOR_LESS_THAN: { 660 Ra().Emit<EcmaLessdyn>(node, lhs); 661 break; 662 } 663 case lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL: { 664 Ra().Emit<EcmaLesseqdyn>(node, lhs); 665 break; 666 } 667 case lexer::TokenType::PUNCTUATOR_GREATER_THAN: { 668 Ra().Emit<EcmaGreaterdyn>(node, lhs); 669 break; 670 } 671 case lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL: { 672 Ra().Emit<EcmaGreatereqdyn>(node, lhs); 673 break; 674 } 675 default: { 676 UNREACHABLE(); 677 } 678 } 679 680 BranchIfFalse(node, ifFalse); 681} 682 683void PandaGen::Unary(const ir::AstNode *node, lexer::TokenType op, VReg operand) 684{ 685 switch (op) { 686 case lexer::TokenType::PUNCTUATOR_PLUS: { 687 Ra().Emit<EcmaTonumber>(node, operand); 688 break; 689 } 690 case lexer::TokenType::PUNCTUATOR_MINUS: { 691 Ra().Emit<EcmaNegdyn>(node, operand); 692 break; 693 } 694 case lexer::TokenType::PUNCTUATOR_TILDE: { 695 Ra().Emit<EcmaNotdyn>(node, operand); 696 break; 697 } 698 case lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK: { 699 Sa().Emit<EcmaNegate>(node); 700 break; 701 } 702 case lexer::TokenType::PUNCTUATOR_PLUS_PLUS: { 703 Ra().Emit<EcmaIncdyn>(node, operand); 704 break; 705 } 706 case lexer::TokenType::PUNCTUATOR_MINUS_MINUS: { 707 Ra().Emit<EcmaDecdyn>(node, operand); 708 break; 709 } 710 case lexer::TokenType::KEYW_VOID: 711 case lexer::TokenType::KEYW_DELETE: { 712 LoadConst(node, Constant::JS_UNDEFINED); 713 break; 714 } 715 default: { 716 UNREACHABLE(); 717 } 718 } 719} 720 721void PandaGen::Binary(const ir::AstNode *node, lexer::TokenType op, VReg lhs) 722{ 723 switch (op) { 724 case lexer::TokenType::PUNCTUATOR_EQUAL: { 725 Ra().Emit<EcmaEqdyn>(node, lhs); 726 break; 727 } 728 case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: { 729 Ra().Emit<EcmaNoteqdyn>(node, lhs); 730 break; 731 } 732 case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL: { 733 Ra().Emit<EcmaStricteqdyn>(node, lhs); 734 break; 735 } 736 case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL: { 737 Ra().Emit<EcmaStrictnoteqdyn>(node, lhs); 738 break; 739 } 740 case lexer::TokenType::PUNCTUATOR_LESS_THAN: { 741 Ra().Emit<EcmaLessdyn>(node, lhs); 742 break; 743 } 744 case lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL: { 745 Ra().Emit<EcmaLesseqdyn>(node, lhs); 746 break; 747 } 748 case lexer::TokenType::PUNCTUATOR_GREATER_THAN: { 749 Ra().Emit<EcmaGreaterdyn>(node, lhs); 750 break; 751 } 752 case lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL: { 753 Ra().Emit<EcmaGreatereqdyn>(node, lhs); 754 break; 755 } 756 case lexer::TokenType::PUNCTUATOR_PLUS: 757 case lexer::TokenType::PUNCTUATOR_PLUS_EQUAL: { 758 Ra().Emit<EcmaAdd2dyn>(node, lhs); 759 break; 760 } 761 case lexer::TokenType::PUNCTUATOR_MINUS: 762 case lexer::TokenType::PUNCTUATOR_MINUS_EQUAL: { 763 Ra().Emit<EcmaSub2dyn>(node, lhs); 764 break; 765 } 766 case lexer::TokenType::PUNCTUATOR_MULTIPLY: 767 case lexer::TokenType::PUNCTUATOR_MULTIPLY_EQUAL: { 768 Ra().Emit<EcmaMul2dyn>(node, lhs); 769 break; 770 } 771 case lexer::TokenType::PUNCTUATOR_DIVIDE: 772 case lexer::TokenType::PUNCTUATOR_DIVIDE_EQUAL: { 773 Ra().Emit<EcmaDiv2dyn>(node, lhs); 774 break; 775 } 776 case lexer::TokenType::PUNCTUATOR_MOD: 777 case lexer::TokenType::PUNCTUATOR_MOD_EQUAL: { 778 Ra().Emit<EcmaMod2dyn>(node, lhs); 779 break; 780 } 781 case lexer::TokenType::PUNCTUATOR_EXPONENTIATION_EQUAL: 782 case lexer::TokenType::PUNCTUATOR_EXPONENTIATION: { 783 Ra().Emit<EcmaExpdyn>(node, lhs); 784 break; 785 } 786 case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT: 787 case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT_EQUAL: { 788 Ra().Emit<EcmaShl2dyn>(node, lhs); 789 break; 790 } 791 case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT: 792 case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT_EQUAL: { 793 Ra().Emit<EcmaShr2dyn>(node, lhs); 794 break; 795 } 796 case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT: 797 case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT_EQUAL: { 798 Ra().Emit<EcmaAshr2dyn>(node, lhs); 799 break; 800 } 801 case lexer::TokenType::PUNCTUATOR_BITWISE_AND: 802 case lexer::TokenType::PUNCTUATOR_BITWISE_AND_EQUAL: { 803 Ra().Emit<EcmaAnd2dyn>(node, lhs); 804 break; 805 } 806 case lexer::TokenType::PUNCTUATOR_BITWISE_OR: 807 case lexer::TokenType::PUNCTUATOR_BITWISE_OR_EQUAL: { 808 Ra().Emit<EcmaOr2dyn>(node, lhs); 809 break; 810 } 811 case lexer::TokenType::PUNCTUATOR_BITWISE_XOR: 812 case lexer::TokenType::PUNCTUATOR_BITWISE_XOR_EQUAL: { 813 Ra().Emit<EcmaXor2dyn>(node, lhs); 814 break; 815 } 816 case lexer::TokenType::KEYW_IN: { 817 Ra().Emit<EcmaIsindyn>(node, lhs); 818 break; 819 } 820 case lexer::TokenType::KEYW_INSTANCEOF: { 821 Ra().Emit<EcmaInstanceofdyn>(node, lhs); 822 break; 823 } 824 case lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING: 825 case lexer::TokenType::PUNCTUATOR_LOGICAL_NULLISH_EQUAL: { 826 Unimplemented(); 827 break; 828 } 829 default: { 830 UNREACHABLE(); 831 } 832 } 833} 834 835void PandaGen::BranchIfUndefined(const ir::AstNode *node, Label *target) 836{ 837 Sa().Emit<EcmaIsundefined>(node); 838 BranchIfTrue(node, target); 839} 840 841void PandaGen::BranchIfNotUndefined(const ir::AstNode *node, Label *target) 842{ 843 Sa().Emit<EcmaIsundefined>(node); 844 BranchIfFalse(node, target); 845} 846 847void PandaGen::BranchIfTrue(const ir::AstNode *node, Label *target) 848{ 849 Sa().Emit<EcmaJtrue>(node, target); 850} 851 852void PandaGen::BranchIfNotTrue(const ir::AstNode *node, Label *target) 853{ 854 Sa().Emit<EcmaIstrue>(node); 855 BranchIfFalse(node, target); 856} 857 858void PandaGen::BranchIfFalse(const ir::AstNode *node, Label *target) 859{ 860 Sa().Emit<EcmaJfalse>(node, target); 861} 862 863void PandaGen::BranchIfCoercible(const ir::AstNode *node, Label *target) 864{ 865 Sa().Emit<EcmaIscoercible>(node); 866 BranchIfTrue(node, target); 867} 868 869void PandaGen::EmitThrow(const ir::AstNode *node) 870{ 871 Sa().Emit<EcmaThrowdyn>(node); 872} 873 874void PandaGen::EmitRethrow(const ir::AstNode *node) 875{ 876 Sa().Emit<EcmaRethrowdyn>(node); 877} 878 879void PandaGen::EmitReturn(const ir::AstNode *node) 880{ 881 Sa().Emit<EcmaReturnDyn>(node); 882} 883 884void PandaGen::EmitReturnUndefined(const ir::AstNode *node) 885{ 886 Sa().Emit<EcmaReturnundefined>(node); 887} 888 889void PandaGen::ImplicitReturn(const ir::AstNode *node) 890{ 891 builder_->ImplicitReturn(node); 892} 893 894void PandaGen::DirectReturn(const ir::AstNode *node) 895{ 896 builder_->DirectReturn(node); 897} 898 899void PandaGen::ValidateClassDirectReturn(const ir::AstNode *node) 900{ 901 const ir::ScriptFunction *func = util::Helpers::GetContainingFunction(node); 902 903 if (func == nullptr || !func->IsConstructor()) { 904 return; 905 } 906 907 RegScope rs(this); 908 VReg value = AllocReg(); 909 StoreAccumulator(node, value); 910 911 auto *notUndefined = AllocLabel(); 912 auto *condEnd = AllocLabel(); 913 914 BranchIfNotUndefined(node, notUndefined); 915 GetThis(func); 916 ThrowIfSuperNotCorrectCall(func, 0); 917 Branch(node, condEnd); 918 919 SetLabel(node, notUndefined); 920 LoadAccumulator(node, value); 921 922 SetLabel(node, condEnd); 923} 924 925void PandaGen::EmitAwait(const ir::AstNode *node) 926{ 927 builder_->Await(node); 928} 929 930void PandaGen::Call0This(const ir::AstNode *node, VReg callee, VReg thisReg) 931{ 932 LoadAccumulator(node, thisReg); 933 Ra().Emit<EcmaCall0thisdyn>(node, callee); 934} 935 936void PandaGen::Call1This(const ir::AstNode *node, VReg callee, VReg thisReg, VReg arg0) 937{ 938 LoadAccumulator(node, arg0); 939 Ra().Emit<EcmaCall1thisdyn>(node, callee, thisReg); 940} 941 942void PandaGen::Call0Args(const ir::AstNode *n, VReg c, VReg thisR, bool hasThis) 943{ 944 if (hasThis) { 945 Call0This(n, c, thisR); 946 } else { 947 Sa().Emit<EcmaCall0dyn>(n); 948 } 949} 950 951void PandaGen::Call1Arg(const ir::AstNode *n, VReg c, VReg thisR, const ArenaVector<ir::Expression *> &args, 952 bool hasThis) 953{ 954 const auto *arg0 = args[0]; 955 arg0->Compile(this); 956 957 if (hasThis) { 958 Ra().Emit<EcmaCall1thisdyn>(n, c, thisR); 959 } else { 960 Ra().Emit<EcmaCall1dyn>(n, c); 961 } 962} 963 964void PandaGen::Call2Args(const ir::AstNode *n, VReg c, VReg thisR, const ArenaVector<ir::Expression *> &args, 965 bool hasThis) 966{ 967 const auto *arg0 = args[0]; 968 arg0->Compile(this); 969 compiler::VReg arg0Reg = AllocReg(); 970 StoreAccumulator(arg0, arg0Reg); 971 972 const auto *arg1 = args[1]; 973 arg1->Compile(this); 974 975 if (hasThis) { 976 Ra().Emit<EcmaCall2thisdyn>(n, c, thisR, arg0Reg); 977 } else { 978 Ra().Emit<EcmaCall2dyn>(n, c, arg0Reg); 979 } 980} 981 982void PandaGen::Call3Args(const ir::AstNode *n, VReg c, VReg thisR, const ArenaVector<ir::Expression *> &args, 983 bool hasThis) 984{ 985 const auto *arg0 = args[0]; 986 arg0->Compile(this); 987 compiler::VReg arg0Reg = AllocReg(); 988 StoreAccumulator(arg0, arg0Reg); 989 990 const auto *arg1 = args[1]; 991 arg1->Compile(this); 992 compiler::VReg arg1Reg = AllocReg(); 993 StoreAccumulator(arg1, arg1Reg); 994 995 const auto *arg2 = args[2]; 996 arg2->Compile(this); 997 998 if (hasThis) { 999 Ra().Emit<EcmaCall3thisdyn>(n, c, thisR, arg0Reg, arg1Reg); 1000 } else { 1001 Ra().Emit<EcmaCall3dyn>(n, c, arg0Reg, arg1Reg); 1002 } 1003} 1004 1005void PandaGen::Call(const ir::AstNode *node, VReg callee, VReg thisReg, const ArenaVector<ir::Expression *> &arguments) 1006{ 1007 bool hasThis = !thisReg.IsInvalid(); 1008 1009 switch (arguments.size()) { 1010 case 0: { // 0 args 1011 Call0Args(node, callee, thisReg, hasThis); 1012 return; 1013 } 1014 case 1: { // 1 arg 1015 Call1Arg(node, callee, thisReg, arguments, hasThis); 1016 return; 1017 } 1018 case 2: { // 2 args 1019 Call2Args(node, callee, thisReg, arguments, hasThis); 1020 return; 1021 } 1022 case 3: { // 3 args 1023 Call3Args(node, callee, thisReg, arguments, hasThis); 1024 return; 1025 } 1026 default: { 1027 break; 1028 } 1029 } 1030 1031 for (const auto *it : arguments) { 1032 it->Compile(this); 1033 compiler::VReg arg = AllocReg(); 1034 StoreAccumulator(it, arg); 1035 } 1036 1037 if (hasThis) { 1038 size_t argCount = arguments.size() + 1; 1039 auto constexpr EXTRA_ARGS = 2; 1040 Rra().Emit<EcmaCallithisrangedyn>(node, callee, argCount + EXTRA_ARGS, static_cast<int64_t>(argCount), callee); 1041 } else { 1042 size_t argCount = arguments.size(); 1043 Rra().Emit<EcmaCallirangedyn>(node, callee, argCount + 1, static_cast<int64_t>(argCount), callee); 1044 } 1045} 1046 1047bool PandaGen::CallArgsTagged(const ir::AstNode *node, VReg callee, VReg thisReg, 1048 const ArenaVector<ir::Expression *> &arguments, bool hasThis) 1049{ 1050 VReg arg0Reg = AllocReg(); 1051 StoreAccumulator(node, arg0Reg); 1052 1053 const auto call1 = [this, hasThis, arg0Reg](const ir::AstNode *n, VReg c, VReg thisR, 1054 const ArenaVector<ir::Expression *> &args) { 1055 const auto *arg = args[0]; 1056 arg->Compile(this); 1057 1058 if (hasThis) { 1059 Ra().Emit<EcmaCall2thisdyn>(n, c, thisR, arg0Reg); 1060 } else { 1061 Ra().Emit<EcmaCall2dyn>(n, c, arg0Reg); 1062 } 1063 }; 1064 const auto call2 = [this, hasThis, arg0Reg](const ir::AstNode *n, VReg c, VReg thisR, 1065 const ArenaVector<ir::Expression *> &args) { 1066 const auto *arg1 = args[0]; 1067 arg1->Compile(this); 1068 compiler::VReg arg1Reg = AllocReg(); 1069 StoreAccumulator(arg1, arg1Reg); 1070 1071 const auto *arg2 = args[1]; 1072 arg2->Compile(this); 1073 1074 if (hasThis) { 1075 Ra().Emit<EcmaCall3thisdyn>(n, c, thisR, arg0Reg, arg1Reg); 1076 } else { 1077 Ra().Emit<EcmaCall3dyn>(n, c, arg0Reg, arg1Reg); 1078 } 1079 }; 1080 1081 switch (arguments.size()) { 1082 case 1: { 1083 call1(node, callee, thisReg, arguments); 1084 return true; 1085 } 1086 case 2: { // 2:2 args 1087 call2(node, callee, thisReg, arguments); 1088 return true; 1089 } 1090 default: { 1091 break; 1092 } 1093 } 1094 return false; 1095} 1096 1097void PandaGen::CallTagged(const ir::AstNode *node, VReg callee, VReg thisReg, 1098 const ArenaVector<ir::Expression *> &arguments) 1099{ 1100 bool hasThis = !thisReg.IsInvalid(); 1101 1102 StoreAccumulator(node, callee); 1103 Literals::GetTemplateObject(this, node->AsTaggedTemplateExpression()); 1104 1105 if (arguments.empty()) { 1106 if (hasThis) { 1107 Ra().Emit<EcmaCall1thisdyn>(node, callee, thisReg); 1108 } else { 1109 Sa().Emit<EcmaCall1dyn>(node, callee); 1110 } 1111 return; 1112 } 1113 1114 if (CallArgsTagged(node, callee, thisReg, arguments, hasThis)) { 1115 return; 1116 } 1117 1118 for (const auto *it : arguments) { 1119 it->Compile(this); 1120 compiler::VReg arg = AllocReg(); 1121 StoreAccumulator(it, arg); 1122 } 1123 1124 if (hasThis) { 1125 auto constexpr EXTRA_ARGS = 2; 1126 size_t argCount = arguments.size() + EXTRA_ARGS; 1127 Rra().Emit<EcmaCallithisrangedyn>(node, callee, argCount + EXTRA_ARGS, static_cast<int64_t>(argCount), callee); 1128 } else { 1129 size_t argCount = arguments.size() + 1; 1130 Rra().Emit<EcmaCallirangedyn>(node, callee, argCount + 1, static_cast<int64_t>(argCount), callee); 1131 } 1132} 1133 1134void PandaGen::SuperCall(const ir::AstNode *node, VReg startReg, size_t argCount) 1135{ 1136 Rra().Emit<EcmaSupercall>(node, startReg, argCount, static_cast<int64_t>(argCount), startReg); 1137} 1138 1139void PandaGen::SuperCallSpread(const ir::AstNode *node, VReg vs) 1140{ 1141 Ra().Emit<EcmaSupercallspread>(node, vs); 1142} 1143 1144void PandaGen::NewObject(const ir::AstNode *node, VReg startReg, size_t argCount) 1145{ 1146 Rra().Emit<EcmaNewobjdynrange>(node, startReg, argCount, static_cast<int64_t>(argCount), startReg); 1147} 1148 1149void PandaGen::LoadHomeObject(const ir::AstNode *node) 1150{ 1151 Sa().Emit<EcmaLdhomeobject>(node); 1152} 1153 1154void PandaGen::DefineMethod(const ir::AstNode *node, const util::StringView &name) 1155{ 1156 Ra().Emit<EcmaDefinemethod>(node, name, LexEnv()); 1157} 1158 1159void PandaGen::DefineFunction(const ir::AstNode *node, const ir::ScriptFunction *realNode, const util::StringView &name) 1160{ 1161 if (realNode->IsAsyncFunc()) { 1162 if (realNode->IsGenerator()) { 1163 Ra().Emit<EcmaDefineasyncgeneratorfunc>(node, name, LexEnv()); 1164 } else { 1165 Ra().Emit<EcmaDefineasyncfunc>(node, name, LexEnv()); 1166 } 1167 } else if (realNode->IsGenerator()) { 1168 Ra().Emit<EcmaDefinegeneratorfunc>(node, name, LexEnv()); 1169 } else if (realNode->IsArrow()) { 1170 LoadHomeObject(node); 1171 Ra().Emit<EcmaDefinencfuncdyn>(node, name, LexEnv()); 1172 } else if (realNode->IsMethod()) { 1173 DefineMethod(node, name); 1174 } else { 1175 Ra().Emit<EcmaDefinefuncdyn>(node, name, LexEnv()); 1176 } 1177} 1178 1179void PandaGen::TypeOf(const ir::AstNode *node) 1180{ 1181 Sa().Emit<EcmaTypeofdyn>(node); 1182} 1183 1184void PandaGen::CallSpread(const ir::AstNode *node, VReg func, VReg thisReg, VReg args) 1185{ 1186 Ra().Emit<EcmaCallspreaddyn>(node, func, thisReg, args); 1187} 1188 1189void PandaGen::NewObjSpread(const ir::AstNode *node, VReg obj, VReg target) 1190{ 1191 Ra().Emit<EcmaNewobjspreaddyn>(node, obj, target); 1192} 1193 1194void PandaGen::GetUnmappedArgs(const ir::AstNode *node) 1195{ 1196 Sa().Emit<EcmaGetunmappedargs>(node); 1197} 1198 1199void PandaGen::Negate(const ir::AstNode *node) 1200{ 1201 Sa().Emit<EcmaNegate>(node); 1202} 1203 1204void PandaGen::ToBoolean(const ir::AstNode *node) 1205{ 1206 Sa().Emit<EcmaToboolean>(node); 1207} 1208 1209void PandaGen::ToNumber(const ir::AstNode *node, VReg arg) 1210{ 1211 Ra().Emit<EcmaTonumber>(node, arg); 1212} 1213 1214void PandaGen::GetMethod(const ir::AstNode *node, VReg obj, const util::StringView &name) 1215{ 1216 Ra().Emit<EcmaGetmethod>(node, name, obj); 1217} 1218 1219void PandaGen::CreateGeneratorObj(const ir::AstNode *node, VReg funcObj) 1220{ 1221 Ra().Emit<EcmaCreategeneratorobj>(node, funcObj); 1222} 1223 1224void PandaGen::CreateAsyncGeneratorObj(const ir::AstNode *node, VReg funcObj) 1225{ 1226 Ra().Emit<EcmaCreateasyncgeneratorobj>(node, funcObj); 1227} 1228 1229void PandaGen::CreateIterResultObject(const ir::AstNode *node, bool done) 1230{ 1231 Ra().Emit<EcmaCreateiterresultobj>(node, static_cast<int32_t>(done)); 1232} 1233 1234void PandaGen::SuspendGenerator(const ir::AstNode *node, VReg genObj) 1235{ 1236 Ra().Emit<EcmaSuspendgenerator>(node, genObj); 1237} 1238 1239void PandaGen::SuspendAsyncGenerator(const ir::AstNode *node, VReg asyncGenObj) 1240{ 1241 Ra().Emit<EcmaSuspendasyncgenerator>(node, asyncGenObj); 1242} 1243 1244void PandaGen::GeneratorYield(const ir::AstNode *node, VReg genObj) 1245{ 1246 Ra().Emit<EcmaSetgeneratorstate>(node, genObj, static_cast<int32_t>(GeneratorState::SUSPENDED_YIELD)); 1247} 1248 1249void PandaGen::GeneratorComplete(const ir::AstNode *node, VReg genObj) 1250{ 1251 Ra().Emit<EcmaSetgeneratorstate>(node, genObj, static_cast<int32_t>(GeneratorState::COMPLETED)); 1252} 1253 1254void PandaGen::ResumeGenerator(const ir::AstNode *node, VReg genObj) 1255{ 1256 Ra().Emit<EcmaResumegenerator>(node, genObj); 1257} 1258 1259void PandaGen::GetResumeMode(const ir::AstNode *node, VReg genObj) 1260{ 1261 Ra().Emit<EcmaGetresumemode>(node, genObj); 1262} 1263 1264void PandaGen::AsyncFunctionEnter(const ir::AstNode *node) 1265{ 1266 Sa().Emit<EcmaAsyncfunctionenter>(node); 1267} 1268 1269void PandaGen::AsyncFunctionAwait(const ir::AstNode *node, VReg asyncFuncObj) 1270{ 1271 Ra().Emit<EcmaAsyncfunctionawait>(node, asyncFuncObj); 1272} 1273 1274void PandaGen::AsyncFunctionResolve(const ir::AstNode *node, VReg asyncFuncObj) 1275{ 1276 Ra().Emit<EcmaAsyncfunctionresolve>(node, asyncFuncObj); 1277} 1278 1279void PandaGen::AsyncFunctionReject(const ir::AstNode *node, VReg asyncFuncObj) 1280{ 1281 Ra().Emit<EcmaAsyncfunctionreject>(node, asyncFuncObj); 1282} 1283 1284void PandaGen::AsyncGeneratorResolve(const ir::AstNode *node, VReg asyncGenObj) 1285{ 1286 Ra().Emit<EcmaAsyncgeneratorresolve>(node, asyncGenObj); 1287} 1288 1289void PandaGen::AsyncGeneratorReject(const ir::AstNode *node, VReg asyncGenObj) 1290{ 1291 Ra().Emit<EcmaAsyncgeneratorreject>(node, asyncGenObj); 1292} 1293 1294void PandaGen::GetTemplateObject(const ir::AstNode *node, VReg value) 1295{ 1296 Ra().Emit<EcmaGettemplateobject>(node, value); 1297} 1298 1299void PandaGen::CopyRestArgs(const ir::AstNode *node, uint32_t index) 1300{ 1301 Sa().Emit<EcmaCopyrestargs>(node, index); 1302} 1303 1304void PandaGen::GetPropIterator(const ir::AstNode *node) 1305{ 1306 Sa().Emit<EcmaGetpropiterator>(node); 1307} 1308 1309void PandaGen::GetNextPropName(const ir::AstNode *node, VReg iter) 1310{ 1311 Ra().Emit<EcmaGetnextpropname>(node, iter); 1312} 1313 1314void PandaGen::CreateEmptyObject(const ir::AstNode *node) 1315{ 1316 Sa().Emit<EcmaCreateemptyobject>(node); 1317} 1318 1319void PandaGen::CreateObjectWithBuffer(const ir::AstNode *node, uint32_t idx) 1320{ 1321 ASSERT(util::Helpers::IsInteger<uint32_t>(idx)); 1322 Sa().Emit<EcmaCreateobjectwithbuffer>(node, util::Helpers::ToStringView(Allocator(), idx)); 1323} 1324 1325void PandaGen::CreateObjectHavingMethod(const ir::AstNode *node, uint32_t idx) 1326{ 1327 ASSERT(util::Helpers::IsInteger<uint32_t>(idx)); 1328 LoadAccumulator(node, LexEnv()); 1329 Sa().Emit<EcmaCreateobjecthavingmethod>(node, util::Helpers::ToStringView(Allocator(), idx)); 1330} 1331 1332void PandaGen::SetObjectWithProto(const ir::AstNode *node, VReg proto, VReg obj) 1333{ 1334 Ra().Emit<EcmaSetobjectwithproto>(node, proto, obj); 1335} 1336 1337void PandaGen::CopyDataProperties(const ir::AstNode *node, VReg dst, VReg src) 1338{ 1339 Ra().Emit<EcmaCopydataproperties>(node, dst, src); 1340} 1341 1342void PandaGen::DefineGetterSetterByValue(const ir::AstNode *node, std::tuple<VReg, VReg, VReg, VReg> registers, 1343 bool setName) 1344{ 1345 const auto [obj, name, getter, setter] = registers; 1346 LoadConst(node, setName ? Constant::JS_TRUE : Constant::JS_FALSE); 1347 Ra().Emit<EcmaDefinegettersetterbyvalue>(node, obj, name, getter, setter); 1348} 1349 1350void PandaGen::CreateEmptyArray(const ir::AstNode *node) 1351{ 1352 Sa().Emit<EcmaCreateemptyarray>(node); 1353} 1354 1355void PandaGen::CreateArrayWithBuffer(const ir::AstNode *node, uint32_t idx) 1356{ 1357 ASSERT(util::Helpers::IsInteger<uint32_t>(idx)); 1358 Sa().Emit<EcmaCreatearraywithbuffer>(node, util::Helpers::ToStringView(Allocator(), idx)); 1359} 1360 1361size_t PandaGen::HandleArrayLiterals(const ir::AstNode *node, const ArenaVector<ir::Expression *> &elements) 1362{ 1363 LiteralBuffer buf {}; 1364 1365 size_t i = 0; 1366 // This loop handles constant literal data by collecting it into a literal buffer 1367 // until a non-constant element is encountered. 1368 while (i < elements.size()) { 1369 Literal lit = util::Helpers::ToConstantLiteral(elements[i]); 1370 if (lit.IsInvalid()) { 1371 break; 1372 } 1373 1374 buf.emplace_back(std::move(lit)); 1375 i++; 1376 } 1377 1378 if (buf.empty()) { 1379 CreateEmptyArray(node); 1380 } else { 1381 uint32_t bufIdx = AddLiteralBuffer(std::move(buf)); 1382 CreateArrayWithBuffer(node, bufIdx); 1383 } 1384 return i; 1385} 1386 1387void PandaGen::HandleArraySpread(const ir::AstNode *node, const ArenaVector<ir::Expression *> &elements, VReg obj) 1388{ 1389 size_t i = 0; 1390 bool hasSpread = false; 1391 1392 // This loop handles array elements until a spread element is encountered 1393 for (; i < elements.size(); i++) { 1394 const ir::Expression *elem = elements[i]; 1395 1396 if (elem->IsOmittedExpression()) { 1397 continue; 1398 } 1399 1400 if (elem->IsSpreadElement()) { 1401 // The next loop will handle arrays that have a spread element 1402 hasSpread = true; 1403 break; 1404 } 1405 1406 elem->Compile(this); 1407 StOwnByIndex(elem, obj, i); 1408 } 1409 1410 RegScope rs(this); 1411 VReg idxReg {}; 1412 1413 if (hasSpread) { 1414 idxReg = AllocReg(); 1415 LoadAccumulatorInt(node, i); 1416 StoreAccumulator(node, idxReg); 1417 } 1418 1419 // This loop handles arrays that contain spread elements 1420 for (; i < elements.size(); i++) { 1421 const ir::Expression *elem = elements[i]; 1422 1423 if (elem->IsSpreadElement()) { 1424 elem->AsSpreadElement()->Argument()->Compile(this); 1425 1426 StoreArraySpread(elem, obj, idxReg); 1427 StoreAccumulator(elem, idxReg); 1428 continue; 1429 } 1430 1431 if (!elem->IsOmittedExpression()) { 1432 elem->Compile(this); 1433 StOwnByValue(elem, obj, idxReg); 1434 } 1435 1436 Unary(elem, lexer::TokenType::PUNCTUATOR_PLUS_PLUS, idxReg); 1437 StoreAccumulator(elem, idxReg); 1438 } 1439 1440 // If the last element is omitted, we also have to update the length property 1441 if (elements.back()->IsOmittedExpression()) { 1442 // if there was a spread value then acc already contains the length 1443 if (!hasSpread) { 1444 LoadAccumulatorInt(node, i); 1445 } 1446 1447 StOwnByName(node, obj, "length"); 1448 } 1449} 1450 1451void PandaGen::CreateArray(const ir::AstNode *node, const ArenaVector<ir::Expression *> &elements, VReg obj) 1452{ 1453 if (elements.empty()) { 1454 CreateEmptyArray(node); 1455 StoreAccumulator(node, obj); 1456 return; 1457 } 1458 1459 const auto i = HandleArrayLiterals(node, elements); 1460 1461 StoreAccumulator(node, obj); 1462 1463 if (i == elements.size()) { 1464 return; 1465 } 1466 1467 HandleArraySpread(node, elements, obj); 1468 1469 LoadAccumulator(node, obj); 1470} 1471 1472void PandaGen::StoreArraySpread(const ir::AstNode *node, VReg array, VReg index) 1473{ 1474 Ra().Emit<EcmaStarrayspread>(node, array, index); 1475} 1476 1477void PandaGen::CreateRegExpWithLiteral(const ir::AstNode *node, const util::StringView &pattern, uint8_t flags) 1478{ 1479 Sa().Emit<EcmaCreateregexpwithliteral>(node, pattern, flags); 1480} 1481 1482void PandaGen::ThrowIfNotObject(const ir::AstNode *node) 1483{ 1484 Ra().Emit<EcmaThrowifnotobject>(node); 1485} 1486 1487void PandaGen::ThrowThrowNotExist(const ir::AstNode *node) 1488{ 1489 Sa().Emit<EcmaThrowthrownotexists>(node); 1490} 1491 1492void PandaGen::GetIterator(const ir::AstNode *node) 1493{ 1494 Sa().Emit<EcmaGetiterator>(node); 1495} 1496 1497void PandaGen::GetAsyncIterator(const ir::AstNode *node) 1498{ 1499 Sa().Emit<EcmaGetasynciterator>(node); 1500} 1501 1502void PandaGen::CreateObjectWithExcludedKeys(const ir::AstNode *node, VReg obj, VReg argStart, size_t argCount) 1503{ 1504 ASSERT(argStart.GetIndex() == obj.GetIndex() - 1); 1505 if (argCount == 0) { // Do not emit undefined register 1506 argStart = obj; 1507 } 1508 1509 Rra().Emit<EcmaCreateobjectwithexcludedkeys>(node, argStart, argCount, static_cast<int64_t>(argCount), obj, 1510 argStart); 1511} 1512 1513void PandaGen::ThrowObjectNonCoercible(const ir::AstNode *node) 1514{ 1515 Sa().Emit<EcmaThrowpatternnoncoercible>(node); 1516} 1517 1518void PandaGen::CloseIterator(const ir::AstNode *node, VReg iter) 1519{ 1520 Ra().Emit<EcmaCloseiterator>(node, iter); 1521} 1522 1523void PandaGen::ImportModule(const ir::AstNode *node, const util::StringView &name) 1524{ 1525 Sa().Emit<EcmaImportmodule>(node, name); 1526} 1527 1528void PandaGen::SetClassComputedFields(const ir::AstNode *node, VReg classReg, VReg computedInstanceFieldArray) 1529{ 1530 Ra().Emit<EcmaSetclasscomputedfields>(node, classReg, computedInstanceFieldArray); 1531} 1532 1533void PandaGen::DefineClassWithBuffer(const ir::AstNode *node, const util::StringView &ctorId, uint32_t litIdx, 1534 VReg lexenv, VReg base) 1535{ 1536 Ra().Emit<EcmaDefineclasswithbuffer>(node, ctorId, litIdx, lexenv, base); 1537} 1538 1539void PandaGen::LoadClassComputedInstanceFields(const ir::AstNode *node, VReg ctor) 1540{ 1541 Sa().Emit<EcmaLoadclasscomputedinstancefields>(node, ctor); 1542} 1543 1544void PandaGen::DefineClassPrivateFields(const ir::AstNode *node, uint32_t privateBufIdx) 1545{ 1546 Sa().Emit<EcmaDefineclassprivatefields>(node, util::Helpers::ToStringView(Allocator(), privateBufIdx), LexEnv()); 1547} 1548 1549void PandaGen::ClassFieldAdd(const ir::AstNode *node, VReg obj, VReg prop) 1550{ 1551 Ra().Emit<EcmaClassfieldadd>(node, obj, prop); 1552} 1553 1554void PandaGen::ClassPrivateFieldAdd(const ir::AstNode *node, VReg ctor, VReg obj, const util::StringView &prop) 1555{ 1556 Ra().Emit<EcmaClassprivatefieldadd>(node, prop, ctor, obj); 1557} 1558 1559void PandaGen::ClassPrivateMethodOrAccessorAdd(const ir::AstNode *node, VReg ctor, VReg obj) 1560{ 1561 Ra().Emit<EcmaClassprivatemethodoraccessoradd>(node, ctor, obj); 1562} 1563 1564void PandaGen::ClassPrivateFieldGet(const ir::AstNode *node, VReg ctor, VReg obj, const util::StringView &prop) 1565{ 1566 Ra().Emit<EcmaClassprivatefieldget>(node, prop, ctor, obj); 1567} 1568 1569void PandaGen::ClassPrivateFieldSet(const ir::AstNode *node, VReg ctor, VReg obj, const util::StringView &prop) 1570{ 1571 Ra().Emit<EcmaClassprivatefieldset>(node, prop, ctor, obj); 1572} 1573 1574void PandaGen::ClassPrivateFieldIn(const ir::AstNode *node, VReg ctor, const util::StringView &prop) 1575{ 1576 Ra().Emit<EcmaClassprivatefieldin>(node, prop, ctor); 1577} 1578 1579void PandaGen::LoadModuleVariable(const ir::AstNode *node, VReg module, const util::StringView &name) 1580{ 1581 Ra().Emit<EcmaLdmodvarbyname>(node, name, module); 1582} 1583 1584void PandaGen::StoreModuleVar(const ir::AstNode *node, const util::StringView &name) 1585{ 1586 Sa().Emit<EcmaStmodulevar>(node, name); 1587} 1588 1589void PandaGen::CopyModule(const ir::AstNode *node, VReg module) 1590{ 1591 Ra().Emit<EcmaCopymodule>(node, module); 1592} 1593 1594void PandaGen::StSuperByName(const ir::AstNode *node, VReg obj, const util::StringView &key) 1595{ 1596 Ra().Emit<EcmaStsuperbyname>(node, key, obj); 1597} 1598 1599void PandaGen::LdSuperByName(const ir::AstNode *node, const util::StringView &key) 1600{ 1601 Ra().Emit<EcmaLdsuperbyname>(node, key); 1602} 1603 1604void PandaGen::StSuperByValue(const ir::AstNode *node, VReg obj, VReg prop) 1605{ 1606 Ra().Emit<EcmaStsuperbyvalue>(node, obj, prop); 1607} 1608 1609void PandaGen::LdSuperByValue(const ir::AstNode *node, VReg obj) 1610{ 1611 Ra().Emit<EcmaLdsuperbyvalue>(node, obj); 1612} 1613 1614void PandaGen::StoreSuperProperty(const ir::AstNode *node, VReg obj, const Operand &prop) 1615{ 1616 if (std::holds_alternative<util::StringView>(prop)) { 1617 StSuperByName(node, obj, std::get<util::StringView>(prop)); 1618 return; 1619 } 1620 1621 ASSERT(std::holds_alternative<VReg>(prop)); 1622 StSuperByValue(node, obj, std::get<VReg>(prop)); 1623} 1624 1625void PandaGen::LoadSuperProperty(const ir::AstNode *node, const Operand &prop) 1626{ 1627 if (std::holds_alternative<util::StringView>(prop)) { 1628 LdSuperByName(node, std::get<util::StringView>(prop)); 1629 return; 1630 } 1631 1632 ASSERT(std::holds_alternative<VReg>(prop)); 1633 LdSuperByValue(node, std::get<VReg>(prop)); 1634} 1635 1636void PandaGen::LoadLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot) 1637{ 1638 Sa().Emit<EcmaLdlexvardyn>(node, level, slot); 1639} 1640 1641void PandaGen::LoadLexical(const ir::AstNode *node, const util::StringView &name, uint32_t level, uint32_t slot) 1642{ 1643 Sa().Emit<EcmaLdlexdyn>(node, name, level, slot); 1644} 1645 1646void PandaGen::StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot) 1647{ 1648 Ra().Emit<EcmaStlexvardyn>(node, level, slot); 1649} 1650 1651void PandaGen::StoreLexical(const ir::AstNode *node, const util::StringView &name, uint32_t level, uint32_t slot) 1652{ 1653 Ra().Emit<EcmaStlexdyn>(node, name, level, slot); 1654} 1655 1656void PandaGen::ThrowIfSuperNotCorrectCall(const ir::AstNode *node, int64_t num) 1657{ 1658 Sa().Emit<EcmaThrowifsupernotcorrectcall>(node, num); 1659} 1660 1661void PandaGen::ThrowTdz(const ir::AstNode *node, const util::StringView &name) 1662{ 1663 Sa().Emit<EcmaThrowtdz>(node, name); 1664} 1665 1666void PandaGen::ThrowConstAssignment(const ir::AstNode *node, const util::StringView &name) 1667{ 1668 Ra().Emit<EcmaThrowconstassignment>(node, name); 1669} 1670 1671void PandaGen::PopLexEnv(const ir::AstNode *node) 1672{ 1673 Sa().Emit<EcmaPoplexenvdyn>(node); 1674} 1675 1676void PandaGen::CopyLexEnv(const ir::AstNode *node) 1677{ 1678 Sa().Emit<EcmaCopylexenvdyn>(node); 1679} 1680 1681void PandaGen::NewLexEnv(const ir::AstNode *node, uint32_t num) 1682{ 1683 Sa().Emit<EcmaNewlexenvdyn>(node, num); 1684} 1685 1686void PandaGen::LdLexEnv(const ir::AstNode *node) 1687{ 1688 Sa().Emit<EcmaLdlexenvdyn>(node); 1689} 1690 1691Operand PandaGen::ToNamedPropertyKey(const ir::Expression *prop, bool isComputed) 1692{ 1693 VReg res {VReg::REG_START}; 1694 1695 if (!isComputed) { 1696 if (prop->IsIdentifier()) { 1697 return prop->AsIdentifier()->Name(); 1698 } 1699 return res; 1700 } 1701 1702 if (prop->IsStringLiteral()) { 1703 const util::StringView &str = prop->AsStringLiteral()->Str(); 1704 1705 /* NOTE: dbatyai. remove this when runtime handles __proto__ as property name correctly */ 1706 if (str.Is("__proto__")) { 1707 return res; 1708 } 1709 1710 int64_t index = util::Helpers::GetIndex(str); 1711 if (index != util::Helpers::INVALID_INDEX) { 1712 return index; 1713 } 1714 1715 return str; 1716 } 1717 1718 if (prop->IsNumberLiteral()) { 1719 auto num = prop->AsNumberLiteral()->Number().GetDouble(); 1720 if (util::Helpers::IsIndex(num)) { 1721 return static_cast<int64_t>(num); 1722 } 1723 1724 return prop->AsNumberLiteral()->Str(); 1725 } 1726 1727 return res; 1728} 1729 1730Operand PandaGen::ToPropertyKey(const ir::Expression *prop, bool isComputed, bool isSuperExpression) 1731{ 1732 Operand op = ToNamedPropertyKey(prop, isComputed); 1733 if (std::holds_alternative<util::StringView>(op)) { 1734 return op; 1735 } 1736 1737 if (std::holds_alternative<int64_t>(op) && !isSuperExpression) { 1738 return op; 1739 } 1740 1741 VReg objReg = AllocReg(); 1742 StoreAccumulator(prop, objReg); 1743 prop->Compile(this); 1744 1745 return objReg; 1746} 1747 1748Operand PandaGen::ToOwnPropertyKey(const ir::Expression *prop, bool isComputed) 1749{ 1750 Operand op = ToNamedPropertyKey(prop, isComputed); 1751 if (std::holds_alternative<util::StringView>(op)) { 1752 ASSERT(std::holds_alternative<util::StringView>(op) || std::holds_alternative<int64_t>(op)); 1753 return op; 1754 } 1755 1756 if (std::holds_alternative<int64_t>(op)) { 1757 return op; 1758 } 1759 1760 VReg propReg = AllocReg(); 1761 prop->Compile(this); 1762 StoreAccumulator(prop, propReg); 1763 1764 return propReg; 1765} 1766 1767void PandaGen::LoadPropertyKeyAcc(const ir::Expression *prop, bool isComputed) 1768{ 1769 Operand op = ToNamedPropertyKey(prop, isComputed); 1770 if (std::holds_alternative<util::StringView>(op)) { 1771 LoadAccumulatorString(prop, std::get<util::StringView>(op)); 1772 } else if (std::holds_alternative<int64_t>(op)) { 1773 LoadAccumulatorInt(prop, static_cast<size_t>(std::get<int64_t>(op))); 1774 } else { 1775 prop->Compile(this); 1776 } 1777} 1778 1779VReg PandaGen::LoadPropertyKey(const ir::Expression *prop, bool isComputed) 1780{ 1781 LoadPropertyKeyAcc(prop, isComputed); 1782 1783 VReg propReg = AllocReg(); 1784 StoreAccumulator(prop, propReg); 1785 1786 return propReg; 1787} 1788 1789void PandaGen::LoadEvalVariable(const ir::AstNode *node, const util::StringView &name) 1790{ 1791 RegScope rs(this); 1792 LoadLexicalContext(node); 1793 Ra().Emit<EcmaLdevalvar>(node, name); 1794} 1795 1796void PandaGen::StoreEvalVariable(const ir::AstNode *node, const util::StringView &name) 1797{ 1798 RegScope rs(this); 1799 VReg value = AllocReg(); 1800 StoreAccumulator(node, value); 1801 LoadLexicalContext(node); 1802 Ra().Emit<EcmaStevalvar>(node, name, value); 1803} 1804 1805void PandaGen::DirectEval(const ir::AstNode *node, uint32_t parserStatus) 1806{ 1807 RegScope rs(this); 1808 1809 uint32_t index = 0; 1810 uint32_t evalBindingsIndex = 0; 1811 VReg arg0 = AllocReg(); 1812 StoreAccumulator(node, arg0); 1813 VReg bindings = AllocReg(); 1814 CreateEmptyArray(node); 1815 StoreAccumulator(node, bindings); 1816 1817 GetFunctionObject(node); 1818 StOwnByIndex(node, bindings, index++); 1819 GetNewTarget(node); 1820 StOwnByIndex(node, bindings, index++); 1821 GetThis(node); 1822 StOwnByIndex(node, bindings, index++); 1823 1824 VReg evalBindings = AllocReg(); 1825 CreateEmptyArray(node); 1826 StoreAccumulator(node, evalBindings); 1827 1828 LoadAccumulator(node, LexEnv()); 1829 StOwnByIndex(node, evalBindings, evalBindingsIndex++); 1830 1831 const auto *iter = Scope()->EnclosingVariableScope(); 1832 1833 while (true) { 1834 uint32_t scopeBindingsBuf = iter->EvalBindings(); 1835 if (scopeBindingsBuf != INVALID_LITERAL_BUFFER_ID) { 1836 Sa().Emit<EcmaLdevalbindings>(node, util::Helpers::ToStringView(Allocator(), scopeBindingsBuf)); 1837 StOwnByIndex(node, evalBindings, evalBindingsIndex++); 1838 } 1839 1840 if (iter->Parent() == nullptr) { 1841 break; 1842 } 1843 1844 iter = iter->Parent()->EnclosingVariableScope(); 1845 } 1846 1847 LoadAccumulator(node, evalBindings); 1848 StOwnByIndex(node, bindings, index++); 1849 1850 Sa().Emit<EcmaDirecteval>(node, static_cast<int64_t>(parserStatus), arg0, bindings); 1851} 1852 1853void PandaGen::LoadLexicalContext(const ir::AstNode *node) 1854{ 1855 auto result = Scope()->Find(varbinder::VarBinder::LEXICAL_CONTEXT_PARAM); 1856 LoadLexicalVar(node, result.lexLevel, result.variable->AsLocalVariable()->LexIdx()); 1857} 1858 1859bool PandaGen::IsDirectEval() const 1860{ 1861 return Context()->config->options->CompilerOptions().isDirectEval; 1862} 1863 1864bool PandaGen::IsEval() const 1865{ 1866 return Context()->config->options->CompilerOptions().isEval; 1867} 1868 1869const checker::Type *PandaGen::GetVRegType(VReg vreg) const 1870{ 1871 // We assume that all used regs have any type 1872 if (vreg.GetIndex() > NextReg().GetIndex()) { 1873 return Context()->checker->GetGlobalTypesHolder()->GlobalAnyType(); 1874 } 1875 1876 return nullptr; 1877} 1878 1879} // namespace ark::es2panda::compiler 1880