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}
This commit is contained in:
parent
2a3962d9d2
commit
b1c7340275
@ -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);
|
||||
|
129
src/preparser.h
129
src/preparser.h
@ -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));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user