From b573d7e57bcb51e3368b2c96338ad454bf3393c8 Mon Sep 17 00:00:00 2001 From: ctw-ian Date: Fri, 28 Oct 2022 09:10:55 +0000 Subject: [PATCH] Support Nullish Coalesce on es2abc Issue:I5YDWR Signed-off-by: ctw-ian Change-Id: I9c4721ae3b5ddfb7778da12774a1d964df3a1e2c --- es2panda/compiler/core/pandagen.cpp | 10 ++++++++++ es2panda/compiler/core/pandagen.h | 1 + es2panda/ir/expressions/binaryExpression.cpp | 20 +++++++++++-------- .../nullishCoalesce-expected.txt | 3 +++ .../js/binaryExpression/nullishCoalesce.js | 9 +++++++++ 5 files changed, 35 insertions(+), 8 deletions(-) create mode 100644 es2panda/test/compiler/js/binaryExpression/nullishCoalesce-expected.txt create mode 100644 es2panda/test/compiler/js/binaryExpression/nullishCoalesce.js diff --git a/es2panda/compiler/core/pandagen.cpp b/es2panda/compiler/core/pandagen.cpp index 3488d439f9..ed81f39bda 100644 --- a/es2panda/compiler/core/pandagen.cpp +++ b/es2panda/compiler/core/pandagen.cpp @@ -1071,6 +1071,16 @@ void PandaGen::BranchIfFalse(const ir::AstNode *node, Label *target) sa_.Emit(node, target); } +void PandaGen::BranchIfStrictNull(const ir::AstNode *node, class Label *target) +{ + RegScope rs(this); + VReg tmp = AllocReg(); + StoreAccumulator(node, tmp); + LoadConst(node, Constant::JS_NULL); + ra_.Emit(node, 0, tmp); + sa_.Emit(node, target); +} + void PandaGen::EmitThrow(const ir::AstNode *node) { sa_.Emit(node); diff --git a/es2panda/compiler/core/pandagen.h b/es2panda/compiler/core/pandagen.h index cdc5a69bc9..02f17f126c 100644 --- a/es2panda/compiler/core/pandagen.h +++ b/es2panda/compiler/core/pandagen.h @@ -313,6 +313,7 @@ public: 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 BranchIfStrictNull(const ir::AstNode *node, class Label *target); void EmitThrow(const ir::AstNode *node); void EmitRethrow(const ir::AstNode *node); diff --git a/es2panda/ir/expressions/binaryExpression.cpp b/es2panda/ir/expressions/binaryExpression.cpp index 58fafd3d1a..526685b453 100644 --- a/es2panda/ir/expressions/binaryExpression.cpp +++ b/es2panda/ir/expressions/binaryExpression.cpp @@ -43,13 +43,9 @@ void BinaryExpression::CompileLogical(compiler::PandaGen *pg) const compiler::RegScope rs(pg); compiler::VReg lhs = pg->AllocReg(); - if (operator_ == lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING) { - // TODO(parser): Nullish Coalesce - compiler::PandaGen::Unimplemented(); - } - ASSERT(operator_ == lexer::TokenType::PUNCTUATOR_LOGICAL_AND || - operator_ == lexer::TokenType::PUNCTUATOR_LOGICAL_OR); + operator_ == lexer::TokenType::PUNCTUATOR_LOGICAL_OR || + operator_ == lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING); auto *skipRight = pg->AllocLabel(); auto *endLabel = pg->AllocLabel(); @@ -59,9 +55,17 @@ void BinaryExpression::CompileLogical(compiler::PandaGen *pg) const if (operator_ == lexer::TokenType::PUNCTUATOR_LOGICAL_AND) { pg->BranchIfFalse(this, skipRight); - } else { - ASSERT(operator_ == lexer::TokenType::PUNCTUATOR_LOGICAL_OR); + } else if (operator_ == lexer::TokenType::PUNCTUATOR_LOGICAL_OR) { pg->BranchIfTrue(this, skipRight); + } else { + ASSERT(operator_ == lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING); + auto *nullish = pg->AllocLabel(); + // if lhs === null + pg->BranchIfStrictNull(this, nullish); + pg->LoadAccumulator(this, lhs); + // if lhs === undefined + pg->BranchIfStrictNotUndefined(this, skipRight); + pg->SetLabel(this, nullish); } // left is true/false(and/or) then right -> acc diff --git a/es2panda/test/compiler/js/binaryExpression/nullishCoalesce-expected.txt b/es2panda/test/compiler/js/binaryExpression/nullishCoalesce-expected.txt new file mode 100644 index 0000000000..0429fae9e5 --- /dev/null +++ b/es2panda/test/compiler/js/binaryExpression/nullishCoalesce-expected.txt @@ -0,0 +1,3 @@ +2 +4 +5 diff --git a/es2panda/test/compiler/js/binaryExpression/nullishCoalesce.js b/es2panda/test/compiler/js/binaryExpression/nullishCoalesce.js new file mode 100644 index 0000000000..45d895e52b --- /dev/null +++ b/es2panda/test/compiler/js/binaryExpression/nullishCoalesce.js @@ -0,0 +1,9 @@ +let a = 2; +let b = a ?? 3; +print(b); +a = null; +b = a ?? 4; +print(b); +a = undefined; +b = a ?? 5; +print(b); \ No newline at end of file -- Gitee