Commit b1c73402 authored by arv's avatar arv Committed by Commit bot

Revert of Revert of [es6] Parsing of new.target (patchset #1 id:1 of...

Revert of Revert of [es6] Parsing of new.target (patchset #1 id:1 of https://codereview.chromium.org/1170263002/)

Reason for revert:
The bot needs to be clobbered.

Original issue's description:
> Revert of [es6] Parsing of new.target (patchset #2 id:20001 of https://codereview.chromium.org/1169853002/)
>
> Reason for revert:
> [Sheriff] fails messages:
> http://build.chromium.org/p/client.v8/builders/V8%20Linux64%20-%20custom%20snapshot%20-%20debug/builds/1703
>
> Original issue's description:
> > [es6] Parsing of new.target
> >
> > BUG=v8:3887
> > LOG=N
> > R=adamk@chromium.org, dslomov@chromium.org
> >
> > Committed: https://crrev.com/ae06bdde7763d673b39948b710df414217265cce
> > Cr-Commit-Position: refs/heads/master@{#28865}
>
> TBR=adamk@chromium.org,dslomov@chromium.org,arv@chromium.org
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=v8:3887
>
> Committed: https://crrev.com/fe97cfccf3faabbeff87b9b5fbacd7ceb8219304
> Cr-Commit-Position: refs/heads/master@{#28868}

TBR=adamk@chromium.org,dslomov@chromium.org,machenbach@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=v8:3887

Review URL: https://codereview.chromium.org/1168393008

Cr-Commit-Position: refs/heads/master@{#28870}
parent 2a3962d9
......@@ -1768,6 +1768,7 @@ EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_object)
EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_spread_arrays)
EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_sharedarraybuffer)
EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_atomics)
EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_new_target)
void Genesis::InstallNativeFunctions_harmony_proxies() {
......@@ -1801,6 +1802,7 @@ EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_destructuring)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_object)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_spread_arrays)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_atomics)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_new_target)
void Genesis::InitializeGlobal_harmony_regexps() {
Handle<JSObject> builtins(native_context()->builtins());
......@@ -2447,6 +2449,7 @@ bool Genesis::InstallExperimentalNatives() {
"native harmony-sharedarraybuffer.js", NULL};
static const char* harmony_atomics_natives[] = {"native harmony-atomics.js",
nullptr};
static const char* harmony_new_target_natives[] = {nullptr};
for (int i = ExperimentalNatives::GetDebuggerCount();
i < ExperimentalNatives::GetBuiltinsCount(); i++) {
......
......@@ -192,7 +192,8 @@ DEFINE_IMPLICATION(es_staging, harmony)
V(harmony_reflect, "harmony Reflect API") \
V(harmony_destructuring, "harmony destructuring") \
V(harmony_sharedarraybuffer, "harmony sharedarraybuffer") \
V(harmony_atomics, "harmony atomics")
V(harmony_atomics, "harmony atomics") \
V(harmony_new_target, "harmony new.target")
// Features that are complete (but still behind --harmony/es-staging flag).
#define HARMONY_STAGED(V) \
......
......@@ -400,6 +400,7 @@ class CallSite {
T(UnexpectedReserved, "Unexpected reserved word") \
T(UnexpectedStrictReserved, "Unexpected strict mode reserved word") \
T(UnexpectedSuper, "'super' keyword unexpected here") \
T(UnexpectedNewTarget, "new.target expression is not allowed here") \
T(UnexpectedTemplateString, "Unexpected template string") \
T(UnexpectedToken, "Unexpected token %") \
T(UnexpectedTokenIdentifier, "Unexpected identifier") \
......
......@@ -754,6 +754,7 @@ Expression* ParserTraits::ThisExpression(Scope* scope, AstNodeFactory* factory,
Variable::THIS, pos, pos + 4);
}
Expression* ParserTraits::SuperPropertyReference(Scope* scope,
AstNodeFactory* factory,
int pos) {
......@@ -784,6 +785,16 @@ Expression* ParserTraits::SuperCallReference(Scope* scope,
}
Expression* ParserTraits::NewTargetExpression(Scope* scope,
AstNodeFactory* factory,
int pos) {
static const int kNewTargetStringLength = 10;
return scope->NewUnresolved(
factory, parser_->ast_value_factory()->new_target_string(),
Variable::NORMAL, pos, pos + kNewTargetStringLength);
}
Expression* ParserTraits::DefaultConstructor(bool call_super, Scope* scope,
int pos, int end_pos) {
return parser_->DefaultConstructor(call_super, scope, pos, end_pos);
......@@ -908,6 +919,7 @@ Parser::Parser(ParseInfo* info)
set_allow_harmony_spreadcalls(FLAG_harmony_spreadcalls);
set_allow_harmony_destructuring(FLAG_harmony_destructuring);
set_allow_harmony_spread_arrays(FLAG_harmony_spread_arrays);
set_allow_harmony_new_target(FLAG_harmony_new_target);
set_allow_strong_mode(FLAG_strong_mode);
for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
++feature) {
......@@ -4277,26 +4289,22 @@ PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser(
reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(),
NULL, stack_limit_);
reusable_preparser_->set_allow_lazy(true);
reusable_preparser_->set_allow_natives(allow_natives());
reusable_preparser_->set_allow_harmony_modules(allow_harmony_modules());
reusable_preparser_->set_allow_harmony_arrow_functions(
allow_harmony_arrow_functions());
reusable_preparser_->set_allow_harmony_classes(allow_harmony_classes());
reusable_preparser_->set_allow_harmony_object_literals(
allow_harmony_object_literals());
reusable_preparser_->set_allow_harmony_sloppy(allow_harmony_sloppy());
reusable_preparser_->set_allow_harmony_unicode(allow_harmony_unicode());
reusable_preparser_->set_allow_harmony_computed_property_names(
allow_harmony_computed_property_names());
reusable_preparser_->set_allow_harmony_rest_params(
allow_harmony_rest_params());
reusable_preparser_->set_allow_harmony_spreadcalls(
allow_harmony_spreadcalls());
reusable_preparser_->set_allow_harmony_destructuring(
allow_harmony_destructuring());
reusable_preparser_->set_allow_harmony_spread_arrays(
allow_harmony_spread_arrays());
reusable_preparser_->set_allow_strong_mode(allow_strong_mode());
#define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name());
SET_ALLOW(natives);
SET_ALLOW(harmony_modules);
SET_ALLOW(harmony_arrow_functions);
SET_ALLOW(harmony_classes);
SET_ALLOW(harmony_object_literals);
SET_ALLOW(harmony_sloppy);
SET_ALLOW(harmony_unicode);
SET_ALLOW(harmony_computed_property_names);
SET_ALLOW(harmony_rest_params);
SET_ALLOW(harmony_spreadcalls);
SET_ALLOW(harmony_destructuring);
SET_ALLOW(harmony_spread_arrays);
SET_ALLOW(harmony_new_target);
SET_ALLOW(strong_mode);
#undef SET_ALLOW
}
PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction(
language_mode(), function_state_->kind(), logger, bookmark);
......
......@@ -730,6 +730,8 @@ class ParserTraits {
int pos);
Expression* SuperCallReference(Scope* scope, AstNodeFactory* factory,
int pos);
Expression* NewTargetExpression(Scope* scope, AstNodeFactory* factory,
int pos);
Expression* DefaultConstructor(bool call_super, Scope* scope, int pos,
int end_pos);
Literal* ExpressionFromLiteral(Token::Value token, int pos, Scanner* scanner,
......
......@@ -110,7 +110,8 @@ PreParser::PreParseResult PreParser::PreParseLazyFunction(
FunctionState top_state(&function_state_, &scope_, top_scope, kNormalFunction,
&top_factory);
scope_->SetLanguageMode(language_mode);
Scope* function_scope = NewScope(scope_, FUNCTION_SCOPE, kind);
Scope* function_scope = NewScope(
scope_, IsArrowFunction(kind) ? ARROW_SCOPE : FUNCTION_SCOPE, kind);
PreParserFactory function_factory(NULL);
FunctionState function_state(&function_state_, &scope_, function_scope, kind,
&function_factory);
......
......@@ -97,76 +97,36 @@ class ParserBase : public Traits {
allow_harmony_computed_property_names_(false),
allow_harmony_rest_params_(false),
allow_harmony_spreadcalls_(false),
allow_harmony_destructuring_(false),
allow_harmony_spread_arrays_(false),
allow_harmony_new_target_(false),
allow_strong_mode_(false) {}
// Getters that indicate whether certain syntactical constructs are
// allowed to be parsed by this instance of the parser.
bool allow_lazy() const { return allow_lazy_; }
bool allow_natives() const { return allow_natives_; }
bool allow_harmony_arrow_functions() const {
return allow_harmony_arrow_functions_;
}
#define ALLOW_ACCESSORS(name) \
bool allow_##name() const { return allow_##name##_; } \
void set_allow_##name(bool allow) { allow_##name##_ = allow; }
ALLOW_ACCESSORS(lazy);
ALLOW_ACCESSORS(natives);
ALLOW_ACCESSORS(harmony_arrow_functions);
ALLOW_ACCESSORS(harmony_object_literals);
ALLOW_ACCESSORS(harmony_sloppy);
ALLOW_ACCESSORS(harmony_computed_property_names);
ALLOW_ACCESSORS(harmony_rest_params);
ALLOW_ACCESSORS(harmony_spreadcalls);
ALLOW_ACCESSORS(harmony_destructuring);
ALLOW_ACCESSORS(harmony_spread_arrays);
ALLOW_ACCESSORS(harmony_new_target);
ALLOW_ACCESSORS(strong_mode);
#undef ALLOW_ACCESSORS
bool allow_harmony_modules() const { return scanner()->HarmonyModules(); }
bool allow_harmony_classes() const { return scanner()->HarmonyClasses(); }
bool allow_harmony_object_literals() const {
return allow_harmony_object_literals_;
}
bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; }
bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); }
bool allow_harmony_computed_property_names() const {
return allow_harmony_computed_property_names_;
}
bool allow_harmony_rest_params() const {
return allow_harmony_rest_params_;
}
bool allow_harmony_spreadcalls() const { return allow_harmony_spreadcalls_; }
bool allow_harmony_destructuring() const {
return allow_harmony_destructuring_;
}
bool allow_harmony_spread_arrays() const {
return allow_harmony_spread_arrays_;
}
bool allow_strong_mode() const { return allow_strong_mode_; }
// Setters that determine whether certain syntactical constructs are
// allowed to be parsed by this instance of the parser.
void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
void set_allow_natives(bool allow) { allow_natives_ = allow; }
void set_allow_harmony_arrow_functions(bool allow) {
allow_harmony_arrow_functions_ = allow;
}
void set_allow_harmony_modules(bool allow) {
scanner()->SetHarmonyModules(allow);
}
void set_allow_harmony_classes(bool allow) {
scanner()->SetHarmonyClasses(allow);
}
void set_allow_harmony_object_literals(bool allow) {
allow_harmony_object_literals_ = allow;
}
void set_allow_harmony_sloppy(bool allow) {
allow_harmony_sloppy_ = allow;
}
void set_allow_harmony_unicode(bool allow) {
scanner()->SetHarmonyUnicode(allow);
}
void set_allow_harmony_computed_property_names(bool allow) {
allow_harmony_computed_property_names_ = allow;
}
void set_allow_harmony_rest_params(bool allow) {
allow_harmony_rest_params_ = allow;
}
void set_allow_harmony_spreadcalls(bool allow) {
allow_harmony_spreadcalls_ = allow;
}
void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; }
void set_allow_harmony_destructuring(bool allow) {
allow_harmony_destructuring_ = allow;
}
void set_allow_harmony_spread_arrays(bool allow) {
allow_harmony_spread_arrays_ = allow;
}
void set_allow_harmony_modules(bool a) { scanner()->SetHarmonyModules(a); }
void set_allow_harmony_classes(bool a) { scanner()->SetHarmonyClasses(a); }
void set_allow_harmony_unicode(bool a) { scanner()->SetHarmonyUnicode(a); }
protected:
enum AllowRestrictedIdentifiers {
......@@ -340,7 +300,7 @@ class ParserBase : public Traits {
Scope* NewScope(Scope* parent, ScopeType scope_type, FunctionKind kind) {
DCHECK(ast_value_factory());
DCHECK(scope_type != MODULE_SCOPE || allow_harmony_modules());
DCHECK(scope_type != ARROW_SCOPE || IsArrowFunction(kind));
DCHECK(!IsArrowFunction(kind) || scope_type == ARROW_SCOPE);
Scope* result = new (zone())
Scope(zone(), parent, scope_type, ast_value_factory(), kind);
result->Initialize();
......@@ -903,6 +863,7 @@ class ParserBase : public Traits {
void AddTemplateExpression(ExpressionT);
ExpressionT ParseSuperExpression(bool is_new,
ExpressionClassifier* classifier, bool* ok);
ExpressionT ParseNewTargetExpression(bool* ok);
ExpressionT ParseStrongInitializationExpression(
ExpressionClassifier* classifier, bool* ok);
ExpressionT ParseStrongSuperCallExpression(ExpressionClassifier* classifier,
......@@ -1013,6 +974,7 @@ class ParserBase : public Traits {
bool allow_harmony_spreadcalls_;
bool allow_harmony_destructuring_;
bool allow_harmony_spread_arrays_;
bool allow_harmony_new_target_;
bool allow_strong_mode_;
};
......@@ -1722,6 +1684,12 @@ class PreParserTraits {
return PreParserExpression::Default();
}
static PreParserExpression NewTargetExpression(Scope* scope,
PreParserFactory* factory,
int pos) {
return PreParserExpression::Default();
}
static PreParserExpression DefaultConstructor(bool call_super, Scope* scope,
int pos, int end_pos) {
return PreParserExpression::Default();
......@@ -3319,6 +3287,9 @@ ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(
ExpressionClassifier* classifier, bool* ok) {
// NewExpression ::
// ('new')+ MemberExpression
//
// NewTarget ::
// 'new' '.' 'target'
// The grammar for new expressions is pretty warped. We can have several 'new'
// keywords following each other, and then a MemberExpression. When we see '('
......@@ -3342,6 +3313,8 @@ ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(
if (peek() == Token::SUPER) {
const bool is_new = true;
result = ParseSuperExpression(is_new, classifier, CHECK_OK);
} else if (allow_harmony_new_target() && peek() == Token::PERIOD) {
return ParseNewTargetExpression(CHECK_OK);
} else {
result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK);
}
......@@ -3565,7 +3538,6 @@ ParserBase<Traits>::ParseSuperExpression(bool is_new,
Expect(Token::SUPER, CHECK_OK);
Scope* scope = scope_->DeclarationScope();
while (scope->is_eval_scope() || scope->is_arrow_scope()) {
scope = scope->outer_scope();
DCHECK_NOT_NULL(scope);
......@@ -3602,6 +3574,31 @@ ParserBase<Traits>::ParseSuperExpression(bool is_new,
}
template <class Traits>
typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::ParseNewTargetExpression(bool* ok) {
int pos = position();
Consume(Token::PERIOD);
ExpectContextualKeyword(CStrVector("target"), CHECK_OK);
Scope* scope = scope_->DeclarationScope();
while (scope->is_eval_scope() || scope->is_arrow_scope()) {
scope = scope->outer_scope();
DCHECK_NOT_NULL(scope);
scope = scope->DeclarationScope();
}
if (!scope->is_function_scope()) {
ReportMessageAt(scanner()->location(),
MessageTemplate::kUnexpectedNewTarget);
*ok = false;
return this->EmptyExpression();
}
return this->NewTargetExpression(scope_, factory(), pos);
}
template <class Traits>
typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::ParseMemberExpressionContinuation(
......
......@@ -1386,6 +1386,7 @@ enum ParserFlag {
kAllowHarmonySpreadCalls,
kAllowHarmonyDestructuring,
kAllowHarmonySpreadArrays,
kAllowHarmonyNewTarget,
kAllowStrongMode
};
......@@ -1419,6 +1420,7 @@ void SetParserFlags(i::ParserBase<Traits>* parser,
flags.Contains(kAllowHarmonyDestructuring));
parser->set_allow_harmony_spread_arrays(
flags.Contains(kAllowHarmonySpreadArrays));
parser->set_allow_harmony_new_target(flags.Contains(kAllowHarmonyNewTarget));
parser->set_allow_strong_mode(flags.Contains(kAllowStrongMode));
}
......@@ -6615,3 +6617,58 @@ TEST(SpreadArrayError) {
RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags,
arraysize(always_flags));
}
TEST(NewTarget) {
// clang-format off
const char* good_context_data[][2] = {
{"function f() {", "}"},
{"'use strict'; function f() {", "}"},
{"var f = function() {", "}"},
{"'use strict'; var f = function() {", "}"},
{"({m: function() {", "}})"},
{"'use strict'; ({m: function() {", "}})"},
{"({m() {", "}})"},
{"'use strict'; ({m() {", "}})"},
{"({get x() {", "}})"},
{"'use strict'; ({get x() {", "}})"},
{"({set x(_) {", "}})"},
{"'use strict'; ({set x(_) {", "}})"},
{"class C {m() {", "}}"},
{"class C {get x() {", "}}"},
{"class C {set x(_) {", "}}"},
{NULL}
};
const char* bad_context_data[][2] = {
{"", ""},
{"'use strict';", ""},
{NULL}
};
const char* data[] = {
"new.target",
"{ new.target }",
"() => { new.target }",
"() => new.target",
"if (1) { new.target }",
"if (1) {} else { new.target }",
"while (0) { new.target }",
"do { new.target } while (0)",
NULL
};
static const ParserFlag always_flags[] = {
kAllowHarmonyArrowFunctions,
kAllowHarmonyClasses,
kAllowHarmonyNewTarget,
kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy,
};
// clang-format on
RunParserSyncTest(good_context_data, data, kSuccess, NULL, 0, always_flags,
arraysize(always_flags));
RunParserSyncTest(bad_context_data, data, kError, NULL, 0, always_flags,
arraysize(always_flags));
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment