Merge V8 5.3.332.45. DO NOT MERGE
Test: Manual
FPIIM-449
Change-Id: Id3254828b068abdea3cb10442e0172a8c9a98e03
(cherry picked from commit 13e2dadd00298019ed862f2b2fc5068bba730bcf)
diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h
index 6086f7a..669defa 100644
--- a/src/parsing/parser-base.h
+++ b/src/parsing/parser-base.h
@@ -7,7 +7,7 @@
#include "src/ast/scopes.h"
#include "src/bailout-reason.h"
-#include "src/hashmap.h"
+#include "src/base/hashmap.h"
#include "src/messages.h"
#include "src/parsing/expression-classifier.h"
#include "src/parsing/func-name-inferrer.h"
@@ -196,9 +196,9 @@
allow_harmony_restrictive_declarations_(false),
allow_harmony_do_expressions_(false),
allow_harmony_for_in_(false),
- allow_harmony_function_name_(false),
allow_harmony_function_sent_(false),
- allow_harmony_async_await_(false) {}
+ allow_harmony_async_await_(false),
+ allow_harmony_restrictive_generators_(false) {}
#define ALLOW_ACCESSORS(name) \
bool allow_##name() const { return allow_##name##_; } \
@@ -216,9 +216,9 @@
ALLOW_ACCESSORS(harmony_restrictive_declarations);
ALLOW_ACCESSORS(harmony_do_expressions);
ALLOW_ACCESSORS(harmony_for_in);
- ALLOW_ACCESSORS(harmony_function_name);
ALLOW_ACCESSORS(harmony_function_sent);
ALLOW_ACCESSORS(harmony_async_await);
+ ALLOW_ACCESSORS(harmony_restrictive_generators);
SCANNER_ACCESSORS(harmony_exponentiation_operator);
#undef SCANNER_ACCESSORS
@@ -385,8 +385,8 @@
typename Traits::Type::Factory* factory() { return factory_; }
- const List<DestructuringAssignment>& destructuring_assignments_to_rewrite()
- const {
+ const ZoneList<DestructuringAssignment>&
+ destructuring_assignments_to_rewrite() const {
return destructuring_assignments_to_rewrite_;
}
@@ -408,6 +408,10 @@
}
}
+ ZoneList<typename ExpressionClassifier::Error>* GetReportedErrorList() {
+ return &reported_errors_;
+ }
+
ReturnExprContext return_expr_context() const {
return return_expr_context_;
}
@@ -429,13 +433,16 @@
private:
void AddDestructuringAssignment(DestructuringAssignment pair) {
- destructuring_assignments_to_rewrite_.Add(pair);
+ destructuring_assignments_to_rewrite_.Add(pair, (*scope_stack_)->zone());
}
V8_INLINE Scope* scope() { return *scope_stack_; }
- void AddNonPatternForRewriting(ExpressionT expr) {
+ void AddNonPatternForRewriting(ExpressionT expr, bool* ok) {
non_patterns_to_rewrite_.Add(expr, (*scope_stack_)->zone());
+ if (non_patterns_to_rewrite_.length() >=
+ std::numeric_limits<uint16_t>::max())
+ *ok = false;
}
// Used to assign an index to each literal that needs materialization in
@@ -466,11 +473,13 @@
Scope** scope_stack_;
Scope* outer_scope_;
- List<DestructuringAssignment> destructuring_assignments_to_rewrite_;
+ ZoneList<DestructuringAssignment> destructuring_assignments_to_rewrite_;
TailCallExpressionList tail_call_expressions_;
ReturnExprContext return_expr_context_;
ZoneList<ExpressionT> non_patterns_to_rewrite_;
+ ZoneList<typename ExpressionClassifier::Error> reported_errors_;
+
typename Traits::Type::Factory* factory_;
// If true, the next (and immediately following) function literal is
@@ -658,13 +667,13 @@
Expect(Token::SEMICOLON, ok);
}
- bool peek_any_identifier() {
- Token::Value next = peek();
- return next == Token::IDENTIFIER || next == Token::ENUM ||
- next == Token::AWAIT || next == Token::ASYNC ||
- next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
- next == Token::STATIC || next == Token::YIELD;
+ bool is_any_identifier(Token::Value token) {
+ return token == Token::IDENTIFIER || token == Token::ENUM ||
+ token == Token::AWAIT || token == Token::ASYNC ||
+ token == Token::FUTURE_STRICT_RESERVED_WORD || token == Token::LET ||
+ token == Token::STATIC || token == Token::YIELD;
}
+ bool peek_any_identifier() { return is_any_identifier(peek()); }
bool CheckContextualKeyword(Vector<const char> keyword) {
if (PeekContextualKeyword(keyword)) {
@@ -877,6 +886,10 @@
}
}
+ bool IsValidArrowFormalParametersStart(Token::Value token) {
+ return is_any_identifier(token) || token == Token::LPAREN;
+ }
+
void ValidateArrowFormalParameters(const ExpressionClassifier* classifier,
ExpressionT expr,
bool parenthesized_formals, bool is_async,
@@ -1173,9 +1186,9 @@
bool allow_harmony_restrictive_declarations_;
bool allow_harmony_do_expressions_;
bool allow_harmony_for_in_;
- bool allow_harmony_function_name_;
bool allow_harmony_function_sent_;
bool allow_harmony_async_await_;
+ bool allow_harmony_restrictive_generators_;
};
template <class Traits>
@@ -1193,9 +1206,11 @@
outer_function_state_(*function_state_stack),
scope_stack_(scope_stack),
outer_scope_(*scope_stack),
+ destructuring_assignments_to_rewrite_(16, scope->zone()),
tail_call_expressions_(scope->zone()),
return_expr_context_(ReturnExprContext::kInsideValidBlock),
non_patterns_to_rewrite_(0, scope->zone()),
+ reported_errors_(16, scope->zone()),
factory_(factory),
next_function_is_parenthesized_(false),
this_function_is_parenthesized_(false) {
@@ -1552,12 +1567,11 @@
// Parentheses are not valid on the LHS of a BindingPattern, so we use the
// is_valid_binding_pattern() check to detect multiple levels of
// parenthesization.
- if (!classifier->is_valid_binding_pattern()) {
- ArrowFormalParametersUnexpectedToken(classifier);
- }
+ bool pattern_error = !classifier->is_valid_binding_pattern();
classifier->RecordPatternError(scanner()->peek_location(),
MessageTemplate::kUnexpectedToken,
Token::String(Token::LPAREN));
+ if (pattern_error) ArrowFormalParametersUnexpectedToken(classifier);
Consume(Token::LPAREN);
if (Check(Token::RPAREN)) {
// ()=>x. The continuation that looks for the => is in
@@ -1575,8 +1589,11 @@
MessageTemplate::kUnexpectedToken,
Token::String(Token::ELLIPSIS));
classifier->RecordNonSimpleParameter();
- ExpressionT expr =
- this->ParseAssignmentExpression(true, classifier, CHECK_OK);
+ ExpressionClassifier binding_classifier(this);
+ ExpressionT expr = this->ParseAssignmentExpression(
+ true, &binding_classifier, CHECK_OK);
+ classifier->Accumulate(&binding_classifier,
+ ExpressionClassifier::AllProductions);
if (!this->IsIdentifier(expr) && !IsValidPattern(expr)) {
classifier->RecordArrowFormalParametersError(
Scanner::Location(ellipsis_pos, scanner()->location().end_pos),
@@ -1663,11 +1680,14 @@
// AssignmentExpression
// Expression ',' AssignmentExpression
- ExpressionClassifier binding_classifier(this);
- ExpressionT result =
- this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK);
- classifier->Accumulate(&binding_classifier,
- ExpressionClassifier::AllProductions);
+ ExpressionT result = this->EmptyExpression();
+ {
+ ExpressionClassifier binding_classifier(this);
+ result = this->ParseAssignmentExpression(accept_IN, &binding_classifier,
+ CHECK_OK);
+ classifier->Accumulate(&binding_classifier,
+ ExpressionClassifier::AllProductions);
+ }
bool is_simple_parameter_list = this->IsIdentifier(result);
bool seen_rest = false;
while (peek() == Token::COMMA) {
@@ -1690,6 +1710,7 @@
seen_rest = is_rest = true;
}
int pos = position(), expr_pos = peek_position();
+ ExpressionClassifier binding_classifier(this);
ExpressionT right = this->ParseAssignmentExpression(
accept_IN, &binding_classifier, CHECK_OK);
classifier->Accumulate(&binding_classifier,
@@ -1777,7 +1798,15 @@
literal_index, pos);
if (first_spread_index >= 0) {
result = factory()->NewRewritableExpression(result);
- Traits::QueueNonPatternForRewriting(result);
+ Traits::QueueNonPatternForRewriting(result, ok);
+ if (!*ok) {
+ // If the non-pattern rewriting mechanism is used in the future for
+ // rewriting other things than spreads, this error message will have
+ // to change. Also, this error message will never appear while pre-
+ // parsing (this is OK, as it is an implementation limitation).
+ ReportMessage(MessageTemplate::kTooManySpreads);
+ return this->EmptyExpression();
+ }
}
return result;
}
@@ -1917,10 +1946,16 @@
classifier->RecordLetPatternError(
scanner()->location(), MessageTemplate::kLetInLexicalBinding);
}
- if (is_await && is_async_function()) {
- classifier->RecordPatternError(
- Scanner::Location(next_beg_pos, next_end_pos),
- MessageTemplate::kAwaitBindingIdentifier);
+ if (is_await) {
+ if (is_async_function()) {
+ classifier->RecordPatternError(
+ Scanner::Location(next_beg_pos, next_end_pos),
+ MessageTemplate::kAwaitBindingIdentifier);
+ } else {
+ classifier->RecordAsyncArrowFormalParametersError(
+ Scanner::Location(next_beg_pos, next_end_pos),
+ MessageTemplate::kAwaitBindingIdentifier);
+ }
}
ExpressionT lhs = this->ExpressionFromIdentifier(
*name, next_beg_pos, next_end_pos, scope_, factory());
@@ -1941,9 +1976,7 @@
Scanner::Location(next_beg_pos, scanner()->location().end_pos),
MessageTemplate::kInvalidCoverInitializedName);
- if (allow_harmony_function_name()) {
- Traits::SetFunctionNameFromIdentifierRef(rhs, lhs);
- }
+ Traits::SetFunctionNameFromIdentifierRef(rhs, lhs);
} else {
value = lhs;
}
@@ -2098,9 +2131,7 @@
if (fni_ != nullptr) fni_->Infer();
- if (allow_harmony_function_name()) {
- Traits::SetFunctionNameFromPropertyName(property, name);
- }
+ Traits::SetFunctionNameFromPropertyName(property, name);
}
Expect(Token::RBRACE, CHECK_OK);
@@ -2135,7 +2166,10 @@
ExpressionT argument = this->ParseAssignmentExpression(
true, classifier, CHECK_OK_CUSTOM(NullExpressionList));
CheckNoTailCallExpressions(classifier, CHECK_OK_CUSTOM(NullExpressionList));
- Traits::RewriteNonPattern(classifier, CHECK_OK_CUSTOM(NullExpressionList));
+ if (!maybe_arrow) {
+ Traits::RewriteNonPattern(classifier,
+ CHECK_OK_CUSTOM(NullExpressionList));
+ }
if (is_spread) {
if (!spread_arg.IsValid()) {
spread_arg.beg_pos = start_pos;
@@ -2172,11 +2206,17 @@
}
*first_spread_arg_loc = spread_arg;
- if ((!maybe_arrow || peek() != Token::ARROW) && spread_arg.IsValid()) {
- // Unspread parameter sequences are translated into array literals in the
- // parser. Ensure that the number of materialized literals matches between
- // the parser and preparser
- Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count);
+ if (!maybe_arrow || peek() != Token::ARROW) {
+ if (maybe_arrow) {
+ Traits::RewriteNonPattern(classifier,
+ CHECK_OK_CUSTOM(NullExpressionList));
+ }
+ if (spread_arg.IsValid()) {
+ // Unspread parameter sequences are translated into array literals in the
+ // parser. Ensure that the number of materialized literals matches between
+ // the parser and preparser
+ Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count);
+ }
}
return result;
@@ -2206,7 +2246,8 @@
classifier->duplicate_finder());
bool is_async = allow_harmony_async_await() && peek() == Token::ASYNC &&
- !scanner()->HasAnyLineTerminatorAfterNext();
+ !scanner()->HasAnyLineTerminatorAfterNext() &&
+ IsValidArrowFormalParametersStart(PeekAhead());
bool parenthesized_formals = peek() == Token::LPAREN;
if (!is_async && !parenthesized_formals) {
@@ -2224,9 +2265,7 @@
}
if (peek() == Token::ARROW) {
- classifier->RecordPatternError(scanner()->peek_location(),
- MessageTemplate::kUnexpectedToken,
- Token::String(Token::ARROW));
+ Scanner::Location arrow_loc = scanner()->peek_location();
ValidateArrowFormalParameters(&arrow_formals_classifier, expression,
parenthesized_formals, is_async, CHECK_OK);
// This reads strangely, but is correct: it checks whether any
@@ -2263,6 +2302,10 @@
}
expression = this->ParseArrowFunctionLiteral(
accept_IN, parameters, is_async, arrow_formals_classifier, CHECK_OK);
+ arrow_formals_classifier.Discard();
+ classifier->RecordPatternError(arrow_loc,
+ MessageTemplate::kUnexpectedToken,
+ Token::String(Token::ARROW));
if (fni_ != nullptr) fni_->Infer();
@@ -2352,7 +2395,7 @@
}
}
- if (op == Token::ASSIGN && allow_harmony_function_name()) {
+ if (op == Token::ASSIGN) {
Traits::SetFunctionNameFromIdentifierRef(right, expression);
}
@@ -2457,6 +2500,12 @@
*ok = false;
return Traits::EmptyExpression();
}
+ if (is_resumable()) {
+ Scanner::Location sub_loc(sub_expression_pos, loc.end_pos);
+ ReportMessageAt(sub_loc, MessageTemplate::kUnexpectedTailCall);
+ *ok = false;
+ return Traits::EmptyExpression();
+ }
ReturnExprContext return_expr_context =
function_state_->return_expr_context();
if (return_expr_context != ReturnExprContext::kInsideValidReturnStatement) {
@@ -2502,8 +2551,8 @@
if (peek() != Token::CONDITIONAL) return expression;
CheckNoTailCallExpressions(classifier, CHECK_OK);
Traits::RewriteNonPattern(classifier, CHECK_OK);
- ArrowFormalParametersUnexpectedToken(classifier);
BindingPatternUnexpectedToken(classifier);
+ ArrowFormalParametersUnexpectedToken(classifier);
Consume(Token::CONDITIONAL);
// In parsing the first assignment expression in conditional
// expressions we always accept the 'in' keyword; see ECMA-262,
@@ -2667,6 +2716,8 @@
default:
break;
}
+
+ int await_pos = peek_position();
Consume(Token::AWAIT);
ExpressionT value = ParseUnaryExpression(classifier, CHECK_OK);
@@ -2674,7 +2725,7 @@
classifier->RecordFormalParameterInitializerError(
Scanner::Location(beg_pos, scanner()->location().end_pos),
MessageTemplate::kAwaitExpressionFormalParameter);
- return Traits::RewriteAwaitExpression(value, beg_pos);
+ return Traits::RewriteAwaitExpression(value, await_pos);
} else {
return this->ParsePostfixExpression(classifier, ok);
}
@@ -3148,9 +3199,7 @@
init_classifier.Discard();
classifier->RecordNonSimpleParameter();
- if (allow_harmony_function_name()) {
- Traits::SetFunctionNameFromIdentifierRef(initializer, pattern);
- }
+ Traits::SetFunctionNameFromIdentifierRef(initializer, pattern);
}
Traits::AddFormalParameter(parameters, pattern, initializer,
@@ -3317,7 +3366,6 @@
} else {
// Single-expression body
int pos = position();
- ExpressionClassifier classifier(this);
DCHECK(ReturnExprContext::kInsideValidBlock ==
function_state_->return_expr_context());
ReturnExprScope allow_tail_calls(
@@ -3325,6 +3373,7 @@
body = this->NewStatementList(1, zone());
this->AddParameterInitializationBlock(formal_parameters, body, is_async,
CHECK_OK);
+ ExpressionClassifier classifier(this);
if (is_async) {
this->ParseAsyncArrowSingleExpressionBody(body, accept_IN, &classifier,
pos, CHECK_OK);