From abe33bc9238ca978df93027bb183084c687d630a Mon Sep 17 00:00:00 2001 From: hufeng Date: Fri, 29 Jul 2022 11:21:53 +0800 Subject: [PATCH] Compile builtin Function with return global Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/I5JIPO Signed-off-by: hufeng Change-Id: Ib7a265087a989acc9b73cf307013ef7757d9195a --- es2panda/compiler/core/pandagen.cpp | 35 +++++++++++++++++++++- es2panda/compiler/core/pandagen.h | 12 +++++++- es2panda/ir/expressions/callExpression.cpp | 6 ++++ 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/es2panda/compiler/core/pandagen.cpp b/es2panda/compiler/core/pandagen.cpp index 75acc10f55..c98ef1087c 100644 --- a/es2panda/compiler/core/pandagen.cpp +++ b/es2panda/compiler/core/pandagen.cpp @@ -34,11 +34,13 @@ #include #include #include +#include #include -#include #include #include #include +#include +#include namespace panda::es2panda::compiler { @@ -1689,4 +1691,35 @@ void PandaGen::StClassToGlobalRecord(const ir::AstNode *node, const util::String strings_.insert(name); } +bool PandaGen::TryCompileFunctionCallOrNewExpression(const ir::Expression *expr) +{ + ASSERT(expr->IsCallExpression() || expr->IsNewExpression()); + const auto *callee = expr->IsCallExpression() ? expr->AsCallExpression()->Callee() : + expr->AsNewExpression()->Callee(); + + if (!callee->IsIdentifier()) { + return false; + } + + if (callee->AsIdentifier()->Name().Is("Function")) { + auto arguments = expr->IsCallExpression() ? expr->AsCallExpression()->Arguments() : + expr->AsNewExpression()->Arguments(); + if (arguments.empty()) { + return false; + } + + auto *arg = arguments[arguments.size() - 1]; + if (!arg->IsStringLiteral()) { + return false; + } + + if (std::regex_match(arg->AsStringLiteral()->Str().Mutf8(), std::regex(" *return +this[;]? *$"))) { + LoadConst(arg, Constant::JS_GLOBAL); + return true; + } + } + + return false; +} + } // namespace panda::es2panda::compiler diff --git a/es2panda/compiler/core/pandagen.h b/es2panda/compiler/core/pandagen.h index 371a6b1a0c..cf6cc329cd 100644 --- a/es2panda/compiler/core/pandagen.h +++ b/es2panda/compiler/core/pandagen.h @@ -24,7 +24,7 @@ #include #include -#include +#include namespace panda::es2panda::binder { class FunctionScope; @@ -383,6 +383,16 @@ public: Operand ToPropertyKey(const ir::Expression *prop, bool isComputed); VReg LoadPropertyKey(const ir::Expression *prop, bool isComputed); + /* + * Since the [Function] is not implemented yet, We compile the test262's framework code + * which obtains the [global] Object as following into [LoadConst.Global] directly. + * ``` + * var __globalObject = Function("return this;")(); + * var __globalObject = new Function("return this;")(); + * ``` + */ + bool TryCompileFunctionCallOrNewExpression(const ir::Expression *expr); + void SetFirstStmt(const ir::Statement *stmt) { debugInfo_.firstStmt = stmt; diff --git a/es2panda/ir/expressions/callExpression.cpp b/es2panda/ir/expressions/callExpression.cpp index bebd28a679..24dcc81c23 100644 --- a/es2panda/ir/expressions/callExpression.cpp +++ b/es2panda/ir/expressions/callExpression.cpp @@ -60,6 +60,12 @@ compiler::VReg CallExpression::CreateSpreadArguments(compiler::PandaGen *pg) con void CallExpression::Compile(compiler::PandaGen *pg) const { + if (callee_->IsCallExpression() || callee_->IsNewExpression()) { + if (pg->TryCompileFunctionCallOrNewExpression(callee_)) { + return; + } + } + compiler::RegScope rs(pg); bool containsSpread = util::Helpers::ContainSpreadElement(arguments_); -- Gitee