From 41501683d28f7df6f4646eabaef3ffe504102bf4 Mon Sep 17 00:00:00 2001 From: gavin1012_hw Date: Tue, 19 Jul 2022 10:16:07 +0800 Subject: [PATCH] Support Instructions for es2abc 1. Fix BranchIfTrue and BranchIfFalse instruction 2. Support BigInt instruction 3. Support stlettoglobalrecord/stconstttoglobalrecord/stclasstoglobalreocord instruction Issue: I5IH5V Signed-off-by: gavin1012_hw Change-Id: I60daaaf8f189c877551f663b77d6b7913f6ebbbc --- es2panda/binder/binder.cpp | 4 +- es2panda/binder/declaration.h | 14 +++++- es2panda/binder/scope.cpp | 2 +- es2panda/binder/variableFlags.h | 1 + es2panda/compiler/base/lexenv.cpp | 2 +- es2panda/compiler/core/pandagen.cpp | 48 ++++++++++++++++++- es2panda/compiler/core/pandagen.h | 6 +++ es2panda/ir/base/classDefinition.cpp | 3 -- .../ir/expressions/literals/bigIntLiteral.cpp | 4 +- es2panda/parser/statementParser.cpp | 2 +- 10 files changed, 73 insertions(+), 13 deletions(-) diff --git a/es2panda/binder/binder.cpp b/es2panda/binder/binder.cpp index d2a8b2ad39..44ef3b14e5 100644 --- a/es2panda/binder/binder.cpp +++ b/es2panda/binder/binder.cpp @@ -151,7 +151,7 @@ void Binder::LookupIdentReference(ir::Identifier *ident) return; } - if (res.variable->Declaration()->IsLetOrConstDecl() && !res.variable->HasFlag(VariableFlags::INITIALIZED)) { + if (res.variable->Declaration()->IsLetOrConstOrClassDecl() && !res.variable->HasFlag(VariableFlags::INITIALIZED)) { ident->SetTdz(); } @@ -245,7 +245,7 @@ void Binder::BuildClassDefinition(ir::ClassDefinition *classDef) if (classDef->Parent()->IsClassDeclaration()) { ScopeFindResult res = scope_->Find(classDef->Ident()->Name()); - ASSERT(res.variable && res.variable->Declaration()->IsLetDecl()); + ASSERT(res.variable && res.variable->Declaration()->IsClassDecl()); res.variable->AddFlag(VariableFlags::INITIALIZED); } diff --git a/es2panda/binder/declaration.h b/es2panda/binder/declaration.h index ab65a7579a..1e83a306e8 100644 --- a/es2panda/binder/declaration.h +++ b/es2panda/binder/declaration.h @@ -77,9 +77,9 @@ public: node_ = node; } - bool IsLetOrConstDecl() const + bool IsLetOrConstOrClassDecl() const { - return IsLetDecl() || IsConstDecl(); + return IsLetDecl() || IsConstDecl() || IsClassDecl(); } protected: @@ -234,6 +234,16 @@ public: } }; +class ClassDecl : public Decl { +public: + explicit ClassDecl(util::StringView name) : Decl(name) {} + + DeclType Type() const override + { + return DeclType::CLASS; + } +}; + class ParameterDecl : public Decl { public: explicit ParameterDecl(util::StringView name) : Decl(name) {} diff --git a/es2panda/binder/scope.cpp b/es2panda/binder/scope.cpp index 402bdd7a0c..e044f66c46 100644 --- a/es2panda/binder/scope.cpp +++ b/es2panda/binder/scope.cpp @@ -444,7 +444,7 @@ void LoopDeclarationScope::ConvertToVariableScope(ArenaAllocator *allocator) } for (auto &[name, var] : bindings_) { - if (!var->LexicalBound() || !var->Declaration()->IsLetOrConstDecl()) { + if (!var->LexicalBound() || !var->Declaration()->IsLetOrConstOrClassDecl()) { continue; } diff --git a/es2panda/binder/variableFlags.h b/es2panda/binder/variableFlags.h index dee8b14757..3a7f3a7138 100644 --- a/es2panda/binder/variableFlags.h +++ b/es2panda/binder/variableFlags.h @@ -24,6 +24,7 @@ namespace panda::es2panda::binder { _(VAR, VarDecl) \ _(LET, LetDecl) \ _(CONST, ConstDecl) \ + _(CLASS, ClassDecl) \ _(FUNC, FunctionDecl) \ _(PARAM, ParameterDecl) \ _(IMPORT, ImportDecl) \ diff --git a/es2panda/compiler/base/lexenv.cpp b/es2panda/compiler/base/lexenv.cpp index f3410f06c2..0ca34ca25e 100644 --- a/es2panda/compiler/base/lexenv.cpp +++ b/es2panda/compiler/base/lexenv.cpp @@ -91,7 +91,7 @@ static void ExpandStoreLexVar(PandaGen *pg, const ir::AstNode *node, const binde const auto *decl = result.variable->Declaration(); - if (decl->IsLetOrConstDecl() && !isDecl) { + if (decl->IsLetOrConstOrClassDecl() && !isDecl) { RegScope rs(pg); VReg valueReg = pg->AllocReg(); diff --git a/es2panda/compiler/core/pandagen.cpp b/es2panda/compiler/core/pandagen.cpp index 7cf1bb96f5..c95c4539d4 100644 --- a/es2panda/compiler/core/pandagen.cpp +++ b/es2panda/compiler/core/pandagen.cpp @@ -222,6 +222,12 @@ void PandaGen::LoadVar(const ir::Identifier *node, const binder::ScopeFindResult } ASSERT(var->IsLocalVariable()); + + if (var->Declaration()->IsLetOrConstOrClassDecl() && result.scope->IsGlobalScope()) { + TryLoadGlobalByName(node, result.name); + return; + } + LoadAccFromLexEnv(node, result); } @@ -245,6 +251,20 @@ void PandaGen::StoreVar(const ir::AstNode *node, const binder::ScopeFindResult & } ASSERT(var->IsLocalVariable()); + + 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()->IsConstDecl()) { + StConstToGlobalRecord(node, var->Name()); + } else if (var->Declaration()->IsClassDecl()) { + StClassToGlobalRecord(node, var->Name()); + } + return; + } + StoreAccToLexEnv(node, result, isDeclaration); } @@ -455,6 +475,12 @@ void PandaGen::LoadAccumulatorInt(const ir::AstNode *node, size_t num) sa_.Emit(node, static_cast(num)); } +void PandaGen::LoadAccumulatorBigInt(const ir::AstNode *node, const util::StringView &num) +{ + sa_.Emit(node, num); + strings_.insert(num); +} + void PandaGen::StoreConst(const ir::AstNode *node, VReg reg, Constant id) { LoadConst(node, id); @@ -804,6 +830,7 @@ void PandaGen::BranchIfNotUndefined(const ir::AstNode *node, Label *target) void PandaGen::BranchIfTrue(const ir::AstNode *node, Label *target) { + sa_.Emit(node); sa_.Emit(node, target); } @@ -815,7 +842,8 @@ void PandaGen::BranchIfNotTrue(const ir::AstNode *node, Label *target) void PandaGen::BranchIfFalse(const ir::AstNode *node, Label *target) { - sa_.Emit(node, target); + sa_.Emit(node); + sa_.Emit(node, target); } void PandaGen::EmitThrow(const ir::AstNode *node) @@ -1594,4 +1622,22 @@ VReg PandaGen::LoadPropertyKey(const ir::Expression *prop, bool isComputed) return propReg; } +void PandaGen::StLetToGlobalRecord(const ir::AstNode *node, const util::StringView &name) +{ + sa_.Emit(node, 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); + strings_.insert(name); +} + } // namespace panda::es2panda::compiler diff --git a/es2panda/compiler/core/pandagen.h b/es2panda/compiler/core/pandagen.h index 77d127c423..375c0e6de3 100644 --- a/es2panda/compiler/core/pandagen.h +++ b/es2panda/compiler/core/pandagen.h @@ -208,6 +208,10 @@ 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 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); void LoadObjProperty(const ir::AstNode *node, VReg obj, const Operand &prop); @@ -234,6 +238,7 @@ public: void LoadAccumulatorFloat(const ir::AstNode *node, double num); void LoadAccumulatorInt(const ir::AstNode *node, int32_t num); void LoadAccumulatorInt(const ir::AstNode *node, size_t num); + void LoadAccumulatorBigInt(const ir::AstNode *node, const util::StringView &num); void LoadConst(const ir::AstNode *node, Constant id); void StoreConst(const ir::AstNode *node, VReg reg, Constant id); @@ -255,6 +260,7 @@ public: void BranchIfTrue(const ir::AstNode *node, class Label *target); void BranchIfNotTrue(const ir::AstNode *node, class Label *target); void BranchIfFalse(const ir::AstNode *node, class Label *target); + void BranchIfNotFalse(const ir::AstNode *node, class Label *target); void EmitThrow(const ir::AstNode *node); void EmitRethrow(const ir::AstNode *node); diff --git a/es2panda/ir/base/classDefinition.cpp b/es2panda/ir/base/classDefinition.cpp index bd18a40d34..7eea3dab22 100644 --- a/es2panda/ir/base/classDefinition.cpp +++ b/es2panda/ir/base/classDefinition.cpp @@ -269,9 +269,6 @@ void ClassDefinition::Compile(compiler::PandaGen *pg) const int32_t bufIdx = CreateClassStaticProperties(pg, compiled); pg->DefineClassWithBuffer(this, ctorId, bufIdx, lexenv, baseReg); - if (scope_->Parent()->IsGlobalScope() && ident_) { - pg->StoreGlobalLet(this, ident_->Name()); - } pg->StoreAccumulator(this, classReg); InitializeClassName(pg); diff --git a/es2panda/ir/expressions/literals/bigIntLiteral.cpp b/es2panda/ir/expressions/literals/bigIntLiteral.cpp index 7d3a149f8f..19290522c6 100644 --- a/es2panda/ir/expressions/literals/bigIntLiteral.cpp +++ b/es2panda/ir/expressions/literals/bigIntLiteral.cpp @@ -30,8 +30,8 @@ void BigIntLiteral::Dump(ir::AstDumper *dumper) const void BigIntLiteral::Compile(compiler::PandaGen *pg) const { - // TODO() - pg->Unimplemented(); + util::StringView bigIntValue = src_.Substr(0, src_.Length()-1); + pg->LoadAccumulatorBigInt(this, bigIntValue); } checker::Type *BigIntLiteral::Check(checker::Checker *checker) const diff --git a/es2panda/parser/statementParser.cpp b/es2panda/parser/statementParser.cpp index 2a06a84efb..ca09b54cb2 100644 --- a/es2panda/parser/statementParser.cpp +++ b/es2panda/parser/statementParser.cpp @@ -501,7 +501,7 @@ ir::ClassDeclaration *ParserImpl::ParseClassDeclaration(bool idRequired, ArenaVe ir::ClassDefinition *classDefinition = ParseClassDefinition(true, idRequired, isDeclare, isAbstract); auto *decl = - Binder()->AddDecl(classDefinition->Ident()->Start(), classDefinition->Ident()->Name()); + Binder()->AddDecl(classDefinition->Ident()->Start(), classDefinition->Ident()->Name()); decl->BindNode(classDefinition); lexer::SourcePosition endLoc = classDefinition->End(); -- Gitee