diff --git a/es2panda/compiler/core/function.cpp b/es2panda/compiler/core/function.cpp index a284a72bc691b40bdf068fbc5981f8fd7078698a..d25dfb8a2eb0f1e70faccb12bc5f3a2799178b03 100644 --- a/es2panda/compiler/core/function.cpp +++ b/es2panda/compiler/core/function.cpp @@ -203,8 +203,8 @@ static void CompileFunctionOrProgram(PandaGen *pg) void Function::Compile(PandaGen *pg) { - CompileFunctionOrProgram(pg); pg->SetFunctionKind(); + CompileFunctionOrProgram(pg); pg->SetSourceLocationFlag(lexer::SourceLocationFlag::INVALID_SOURCE_LOCATION); pg->CopyFunctionArguments(pg->RootNode()); pg->InitializeLexEnv(pg->RootNode()); diff --git a/es2panda/compiler/core/pandagen.cpp b/es2panda/compiler/core/pandagen.cpp index babd7f15dde9a817e67e703440b85ab5b42c2283..cfdcc1bf6eee143d573f7dd226fb7a7a6ff43513 100644 --- a/es2panda/compiler/core/pandagen.cpp +++ b/es2panda/compiler/core/pandagen.cpp @@ -1271,6 +1271,13 @@ void PandaGen::SuperCallSpread(const ir::AstNode *node, VReg vs) ra_.Emit(node, 0, vs); } +void PandaGen::NotifyConcurrentResult(const ir::AstNode *node) +{ + if (IsConcurrent()) { + ra_.Emit(node); + } +} + void PandaGen::NewObject(const ir::AstNode *node, VReg startReg, size_t argCount) { if (argCount <= util::Helpers::MAX_INT8) { diff --git a/es2panda/compiler/core/pandagen.h b/es2panda/compiler/core/pandagen.h index 4b17ee205ca3f1a2b594cb4b54622e3dd54fcf8d..344ef308e0312160f4b0677cee0b95c5de4592f9 100644 --- a/es2panda/compiler/core/pandagen.h +++ b/es2panda/compiler/core/pandagen.h @@ -225,6 +225,11 @@ public: return funcKind_; } + bool IsConcurrent() const + { + return funcKind_ == panda::panda_file::FunctionKind::CONCURRENT_FUNCTION; + } + void SetFunctionKind(); bool IsDebug() const; @@ -339,6 +344,7 @@ public: void CallSpread(const ir::AstNode *node, VReg func, VReg thisReg, VReg args); void SuperCall(const ir::AstNode *node, VReg startReg, size_t argCount); void SuperCallSpread(const ir::AstNode *node, VReg vs); + void NotifyConcurrentResult(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); diff --git a/es2panda/compiler/function/asyncFunctionBuilder.cpp b/es2panda/compiler/function/asyncFunctionBuilder.cpp index da2a187e2212b6f57cd2b79b8f504b850124a3ab..c02a8cfc135024bce3f8a493ce28c416fc8ea051 100644 --- a/es2panda/compiler/function/asyncFunctionBuilder.cpp +++ b/es2panda/compiler/function/asyncFunctionBuilder.cpp @@ -24,6 +24,7 @@ namespace panda::es2panda::compiler { void AsyncFunctionBuilder::DirectReturn(const ir::AstNode *node) const { pg_->AsyncFunctionResolve(node, funcObj_); // retVal is in acc + pg_->NotifyConcurrentResult(node); pg_->EmitReturn(node); } @@ -50,6 +51,7 @@ void AsyncFunctionBuilder::CleanUp(const ir::ScriptFunction *node) const VReg exception = pg_->AllocReg(); pg_->StoreAccumulator(node, exception); pg_->AsyncFunctionReject(node, funcObj_); + pg_->NotifyConcurrentResult(node); pg_->EmitReturn(node); pg_->SetLabel(node, labelSet.CatchEnd()); } diff --git a/es2panda/compiler/function/functionBuilder.cpp b/es2panda/compiler/function/functionBuilder.cpp index 5a808fded2ae65e82b6ab783e528d30f3c268536..eb79e61556d30d08c5647cb524337f7b218d71ff 100644 --- a/es2panda/compiler/function/functionBuilder.cpp +++ b/es2panda/compiler/function/functionBuilder.cpp @@ -36,6 +36,7 @@ IteratorType FunctionBuilder::GeneratorKind() const void FunctionBuilder::DirectReturn(const ir::AstNode *node) const { + pg_->NotifyConcurrentResult(node); pg_->EmitReturn(node); } @@ -45,15 +46,19 @@ void FunctionBuilder::ImplicitReturn(const ir::AstNode *node) const if (!rootNode->IsScriptFunction() || !rootNode->AsScriptFunction()->IsConstructor()) { if (pg_->isDebuggerEvaluateExpressionMode()) { + pg_->NotifyConcurrentResult(node); pg_->EmitReturn(node); return; } + pg_->LoadConst(node, Constant::JS_UNDEFINED); + pg_->NotifyConcurrentResult(node); pg_->EmitReturnUndefined(node); return; } pg_->GetThis(rootNode); pg_->ThrowIfSuperNotCorrectCall(rootNode, 0); + pg_->NotifyConcurrentResult(node); pg_->EmitReturn(node); } diff --git a/es2panda/ir/base/scriptFunction.h b/es2panda/ir/base/scriptFunction.h index 0e1514a8a0af7134ad33542e16b4470270748c2f..56e4c910f51b4cc0256cefbca8040cc22310b610 100644 --- a/es2panda/ir/base/scriptFunction.h +++ b/es2panda/ir/base/scriptFunction.h @@ -174,7 +174,7 @@ public: bool CanBeConcurrent() const { - return !(IsGenerator() || IsAsync() || IsArrow() || IsConstructor() || IsMethod()); + return !(IsGenerator() || IsArrow() || IsConstructor() || IsMethod()); } void Iterate(const NodeTraverser &cb) const override; diff --git a/es2panda/test/compiler/js/concurrent/concurrent-async-function-decl-explicit-return-expected.txt b/es2panda/test/compiler/js/concurrent/concurrent-async-function-decl-explicit-return-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..96890454383b0847cd474c29cfbcd501a90dd9fc --- /dev/null +++ b/es2panda/test/compiler/js/concurrent/concurrent-async-function-decl-explicit-return-expected.txt @@ -0,0 +1,2 @@ +[object Promise] +111 diff --git a/es2panda/test/compiler/js/concurrent/concurrent-async-function-decl-explicit-return.js b/es2panda/test/compiler/js/concurrent/concurrent-async-function-decl-explicit-return.js new file mode 100644 index 0000000000000000000000000000000000000000..e82948db0c78b800a9e0fb509de1ac7a435063a6 --- /dev/null +++ b/es2panda/test/compiler/js/concurrent/concurrent-async-function-decl-explicit-return.js @@ -0,0 +1,10 @@ +"use strict"; + +async function a() { + "use concurrent"; + await 1; + print(111); + return 1; +} + +print(a()); diff --git a/es2panda/test/compiler/js/concurrent/concurrent-async-function-decl-implicit-return-expected.txt b/es2panda/test/compiler/js/concurrent/concurrent-async-function-decl-implicit-return-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..58c9bdf9d017fcd178dc8c073cbfcbb7ff240d6c --- /dev/null +++ b/es2panda/test/compiler/js/concurrent/concurrent-async-function-decl-implicit-return-expected.txt @@ -0,0 +1 @@ +111 diff --git a/es2panda/test/compiler/js/concurrent/concurrent-async-function-decl-implicit-return.js b/es2panda/test/compiler/js/concurrent/concurrent-async-function-decl-implicit-return.js new file mode 100644 index 0000000000000000000000000000000000000000..de77a9453fb59431f4b5be3d3ccb011415ec32a7 --- /dev/null +++ b/es2panda/test/compiler/js/concurrent/concurrent-async-function-decl-implicit-return.js @@ -0,0 +1,9 @@ +"use strict"; + +async function a() { + "use concurrent"; + await 1; + print(111); +} + +a(); diff --git a/es2panda/test/compiler/js/concurrent/concurrent-function-decl-explicit-return-expected.txt b/es2panda/test/compiler/js/concurrent/concurrent-function-decl-explicit-return-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..9737894eb6f0c98e27ba00f0707e564c70ca5c78 --- /dev/null +++ b/es2panda/test/compiler/js/concurrent/concurrent-function-decl-explicit-return-expected.txt @@ -0,0 +1,2 @@ +111 +1 diff --git a/es2panda/test/compiler/js/concurrent/concurrent-function-decl-explicit-return.js b/es2panda/test/compiler/js/concurrent/concurrent-function-decl-explicit-return.js new file mode 100644 index 0000000000000000000000000000000000000000..75e95b9b90e4100754abd7cfa602e16510d623f9 --- /dev/null +++ b/es2panda/test/compiler/js/concurrent/concurrent-function-decl-explicit-return.js @@ -0,0 +1,9 @@ +"use strict"; + +function a() { + "use concurrent"; + print(111); + return 1; +} + +print(a()); diff --git a/es2panda/test/compiler/js/concurrent/concurrent-function-decl-implicit-return-expected.txt b/es2panda/test/compiler/js/concurrent/concurrent-function-decl-implicit-return-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..58c9bdf9d017fcd178dc8c073cbfcbb7ff240d6c --- /dev/null +++ b/es2panda/test/compiler/js/concurrent/concurrent-function-decl-implicit-return-expected.txt @@ -0,0 +1 @@ +111 diff --git a/es2panda/test/compiler/js/concurrent/concurrent-function-decl-implicit-return.js b/es2panda/test/compiler/js/concurrent/concurrent-function-decl-implicit-return.js new file mode 100644 index 0000000000000000000000000000000000000000..b9459e47512c145cd3fbd1d59f26fecc68d3fad0 --- /dev/null +++ b/es2panda/test/compiler/js/concurrent/concurrent-function-decl-implicit-return.js @@ -0,0 +1,8 @@ +"use strict"; + +function a() { + "use concurrent"; + print(111); +} + +a(); diff --git a/es2panda/test/parser/concurrent/invalid-concurrent-async-function-expected.txt b/es2panda/test/parser/concurrent/invalid-concurrent-async-function-expected.txt deleted file mode 100644 index a53c7f64929ef3f96861024be9862ccb44f5459a..0000000000000000000000000000000000000000 --- a/es2panda/test/parser/concurrent/invalid-concurrent-async-function-expected.txt +++ /dev/null @@ -1,2 +0,0 @@ -Error: Concurrent function should only be function declaration [invalid-concurrent-async-function.js:18:4] -the size of programs is expected to be 1, but is 0 diff --git a/es2panda/test/parser/concurrent/invalid-concurrent-async-function.js b/es2panda/test/parser/concurrent/invalid-concurrent-async-function.js deleted file mode 100644 index 45d163165b2de01991ead5af307936e0ef7cc5a8..0000000000000000000000000000000000000000 --- a/es2panda/test/parser/concurrent/invalid-concurrent-async-function.js +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -"use strict"; - -async function a() { - "use concurrent"; -} \ No newline at end of file diff --git a/ts2panda/templates/irnodes.ts.erb b/ts2panda/templates/irnodes.ts.erb index a083d8b5a37114070095ef6ae3969363216c3c6c..acb70721c29bcbd4acc07ef3ae09fd6cce40d2b4 100755 --- a/ts2panda/templates/irnodes.ts.erb +++ b/ts2panda/templates/irnodes.ts.erb @@ -75,6 +75,9 @@ import { PandaGen } from "./pandagen" % end % % def is_Call(insn) +% if insn.mnemonic.start_with? "callruntime" +% return false +% end % if insn.mnemonic.start_with? "call" % return true % end