diff --git a/es2panda/binder/binder.cpp b/es2panda/binder/binder.cpp index 43a98efbaadad7c669278604df5e3d24fc8176da..a094a339ee453509c84826ba16be5d8415e58c52 100644 --- a/es2panda/binder/binder.cpp +++ b/es2panda/binder/binder.cpp @@ -93,6 +93,12 @@ void Binder::ThrowUndeclaredExport(const lexer::SourcePosition &pos, const util: throw Error(ErrorType::SYNTAX, ss.str(), loc.line, loc.col); } +void Binder::AssignIndexToModuleVariable() +{ + ASSERT(program_->ModuleRecord()); + program_->ModuleRecord()->AssignIndexToModuleVariable(topScope_->AsModuleScope()); +} + void Binder::IdentifierAnalysis() { ASSERT(program_->Ast()); @@ -101,6 +107,9 @@ void Binder::IdentifierAnalysis() BuildFunction(topScope_, MAIN_FUNC_NAME); ResolveReferences(program_->Ast()); AddMandatoryParams(); + if (topScope_->IsModuleScope()) { + AssignIndexToModuleVariable(); + } } void Binder::ValidateExportDecl(const ir::ExportNamedDeclaration *exportDecl) diff --git a/es2panda/binder/binder.h b/es2panda/binder/binder.h index 7f07e686e203f76e8e12131625a62b5037b58526..e9213c472e5ba71165c7711659bbb279ff672a93 100644 --- a/es2panda/binder/binder.h +++ b/es2panda/binder/binder.h @@ -161,6 +161,7 @@ private: } void AddMandatoryParams(); + void AssignIndexToModuleVariable(); void BuildFunction(FunctionScope *funcScope, util::StringView name); void BuildScriptFunction(Scope *outerScope, const ir::ScriptFunction *scriptFunc); void BuildClassDefinition(ir::ClassDefinition *classDef); diff --git a/es2panda/binder/scope.cpp b/es2panda/binder/scope.cpp index 21649a4b8c95046eb94d3c3392e067af5c7bd9fc..634676482a8d63ea7f5b39091cba8c71b4bab17c 100644 --- a/es2panda/binder/scope.cpp +++ b/es2panda/binder/scope.cpp @@ -358,6 +358,14 @@ void ModuleScope::ConvertLocalVariableToModuleVariable(ArenaAllocator *allocator } } +void ModuleScope::AssignIndexToModuleVariable(util::StringView name, uint32_t index) +{ + auto *moduleVar = FindLocal(name); + ASSERT(moduleVar != nullptr); + ASSERT(moduleVar->IsModuleVariable()); + moduleVar->AsModuleVariable()->AssignIndex(index); +} + bool ModuleScope::AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, [[maybe_unused]] ScriptExtension extension) { diff --git a/es2panda/binder/scope.h b/es2panda/binder/scope.h index ad0783e33bf004ab87618cc4b0b3cc8fc50a2113..94b3791028e56c0f3558af5cb6b36aebd20cc862 100644 --- a/es2panda/binder/scope.h +++ b/es2panda/binder/scope.h @@ -599,6 +599,8 @@ public: return ScopeType::MODULE; } + void AssignIndexToModuleVariable(util::StringView name, uint32_t index); + void ConvertLocalVariableToModuleVariable(ArenaAllocator *allocator, util::StringView localName); bool AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, diff --git a/es2panda/binder/variable.h b/es2panda/binder/variable.h index 80086ef9f65b1926f1b65501ea19a41d1cb0c504..a17b88885a19d065ed153e5c86eeee397dcdf73b 100644 --- a/es2panda/binder/variable.h +++ b/es2panda/binder/variable.h @@ -184,6 +184,19 @@ public: } void SetLexical([[maybe_unused]] Scope *scope, [[maybe_unused]] util::Hotfix *hotfixHelper = nullptr) override; + + void AssignIndex(uint32_t index) + { + index_ = index; + } + + uint32_t Index() const + { + return index_; + } + +private: + uint32_t index_; }; class EnumVariable : public Variable { diff --git a/es2panda/compiler/base/destructuring.cpp b/es2panda/compiler/base/destructuring.cpp index 70d9ef0754d749ed9ca0aee4dbe9c1fd9857bf7c..5761a021774bc9898ddb012a2f56585f9e508ed6 100644 --- a/es2panda/compiler/base/destructuring.cpp +++ b/es2panda/compiler/base/destructuring.cpp @@ -145,8 +145,8 @@ static void GenArray(PandaGen *pg, const ir::ArrayExpression *array) pg->SetLabel(array, labelSet.CatchEnd()); } -static void GenObjectProperty(PandaGen *pg, const ir::ObjectExpression *object, const ir::Expression *element, - VReg value, VReg propReg) +static void GenObjectProperty(PandaGen *pg, const ir::ObjectExpression *object, + const ir::Expression *element, VReg value) { RegScope propScope(pg); VReg loadedValue = pg->AllocReg(); @@ -169,12 +169,10 @@ static void GenObjectProperty(PandaGen *pg, const ir::ObjectExpression *object, key->Compile(pg); } - pg->StoreAccumulator(key, propReg); - LReference lref = LReference::CreateLRef(pg, target, object->IsDeclaration()); // load obj property from rhs, return undefined if no corresponding property exists - pg->LoadObjByValue(element, value, propReg); + pg->LoadObjByValue(element, value); pg->StoreAccumulator(element, loadedValue); if (init != nullptr) { @@ -211,8 +209,7 @@ static void GenObjectWithRest(PandaGen *pg, const ir::ObjectExpression *object, break; } - VReg propReg = pg->AllocReg(); - GenObjectProperty(pg, object, element, rhs, propReg); + GenObjectProperty(pg, object, element, rhs); } } @@ -241,10 +238,7 @@ static void GenObject(PandaGen *pg, const ir::ObjectExpression *object, VReg rhs } for (const auto *element : properties) { - RegScope rs(pg); - VReg propReg = pg->AllocReg(); - - GenObjectProperty(pg, object, element, rhs, propReg); + GenObjectProperty(pg, object, element, rhs); } } diff --git a/es2panda/compiler/base/hoisting.cpp b/es2panda/compiler/base/hoisting.cpp index e8b61fc97d3252b521f595b266bd3675664f6729..5f5b6370b65be4bfa2cc4122dbe808fd3a1a6ac8 100644 --- a/es2panda/compiler/base/hoisting.cpp +++ b/es2panda/compiler/base/hoisting.cpp @@ -27,7 +27,9 @@ static void StoreModuleVarOrLocalVar(PandaGen *pg, binder::ScopeFindResult &resu { if (decl->IsImportOrExportDecl()) { ASSERT(pg->Scope()->IsModuleScope()); - pg->StoreModuleVariable(decl->Node(), decl->Name()); + auto *var = pg->Scope()->FindLocal(decl->Name()); + ASSERT(var->IsModuleVariable()); + pg->StoreModuleVariable(decl->Node(), var->AsModuleVariable()); } else { pg->StoreAccToLexEnv(decl->Node(), result, true); } @@ -84,7 +86,7 @@ static void HoistNameSpaceImports(PandaGen *pg) ASSERT(var != nullptr); auto *node = var->Declaration()->Node(); ASSERT(node != nullptr); - pg->GetModuleNamespace(node, nameSpaceEntry->localName_); + pg->GetModuleNamespace(node, nameSpaceEntry->moduleRequestIdx_); pg->StoreVar(node, {nameSpaceEntry->localName_, pg->TopScope(), 0, var}, true); } } diff --git a/es2panda/compiler/core/compilerContext.cpp b/es2panda/compiler/core/compilerContext.cpp index 81434e630b0a4cdccc30fa37dc54886355150f91..f3549110db087121ab07c049dfe76cea3a76e401 100644 --- a/es2panda/compiler/core/compilerContext.cpp +++ b/es2panda/compiler/core/compilerContext.cpp @@ -20,9 +20,10 @@ namespace panda::es2panda::compiler { CompilerContext::CompilerContext(binder::Binder *binder, bool isDebug, bool isDebuggerEvaluateExpressionMode, - bool isMergeAbc, std::string sourceFile) + bool isMergeAbc, std::string sourceFile, util::StringView recordName) : binder_(binder), isDebug_(isDebug), isDebuggerEvaluateExpressionMode_(isDebuggerEvaluateExpressionMode), - isMergeAbc_(isMergeAbc), sourceFile_(sourceFile), emitter_(std::make_unique(this)) + isMergeAbc_(isMergeAbc), sourceFile_(sourceFile), emitter_(std::make_unique(this)), + recordName_(recordName) { } diff --git a/es2panda/compiler/core/compilerContext.h b/es2panda/compiler/core/compilerContext.h index 6acc7b83fb53a24cf1004237abdbab7734ca6349..5348d48fd36f327edbe0bc513932a09d4c209635 100644 --- a/es2panda/compiler/core/compilerContext.h +++ b/es2panda/compiler/core/compilerContext.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -35,7 +36,7 @@ class Emitter; class CompilerContext { public: CompilerContext(binder::Binder *binder, bool isDebug, bool isDebuggerEvaluateExpressionMode, - bool isMergeAbc, std::string sourceFile); + bool isMergeAbc, std::string sourceFile, util::StringView recordName); NO_COPY_SEMANTIC(CompilerContext); NO_MOVE_SEMANTIC(CompilerContext); ~CompilerContext() = default; @@ -96,6 +97,11 @@ public: return hotfixHelper_; } + util::StringView RecordName() const + { + return recordName_; + } + private: binder::Binder *binder_; int32_t literalBufferIdx_ {0}; @@ -106,6 +112,7 @@ private: std::string sourceFile_; std::unique_ptr emitter_; util::Hotfix *hotfixHelper_ {nullptr}; + util::StringView recordName_; }; } // namespace panda::es2panda::compiler diff --git a/es2panda/compiler/core/compilerImpl.cpp b/es2panda/compiler/core/compilerImpl.cpp index 5561346b974793c47b68f0e8599a6c22d805f6e7..368783be9633a58dc2a8ce8f99c98582a2344101 100644 --- a/es2panda/compiler/core/compilerImpl.cpp +++ b/es2panda/compiler/core/compilerImpl.cpp @@ -39,7 +39,7 @@ panda::pandasm::Program *CompilerImpl::Compile(parser::Program *program, const e const std::string &debugInfoSourceFile) { CompilerContext context(program->Binder(), options.isDebug, options.isDebuggerEvaluateExpressionMode, - options.mergeAbc, debugInfoSourceFile); + options.mergeAbc, debugInfoSourceFile, program->RecordName()); if (hotfixHelper_ != nullptr) { context.AddHotfixHelper(hotfixHelper_); diff --git a/es2panda/compiler/core/emitter/emitter.cpp b/es2panda/compiler/core/emitter/emitter.cpp index 53064fdc1dea20e7c450060e75a09504cadcdc15..13f1b0a41d5c9bd189e41198b8670c373111b8fd 100644 --- a/es2panda/compiler/core/emitter/emitter.cpp +++ b/es2panda/compiler/core/emitter/emitter.cpp @@ -57,6 +57,7 @@ FunctionEmitter::FunctionEmitter(ArenaAllocator *allocator, const PandaGen *pg) void FunctionEmitter::Generate(util::Hotfix *hotfixHelper) { + GenFunctionKind(); GenFunctionInstructions(); GenVariablesDebugInfo(); GenSourceFileDebugInfo(); @@ -72,6 +73,16 @@ const ArenaSet &FunctionEmitter::Strings() const return pg_->Strings(); } +void FunctionEmitter::GenFunctionKind() +{ + func_->SetFunctionKind(static_cast(pg_->GetFunctionKind())); +} + +void FunctionEmitter::GenIcSize() +{ + func_->SetSlotsNum(pg_->GetCurrentSlot()); +} + void FunctionEmitter::GenBufferLiterals(const LiteralBuffer *buff) { auto &[idx, array] = literalBuffers_.emplace_back(); diff --git a/es2panda/compiler/core/emitter/emitter.h b/es2panda/compiler/core/emitter/emitter.h index f689a4e57c80e973f81be76d7c0064134343f076..3bf135f729da4656bed90d9673739d5ed3e30223 100644 --- a/es2panda/compiler/core/emitter/emitter.h +++ b/es2panda/compiler/core/emitter/emitter.h @@ -81,6 +81,8 @@ private: void GenScopeVariableInfo(const binder::Scope *scope); void GenSourceFileDebugInfo(); void GenVariablesDebugInfo(); + void GenFunctionKind(); + void GenIcSize(); util::StringView SourceCode() const; lexer::LineIndex &GetLineIndex() const; diff --git a/es2panda/compiler/core/envScope.cpp b/es2panda/compiler/core/envScope.cpp index a6c123937c6f11cf1f0d2398dc394504f5ebffed..6cb007c87e5599bda9ef68b52009c49f28edf250 100644 --- a/es2panda/compiler/core/envScope.cpp +++ b/es2panda/compiler/core/envScope.cpp @@ -30,11 +30,10 @@ ScopeContext::~ScopeContext() pg_->scope_ = prevScope_; } -void EnvScope::Initialize(PandaGen *pg, VReg lexEnv) +void EnvScope::Initialize(PandaGen *pg) { pg_ = pg; prev_ = pg_->envScope_; - lexEnv_ = lexEnv; pg_->envScope_ = this; } @@ -53,10 +52,9 @@ void LoopEnvScope::CopyBindings(PandaGen *pg, binder::VariableScope *scope, bind return; } - Initialize(pg, pg->AllocReg()); + Initialize(pg); pg_->NewLexicalEnv(scope_->Node(), scope->LexicalSlots(), scope_); - pg_->StoreAccumulator(scope_->Node(), lexEnv_); ASSERT(scope->NeedLexEnv()); @@ -89,7 +87,6 @@ void LoopEnvScope::CopyPetIterationCtx() } pg_->PopLexEnv(scope_->Node()); pg_->NewLexicalEnv(scope_->Node(), num, scope_); - pg_->StoreAccumulator(scope_->Node(), lexEnv_); for (uint32_t i = 0; i < num; i++) { pg_->StoreLexicalVar(scope_->Node(), 0, i, lexicals[i]); diff --git a/es2panda/compiler/core/envScope.h b/es2panda/compiler/core/envScope.h index 55b801a7a1f3e026a9403344d896fdbedc68ecbe..a21c2a3e52022a8ec6e51467b395d410cda5f5e8 100644 --- a/es2panda/compiler/core/envScope.h +++ b/es2panda/compiler/core/envScope.h @@ -52,12 +52,7 @@ public: NO_MOVE_SEMANTIC(EnvScope); ~EnvScope(); - void Initialize(PandaGen *pg, VReg lexEnv); - - VReg LexEnv() const - { - return lexEnv_; - } + void Initialize(PandaGen *pg); EnvScope *Prev() const { @@ -69,7 +64,6 @@ protected: PandaGen *pg_ {}; EnvScope *prev_ {}; - VReg lexEnv_ {}; }; class LoopEnvScope : public EnvScope { diff --git a/es2panda/compiler/core/function.cpp b/es2panda/compiler/core/function.cpp index 3f4a050ea07cc44fde3dc3c1d3779b8e2fdf6b89..1df946cfa6ad5c3f0fa3eab99962806bb159d67b 100644 --- a/es2panda/compiler/core/function.cpp +++ b/es2panda/compiler/core/function.cpp @@ -170,7 +170,7 @@ static void CompileFunction(PandaGen *pg) pg->FunctionExit(); } -static VReg CompileFunctionOrProgram(PandaGen *pg) +static void CompileFunctionOrProgram(PandaGen *pg) { FunctionRegScope lrs(pg); const auto *topScope = pg->TopScope(); @@ -192,16 +192,15 @@ static VReg CompileFunctionOrProgram(PandaGen *pg) CompileSourceBlock(pg, pg->RootNode()->AsBlockStatement()); } } - - return pg->GetEnvScope()->LexEnv(); } void Function::Compile(PandaGen *pg) { - VReg lexEnv = CompileFunctionOrProgram(pg); + CompileFunctionOrProgram(pg); + pg->SetFunctionKind(); pg->SetSourceLocationFlag(lexer::SourceLocationFlag::INVALID_SOURCE_LOCATION); pg->CopyFunctionArguments(pg->RootNode()); - pg->InitializeLexEnv(pg->RootNode(), lexEnv); + pg->InitializeLexEnv(pg->RootNode()); pg->SetSourceLocationFlag(lexer::SourceLocationFlag::VALID_SOURCE_LOCATION); pg->SortCatchTables(); } diff --git a/es2panda/compiler/core/pandagen.cpp b/es2panda/compiler/core/pandagen.cpp index e56e28c72dc42d6fc0fdc2f07c3049f0955913d6..b9a4616bf56784ae53c2a83bdb3489309f50dced 100644 --- a/es2panda/compiler/core/pandagen.cpp +++ b/es2panda/compiler/core/pandagen.cpp @@ -42,11 +42,52 @@ #include #include #include +#include namespace panda::es2panda::compiler { // PandaGen +void PandaGen::SetFunctionKind() +{ + if (rootNode_->IsProgram()) { + funcKind_ = FunctionKind::FUNCTION; + return; + } + + auto *func = rootNode_->AsScriptFunction(); + if (func->IsMethod()) { + return; + } + + if (func->IsAsync()) { + if (func->IsGenerator()) { + funcKind_ = FunctionKind::ASYNC_GENERATOR_FUNCTION; + return; + } + + if (func->IsArrow()) { + funcKind_ = FunctionKind::ASYNC_NCFUNCTION; + return; + } + + funcKind_ = FunctionKind::ASYNC_FUNCTION; + return; + } + + if (func->IsGenerator()) { + funcKind_ = FunctionKind::GENERATOR_FUNCTION; + return; + } + + if (func->IsArrow()) { + funcKind_ = FunctionKind::NC_FUNCTION; + return; + } + + funcKind_ = FunctionKind::FUNCTION; +} + Label *PandaGen::AllocLabel() { std::string id = std::string {Label::PREFIX} + std::to_string(labelId_++); @@ -157,17 +198,13 @@ void PandaGen::FunctionExit() builder_->CleanUp(rootNode_->AsScriptFunction()); } -void PandaGen::InitializeLexEnv(const ir::AstNode *node, VReg lexEnv) +void PandaGen::InitializeLexEnv(const ir::AstNode *node) { FrontAllocator fa(this); if (topScope_->NeedLexEnv()) { NewLexicalEnv(node, topScope_->LexicalSlots(), topScope_); - } else { - LdLexEnv(node); } - - StoreAccumulator(node, lexEnv); } void PandaGen::CopyFunctionArguments(const ir::AstNode *node) @@ -179,7 +216,7 @@ void PandaGen::CopyFunctionArguments(const ir::AstNode *node) if (param->LexicalBound()) { StoreLexicalVar(node, 0, param->LexIdx(), targetReg++); } else { - ra_.Emit(node, param->Vreg(), targetReg++); + MoveVreg(node, param->Vreg(), targetReg++); } } } @@ -242,7 +279,8 @@ void PandaGen::LoadVar(const ir::Identifier *node, const binder::ScopeFindResult } if (var->IsModuleVariable()) { - LoadModuleVariable(node, var->Name(), var->HasFlag(binder::VariableFlags::LOCAL_EXPORT)); + var->HasFlag(binder::VariableFlags::LOCAL_EXPORT) ? LoadLocalModuleVariable(node, var->AsModuleVariable()) : + LoadExternalModuleVariable(node, var->AsModuleVariable()); if (var->Declaration()->IsLetOrConstOrClassDecl()) { ThrowUndefinedIfHole(node, var->Name()); } @@ -284,12 +322,12 @@ void PandaGen::StoreVar(const ir::AstNode *node, const binder::ScopeFindResult & RegScope rs(this); VReg valueReg = AllocReg(); StoreAccumulator(node, valueReg); - LoadModuleVariable(node, var->Name(), true); + LoadLocalModuleVariable(node, var->AsModuleVariable()); ThrowUndefinedIfHole(node, var->Name()); LoadAccumulator(node, valueReg); } - StoreModuleVariable(node, var->Name()); + StoreModuleVariable(node, var->AsModuleVariable()); return; } @@ -298,13 +336,12 @@ void PandaGen::StoreVar(const ir::AstNode *node, const binder::ScopeFindResult & if (var->Declaration()->IsLetOrConstOrClassDecl() && result.scope->IsGlobalScope()) { if (!isDeclaration) { TryStoreGlobalByName(node, var->Name()); - } else if (var->Declaration()->IsLetDecl()) { - StLetToGlobalRecord(node, var->Name()); + } else if (var->Declaration()->IsLetDecl() || var->Declaration()->IsClassDecl()) { + StLetOrClassToGlobalRecord(node, var->Name()); } else if (var->Declaration()->IsConstDecl()) { StConstToGlobalRecord(node, var->Name()); - } else if (var->Declaration()->IsClassDecl()) { - StClassToGlobalRecord(node, var->Name()); } + return; } @@ -313,7 +350,7 @@ void PandaGen::StoreVar(const ir::AstNode *node, const binder::ScopeFindResult & void PandaGen::StoreAccumulator(const ir::AstNode *node, VReg vreg) { - ra_.Emit(node, vreg); + ra_.Emit(node, vreg); } void PandaGen::LoadAccFromArgs(const ir::AstNode *node) @@ -334,7 +371,8 @@ void PandaGen::LoadAccFromArgs(const ir::AstNode *node) void PandaGen::LoadObjProperty(const ir::AstNode *node, VReg obj, const Operand &prop) { if (std::holds_alternative(prop)) { - LoadObjByValue(node, obj, std::get(prop)); + LoadAccumulator(node, std::get(prop)); + LoadObjByValue(node, obj); return; } @@ -409,7 +447,8 @@ void PandaGen::TryLoadGlobalByName(const ir::AstNode *node, const util::StringVi if (isDebuggerEvaluateExpressionMode()) { LoadObjByNameViaDebugger(node, name, true); } else { - sa_.Emit(node, name); + // modify ic later + sa_.Emit(node, 0, name); } strings_.insert(name); } @@ -437,109 +476,121 @@ void PandaGen::TryStoreGlobalByName(const ir::AstNode *node, const util::StringV if (isDebuggerEvaluateExpressionMode()) { StoreObjByNameViaDebugger(node, name); } else { - sa_.Emit(node, name); + // modify ic later + sa_.Emit(node, 0, name); } strings_.insert(name); } void PandaGen::LoadObjByName(const ir::AstNode *node, VReg obj, const util::StringView &prop) { - ra_.Emit(node, prop, obj); + // modify ic later + LoadAccumulator(node, obj); // object is load to acc + sa_.Emit(node, 0, prop); strings_.insert(prop); } void PandaGen::StoreObjByName(const ir::AstNode *node, VReg obj, const util::StringView &prop) { - ra_.Emit(node, prop, obj); + // modify ic later + ra_.Emit(node, 0, prop, obj); strings_.insert(prop); } void PandaGen::LoadObjByIndex(const ir::AstNode *node, VReg obj, int64_t index) { - ra_.Emit(node, index, obj); + LoadAccumulator(node, obj); // object is load to acc + if (index <= util::Helpers::MAX_INT16) { + // modify ic later + sa_.Emit(node, 0, index); + return; + } + + sa_.Emit(node, index); } -void PandaGen::LoadObjByValue(const ir::AstNode *node, VReg obj, VReg prop) +void PandaGen::LoadObjByValue(const ir::AstNode *node, VReg obj) { - ra_.Emit(node, obj, prop); + // modify ic later + ra_.Emit(node, 0, obj); // prop is in acc } void PandaGen::StoreObjByValue(const ir::AstNode *node, VReg obj, VReg prop) { - ra_.Emit(node, obj, prop); + // modify ic later + ra_.Emit(node, 0, obj, prop); } void PandaGen::StoreObjByIndex(const ir::AstNode *node, VReg obj, int64_t index) { - ra_.Emit(node, index, obj); + if (index <= util::Helpers::MAX_INT16) { + // modify ic later + ra_.Emit(node, 0, obj, index); + return; + } + + ra_.Emit(node, obj, index); } void PandaGen::StOwnByName(const ir::AstNode *node, VReg obj, const util::StringView &prop, bool nameSetting) { - nameSetting ? ra_.Emit(node, prop, obj) : - ra_.Emit(node, prop, obj); + // modify ic later + nameSetting ? ra_.Emit(node, 0, prop, obj) : + ra_.Emit(node, 0, prop, obj); strings_.insert(prop); } void PandaGen::StOwnByValue(const ir::AstNode *node, VReg obj, VReg prop, bool nameSetting) { - nameSetting ? ra_.Emit(node, obj, prop) : - ra_.Emit(node, obj, prop); + // modify ic later + nameSetting ? ra_.Emit(node, 0, obj, prop) : + ra_.Emit(node, 0, obj, prop); } void PandaGen::StOwnByIndex(const ir::AstNode *node, VReg obj, int64_t index) { - ra_.Emit(node, obj, index); + if (index <= util::Helpers::MAX_INT16) { + // modify ic later + ra_.Emit(node, 0, obj, index); + return; + } + + ra_.Emit(node, obj, index); } void PandaGen::DeleteObjProperty(const ir::AstNode *node, VReg obj, const Operand &prop) { - VReg property {}; - if (std::holds_alternative(prop)) { - property = std::get(prop); + LoadAccumulator(node, std::get(prop)); } else if (std::holds_alternative(prop)) { LoadAccumulatorInt(node, static_cast(std::get(prop))); - property = AllocReg(); - StoreAccumulator(node, property); } else { ASSERT(std::holds_alternative(prop)); LoadAccumulatorString(node, std::get(prop)); - property = AllocReg(); - StoreAccumulator(node, property); } - ra_.Emit(node, obj, property); + ra_.Emit(node, obj); // property is load to acc } void PandaGen::LoadAccumulator(const ir::AstNode *node, VReg reg) { - ra_.Emit(node, reg); + ra_.Emit(node, reg); } void PandaGen::LoadGlobalVar(const ir::AstNode *node, const util::StringView &name) { - sa_.Emit(node, name); + // modify ic later + sa_.Emit(node, 0, name); strings_.insert(name); } void PandaGen::StoreGlobalVar(const ir::AstNode *node, const util::StringView &name) { - sa_.Emit(node, name); - strings_.insert(name); -} - -void PandaGen::StoreGlobalLet(const ir::AstNode *node, const util::StringView &name) -{ - sa_.Emit(node, name); + // modify ic later + sa_.Emit(node, 0, name); strings_.insert(name); } -VReg PandaGen::LexEnv() const -{ - return envScope_->LexEnv(); -} - void PandaGen::LoadAccFromLexEnv(const ir::AstNode *node, const binder::ScopeFindResult &result) { VirtualLoadVar::Expand(this, node, result); @@ -558,22 +609,22 @@ void PandaGen::LoadAccumulatorString(const ir::AstNode *node, const util::String void PandaGen::LoadAccumulatorFloat(const ir::AstNode *node, double num) { - sa_.Emit(node, num); + sa_.Emit(node, num); } void PandaGen::LoadAccumulatorInt(const ir::AstNode *node, int32_t num) { - sa_.Emit(node, num); + sa_.Emit(node, num); } void PandaGen::LoadAccumulatorInt(const ir::AstNode *node, size_t num) { - sa_.Emit(node, static_cast(num)); + sa_.Emit(node, static_cast(num)); } void PandaGen::LoadAccumulatorBigInt(const ir::AstNode *node, const util::StringView &num) { - sa_.Emit(node, num); + sa_.Emit(node, num); strings_.insert(num); } @@ -587,39 +638,39 @@ void PandaGen::LoadConst(const ir::AstNode *node, Constant id) { switch (id) { case Constant::JS_HOLE: { - sa_.Emit(node); + sa_.Emit(node); break; } case Constant::JS_NAN: { - sa_.Emit(node); + sa_.Emit(node); break; } case Constant::JS_INFINITY: { - sa_.Emit(node); + sa_.Emit(node); break; } case Constant::JS_GLOBAL: { - sa_.Emit(node); + sa_.Emit(node); break; } case Constant::JS_UNDEFINED: { - sa_.Emit(node); + sa_.Emit(node); break; } case Constant::JS_SYMBOL: { - sa_.Emit(node); + sa_.Emit(node); break; } case Constant::JS_NULL: { - sa_.Emit(node); + sa_.Emit(node); break; } case Constant::JS_TRUE: { - sa_.Emit(node); + sa_.Emit(node); break; } case Constant::JS_FALSE: { - sa_.Emit(node); + sa_.Emit(node); break; } default: { @@ -630,7 +681,7 @@ void PandaGen::LoadConst(const ir::AstNode *node, Constant id) void PandaGen::MoveVreg(const ir::AstNode *node, VReg vd, VReg vs) { - ra_.Emit(node, vd, vs); + ra_.Emit(node, vd, vs); } void PandaGen::SetLabel([[maybe_unused]] const ir::AstNode *node, Label *label) @@ -713,35 +764,35 @@ void PandaGen::Condition(const ir::AstNode *node, lexer::TokenType op, VReg lhs, { switch (op) { case lexer::TokenType::PUNCTUATOR_EQUAL: { - ra_.Emit(node, lhs); + Equal(node, lhs); break; } case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: { - ra_.Emit(node, lhs); + NotEqual(node, lhs); break; } case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL: { - ra_.Emit(node, lhs); + StrictEqual(node, lhs); break; } case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL: { - ra_.Emit(node, lhs); + StrictNotEqual(node, lhs); break; } case lexer::TokenType::PUNCTUATOR_LESS_THAN: { - ra_.Emit(node, lhs); + LessThan(node, lhs); break; } case lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL: { - ra_.Emit(node, lhs); + LessEqual(node, lhs); break; } case lexer::TokenType::PUNCTUATOR_GREATER_THAN: { - ra_.Emit(node, lhs); + GreaterThan(node, lhs); break; } case lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL: { - ra_.Emit(node, lhs); + GreaterEqual(node, lhs); break; } default: { @@ -756,15 +807,17 @@ void PandaGen::Unary(const ir::AstNode *node, lexer::TokenType op, VReg operand) { switch (op) { case lexer::TokenType::PUNCTUATOR_PLUS: { - ra_.Emit(node, operand); + ToNumber(node, operand); break; } case lexer::TokenType::PUNCTUATOR_MINUS: { - ra_.Emit(node, operand); + LoadAccumulator(node, operand); + sa_.Emit(node, 0); break; } case lexer::TokenType::PUNCTUATOR_TILDE: { - ra_.Emit(node, operand); + LoadAccumulator(node, operand); + sa_.Emit(node, 0); break; } case lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK: { @@ -772,11 +825,13 @@ void PandaGen::Unary(const ir::AstNode *node, lexer::TokenType op, VReg operand) break; } case lexer::TokenType::PUNCTUATOR_PLUS_PLUS: { - ra_.Emit(node, operand); + LoadAccumulator(node, operand); + sa_.Emit(node, 0); break; } case lexer::TokenType::PUNCTUATOR_MINUS_MINUS: { - ra_.Emit(node, operand); + LoadAccumulator(node, operand); + sa_.Emit(node, 0); break; } case lexer::TokenType::KEYW_VOID: @@ -792,105 +847,106 @@ void PandaGen::Unary(const ir::AstNode *node, lexer::TokenType op, VReg operand) void PandaGen::Binary(const ir::AstNode *node, lexer::TokenType op, VReg lhs) { + // modify ic later switch (op) { case lexer::TokenType::PUNCTUATOR_EQUAL: { - ra_.Emit(node, lhs); + Equal(node, lhs); break; } case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: { - ra_.Emit(node, lhs); + NotEqual(node, lhs); break; } case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL: { - ra_.Emit(node, lhs); + StrictEqual(node, lhs); break; } case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL: { - ra_.Emit(node, lhs); + StrictNotEqual(node, lhs); break; } case lexer::TokenType::PUNCTUATOR_LESS_THAN: { - ra_.Emit(node, lhs); + LessThan(node, lhs); break; } case lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL: { - ra_.Emit(node, lhs); + LessEqual(node, lhs); break; } case lexer::TokenType::PUNCTUATOR_GREATER_THAN: { - ra_.Emit(node, lhs); + GreaterThan(node, lhs); break; } case lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL: { - ra_.Emit(node, lhs); + GreaterEqual(node, lhs); break; } case lexer::TokenType::PUNCTUATOR_PLUS: case lexer::TokenType::PUNCTUATOR_PLUS_EQUAL: { - ra_.Emit(node, lhs); + ra_.Emit(node, 0, lhs); break; } case lexer::TokenType::PUNCTUATOR_MINUS: case lexer::TokenType::PUNCTUATOR_MINUS_EQUAL: { - ra_.Emit(node, lhs); + ra_.Emit(node, 0, lhs); break; } case lexer::TokenType::PUNCTUATOR_MULTIPLY: case lexer::TokenType::PUNCTUATOR_MULTIPLY_EQUAL: { - ra_.Emit(node, lhs); + ra_.Emit(node, 0, lhs); break; } case lexer::TokenType::PUNCTUATOR_DIVIDE: case lexer::TokenType::PUNCTUATOR_DIVIDE_EQUAL: { - ra_.Emit(node, lhs); + ra_.Emit(node, 0, lhs); break; } case lexer::TokenType::PUNCTUATOR_MOD: case lexer::TokenType::PUNCTUATOR_MOD_EQUAL: { - ra_.Emit(node, lhs); + ra_.Emit(node, 0, lhs); break; } case lexer::TokenType::PUNCTUATOR_EXPONENTIATION_EQUAL: case lexer::TokenType::PUNCTUATOR_EXPONENTIATION: { - ra_.Emit(node, lhs); + ra_.Emit(node, 0, lhs); break; } case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT: case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT_EQUAL: { - ra_.Emit(node, lhs); + ra_.Emit(node, 0, lhs); break; } case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT: case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT_EQUAL: { - ra_.Emit(node, lhs); + ra_.Emit(node, 0, lhs); break; } case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT: case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT_EQUAL: { - ra_.Emit(node, lhs); + ra_.Emit(node, 0, lhs); break; } case lexer::TokenType::PUNCTUATOR_BITWISE_AND: case lexer::TokenType::PUNCTUATOR_BITWISE_AND_EQUAL: { - ra_.Emit(node, lhs); + ra_.Emit(node, 0, lhs); break; } case lexer::TokenType::PUNCTUATOR_BITWISE_OR: case lexer::TokenType::PUNCTUATOR_BITWISE_OR_EQUAL: { - ra_.Emit(node, lhs); + ra_.Emit(node, 0, lhs); break; } case lexer::TokenType::PUNCTUATOR_BITWISE_XOR: case lexer::TokenType::PUNCTUATOR_BITWISE_XOR_EQUAL: { - ra_.Emit(node, lhs); + ra_.Emit(node, 0, lhs); break; } case lexer::TokenType::KEYW_IN: { - ra_.Emit(node, lhs); + ra_.Emit(node, 0, lhs); break; } case lexer::TokenType::KEYW_INSTANCEOF: { - ra_.Emit(node, lhs); + ra_.Emit(node, 0, lhs); break; } case lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING: @@ -904,13 +960,66 @@ void PandaGen::Binary(const ir::AstNode *node, lexer::TokenType op, VReg lhs) } } +void PandaGen::Equal(const ir::AstNode *node, VReg lhs) +{ + // modify ic later + ra_.Emit(node, 0, lhs); +} + +void PandaGen::NotEqual(const ir::AstNode *node, VReg lhs) +{ + // modify ic later + ra_.Emit(node, 0, lhs); +} + +void PandaGen::StrictEqual(const ir::AstNode *node, VReg lhs) +{ + // modify ic later + ra_.Emit(node, 0, lhs); +} + +void PandaGen::StrictNotEqual(const ir::AstNode *node, VReg lhs) +{ + // modify ic later + ra_.Emit(node, 0, lhs); +} + +void PandaGen::LessThan(const ir::AstNode *node, VReg lhs) +{ + // modify ic later + ra_.Emit(node, 0, lhs); +} + +void PandaGen::LessEqual(const ir::AstNode *node, VReg lhs) +{ + // modify ic later + ra_.Emit(node, 0, lhs); +} + +void PandaGen::GreaterThan(const ir::AstNode *node, VReg lhs) +{ + // modify ic later + ra_.Emit(node, 0, lhs); +} + +void PandaGen::GreaterEqual(const ir::AstNode *node, VReg lhs) +{ + // modify ic later + ra_.Emit(node, 0, lhs); +} + +void PandaGen::IsTrue(const ir::AstNode *node) +{ + sa_.Emit(node); +} + void PandaGen::BranchIfUndefined(const ir::AstNode *node, Label *target) { RegScope rs(this); VReg tmp = AllocReg(); StoreAccumulator(node, tmp); - sa_.Emit(node); - ra_.Emit(node, tmp); + LoadConst(node, Constant::JS_UNDEFINED); + Equal(node, tmp); sa_.Emit(node, target); } @@ -919,8 +1028,8 @@ void PandaGen::BranchIfNotUndefined(const ir::AstNode *node, Label *target) RegScope rs(this); VReg tmp = AllocReg(); StoreAccumulator(node, tmp); - sa_.Emit(node); - ra_.Emit(node, tmp); + LoadConst(node, Constant::JS_UNDEFINED); + Equal(node, tmp); sa_.Emit(node, target); } @@ -930,31 +1039,31 @@ void PandaGen::BranchIfStrictNotUndefined(const ir::AstNode *node, class Label * VReg tmp = AllocReg(); StoreAccumulator(node, tmp); LoadConst(node, Constant::JS_UNDEFINED); - ra_.Emit(node, tmp); + StrictEqual(node, tmp); sa_.Emit(node, target); } void PandaGen::BranchIfTrue(const ir::AstNode *node, Label *target) { - sa_.Emit(node); + IsTrue(node); sa_.Emit(node, target); } void PandaGen::BranchIfNotTrue(const ir::AstNode *node, Label *target) { - sa_.Emit(node); + IsTrue(node); BranchIfFalse(node, target); } void PandaGen::BranchIfFalse(const ir::AstNode *node, Label *target) { - sa_.Emit(node); + sa_.Emit(node); sa_.Emit(node, target); } void PandaGen::EmitThrow(const ir::AstNode *node) { - sa_.Emit(node); + sa_.Emit(node); } void PandaGen::EmitRethrow(const ir::AstNode *node) @@ -970,24 +1079,24 @@ void PandaGen::EmitRethrow(const ir::AstNode *node) StoreConst(node, hole, Constant::JS_HOLE); LoadAccumulator(node, exception); - ra_.Emit(node, hole); + NotEqual(node, hole); sa_.Emit(node, skipThrow); SetLabel(node, doThrow); LoadAccumulator(node, exception); - sa_.Emit(node); + EmitThrow(node); SetLabel(node, skipThrow); } void PandaGen::EmitReturn(const ir::AstNode *node) { - sa_.Emit(node); + sa_.Emit(node); } void PandaGen::EmitReturnUndefined(const ir::AstNode *node) { - sa_.Emit(node); + sa_.Emit(node); } void PandaGen::ImplicitReturn(const ir::AstNode *node) @@ -1033,38 +1142,80 @@ void PandaGen::EmitAwait(const ir::AstNode *node) void PandaGen::CallThis(const ir::AstNode *node, VReg startReg, size_t argCount) { - rra_.Emit(node, startReg, argCount + 2, static_cast(argCount), startReg); + // modify ic later + LoadAccumulator(node, startReg); // callee is load to acc + VReg thisReg = startReg + 1; + switch (argCount) { + case 1: { // no args + ra_.Emit(node, 0, thisReg); + break; + } + case 2: { // 1 arg + VReg arg0 = thisReg + 1; + ra_.Emit(node, 0, thisReg, arg0); + break; + } + case 3: { // 2 args + VReg arg0 = thisReg + 1; + VReg arg1 = arg0 + 1; + ra_.Emit(node, 0, thisReg , arg0, arg1); + break; + } + case 4: { // 3 args + VReg arg0 = thisReg + 1; + VReg arg1 = arg0 + 1; + VReg arg2 = arg1 + 1; + ra_.Emit(node, 0, thisReg , arg0, arg1, arg2); + break; + } + default: { + int64_t actualArgs = argCount - 1; + if (actualArgs <= util::Helpers::MAX_INT8) { + rra_.Emit(node, thisReg, argCount + 1, 0, actualArgs, thisReg); + break; + } + + rra_.Emit(node, thisReg, argCount + 1, actualArgs, thisReg); + break; + } + } } void PandaGen::Call(const ir::AstNode *node, VReg startReg, size_t argCount) { - VReg callee = startReg; - + LoadAccumulator(node, startReg); // callee is load to acc + // modify ic later switch (argCount) { case 0: { // 0 args - ra_.Emit(node, callee); + sa_.Emit(node, 0); break; } case 1: { // 1 arg - VReg arg0 = callee + 1; - ra_.Emit(node, callee, arg0); + VReg arg0 = startReg + 1; + ra_.Emit(node, 0, arg0); break; } case 2: { // 2 args - VReg arg0 = callee + 1; + VReg arg0 = startReg + 1; VReg arg1 = arg0 + 1; - ra_.Emit(node, callee, arg0, arg1); + ra_.Emit(node, 0, arg0, arg1); break; } case 3: { // 3 args - VReg arg0 = callee + 1; + VReg arg0 = startReg + 1; VReg arg1 = arg0 + 1; VReg arg2 = arg1 + 1; - ra_.Emit(node, callee, arg0, arg1, arg2); + ra_.Emit(node, 0, arg0, arg1, arg2); break; } default: { - rra_.Emit(node, startReg, argCount + 1, static_cast(argCount), startReg); + VReg arg0 = startReg + 1; + if (argCount <= util::Helpers::MAX_INT8) { + rra_.Emit(node, arg0, argCount, 0, argCount, arg0); + break; + } + + rra_.Emit(node, arg0, argCount, argCount, arg0); break; } } @@ -1072,22 +1223,41 @@ void PandaGen::Call(const ir::AstNode *node, VReg startReg, size_t argCount) void PandaGen::SuperCall(const ir::AstNode *node, VReg startReg, size_t argCount) { - rra_.Emit(node, startReg, argCount, static_cast(argCount), startReg); + // modify ic later + if (RootNode()->IsArrowFunctionExpression()) { + GetFunctionObject(node); // load funcobj to acc for super call in arrow function + if (argCount <= util::Helpers::MAX_INT8) { + rra_.Emit(node, startReg, argCount, 0, static_cast(argCount), startReg); + } else { + rra_.Emit(node, startReg, argCount, static_cast(argCount), startReg); + } + return; + } + + if (argCount <= util::Helpers::MAX_INT8) { + // no need to load funcobj to acc for super call in other kinds of functions + rra_.Emit(node, startReg, argCount, 0, static_cast(argCount), startReg); + return; + } + + rra_.Emit(node, startReg, argCount, static_cast(argCount), startReg); } void PandaGen::SuperCallSpread(const ir::AstNode *node, VReg vs) { - ra_.Emit(node, vs); + // modify ic later + ra_.Emit(node, 0, vs); } void PandaGen::NewObject(const ir::AstNode *node, VReg startReg, size_t argCount) { - rra_.Emit(node, startReg, argCount, static_cast(argCount), startReg); -} + if (argCount <= util::Helpers::MAX_INT8) { + // modify ic later + rra_.Emit(node, startReg, argCount, 0, static_cast(argCount), startReg); + return; + } -void PandaGen::LoadHomeObject(const ir::AstNode *node) -{ - sa_.Emit(node); + rra_.Emit(node, startReg, argCount, static_cast(argCount), startReg); } void PandaGen::DefineFunction(const ir::AstNode *node, const ir::ScriptFunction *realNode, const util::StringView &name) @@ -1096,22 +1266,12 @@ void PandaGen::DefineFunction(const ir::AstNode *node, const ir::ScriptFunction return; } + // modify ic later auto formalParamCnt = realNode->FormalParamsLength(); if (realNode->IsMethod()) { - ra_.Emit(node, name, static_cast(formalParamCnt), LexEnv()); - } else if (realNode->IsAsync()) { - if (realNode->IsGenerator()) { - // TODO(): async generator - } else { - ra_.Emit(node, name, static_cast(formalParamCnt), LexEnv()); - } - } else if (realNode->IsGenerator()) { - ra_.Emit(node, name, static_cast(formalParamCnt), LexEnv()); - } else if (realNode->IsArrow()) { - LoadHomeObject(node); - ra_.Emit(node, name, static_cast(formalParamCnt), LexEnv()); - } else { - ra_.Emit(node, name, static_cast(formalParamCnt), LexEnv()); + ra_.Emit(node, 0, name, static_cast(formalParamCnt)); + } else { + ra_.Emit(node, 0, name, static_cast(formalParamCnt)); } strings_.insert(name); @@ -1119,22 +1279,26 @@ void PandaGen::DefineFunction(const ir::AstNode *node, const ir::ScriptFunction void PandaGen::TypeOf(const ir::AstNode *node) { - sa_.Emit(node); + // modify ic later + sa_.Emit(node, 0); } void PandaGen::CallSpread(const ir::AstNode *node, VReg func, VReg thisReg, VReg args) { - ra_.Emit(node, func, thisReg, args); + // modify ic later + LoadAccumulator(node, func); // callee is load to acc + ra_.Emit(node, 0, thisReg, args); } -void PandaGen::NewObjSpread(const ir::AstNode *node, VReg obj, VReg target) +void PandaGen::NewObjSpread(const ir::AstNode *node, VReg obj) { - ra_.Emit(node, obj, target); + // modify ic later + ra_.Emit(node, 0, obj); } void PandaGen::GetUnmappedArgs(const ir::AstNode *node) { - sa_.Emit(node); + sa_.Emit(node); } void PandaGen::Negate(const ir::AstNode *node) @@ -1151,35 +1315,39 @@ void PandaGen::Negate(const ir::AstNode *node) void PandaGen::ToNumber(const ir::AstNode *node, VReg arg) { - ra_.Emit(node, arg); + // modify ic later + LoadAccumulator(node, arg); + sa_.Emit(node, 0); } void PandaGen::ToNumeric(const ir::AstNode *node, VReg arg) { - ra_.Emit(node, arg); + // modify ic later + LoadAccumulator(node, arg); + sa_.Emit(node, 0); } void PandaGen::CreateGeneratorObj(const ir::AstNode *node, VReg funcObj) { - ra_.Emit(node, funcObj); + ra_.Emit(node, funcObj); } void PandaGen::CreateAsyncGeneratorObj(const ir::AstNode *node, VReg funcObj) { /* * TODO: async generator - * ra_.Emit(node, funcObj); + * ra_.Emit(node, funcObj); */ } void PandaGen::CreateIterResultObject(const ir::AstNode *node, VReg value, VReg done) { - ra_.Emit(node, value, done); + ra_.Emit(node, value, done); } -void PandaGen::SuspendGenerator(const ir::AstNode *node, VReg genObj, VReg iterResult) +void PandaGen::SuspendGenerator(const ir::AstNode *node, VReg genObj) { - ra_.Emit(node, genObj, iterResult); + ra_.Emit(node, genObj); // iterResult is in acc } void PandaGen::SuspendAsyncGenerator(const ir::AstNode *node, VReg asyncGenObj) @@ -1208,39 +1376,41 @@ void PandaGen::GeneratorComplete(const ir::AstNode *node, VReg genObj) void PandaGen::ResumeGenerator(const ir::AstNode *node, VReg genObj) { - ra_.Emit(node, genObj); + LoadAccumulator(node, genObj); + sa_.Emit(node); } void PandaGen::GetResumeMode(const ir::AstNode *node, VReg genObj) { - ra_.Emit(node, genObj); + LoadAccumulator(node, genObj); + sa_.Emit(node); } void PandaGen::AsyncFunctionEnter(const ir::AstNode *node) { - sa_.Emit(node); + sa_.Emit(node); } -void PandaGen::AsyncFunctionAwait(const ir::AstNode *node, VReg asyncFuncObj, VReg retVal) +void PandaGen::AsyncFunctionAwait(const ir::AstNode *node, VReg asyncFuncObj) { - ra_.Emit(node, asyncFuncObj, retVal); + ra_.Emit(node, asyncFuncObj); // receivedValue is in acc } -void PandaGen::AsyncFunctionResolve(const ir::AstNode *node, VReg asyncFuncObj, VReg value, VReg canSuspend) +void PandaGen::AsyncFunctionResolve(const ir::AstNode *node, VReg asyncFuncObj) { - ra_.Emit(node, asyncFuncObj, canSuspend, value); + ra_.Emit(node, asyncFuncObj); // use retVal in acc } -void PandaGen::AsyncFunctionReject(const ir::AstNode *node, VReg asyncFuncObj, VReg value, VReg canSuspend) +void PandaGen::AsyncFunctionReject(const ir::AstNode *node, VReg asyncFuncObj) { - ra_.Emit(node, asyncFuncObj, canSuspend, value); + ra_.Emit(node, asyncFuncObj); // exception is in acc } void PandaGen::AsyncGeneratorResolve(const ir::AstNode *node, VReg asyncGenObj) { /* * TODO: async generator resolve - * ra_.Emit(node, asyncGenObj); + * ra_.Emit(node, asyncGenObj); */ } @@ -1254,68 +1424,69 @@ void PandaGen::AsyncGeneratorReject(const ir::AstNode *node, VReg asyncGenObj) void PandaGen::GetTemplateObject(const ir::AstNode *node, VReg value) { - ra_.Emit(node, value); + // modify ic later + LoadAccumulator(node, value); + sa_.Emit(node, 0); } void PandaGen::CopyRestArgs(const ir::AstNode *node, uint32_t index) { - sa_.Emit(node, index); + index <= util::Helpers::MAX_INT8 ? sa_.Emit(node, index) : sa_.Emit(node, index); } void PandaGen::GetPropIterator(const ir::AstNode *node) { - sa_.Emit(node); + sa_.Emit(node); } void PandaGen::GetNextPropName(const ir::AstNode *node, VReg iter) { - ra_.Emit(node, iter); + ra_.Emit(node, iter); } void PandaGen::CreateEmptyObject(const ir::AstNode *node) { - sa_.Emit(node); + sa_.Emit(node); } void PandaGen::CreateObjectWithBuffer(const ir::AstNode *node, uint32_t idx) { ASSERT(util::Helpers::IsInteger(idx)); - sa_.Emit(node, idx); -} - -void PandaGen::CreateObjectHavingMethod(const ir::AstNode *node, uint32_t idx) -{ - ASSERT(util::Helpers::IsInteger(idx)); - LoadAccumulator(node, LexEnv()); - sa_.Emit(node, idx); + std::string idxStr = std::string(context_->RecordName()) + std::to_string(idx); + util::UString litId(idxStr, allocator_); + sa_.Emit(node, 0, litId.View()); } void PandaGen::SetObjectWithProto(const ir::AstNode *node, VReg proto, VReg obj) { - ra_.Emit(node, proto, obj); + LoadAccumulator(node, obj); + ra_.Emit(node, 0, proto); } -void PandaGen::CopyDataProperties(const ir::AstNode *node, VReg dst, VReg src) +void PandaGen::CopyDataProperties(const ir::AstNode *node, VReg dst) { - ra_.Emit(node, dst, src); + ra_.Emit(node, dst); // use acc as srcObj } void PandaGen::DefineGetterSetterByValue(const ir::AstNode *node, VReg obj, VReg name, VReg getter, VReg setter, bool setName) { LoadConst(node, setName ? Constant::JS_TRUE : Constant::JS_FALSE); - ra_.Emit(node, obj, name, getter, setter); + ra_.Emit(node, obj, name, getter, setter); } void PandaGen::CreateEmptyArray(const ir::AstNode *node) { - sa_.Emit(node); + // modify ic later + sa_.Emit(node, 0); } void PandaGen::CreateArrayWithBuffer(const ir::AstNode *node, uint32_t idx) { ASSERT(util::Helpers::IsInteger(idx)); - sa_.Emit(node, idx); + std::string idxStr = std::string(context_->RecordName()) + std::to_string(idx); + util::UString litId(idxStr, allocator_); + sa_.Emit(node, 0, litId.View()); } void PandaGen::CreateArray(const ir::AstNode *node, const ArenaVector &elements, VReg obj) @@ -1416,22 +1587,23 @@ void PandaGen::CreateArray(const ir::AstNode *node, const ArenaVector(node, array, index); + ra_.Emit(node, array, index); } void PandaGen::ThrowIfNotObject(const ir::AstNode *node, VReg obj) { - ra_.Emit(node, obj); + ra_.Emit(node, obj); } void PandaGen::ThrowThrowNotExist(const ir::AstNode *node) { - sa_.Emit(node); + sa_.Emit(node); } void PandaGen::GetIterator(const ir::AstNode *node) { - sa_.Emit(node); + // modify ic later + sa_.Emit(node, 0); } void PandaGen::GetAsyncIterator(const ir::AstNode *node) @@ -1451,71 +1623,93 @@ void PandaGen::CreateObjectWithExcludedKeys(const ir::AstNode *node, VReg obj, V } size_t argRegCnt = (argCount == 0 ? argCount : argCount - 1); - rra_.Emit(node, argStart, argCount, static_cast(argRegCnt), obj, - argStart); + + if (argRegCnt <= util::Helpers::MAX_INT8) { + rra_.Emit(node, argStart, argCount, static_cast(argRegCnt), + obj, argStart); + return; + } + + rra_.Emit(node, argStart, argCount, static_cast(argRegCnt), + obj, argStart); } void PandaGen::ThrowObjectNonCoercible(const ir::AstNode *node) { - sa_.Emit(node); + sa_.Emit(node); } void PandaGen::CloseIterator(const ir::AstNode *node, VReg iter) { - ra_.Emit(node, iter); + // modify ic later + ra_.Emit(node, 0, iter); } -void PandaGen::DefineClassWithBuffer(const ir::AstNode *node, const util::StringView &ctorId, int32_t litIdx, - VReg lexenv, VReg base) +void PandaGen::DefineClassWithBuffer(const ir::AstNode *node, const util::StringView &ctorId, int32_t litIdx, VReg base) { + // modify ic later auto formalParamCnt = node->AsClassDefinition()->Ctor()->Function()->FormalParamsLength(); - ra_.Emit(node, ctorId, litIdx, static_cast(formalParamCnt), lexenv, base); + std::string idxStr = std::string(context_->RecordName()) + std::to_string(litIdx); + util::UString litId(idxStr, allocator_); + ra_.Emit(node, 0, ctorId, litId.View(), static_cast(formalParamCnt), base); strings_.insert(ctorId); } -void PandaGen::LoadModuleVariable(const ir::AstNode *node, const util::StringView &name, bool isLocalExport) +void PandaGen::LoadLocalModuleVariable(const ir::AstNode *node, const binder::ModuleVariable *variable) { - ra_.Emit(node, name, isLocalExport ? static_cast(1) : static_cast(0)); - strings_.insert(name); + auto index = variable->Index(); + index <= util::Helpers::MAX_INT8 ? sa_.Emit(node, index) : + sa_.Emit(node, index); } -void PandaGen::StoreModuleVariable(const ir::AstNode *node, const util::StringView &name) +void PandaGen::LoadExternalModuleVariable(const ir::AstNode *node, const binder::ModuleVariable *variable) { - sa_.Emit(node, name); - strings_.insert(name); + auto index = variable->Index(); + index <= util::Helpers::MAX_INT8 ? sa_.Emit(node, index) : + sa_.Emit(node, index); } -void PandaGen::GetModuleNamespace(const ir::AstNode *node, const util::StringView &name) +void PandaGen::StoreModuleVariable(const ir::AstNode *node, const binder::ModuleVariable *variable) { - sa_.Emit(node, name); - strings_.insert(name); + auto index = variable->Index(); + index <= util::Helpers::MAX_INT8 ? sa_.Emit(node, index) : + sa_.Emit(node, index); } -void PandaGen::DynamicImportCall(const ir::AstNode *node, VReg moduleSpecifier) +void PandaGen::GetModuleNamespace(const ir::AstNode *node, uint32_t index) { - ra_.Emit(node, moduleSpecifier); + index <= util::Helpers::MAX_INT8 ? sa_.Emit(node, index) : + sa_.Emit(node, index); +} + +void PandaGen::DynamicImportCall(const ir::AstNode *node) +{ + ra_.Emit(node); } void PandaGen::StSuperByName(const ir::AstNode *node, VReg obj, const util::StringView &key) { - ra_.Emit(node, key, obj); + ra_.Emit(node, 0, key, obj); strings_.insert(key); } void PandaGen::LdSuperByName(const ir::AstNode *node, VReg obj, const util::StringView &key) { - ra_.Emit(node, key, obj); + // modify ic later + LoadAccumulator(node, obj); // object is load to acc + sa_.Emit(node, 0, key); strings_.insert(key); } void PandaGen::StSuperByValue(const ir::AstNode *node, VReg obj, VReg prop) { - ra_.Emit(node, obj, prop); + ra_.Emit(node, 0, obj, prop); } -void PandaGen::LdSuperByValue(const ir::AstNode *node, VReg obj, VReg prop) +void PandaGen::LdSuperByValue(const ir::AstNode *node, VReg obj) { - ra_.Emit(node, obj, prop); + // modify ic later + ra_.Emit(node, 0, obj); // prop is in acc } void PandaGen::StoreSuperProperty(const ir::AstNode *node, VReg obj, const Operand &prop) @@ -1550,63 +1744,80 @@ void PandaGen::LoadSuperProperty(const ir::AstNode *node, VReg obj, const Operan } if (std::holds_alternative(prop)) { - LdSuperByValue(node, obj, std::get(prop)); + LoadAccumulator(node, std::get(prop)); + LdSuperByValue(node, obj); return; } ASSERT(std::holds_alternative(prop)); - RegScope rs(this); LoadAccumulatorInt(node, static_cast(std::get(prop))); - VReg property = AllocReg(); - StoreAccumulator(node, property); - LdSuperByValue(node, obj, property); + LdSuperByValue(node, obj); } void PandaGen::LoadLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot) { - sa_.Emit(node, level, slot); + if ((level > util::Helpers::MAX_INT8) || (slot > util::Helpers::MAX_INT8)) { + sa_.Emit(node, level, slot); + return; + } + + sa_.Emit(node, level, slot); } void PandaGen::LoadLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot, const util::StringView &name) { if (context_->HotfixHelper() && context_->HotfixHelper()->IsPatchVar(slot)) { uint32_t patchSlot = context_->HotfixHelper()->GetPatchLexicalIdx(std::string(name)); - sa_.Emit(node, patchSlot); + sa_.Emit(node, patchSlot); + return; + } + + if ((level > util::Helpers::MAX_INT8) || (slot > util::Helpers::MAX_INT8)) { + sa_.Emit(node, level, slot); return; } - sa_.Emit(node, level, slot); + + sa_.Emit(node, level, slot); } void PandaGen::StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot) { - RegScope rs(this); - VReg value = AllocReg(); - StoreAccumulator(node, value); - ra_.Emit(node, level, slot, value); + if ((level > util::Helpers::MAX_INT8) || (slot > util::Helpers::MAX_INT8)) { + ra_.Emit(node, level, slot); + return; + } + + ra_.Emit(node, level, slot); } void PandaGen::StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot, VReg value) { - ra_.Emit(node, level, slot, value); + LoadAccumulator(node, value); + if ((level > util::Helpers::MAX_INT8) || (slot > util::Helpers::MAX_INT8)) { + ra_.Emit(node, level, slot); + return; + } + + ra_.Emit(node, level, slot); } void PandaGen::StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot, const util::StringView &name) { if (context_->HotfixHelper() && context_->HotfixHelper()->IsPatchVar(slot)) { uint32_t patchSlot = context_->HotfixHelper()->GetPatchLexicalIdx(std::string(name)); - sa_.Emit(node, patchSlot); + sa_.Emit(node, patchSlot); return; } RegScope rs(this); VReg value = AllocReg(); StoreAccumulator(node, value); - ra_.Emit(node, level, slot, value); + StoreLexicalVar(node, level, slot, value); } void PandaGen::ThrowIfSuperNotCorrectCall(const ir::AstNode *node, int64_t num) { - sa_.Emit(node, num); + sa_.Emit(node, num); } void PandaGen::ThrowUndefinedIfHole(const ir::AstNode *node, const util::StringView &name) @@ -1617,7 +1828,7 @@ void PandaGen::ThrowUndefinedIfHole(const ir::AstNode *node, const util::StringV LoadAccumulatorString(node, name); VReg nameReg = AllocReg(); StoreAccumulator(node, nameReg); - ra_.Emit(node, holeReg, nameReg); + ra_.Emit(node, holeReg, nameReg); LoadAccumulator(node, holeReg); strings_.insert(name); } @@ -1628,13 +1839,13 @@ void PandaGen::ThrowConstAssignment(const ir::AstNode *node, const util::StringV LoadAccumulatorString(node, name); VReg nameReg = AllocReg(); StoreAccumulator(node, nameReg); - ra_.Emit(node, nameReg); + ra_.Emit(node, nameReg); strings_.insert(name); } void PandaGen::PopLexEnv(const ir::AstNode *node) { - sa_.Emit(node); + sa_.Emit(node); } void PandaGen::CopyLexEnv(const ir::AstNode *node) @@ -1658,17 +1869,15 @@ void PandaGen::NewLexicalEnv(const ir::AstNode *node, uint32_t num, binder::Vari void PandaGen::NewLexEnv(const ir::AstNode *node, uint32_t num) { - sa_.Emit(node, num); + num <= util::Helpers::MAX_INT8 ? sa_.Emit(node, num) : sa_.Emit(node, num); } void PandaGen::NewLexEnvWithScopeInfo(const ir::AstNode *node, uint32_t num, int32_t scopeInfoIdx) { - sa_.Emit(node, num, scopeInfoIdx); -} - -void PandaGen::LdLexEnv(const ir::AstNode *node) -{ - sa_.Emit(node); + std::string idxStr = std::string(context_->RecordName()) + std::to_string(scopeInfoIdx); + util::UString litId(idxStr, allocator_); + num <= util::Helpers::MAX_INT8 ? sa_.Emit(node, num, litId.View()) : + sa_.Emit(node, num, litId.View()); } uint32_t PandaGen::TryDepth() const @@ -1786,21 +1995,17 @@ VReg PandaGen::LoadPropertyKey(const ir::Expression *prop, bool isComputed) return propReg; } -void PandaGen::StLetToGlobalRecord(const ir::AstNode *node, const util::StringView &name) +void PandaGen::StLetOrClassToGlobalRecord(const ir::AstNode *node, const util::StringView &name) { - sa_.Emit(node, name); + // modify ic later + sa_.Emit(node, 0, name); strings_.insert(name); } void PandaGen::StConstToGlobalRecord(const ir::AstNode *node, const util::StringView &name) { - sa_.Emit(node, name); - strings_.insert(name); -} - -void PandaGen::StClassToGlobalRecord(const ir::AstNode *node, const util::StringView &name) -{ - sa_.Emit(node, name); + // modify ic later + sa_.Emit(node, 0, name); strings_.insert(name); } diff --git a/es2panda/compiler/core/pandagen.h b/es2panda/compiler/core/pandagen.h index 64fe2d6132bd853e72f05f55102588d262f135a5..bd67715b6ac220e6fa33b3d54de22c3fd8f89665 100644 --- a/es2panda/compiler/core/pandagen.h +++ b/es2panda/compiler/core/pandagen.h @@ -28,6 +28,7 @@ namespace panda::es2panda::binder { class FunctionScope; +class ModuleVaribale; class ScopeFindResult; class Scope; } // namespace panda::es2panda::binder @@ -60,6 +61,16 @@ enum class Constant { JS_GLOBAL, }; +enum class FunctionKind : uint8_t { + NONE = 0x0, // represent method for now + FUNCTION = 0x1, + NC_FUNCTION = 0x2, + GENERATOR_FUNCTION = 0x3, + ASYNC_FUNCTION = 0x4, + ASYNC_GENERATOR_FUNCTION = 0x5, + ASYNC_NCFUNCTION = 0x6 +}; + class DebugInfo { public: explicit DebugInfo(ArenaAllocator *allocator) : variableDebugInfo(allocator->Adapter()) {}; @@ -186,6 +197,13 @@ public: rra_.SetSourceLocationFlag(flag); } + FunctionKind GetFunctionKind() const + { + return funcKind_; + } + + void SetFunctionKind(); + bool IsDebug() const; bool isDebuggerEvaluateExpressionMode() const; std::string SourceFile() const; @@ -198,8 +216,6 @@ public: Label *AllocLabel(); - VReg LexEnv() const; - bool FunctionHasFinalizer() const; void FunctionInit(CatchTable* catchTable); void FunctionEnter(); @@ -209,7 +225,7 @@ public: int32_t AddLiteralBuffer(LiteralBuffer *buf); int32_t AddLexicalVarNamesForDebugInfo(ArenaMap> &lexicalMap); - void InitializeLexEnv(const ir::AstNode *node, VReg lexEnv); + void InitializeLexEnv(const ir::AstNode *node); void CopyFunctionArguments(const ir::AstNode *node); void GetFunctionObject(const ir::AstNode *node); void GetNewTarget(const ir::AstNode *node); @@ -218,9 +234,8 @@ public: void LoadVar(const ir::Identifier *node, const binder::ScopeFindResult &result); void StoreVar(const ir::AstNode *node, const binder::ScopeFindResult &result, bool isDeclaration); - void StLetToGlobalRecord(const ir::AstNode *node, const util::StringView &name); + void StLetOrClassToGlobalRecord(const ir::AstNode *node, const util::StringView &name); void StConstToGlobalRecord(const ir::AstNode *node, const util::StringView &name); - void StClassToGlobalRecord(const ir::AstNode *node, const util::StringView &name); void StoreAccumulator(const ir::AstNode *node, VReg vreg); void LoadAccFromArgs(const ir::AstNode *node); @@ -234,7 +249,6 @@ public: void LoadAccumulator(const ir::AstNode *node, VReg reg); void LoadGlobalVar(const ir::AstNode *node, const util::StringView &name); void StoreGlobalVar(const ir::AstNode *node, const util::StringView &name); - void StoreGlobalLet(const ir::AstNode *node, const util::StringView &name); void TryLoadGlobalByValue(const ir::AstNode *node, VReg key); void TryStoreGlobalByValue(const ir::AstNode *node, VReg key); @@ -265,6 +279,15 @@ public: void Condition(const ir::AstNode *node, lexer::TokenType op, VReg lhs, class Label *ifFalse); void Unary(const ir::AstNode *node, lexer::TokenType op, VReg operand); void Binary(const ir::AstNode *node, lexer::TokenType op, VReg lhs); + void Equal(const ir::AstNode *node, VReg lhs); + void NotEqual(const ir::AstNode *node, VReg lhs); + void StrictEqual(const ir::AstNode *node, VReg lhs); + void StrictNotEqual(const ir::AstNode *node, VReg lhs); + void LessThan(const ir::AstNode *node, VReg lhs); + void LessEqual(const ir::AstNode *node, VReg lhs); + void GreaterThan(const ir::AstNode *node, VReg lhs); + void GreaterEqual(const ir::AstNode *node, VReg lhs); + void IsTrue(const ir::AstNode *node); void BranchIfUndefined(const ir::AstNode *node, class Label *target); void BranchIfStrictNotUndefined(const ir::AstNode *node, class Label *target); @@ -290,12 +313,11 @@ public: void SuperCall(const ir::AstNode *node, VReg startReg, size_t argCount); void SuperCallSpread(const ir::AstNode *node, VReg vs); - void LoadHomeObject(const ir::AstNode *node); void NewObject(const ir::AstNode *node, VReg startReg, size_t argCount); void DefineFunction(const ir::AstNode *node, const ir::ScriptFunction *realNode, const util::StringView &name); void TypeOf(const ir::AstNode *node); - void NewObjSpread(const ir::AstNode *node, VReg obj, VReg target); + void NewObjSpread(const ir::AstNode *node, VReg obj); void GetUnmappedArgs(const ir::AstNode *node); void Negate(const ir::AstNode *node); @@ -307,15 +329,15 @@ public: void GetResumeMode(const ir::AstNode *node, VReg genObj); void AsyncFunctionEnter(const ir::AstNode *node); - void AsyncFunctionAwait(const ir::AstNode *node, VReg asyncFuncObj, VReg retVal); - void AsyncFunctionResolve(const ir::AstNode *node, VReg asyncFuncObj, VReg value, VReg canSuspend); - void AsyncFunctionReject(const ir::AstNode *node, VReg asyncFuncObj, VReg value, VReg canSuspend); + void AsyncFunctionAwait(const ir::AstNode *node, VReg asyncFuncObj); + void AsyncFunctionResolve(const ir::AstNode *node, VReg asyncFuncObj); + void AsyncFunctionReject(const ir::AstNode *node, VReg asyncFuncObj); void GeneratorYield(const ir::AstNode *node, VReg genObj); void GeneratorComplete(const ir::AstNode *node, VReg genObj); void CreateAsyncGeneratorObj(const ir::AstNode *node, VReg funcObj); void CreateIterResultObject(const ir::AstNode *node, VReg value, VReg done); - void SuspendGenerator(const ir::AstNode *node, VReg genObj, VReg iterResult); + void SuspendGenerator(const ir::AstNode *node, VReg genObj); void SuspendAsyncGenerator(const ir::AstNode *node, VReg asyncGenObj); void AsyncGeneratorResolve(const ir::AstNode *node, VReg asyncGenObj); @@ -328,9 +350,8 @@ public: void GetNextPropName(const ir::AstNode *node, VReg iter); void CreateEmptyObject(const ir::AstNode *node); void CreateObjectWithBuffer(const ir::AstNode *node, uint32_t idx); - void CreateObjectHavingMethod(const ir::AstNode *node, uint32_t idx); void SetObjectWithProto(const ir::AstNode *node, VReg proto, VReg obj); - void CopyDataProperties(const ir::AstNode *node, VReg dst, VReg src); + void CopyDataProperties(const ir::AstNode *node, VReg dst); void DefineGetterSetterByValue(const ir::AstNode *node, VReg obj, VReg name, VReg getter, VReg setter, bool setName); void CreateEmptyArray(const ir::AstNode *node); @@ -346,22 +367,21 @@ public: void CreateObjectWithExcludedKeys(const ir::AstNode *node, VReg obj, VReg argStart, size_t argCount); void ThrowObjectNonCoercible(const ir::AstNode *node); void CloseIterator(const ir::AstNode *node, VReg iter); - void DefineClassWithBuffer(const ir::AstNode *node, const util::StringView &ctorId, int32_t litIdx, VReg lexenv, - VReg base); + void DefineClassWithBuffer(const ir::AstNode *node, const util::StringView &ctorId, int32_t litIdx, VReg base); - void LoadModuleVariable(const ir::AstNode *node, const util::StringView &name, bool isLocalExport); - void StoreModuleVariable(const ir::AstNode *node, const util::StringView &name); - void GetModuleNamespace(const ir::AstNode *node, const util::StringView &name); - void DynamicImportCall(const ir::AstNode *node, VReg moduleSpecifier); + void LoadLocalModuleVariable(const ir::AstNode *node, const binder::ModuleVariable *variable); + void LoadExternalModuleVariable(const ir::AstNode *node, const binder::ModuleVariable *variable); + void StoreModuleVariable(const ir::AstNode *node, const binder::ModuleVariable *variable); + void GetModuleNamespace(const ir::AstNode *node, uint32_t index); + void DynamicImportCall(const ir::AstNode *node); void StSuperByName(const ir::AstNode *node, VReg obj, const util::StringView &key); void LdSuperByName(const ir::AstNode *node, VReg obj, const util::StringView &key); void StSuperByValue(const ir::AstNode *node, VReg obj, VReg prop); - void LdSuperByValue(const ir::AstNode *node, VReg obj, VReg prop); + void LdSuperByValue(const ir::AstNode *node, VReg obj); void StoreSuperProperty(const ir::AstNode *node, VReg obj, const Operand &prop); void LoadSuperProperty(const ir::AstNode *node, VReg obj, const Operand &prop); - void LdLexEnv(const ir::AstNode *node); void PopLexEnv(const ir::AstNode *node); void CopyLexEnv(const ir::AstNode *node); void NewLexicalEnv(const ir::AstNode *node, uint32_t num, binder::VariableScope *scope); @@ -382,7 +402,7 @@ public: void SortCatchTables(); void LoadObjByIndex(const ir::AstNode *node, VReg obj, int64_t index); - void LoadObjByValue(const ir::AstNode *node, VReg obj, VReg prop); + void LoadObjByValue(const ir::AstNode *node, VReg obj); void StoreObjByName(const ir::AstNode *node, VReg obj, const util::StringView &prop); void StoreObjByIndex(const ir::AstNode *node, VReg obj, int64_t index); @@ -416,6 +436,16 @@ public: throw Error(ErrorType::GENERIC, "Unimplemented code path"); } + ICSize GetCurrentSlot() const + { + return currentSlot_; + } + + void IncreaseCurrentSlot(ICSlot inc) + { + currentSlot_ += inc; + } + private: ArenaAllocator *allocator_; CompilerContext *context_; @@ -434,6 +464,7 @@ private: SimpleAllocator sa_; RegAllocator ra_; RangeRegAllocator rra_; + ICSize currentSlot_ {0}; uint32_t usedRegs_ {0}; uint32_t totalRegs_ {0}; @@ -447,6 +478,7 @@ private: friend class LoopEnvScope; friend class DynamicContext; size_t labelId_ {0}; + FunctionKind funcKind_ {FunctionKind::NONE}; }; } // namespace panda::es2panda::compiler diff --git a/es2panda/compiler/core/regAllocator.cpp b/es2panda/compiler/core/regAllocator.cpp index 1601722e66e1080bf507fe7015f1136c82073397..01f3f81ebad6c75d7f63b52f373fbd1aa3cae358 100644 --- a/es2panda/compiler/core/regAllocator.cpp +++ b/es2panda/compiler/core/regAllocator.cpp @@ -21,7 +21,7 @@ namespace panda::es2panda::compiler { -// RegAllocatorBase +// AllocatorBase void AllocatorBase::PushBack(IRNode *ins) { @@ -33,12 +33,10 @@ ArenaAllocator *AllocatorBase::Allocator() const return pg_->Allocator(); } -// SimpleAllocator - -Label *SimpleAllocator::AllocLabel(std::string &&id) +void AllocatorBase::UpdateIcSlot(IRNode *node) { - const auto *lastInsNode = pg_->Insns().empty() ? FIRST_NODE_OF_FUNCTION : pg_->Insns().back()->Node(); - return Alloc