From 774afefb65b389a19b8e25d6f54364897fa7adf6 Mon Sep 17 00:00:00 2001 From: songqi Date: Thu, 30 Mar 2023 18:32:29 +0800 Subject: [PATCH] Fix runtime error when CallExpression's callee is TSNonNullExpression Issue: I6RQAR Tests: test262/parser/compiler/tsc Signed-off-by: songqi Change-Id: I65e0692cf5c183869cd77d54459475119d909bc0 --- es2panda/ir/expressions/callExpression.cpp | 28 ++++++++++++++----- es2panda/ir/ts/tsNonNullExpression.h | 5 ++++ .../ts-test-call-expression-1-expected.txt | 1 + .../expressions/ts-test-call-expression-1.ts | 28 +++++++++++++++++++ .../ts-test-call-expression-2-expected.txt | 1 + .../expressions/ts-test-call-expression-2.ts | 28 +++++++++++++++++++ .../ts-test-call-expression-3-expected.txt | 1 + .../expressions/ts-test-call-expression-3.ts | 28 +++++++++++++++++++ ...ts-test-non-null-expression-2-expected.txt | 1 + .../ts-test-non-null-expression-2.ts | 28 +++++++++++++++++++ 10 files changed, 142 insertions(+), 7 deletions(-) create mode 100644 es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-call-expression-1-expected.txt create mode 100644 es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-call-expression-1.ts create mode 100644 es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-call-expression-2-expected.txt create mode 100644 es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-call-expression-2.ts create mode 100644 es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-call-expression-3-expected.txt create mode 100644 es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-call-expression-3.ts create mode 100644 es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-non-null-expression-2-expected.txt create mode 100644 es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-non-null-expression-2.ts diff --git a/es2panda/ir/expressions/callExpression.cpp b/es2panda/ir/expressions/callExpression.cpp index 3c83bbc32e..2230541625 100644 --- a/es2panda/ir/expressions/callExpression.cpp +++ b/es2panda/ir/expressions/callExpression.cpp @@ -25,6 +25,9 @@ #include #include #include +#include +#include +#include #include namespace panda::es2panda::ir { @@ -61,8 +64,19 @@ compiler::VReg CallExpression::CreateSpreadArguments(compiler::PandaGen *pg) con void CallExpression::Compile(compiler::PandaGen *pg) const { - if (callee_->IsCallExpression() || callee_->IsNewExpression()) { - if (pg->TryCompileFunctionCallOrNewExpression(callee_)) { + ir::Expression *realCallee = callee_; + while (realCallee->IsTSNonNullExpression() || realCallee->IsTSAsExpression() || realCallee->IsTSTypeAssertion()) { + if (realCallee->IsTSNonNullExpression()) { + realCallee = realCallee->AsTSNonNullExpression()->Expr(); + } else if (realCallee->IsTSAsExpression()) { + realCallee = realCallee->AsTSAsExpression()->Expr(); + } else if (realCallee->IsTSTypeAssertion()) { + realCallee = realCallee->AsTSTypeAssertion()->GetExpression(); + } + } + + if (realCallee->IsCallExpression() || realCallee->IsNewExpression()) { + if (pg->TryCompileFunctionCallOrNewExpression(realCallee)) { return; } } @@ -113,17 +127,17 @@ void CallExpression::Compile(compiler::PandaGen *pg) const bool hasThis = false; compiler::VReg thisReg {}; - if (callee_->IsMemberExpression()) { + if (realCallee->IsMemberExpression()) { hasThis = true; thisReg = pg->AllocReg(); compiler::RegScope mrs(pg); - callee_->AsMemberExpression()->Compile(pg, thisReg); - } else if (callee_->IsChainExpression()) { + realCallee->AsMemberExpression()->Compile(pg, thisReg); + } else if (realCallee->IsChainExpression()) { hasThis = true; - callee_->AsChainExpression()->Compile(pg); + realCallee->AsChainExpression()->Compile(pg); } else { - callee_->Compile(pg); + realCallee->Compile(pg); } pg->StoreAccumulator(this, callee); diff --git a/es2panda/ir/ts/tsNonNullExpression.h b/es2panda/ir/ts/tsNonNullExpression.h index 5d0e858c83..a44c9f8b9d 100644 --- a/es2panda/ir/ts/tsNonNullExpression.h +++ b/es2panda/ir/ts/tsNonNullExpression.h @@ -38,6 +38,11 @@ public: return expr_; } + Expression *Expr() + { + return expr_; + } + void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; void Compile(compiler::PandaGen *pg) const override; diff --git a/es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-call-expression-1-expected.txt b/es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-call-expression-1-expected.txt new file mode 100644 index 0000000000..0cfbf08886 --- /dev/null +++ b/es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-call-expression-1-expected.txt @@ -0,0 +1 @@ +2 diff --git a/es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-call-expression-1.ts b/es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-call-expression-1.ts new file mode 100644 index 0000000000..abb689feb3 --- /dev/null +++ b/es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-call-expression-1.ts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 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. + */ + + +const deserializeTag = Symbol('[[Deserialize]]'); + +class A { + public propA: number = 1; + public [deserializeTag]() { + this.propA = 2; + } +} + +var a = new A(); +(a[deserializeTag] as any)(); +print(a.propA); diff --git a/es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-call-expression-2-expected.txt b/es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-call-expression-2-expected.txt new file mode 100644 index 0000000000..0cfbf08886 --- /dev/null +++ b/es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-call-expression-2-expected.txt @@ -0,0 +1 @@ +2 diff --git a/es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-call-expression-2.ts b/es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-call-expression-2.ts new file mode 100644 index 0000000000..8c564d2ae6 --- /dev/null +++ b/es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-call-expression-2.ts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 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. + */ + + +const deserializeTag = Symbol('[[Deserialize]]'); + +class A { + public propA: number = 1; + public [deserializeTag]() { + this.propA = 2; + } +} + +var a = new A(); +((a[deserializeTag]))(); +print(a.propA); diff --git a/es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-call-expression-3-expected.txt b/es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-call-expression-3-expected.txt new file mode 100644 index 0000000000..0cfbf08886 --- /dev/null +++ b/es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-call-expression-3-expected.txt @@ -0,0 +1 @@ +2 diff --git a/es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-call-expression-3.ts b/es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-call-expression-3.ts new file mode 100644 index 0000000000..870cd35646 --- /dev/null +++ b/es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-call-expression-3.ts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 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. + */ + + +const deserializeTag = Symbol('[[Deserialize]]'); + +class A { + public propA: number = 1; + public [deserializeTag]() { + this.propA = 2; + } +} + +var a = new A(); +(a[deserializeTag] as any)!(); +print(a.propA); diff --git a/es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-non-null-expression-2-expected.txt b/es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-non-null-expression-2-expected.txt new file mode 100644 index 0000000000..0cfbf08886 --- /dev/null +++ b/es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-non-null-expression-2-expected.txt @@ -0,0 +1 @@ +2 diff --git a/es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-non-null-expression-2.ts b/es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-non-null-expression-2.ts new file mode 100644 index 0000000000..0b067ef5d3 --- /dev/null +++ b/es2panda/test/compiler/ts/cases/conformance/expressions/ts-test-non-null-expression-2.ts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 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. + */ + + +const deserializeTag = Symbol('[[Deserialize]]'); + +class A { + public propA: number = 1; + public [deserializeTag]() { + this.propA = 2; + } +} + +var a = new A(); +a[deserializeTag]!(); +print(a.propA); -- Gitee