Upgrade V8 to 5.1.281.57 DO NOT MERGE
FPIIM-449
Change-Id: Id981b686b4d587ac31697662eb98bb34be42ad90
(cherry picked from commit 3b9bc31999c9787eb726ecdbfd5796bfdec32a18)
diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h
index 6be19b3..dde6b1d 100644
--- a/src/parsing/parser-base.h
+++ b/src/parsing/parser-base.h
@@ -24,6 +24,10 @@
kFunctionNameValidityUnknown
};
+enum AllowLabelledFunctionStatement {
+ kAllowLabelledFunctionStatement,
+ kDisallowLabelledFunctionStatement,
+};
struct FormalParametersBase {
explicit FormalParametersBase(Scope* scope) : scope(scope) {}
@@ -108,14 +112,11 @@
stack_overflow_(false),
allow_lazy_(false),
allow_natives_(false),
+ allow_tailcalls_(false),
allow_harmony_sloppy_(false),
allow_harmony_sloppy_function_(false),
allow_harmony_sloppy_let_(false),
- allow_harmony_default_parameters_(false),
- allow_harmony_destructuring_bind_(false),
- allow_harmony_destructuring_assignment_(false),
- allow_strong_mode_(false),
- allow_legacy_const_(true),
+ allow_harmony_restrictive_declarations_(false),
allow_harmony_do_expressions_(false),
allow_harmony_function_name_(false),
allow_harmony_function_sent_(false) {}
@@ -124,19 +125,25 @@
bool allow_##name() const { return allow_##name##_; } \
void set_allow_##name(bool allow) { allow_##name##_ = allow; }
+#define SCANNER_ACCESSORS(name) \
+ bool allow_##name() const { return scanner_->allow_##name(); } \
+ void set_allow_##name(bool allow) { \
+ return scanner_->set_allow_##name(allow); \
+ }
+
ALLOW_ACCESSORS(lazy);
ALLOW_ACCESSORS(natives);
+ ALLOW_ACCESSORS(tailcalls);
ALLOW_ACCESSORS(harmony_sloppy);
ALLOW_ACCESSORS(harmony_sloppy_function);
ALLOW_ACCESSORS(harmony_sloppy_let);
- ALLOW_ACCESSORS(harmony_default_parameters);
- ALLOW_ACCESSORS(harmony_destructuring_bind);
- ALLOW_ACCESSORS(harmony_destructuring_assignment);
- ALLOW_ACCESSORS(strong_mode);
- ALLOW_ACCESSORS(legacy_const);
+ ALLOW_ACCESSORS(harmony_restrictive_declarations);
ALLOW_ACCESSORS(harmony_do_expressions);
ALLOW_ACCESSORS(harmony_function_name);
ALLOW_ACCESSORS(harmony_function_sent);
+ SCANNER_ACCESSORS(harmony_exponentiation_operator);
+
+#undef SCANNER_ACCESSORS
#undef ALLOW_ACCESSORS
uintptr_t stack_limit() const { return stack_limit_; }
@@ -368,7 +375,6 @@
Scope* NewScope(Scope* parent, ScopeType scope_type, FunctionKind kind) {
DCHECK(ast_value_factory());
- DCHECK(scope_type != MODULE_SCOPE || FLAG_harmony_modules);
Scope* result = new (zone())
Scope(zone(), parent, scope_type, ast_value_factory(), kind);
result->Initialize();
@@ -481,12 +487,7 @@
bool CheckInOrOf(ForEachStatement::VisitMode* visit_mode, bool* ok) {
if (Check(Token::IN)) {
- if (is_strong(language_mode())) {
- ReportMessageAt(scanner()->location(), MessageTemplate::kStrongForIn);
- *ok = false;
- } else {
- *visit_mode = ForEachStatement::ENUMERATE;
- }
+ *visit_mode = ForEachStatement::ENUMERATE;
return true;
} else if (CheckContextualKeyword(CStrVector("of"))) {
*visit_mode = ForEachStatement::ITERATE;
@@ -547,12 +548,6 @@
*ok = false;
return;
}
- if (is_strong(language_mode) && this->IsUndefined(function_name)) {
- Traits::ReportMessageAt(function_name_loc,
- MessageTemplate::kStrongUndefined);
- *ok = false;
- return;
- }
}
// Determine precedence of given token.
@@ -570,8 +565,7 @@
bool is_generator() const { return function_state_->is_generator(); }
bool allow_const() {
- return is_strict(language_mode()) || allow_harmony_sloppy() ||
- allow_legacy_const();
+ return is_strict(language_mode()) || allow_harmony_sloppy();
}
bool allow_let() {
@@ -593,7 +587,8 @@
}
void GetUnexpectedTokenMessage(
- Token::Value token, MessageTemplate::Template* message, const char** arg,
+ Token::Value token, MessageTemplate::Template* message,
+ Scanner::Location* location, const char** arg,
MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken);
void ReportUnexpectedToken(Token::Value token);
@@ -657,10 +652,6 @@
!classifier->is_valid_strict_mode_formal_parameters()) {
ReportClassifierError(classifier->strict_mode_formal_parameter_error());
*ok = false;
- } else if (is_strong(language_mode) &&
- !classifier->is_valid_strong_mode_formal_parameters()) {
- ReportClassifierError(classifier->strong_mode_formal_parameter_error());
- *ok = false;
}
}
@@ -698,33 +689,25 @@
void ExpressionUnexpectedToken(ExpressionClassifier* classifier) {
MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
const char* arg;
- GetUnexpectedTokenMessage(peek(), &message, &arg);
- classifier->RecordExpressionError(scanner()->peek_location(), message, arg);
+ Scanner::Location location = scanner()->peek_location();
+ GetUnexpectedTokenMessage(peek(), &message, &location, &arg);
+ classifier->RecordExpressionError(location, message, arg);
}
void BindingPatternUnexpectedToken(ExpressionClassifier* classifier) {
MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
const char* arg;
- GetUnexpectedTokenMessage(peek(), &message, &arg);
- classifier->RecordBindingPatternError(scanner()->peek_location(), message,
- arg);
+ Scanner::Location location = scanner()->peek_location();
+ GetUnexpectedTokenMessage(peek(), &message, &location, &arg);
+ classifier->RecordBindingPatternError(location, message, arg);
}
void ArrowFormalParametersUnexpectedToken(ExpressionClassifier* classifier) {
MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
const char* arg;
- GetUnexpectedTokenMessage(peek(), &message, &arg);
- classifier->RecordArrowFormalParametersError(scanner()->peek_location(),
- message, arg);
- }
-
- void FormalParameterInitializerUnexpectedToken(
- ExpressionClassifier* classifier) {
- MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
- const char* arg;
- GetUnexpectedTokenMessage(peek(), &message, &arg);
- classifier->RecordFormalParameterInitializerError(
- scanner()->peek_location(), message, arg);
+ Scanner::Location location = scanner()->peek_location();
+ GetUnexpectedTokenMessage(peek(), &message, &location, &arg);
+ classifier->RecordArrowFormalParametersError(location, message, arg);
}
// Recursive descent functions:
@@ -804,10 +787,6 @@
ExpressionT ParseSuperExpression(bool is_new,
ExpressionClassifier* classifier, bool* ok);
ExpressionT ParseNewTargetExpression(bool* ok);
- ExpressionT ParseStrongInitializationExpression(
- ExpressionClassifier* classifier, bool* ok);
- ExpressionT ParseStrongSuperCallExpression(ExpressionClassifier* classifier,
- bool* ok);
void ParseFormalParameter(FormalParametersT* parameters,
ExpressionClassifier* classifier, bool* ok);
@@ -825,10 +804,6 @@
ExpressionT CheckAndRewriteReferenceExpression(
ExpressionT expression, int beg_pos, int end_pos,
MessageTemplate::Template message, bool* ok);
- ExpressionT ClassifyAndRewriteReferenceExpression(
- ExpressionClassifier* classifier, ExpressionT expression, int beg_pos,
- int end_pos, MessageTemplate::Template message,
- ParseErrorType type = kSyntaxError);
ExpressionT CheckAndRewriteReferenceExpression(
ExpressionT expression, int beg_pos, int end_pos,
MessageTemplate::Template message, ParseErrorType type, bool* ok);
@@ -841,10 +816,6 @@
Traits::IsEvalOrArguments(Traits::AsIdentifier(expression))) {
return false;
}
- if (is_strong(language_mode()) &&
- Traits::IsUndefined(Traits::AsIdentifier(expression))) {
- return false;
- }
return true;
}
@@ -858,8 +829,12 @@
void CheckPossibleEvalCall(ExpressionT expression, Scope* scope) {
if (Traits::IsIdentifier(expression) &&
Traits::IsEval(Traits::AsIdentifier(expression))) {
- scope->DeclarationScope()->RecordEvalCall();
scope->RecordEvalCall();
+ if (is_sloppy(scope->language_mode())) {
+ // For sloppy scopes we also have to record the call at function level,
+ // in case it includes declarations that will be hoisted.
+ scope->DeclarationScope()->RecordEvalCall();
+ }
}
}
@@ -945,14 +920,11 @@
bool allow_lazy_;
bool allow_natives_;
+ bool allow_tailcalls_;
bool allow_harmony_sloppy_;
bool allow_harmony_sloppy_function_;
bool allow_harmony_sloppy_let_;
- bool allow_harmony_default_parameters_;
- bool allow_harmony_destructuring_bind_;
- bool allow_harmony_destructuring_assignment_;
- bool allow_strong_mode_;
- bool allow_legacy_const_;
+ bool allow_harmony_restrictive_declarations_;
bool allow_harmony_do_expressions_;
bool allow_harmony_function_name_;
bool allow_harmony_function_sent_;
@@ -987,32 +959,28 @@
*function_state_stack_ = outer_function_state_;
}
-
template <class Traits>
void ParserBase<Traits>::GetUnexpectedTokenMessage(
- Token::Value token, MessageTemplate::Template* message, const char** arg,
+ Token::Value token, MessageTemplate::Template* message,
+ Scanner::Location* location, const char** arg,
MessageTemplate::Template default_) {
+ *arg = nullptr;
switch (token) {
case Token::EOS:
*message = MessageTemplate::kUnexpectedEOS;
- *arg = nullptr;
break;
case Token::SMI:
case Token::NUMBER:
*message = MessageTemplate::kUnexpectedTokenNumber;
- *arg = nullptr;
break;
case Token::STRING:
*message = MessageTemplate::kUnexpectedTokenString;
- *arg = nullptr;
break;
case Token::IDENTIFIER:
*message = MessageTemplate::kUnexpectedTokenIdentifier;
- *arg = nullptr;
break;
case Token::FUTURE_RESERVED_WORD:
*message = MessageTemplate::kUnexpectedReserved;
- *arg = nullptr;
break;
case Token::LET:
case Token::STATIC:
@@ -1021,17 +989,22 @@
*message = is_strict(language_mode())
? MessageTemplate::kUnexpectedStrictReserved
: MessageTemplate::kUnexpectedTokenIdentifier;
- *arg = nullptr;
break;
case Token::TEMPLATE_SPAN:
case Token::TEMPLATE_TAIL:
*message = MessageTemplate::kUnexpectedTemplateString;
- *arg = nullptr;
break;
case Token::ESCAPED_STRICT_RESERVED_WORD:
case Token::ESCAPED_KEYWORD:
*message = MessageTemplate::kInvalidEscapedReservedWord;
- *arg = nullptr;
+ break;
+ case Token::ILLEGAL:
+ if (scanner()->has_error()) {
+ *message = scanner()->error();
+ *location = scanner()->error_location();
+ } else {
+ *message = MessageTemplate::kInvalidOrUnexpectedToken;
+ }
break;
default:
const char* name = Token::String(token);
@@ -1053,7 +1026,7 @@
Scanner::Location source_location, Token::Value token,
MessageTemplate::Template message) {
const char* arg;
- GetUnexpectedTokenMessage(token, &message, &arg);
+ GetUnexpectedTokenMessage(token, &message, &source_location, &arg);
Traits::ReportMessageAt(source_location, message, arg);
}
@@ -1105,19 +1078,6 @@
classifier->RecordBindingPatternError(
scanner()->location(), MessageTemplate::kStrictEvalArguments);
}
- if (is_strong(language_mode())) {
- classifier->RecordExpressionError(scanner()->location(),
- MessageTemplate::kStrongArguments);
- }
- }
- if (this->IsUndefined(name)) {
- classifier->RecordStrongModeFormalParameterError(
- scanner()->location(), MessageTemplate::kStrongUndefined);
- if (is_strong(language_mode())) {
- // TODO(dslomov): allow 'undefined' in nested patterns.
- classifier->RecordPatternError(scanner()->location(),
- MessageTemplate::kStrongUndefined);
- }
}
if (classifier->duplicate_finder() != nullptr &&
@@ -1218,8 +1178,7 @@
}
int js_flags = flags.FromJust();
Next();
- return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index,
- is_strong(language_mode()), pos);
+ return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos);
}
@@ -1262,15 +1221,6 @@
case Token::THIS: {
BindingPatternUnexpectedToken(classifier);
Consume(Token::THIS);
- if (FLAG_strong_this && is_strong(language_mode())) {
- // Constructors' usages of 'this' in strong mode are parsed separately.
- // TODO(rossberg): this does not work with arrow functions yet.
- if (IsClassConstructor(function_state_->kind())) {
- ReportMessage(MessageTemplate::kStrongConstructorThis);
- *ok = false;
- return this->EmptyExpression();
- }
- }
return this->ThisExpression(scope_, factory(), beg_pos);
}
@@ -1313,15 +1263,9 @@
return this->ParseRegExpLiteral(false, classifier, ok);
case Token::LBRACK:
- if (!allow_harmony_destructuring_bind()) {
- BindingPatternUnexpectedToken(classifier);
- }
return this->ParseArrayLiteral(classifier, ok);
case Token::LBRACE:
- if (!allow_harmony_destructuring_bind()) {
- BindingPatternUnexpectedToken(classifier);
- }
return this->ParseObjectLiteral(classifier, ok);
case Token::LPAREN: {
@@ -1394,7 +1338,7 @@
CHECK_OK);
class_name_location = scanner()->location();
}
- return this->ParseClassLiteral(name, class_name_location,
+ return this->ParseClassLiteral(classifier, name, class_name_location,
is_strict_reserved_name,
class_token_position, ok);
}
@@ -1510,12 +1454,6 @@
while (peek() != Token::RBRACK) {
ExpressionT elem = this->EmptyExpression();
if (peek() == Token::COMMA) {
- if (is_strong(language_mode())) {
- ReportMessageAt(scanner()->peek_location(),
- MessageTemplate::kStrongEllision);
- *ok = false;
- return this->EmptyExpression();
- }
elem = this->GetLiteralTheHole(peek_position(), factory());
} else if (peek() == Token::ELLIPSIS) {
int start_pos = peek_position();
@@ -1559,9 +1497,8 @@
// Update the scope information before the pre-parsing bailout.
int literal_index = function_state_->NextMaterializedLiteralIndex();
- ExpressionT result =
- factory()->NewArrayLiteral(values, first_spread_index, literal_index,
- is_strong(language_mode()), pos);
+ ExpressionT result = factory()->NewArrayLiteral(values, first_spread_index,
+ literal_index, pos);
if (first_spread_index >= 0) {
result = factory()->NewRewritableExpression(result);
Traits::QueueNonPatternForRewriting(result);
@@ -1823,7 +1760,6 @@
typename Traits::Type::PropertyList properties =
this->NewPropertyList(4, zone_);
int number_of_boilerplate_properties = 0;
- bool has_function = false;
bool has_computed_names = false;
ObjectLiteralChecker checker(this);
@@ -1845,12 +1781,6 @@
has_computed_names = true;
}
- // Mark top-level object literals that contain function literals and
- // pretenure the literal so it can be added as a constant function
- // property. (Parser only.)
- this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property,
- &has_function);
-
// Count CONSTANT or COMPUTED properties to maintain the enumeration order.
if (!has_computed_names && this->IsBoilerplateProperty(property)) {
number_of_boilerplate_properties++;
@@ -1876,8 +1806,6 @@
return factory()->NewObjectLiteral(properties,
literal_index,
number_of_boilerplate_properties,
- has_function,
- is_strong(language_mode()),
pos);
}
@@ -1984,6 +1912,13 @@
Token::String(Token::ARROW));
ValidateArrowFormalParameters(&arrow_formals_classifier, expression,
parenthesized_formals, CHECK_OK);
+ // This reads strangely, but is correct: it checks whether any
+ // sub-expression of the parameter list failed to be a valid formal
+ // parameter initializer. Since YieldExpressions are banned anywhere
+ // in an arrow parameter list, this is correct.
+ // TODO(adamk): Rename "FormalParameterInitializerError" to refer to
+ // "YieldExpression", which is its only use.
+ ValidateFormalParameterInitializer(&arrow_formals_classifier, ok);
Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos);
Scope* scope =
this->NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction);
@@ -2039,23 +1974,10 @@
// Now pending non-pattern expressions must be discarded.
arrow_formals_classifier.Discard();
- if (!(allow_harmony_destructuring_bind() ||
- allow_harmony_default_parameters())) {
- BindingPatternUnexpectedToken(classifier);
- }
-
- if (allow_harmony_destructuring_assignment() && IsValidPattern(expression) &&
- peek() == Token::ASSIGN) {
+ if (IsValidPattern(expression) && peek() == Token::ASSIGN) {
classifier->ForgiveCoverInitializedNameError();
ValidateAssignmentPattern(classifier, CHECK_OK);
is_destructuring_assignment = true;
- } else if (allow_harmony_default_parameters() &&
- !allow_harmony_destructuring_assignment()) {
- // TODO(adamk): This branch should be removed once the destructuring
- // assignment and default parameter flags are removed.
- expression = this->ClassifyAndRewriteReferenceExpression(
- classifier, expression, lhs_beg_pos, scanner()->location().end_pos,
- MessageTemplate::kInvalidLhsInAssignment);
} else {
expression = this->CheckAndRewriteReferenceExpression(
expression, lhs_beg_pos, scanner()->location().end_pos,
@@ -2108,6 +2030,11 @@
Traits::SetFunctionNameFromIdentifierRef(right, expression);
}
+ if (op == Token::ASSIGN_EXP) {
+ DCHECK(!is_destructuring_assignment);
+ return Traits::RewriteAssignExponentiation(expression, right, pos);
+ }
+
ExpressionT result = factory()->NewAssignment(op, expression, right, pos);
if (is_destructuring_assignment) {
@@ -2127,14 +2054,15 @@
int pos = peek_position();
classifier->RecordPatternError(scanner()->peek_location(),
MessageTemplate::kInvalidDestructuringTarget);
- FormalParameterInitializerUnexpectedToken(classifier);
+ classifier->RecordFormalParameterInitializerError(
+ scanner()->peek_location(), MessageTemplate::kYieldInParameter);
Expect(Token::YIELD, CHECK_OK);
ExpressionT generator_object =
factory()->NewVariableProxy(function_state_->generator_object_variable());
ExpressionT expression = Traits::EmptyExpression();
- Yield::Kind kind = Yield::kSuspend;
+ bool delegating = false; // yield*
if (!scanner()->HasAnyLineTerminatorBeforeNext()) {
- if (Check(Token::MUL)) kind = Yield::kDelegating;
+ if (Check(Token::MUL)) delegating = true;
switch (peek()) {
case Token::EOS:
case Token::SEMICOLON:
@@ -2146,10 +2074,8 @@
// The above set of tokens is the complete set of tokens that can appear
// after an AssignmentExpression, and none of them can start an
// AssignmentExpression. This allows us to avoid looking for an RHS for
- // a Yield::kSuspend operation, given only one look-ahead token.
- if (kind == Yield::kSuspend)
- break;
- DCHECK_EQ(Yield::kDelegating, kind);
+ // a regular yield, given only one look-ahead token.
+ if (!delegating) break;
// Delegating yields require an RHS; fall through.
default:
expression = ParseAssignmentExpression(false, classifier, CHECK_OK);
@@ -2157,13 +2083,16 @@
break;
}
}
- if (kind == Yield::kDelegating) {
+
+ if (delegating) {
return Traits::RewriteYieldStar(generator_object, expression, pos);
}
+
+ expression = Traits::BuildIteratorResult(expression, false);
// Hackily disambiguate o from o.next and o [Symbol.iterator]().
// TODO(verwaest): Come up with a better solution.
typename Traits::Type::YieldExpression yield =
- factory()->NewYield(generator_object, expression, kind, pos);
+ factory()->NewYield(generator_object, expression, pos);
return yield;
}
@@ -2215,10 +2144,12 @@
BindingPatternUnexpectedToken(classifier);
ArrowFormalParametersUnexpectedToken(classifier);
Token::Value op = Next();
- Scanner::Location op_location = scanner()->location();
int pos = position();
+
+ const bool is_right_associative = op == Token::EXP;
+ const int next_prec = is_right_associative ? prec1 : prec1 + 1;
ExpressionT y =
- ParseBinaryExpression(prec1 + 1, accept_IN, classifier, CHECK_OK);
+ ParseBinaryExpression(next_prec, accept_IN, classifier, CHECK_OK);
Traits::RewriteNonPattern(classifier, CHECK_OK);
if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos,
@@ -2237,11 +2168,7 @@
case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
default: break;
}
- if (cmp == Token::EQ && is_strong(language_mode())) {
- ReportMessageAt(op_location, MessageTemplate::kStrongEqual);
- *ok = false;
- return this->EmptyExpression();
- } else if (FLAG_harmony_instanceof && cmp == Token::INSTANCEOF) {
+ if (FLAG_harmony_instanceof && cmp == Token::INSTANCEOF) {
x = Traits::RewriteInstanceof(x, y, pos);
} else {
x = factory()->NewCompareOperation(cmp, x, y, pos);
@@ -2250,6 +2177,9 @@
x = factory()->NewUnaryOperation(Token::NOT, x, pos);
}
}
+
+ } else if (op == Token::EXP) {
+ x = Traits::RewriteExponentiation(x, y, pos);
} else {
// We have a "normal" binary operation.
x = factory()->NewBinaryOperation(op, x, y, pos);
@@ -2287,11 +2217,7 @@
Traits::RewriteNonPattern(classifier, CHECK_OK);
if (op == Token::DELETE && is_strict(language_mode())) {
- if (is_strong(language_mode())) {
- ReportMessage(MessageTemplate::kStrongDelete);
- *ok = false;
- return this->EmptyExpression();
- } else if (this->IsIdentifier(expression)) {
+ if (this->IsIdentifier(expression)) {
// "delete identifier" is a syntax error in strict mode.
ReportMessage(MessageTemplate::kStrictDelete);
*ok = false;
@@ -2299,6 +2225,12 @@
}
}
+ if (peek() == Token::EXP) {
+ ReportUnexpectedToken(Next());
+ *ok = false;
+ return this->EmptyExpression();
+ }
+
// Allow Traits do rewrite the expression.
return this->BuildUnaryExpression(expression, op, pos, factory());
} else if (Token::IsCountOp(op)) {
@@ -2386,12 +2318,6 @@
BindingPatternUnexpectedToken(classifier);
ArrowFormalParametersUnexpectedToken(classifier);
- if (is_strong(language_mode()) && this->IsIdentifier(result) &&
- this->IsEval(this->AsIdentifier(result))) {
- ReportMessage(MessageTemplate::kStrongDirectEval);
- *ok = false;
- return this->EmptyExpression();
- }
int pos;
if (scanner()->current_token() == Token::IDENTIFIER ||
scanner()->current_token() == Token::SUPER) {
@@ -2609,148 +2535,6 @@
template <class Traits>
typename ParserBase<Traits>::ExpressionT
-ParserBase<Traits>::ParseStrongInitializationExpression(
- ExpressionClassifier* classifier, bool* ok) {
- // InitializationExpression :: (strong mode)
- // 'this' '.' IdentifierName '=' AssignmentExpression
- // 'this' '[' Expression ']' '=' AssignmentExpression
-
- FuncNameInferrer::State fni_state(fni_);
-
- Consume(Token::THIS);
- int pos = position();
- function_state_->set_this_location(scanner()->location());
- ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos);
-
- ExpressionT left = this->EmptyExpression();
- switch (peek()) {
- case Token::LBRACK: {
- Consume(Token::LBRACK);
- int pos = position();
- ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK);
- Traits::RewriteNonPattern(classifier, CHECK_OK);
- left = factory()->NewProperty(this_expr, index, pos);
- if (fni_ != NULL) {
- this->PushPropertyName(fni_, index);
- }
- Expect(Token::RBRACK, CHECK_OK);
- break;
- }
- case Token::PERIOD: {
- Consume(Token::PERIOD);
- int pos = position();
- IdentifierT name = ParseIdentifierName(CHECK_OK);
- left = factory()->NewProperty(
- this_expr, factory()->NewStringLiteral(name, pos), pos);
- if (fni_ != NULL) {
- this->PushLiteralName(fni_, name);
- }
- break;
- }
- default:
- ReportMessage(MessageTemplate::kStrongConstructorThis);
- *ok = false;
- return this->EmptyExpression();
- }
-
- if (peek() != Token::ASSIGN) {
- ReportMessageAt(function_state_->this_location(),
- MessageTemplate::kStrongConstructorThis);
- *ok = false;
- return this->EmptyExpression();
- }
- Consume(Token::ASSIGN);
- left = this->MarkExpressionAsAssigned(left);
-
- ExpressionT right =
- this->ParseAssignmentExpression(true, classifier, CHECK_OK);
- Traits::RewriteNonPattern(classifier, CHECK_OK);
- this->CheckAssigningFunctionLiteralToProperty(left, right);
- function_state_->AddProperty();
- if (fni_ != NULL) {
- // Check if the right hand side is a call to avoid inferring a
- // name if we're dealing with "this.a = function(){...}();"-like
- // expression.
- if (!right->IsCall() && !right->IsCallNew()) {
- fni_->Infer();
- } else {
- fni_->RemoveLastFunction();
- }
- }
-
- if (function_state_->return_location().IsValid()) {
- ReportMessageAt(function_state_->return_location(),
- MessageTemplate::kStrongConstructorReturnMisplaced);
- *ok = false;
- return this->EmptyExpression();
- }
-
- return factory()->NewAssignment(Token::ASSIGN, left, right, pos);
-}
-
-
-template <class Traits>
-typename ParserBase<Traits>::ExpressionT
-ParserBase<Traits>::ParseStrongSuperCallExpression(
- ExpressionClassifier* classifier, bool* ok) {
- // SuperCallExpression :: (strong mode)
- // 'super' '(' ExpressionList ')'
- BindingPatternUnexpectedToken(classifier);
-
- Consume(Token::SUPER);
- int pos = position();
- Scanner::Location super_loc = scanner()->location();
- ExpressionT expr = this->SuperCallReference(scope_, factory(), pos);
-
- if (peek() != Token::LPAREN) {
- ReportMessage(MessageTemplate::kStrongConstructorSuper);
- *ok = false;
- return this->EmptyExpression();
- }
-
- Scanner::Location spread_pos;
- typename Traits::Type::ExpressionList args =
- ParseArguments(&spread_pos, classifier, CHECK_OK);
-
- // TODO(rossberg): This doesn't work with arrow functions yet.
- if (!IsSubclassConstructor(function_state_->kind())) {
- ReportMessage(MessageTemplate::kUnexpectedSuper);
- *ok = false;
- return this->EmptyExpression();
- } else if (function_state_->super_location().IsValid()) {
- ReportMessageAt(scanner()->location(),
- MessageTemplate::kStrongSuperCallDuplicate);
- *ok = false;
- return this->EmptyExpression();
- } else if (function_state_->this_location().IsValid()) {
- ReportMessageAt(scanner()->location(),
- MessageTemplate::kStrongSuperCallMisplaced);
- *ok = false;
- return this->EmptyExpression();
- } else if (function_state_->return_location().IsValid()) {
- ReportMessageAt(function_state_->return_location(),
- MessageTemplate::kStrongConstructorReturnMisplaced);
- *ok = false;
- return this->EmptyExpression();
- }
-
- function_state_->set_super_location(super_loc);
- if (spread_pos.IsValid()) {
- args = Traits::PrepareSpreadArguments(args);
- expr = Traits::SpreadCall(expr, args, pos);
- } else {
- expr = factory()->NewCall(expr, args, pos);
- }
-
- // Explicit calls to the super constructor using super() perform an implicit
- // binding assignment to the 'this' variable.
- ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos);
- return factory()->NewAssignment(Token::INIT, this_expr, expr, pos);
-}
-
-
-template <class Traits>
-typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::ParseSuperExpression(bool is_new,
ExpressionClassifier* classifier,
bool* ok) {
@@ -2768,13 +2552,6 @@
// new super() is never allowed.
// super() is only allowed in derived constructor
if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) {
- if (is_strong(language_mode())) {
- // Super calls in strong mode are parsed separately.
- ReportMessageAt(scanner()->location(),
- MessageTemplate::kStrongConstructorSuper);
- *ok = false;
- return this->EmptyExpression();
- }
// TODO(rossberg): This might not be the correct FunctionState for the
// method here.
function_state_->set_super_location(scanner()->location());
@@ -2878,6 +2655,11 @@
ParseTemplateLiteral(expression, pos, classifier, CHECK_OK);
break;
}
+ case Token::ILLEGAL: {
+ ReportUnexpectedTokenAt(scanner()->peek_location(), Token::ILLEGAL);
+ *ok = false;
+ return this->EmptyExpression();
+ }
default:
return expression;
}
@@ -2894,7 +2676,6 @@
// BindingElement[?Yield, ?GeneratorParameter]
bool is_rest = parameters->has_rest;
- Token::Value next = peek();
ExpressionT pattern = ParsePrimaryExpression(classifier, ok);
if (!*ok) return;
@@ -2902,11 +2683,6 @@
if (!*ok) return;
if (!Traits::IsIdentifier(pattern)) {
- if (!allow_harmony_destructuring_bind()) {
- ReportUnexpectedToken(next);
- *ok = false;
- return;
- }
parameters->is_simple = false;
ValidateFormalParameterInitializer(classifier, ok);
if (!*ok) return;
@@ -2914,7 +2690,7 @@
}
ExpressionT initializer = Traits::EmptyExpression();
- if (!is_rest && allow_harmony_default_parameters() && Check(Token::ASSIGN)) {
+ if (!is_rest && Check(Token::ASSIGN)) {
ExpressionClassifier init_classifier(this);
initializer = ParseAssignmentExpression(true, &init_classifier, ok);
if (!*ok) return;
@@ -3099,6 +2875,10 @@
body->Add(factory()->NewReturnStatement(expression, pos), zone());
materialized_literal_count = function_state.materialized_literal_count();
expected_property_count = function_state.expected_property_count();
+ // ES6 14.6.1 Static Semantics: IsInTailPosition
+ if (allow_tailcalls() && !is_sloppy(language_mode())) {
+ this->MarkTailPosition(expression);
+ }
}
super_loc = function_state.super_location();
@@ -3253,47 +3033,25 @@
ParserBase<Traits>::CheckAndRewriteReferenceExpression(
ExpressionT expression, int beg_pos, int end_pos,
MessageTemplate::Template message, ParseErrorType type, bool* ok) {
- ExpressionClassifier classifier(this);
- ExpressionT result = ClassifyAndRewriteReferenceExpression(
- &classifier, expression, beg_pos, end_pos, message, type);
- ValidateExpression(&classifier, ok);
- if (!*ok) return this->EmptyExpression();
- return result;
-}
-
-
-template <typename Traits>
-typename ParserBase<Traits>::ExpressionT
-ParserBase<Traits>::ClassifyAndRewriteReferenceExpression(
- ExpressionClassifier* classifier, ExpressionT expression, int beg_pos,
- int end_pos, MessageTemplate::Template message, ParseErrorType type) {
- Scanner::Location location(beg_pos, end_pos);
- if (this->IsIdentifier(expression)) {
- if (is_strict(language_mode()) &&
- this->IsEvalOrArguments(this->AsIdentifier(expression))) {
- classifier->RecordExpressionError(
- location, MessageTemplate::kStrictEvalArguments, kSyntaxError);
- return expression;
- }
- if (is_strong(language_mode()) &&
- this->IsUndefined(this->AsIdentifier(expression))) {
- classifier->RecordExpressionError(
- location, MessageTemplate::kStrongUndefined, kSyntaxError);
- return expression;
- }
+ if (this->IsIdentifier(expression) && is_strict(language_mode()) &&
+ this->IsEvalOrArguments(this->AsIdentifier(expression))) {
+ ReportMessageAt(Scanner::Location(beg_pos, end_pos),
+ MessageTemplate::kStrictEvalArguments, kSyntaxError);
+ *ok = false;
+ return this->EmptyExpression();
}
if (expression->IsValidReferenceExpression()) {
return expression;
- } else if (expression->IsCall()) {
+ }
+ if (expression->IsCall()) {
// If it is a call, make it a runtime error for legacy web compatibility.
// Rewrite `expr' to `expr[throw ReferenceError]'.
- int pos = location.beg_pos;
- ExpressionT error = this->NewThrowReferenceError(message, pos);
- return factory()->NewProperty(expression, error, pos);
- } else {
- classifier->RecordExpressionError(location, message, type);
- return expression;
+ ExpressionT error = this->NewThrowReferenceError(message, beg_pos);
+ return factory()->NewProperty(expression, error, beg_pos);
}
+ ReportMessageAt(Scanner::Location(beg_pos, end_pos), message, type);
+ *ok = false;
+ return this->EmptyExpression();
}