diff --git a/es2panda/compiler/core/pandagen.cpp b/es2panda/compiler/core/pandagen.cpp index 75acc10f55fb40c6166816a96662a288dd590be9..c98ef1087ce657a369f7af8c6dab3098e05c697c 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 371a6b1a0c99c2c5f538efb6ac415560eb1b76f8..cf6cc329cde938ac9350f00843131db13c0e419c 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 bebd28a6792c0b2889299d8e1c05299841f3b55c..24dcc81c234798e76e82c7e53322ab6318329e08 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_);