From 3d4deb8faaf185b48e691a57910633a9a6630b77 Mon Sep 17 00:00:00 2001 From: ctw-ian Date: Mon, 15 Aug 2022 19:38:19 +0800 Subject: [PATCH 1/4] Isa modification Issue:I5MXZZ Signed-off-by: ctw-ian Change-Id: I7dd14beb71b4e48bafe27b62576180b7c80f0ce9 --- es2panda/binder/binder.cpp | 9 + es2panda/binder/binder.h | 1 + es2panda/binder/scope.cpp | 8 + es2panda/binder/scope.h | 2 + es2panda/binder/variable.h | 13 + es2panda/compiler/base/destructuring.cpp | 16 +- es2panda/compiler/base/hoisting.cpp | 6 +- es2panda/compiler/core/compilerContext.cpp | 5 +- es2panda/compiler/core/compilerContext.h | 9 +- es2panda/compiler/core/compilerImpl.cpp | 2 +- es2panda/compiler/core/emitter/emitter.cpp | 6 + es2panda/compiler/core/emitter/emitter.h | 1 + es2panda/compiler/core/envScope.cpp | 7 +- es2panda/compiler/core/envScope.h | 8 +- es2panda/compiler/core/function.cpp | 9 +- es2panda/compiler/core/pandagen.cpp | 696 +++++++++------ es2panda/compiler/core/pandagen.h | 76 +- es2panda/compiler/core/regAllocator.cpp | 25 +- es2panda/compiler/core/regAllocator.h | 8 +- es2panda/compiler/core/regScope.cpp | 2 +- .../function/asyncFunctionBuilder.cpp | 12 +- .../asyncGeneratorFunctionBuilder.cpp | 2 +- .../compiler/function/functionBuilder.cpp | 12 +- es2panda/compiler/templates/isa.h.erb | 74 +- es2panda/ir/base/classDefinition.cpp | 3 +- es2panda/ir/expressions/callExpression.cpp | 1 - es2panda/ir/expressions/importExpression.cpp | 5 +- .../ir/expressions/literals/regExpLiteral.cpp | 4 +- es2panda/ir/expressions/newExpression.cpp | 8 +- es2panda/ir/expressions/objectExpression.cpp | 13 +- es2panda/ir/irnode.h | 5 + .../ir/module/exportDefaultDeclaration.cpp | 5 +- .../parser/module/sourceTextModuleRecord.cpp | 19 + .../parser/module/sourceTextModuleRecord.h | 6 + es2panda/util/helpers.h | 2 + es2panda/util/hotfix.cpp | 20 +- ts2panda/src/base/bcGenUtil.ts | 463 +++++----- ts2panda/src/base/builtIn.ts | 62 +- ts2panda/src/base/iterator.ts | 2 +- ts2panda/src/base/lexEnv.ts | 13 - ts2panda/src/base/util.ts | 70 +- ts2panda/src/base/vregisterCache.ts | 11 +- ts2panda/src/compiler.ts | 32 +- ts2panda/src/compilerDriver.ts | 11 +- ts2panda/src/compilerStatistics.ts | 10 +- ts2panda/src/debuginfo.ts | 10 +- ts2panda/src/ecmaModule.ts | 19 +- ts2panda/src/expression/callExpression.ts | 5 +- ts2panda/src/expression/newExpression.ts | 13 +- .../src/expression/objectLiteralExpression.ts | 18 +- ts2panda/src/function/asyncFunctionBuilder.ts | 20 +- .../function/asyncGeneratorFunctionBuilder.ts | 21 +- .../src/function/generatorFunctionBuilder.ts | 11 +- ts2panda/src/hoisting.ts | 9 +- ts2panda/src/lexenv.ts | 3 +- ts2panda/src/pandagen.ts | 528 +++++++----- ts2panda/src/pandasm.ts | 5 +- ts2panda/src/pass/cacheExpander.ts | 3 + ts2panda/src/recorder.ts | 1 + ts2panda/src/regAllocator.ts | 24 +- ts2panda/src/statement/classStatement.ts | 15 +- ts2panda/src/statement/forOfStatement.ts | 2 +- ts2panda/src/statement/loopStatement.ts | 27 +- ts2panda/src/statement/tryStatement.ts | 3 +- ts2panda/src/ts2panda.ts | 35 +- ts2panda/src/variable.ts | 9 + ts2panda/templates/irnodes.ts.erb | 51 +- ts2panda/tests/builtIns.test.ts | 12 +- ts2panda/tests/commonjs.test.ts | 76 +- ts2panda/tests/esmodule.test.ts | 42 +- ts2panda/tests/expression/arguments.test.ts | 37 +- ts2panda/tests/expression/binary.test.ts | 259 +++--- ts2panda/tests/expression/call.test.ts | 135 +-- ts2panda/tests/expression/cmpBinary.test.ts | 248 +++--- ts2panda/tests/expression/commalist.test.ts | 140 +-- ts2panda/tests/expression/conditions.test.ts | 80 +- ts2panda/tests/expression/delete.test.ts | 72 +- .../tests/expression/elementAccess.test.ts | 68 +- .../expression/functionExpression.test.ts | 215 ++--- ts2panda/tests/expression/literal.test.ts | 204 ++--- ts2panda/tests/expression/logicBinary.test.ts | 36 +- ts2panda/tests/expression/new.test.ts | 96 +-- .../tests/expression/numericLiteral.test.ts | 17 +- .../tests/expression/operationEqual.test.ts | 175 ++-- .../tests/expression/parenthesized.test.ts | 27 +- .../expression/postfixOperations.test.ts | 59 +- .../tests/expression/prefixOperations.test.ts | 123 +-- .../tests/expression/propertyAccess.test.ts | 96 +-- ts2panda/tests/expression/regular.test.js | 13 +- .../expression/templateExpression.test.ts | 293 ++++--- ts2panda/tests/expression/thisKeyWord.test.ts | 12 +- ts2panda/tests/expression/typeOf.test.ts | 51 +- ts2panda/tests/expression/void.test.ts | 21 +- ts2panda/tests/hoist.test.ts | 91 +- ts2panda/tests/lexenv.test.ts | 184 ++-- ts2panda/tests/pandagen.test.ts | 4 +- ts2panda/tests/regAllocator.test.ts | 84 +- ts2panda/tests/statements/debugger.test.ts | 8 +- ts2panda/tests/statements/doWhile.test.ts | 54 +- ts2panda/tests/statements/for.test.ts | 157 ++-- ts2panda/tests/statements/forIn.test.ts | 97 +-- ts2panda/tests/statements/forOf.test.ts | 240 +++--- .../statements/functionDeclaration.test.ts | 65 +- ts2panda/tests/statements/return.test.ts | 4 +- ts2panda/tests/statements/switch.test.ts | 103 ++- ts2panda/tests/statements/tryCatch.test.ts | 97 ++- .../statements/variableDeclaration.test.ts | 79 +- ts2panda/tests/statements/while.test.ts | 92 +- .../tests/watch_expression/addWatch.test.ts | 805 ++++++++++-------- ts2panda/ts2abc/ts2abc.cpp | 9 + ts2panda/ts2abc/type_adapter.cpp | 174 ++++ 111 files changed, 4180 insertions(+), 3380 deletions(-) create mode 100644 ts2panda/ts2abc/type_adapter.cpp diff --git a/es2panda/binder/binder.cpp b/es2panda/binder/binder.cpp index 43a98efbaa..a094a339ee 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 7f07e686e2..e9213c472e 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 21649a4b8c..634676482a 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 ad0783e33b..94b3791028 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 80086ef9f6..a17b88885a 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 70d9ef0754..5761a02177 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 e8b61fc97d..02c8b07813 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()->Index()); } 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 81434e630b..f3549110db 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 6acc7b83fb..5348d48fd3 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 5561346b97..368783be96 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 53064fdc1d..9e759ff8b3 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,11 @@ const ArenaSet &FunctionEmitter::Strings() const return pg_->Strings(); } +void FunctionEmitter::GenFunctionKind() +{ + func_->SetFunctionKind(static_cast(pg_->GetFunctionKind())); +} + 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 f689a4e57c..8fb8b1e4ba 100644 --- a/es2panda/compiler/core/emitter/emitter.h +++ b/es2panda/compiler/core/emitter/emitter.h @@ -81,6 +81,7 @@ private: void GenScopeVariableInfo(const binder::Scope *scope); void GenSourceFileDebugInfo(); void GenVariablesDebugInfo(); + void GenFunctionKind(); util::StringView SourceCode() const; lexer::LineIndex &GetLineIndex() const; diff --git a/es2panda/compiler/core/envScope.cpp b/es2panda/compiler/core/envScope.cpp index a6c123937c..6cb007c87e 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 55b801a7a1..a21c2a3e52 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 3f4a050ea0..1df946cfa6 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 e56e28c72d..8ac605ed32 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,7 @@ void PandaGen::LoadVar(const ir::Identifier *node, const binder::ScopeFindResult } if (var->IsModuleVariable()) { - LoadModuleVariable(node, var->Name(), var->HasFlag(binder::VariableFlags::LOCAL_EXPORT)); + LoadModuleVariable(node, var->AsModuleVariable()->Index(), var->HasFlag(binder::VariableFlags::LOCAL_EXPORT)); if (var->Declaration()->IsLetOrConstOrClassDecl()) { ThrowUndefinedIfHole(node, var->Name()); } @@ -284,12 +321,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); + LoadModuleVariable(node, var->AsModuleVariable()->Index(), true); ThrowUndefinedIfHole(node, var->Name()); LoadAccumulator(node, valueReg); } - StoreModuleVariable(node, var->Name()); + StoreModuleVariable(node, var->AsModuleVariable()->Index()); return; } @@ -298,13 +335,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 +349,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 +370,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 +446,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 +475,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 +608,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 +637,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 +680,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 +763,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 +806,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 +824,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 +846,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 +959,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 +1027,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 +1038,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 +1078,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 +1141,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 +1222,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 +1265,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 +1278,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 +1314,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 +1375,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 +1423,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 +1586,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 +1622,89 @@ 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::LoadModuleVariable(const ir::AstNode *node, uint32_t index, bool isLocalExport) { - ra_.Emit(node, name, isLocalExport ? static_cast(1) : static_cast(0)); - strings_.insert(name); + if (isLocalExport) { + index <= util::Helpers::MAX_INT8 ? sa_.Emit(node, index) : + sa_.Emit(node, index); + } else { + 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::StoreModuleVariable(const ir::AstNode *node, uint32_t index) { - sa_.Emit(node, name); - strings_.insert(name); + 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::GetModuleNamespace(const ir::AstNode *node, uint32_t index) { - sa_.Emit(node, name); - strings_.insert(name); + index <= util::Helpers::MAX_INT8 ? sa_.Emit(node, index) : + sa_.Emit(node, index); } -void PandaGen::DynamicImportCall(const ir::AstNode *node, VReg moduleSpecifier) +void PandaGen::DynamicImportCall(const ir::AstNode *node) { - ra_.Emit(node, moduleSpecifier); + 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 +1739,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 +1823,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 +1834,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 +1864,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 +1990,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 64fe2d6132..d99cde2839 100644 --- a/es2panda/compiler/core/pandagen.h +++ b/es2panda/compiler/core/pandagen.h @@ -60,6 +60,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 +196,13 @@ public: rra_.SetSourceLocationFlag(flag); } + FunctionKind GetFunctionKind() const + { + return funcKind_; + } + + void SetFunctionKind(); + bool IsDebug() const; bool isDebuggerEvaluateExpressionMode() const; std::string SourceFile() const; @@ -198,8 +215,6 @@ public: Label *AllocLabel(); - VReg LexEnv() const; - bool FunctionHasFinalizer() const; void FunctionInit(CatchTable* catchTable); void FunctionEnter(); @@ -209,7 +224,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 +233,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 +248,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 +278,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 +312,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 +328,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 +349,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 +366,20 @@ 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 LoadModuleVariable(const ir::AstNode *node, uint32_t index, bool isLocalExport); + void StoreModuleVariable(const ir::AstNode *node, uint32_t index); + 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 +400,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 +434,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 +462,7 @@ private: SimpleAllocator sa_; RegAllocator ra_; RangeRegAllocator rra_; + ICSize currentSlot_ {0}; uint32_t usedRegs_ {0}; uint32_t totalRegs_ {0}; @@ -447,6 +476,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 1601722e66..01f3f81eba 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