summaryrefslogtreecommitdiff
path: root/deps/v8/src/parsing/parser-base.h
diff options
context:
space:
mode:
authorMyles Borins <mylesborins@google.com>2017-08-01 11:36:44 -0500
committerMyles Borins <mylesborins@google.com>2017-08-01 15:23:15 -0500
commit0a66b223e149a841669bfad5598e4254589730cb (patch)
tree5ec050f7f78aafbf5b1e0e50d639fb843141e162 /deps/v8/src/parsing/parser-base.h
parent1782b3836ba58ef0da6b687f2bb970c0bd8199ad (diff)
downloadandroid-node-v8-0a66b223e149a841669bfad5598e4254589730cb.tar.gz
android-node-v8-0a66b223e149a841669bfad5598e4254589730cb.tar.bz2
android-node-v8-0a66b223e149a841669bfad5598e4254589730cb.zip
deps: update V8 to 6.0.286.52
PR-URL: https://github.com/nodejs/node/pull/14004 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Diffstat (limited to 'deps/v8/src/parsing/parser-base.h')
-rw-r--r--deps/v8/src/parsing/parser-base.h179
1 files changed, 128 insertions, 51 deletions
diff --git a/deps/v8/src/parsing/parser-base.h b/deps/v8/src/parsing/parser-base.h
index 1dbad01dea..2d01398980 100644
--- a/deps/v8/src/parsing/parser-base.h
+++ b/deps/v8/src/parsing/parser-base.h
@@ -20,6 +20,7 @@
namespace v8 {
namespace internal {
+class PreParsedScopeData;
enum FunctionNameValidity {
kFunctionNameIsStrictReserved,
@@ -200,6 +201,7 @@ class ParserBase {
ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
v8::Extension* extension, AstValueFactory* ast_value_factory,
RuntimeCallStats* runtime_call_stats,
+ PreParsedScopeData* preparsed_scope_data,
bool parsing_on_main_thread = true)
: scope_(nullptr),
original_scope_(nullptr),
@@ -207,11 +209,12 @@ class ParserBase {
extension_(extension),
fni_(nullptr),
ast_value_factory_(ast_value_factory),
- ast_node_factory_(ast_value_factory),
+ ast_node_factory_(ast_value_factory, zone),
runtime_call_stats_(runtime_call_stats),
parsing_on_main_thread_(parsing_on_main_thread),
parsing_module_(false),
stack_limit_(stack_limit),
+ preparsed_scope_data_(preparsed_scope_data),
zone_(zone),
classifier_(nullptr),
scanner_(scanner),
@@ -448,6 +451,30 @@ class ParserBase {
next_function_is_likely_called_ = true;
}
+ void RecordFunctionOrEvalCall() { contains_function_or_eval_ = true; }
+ bool contains_function_or_eval() const {
+ return contains_function_or_eval_;
+ }
+
+ class FunctionOrEvalRecordingScope {
+ public:
+ explicit FunctionOrEvalRecordingScope(FunctionState* state)
+ : state_(state) {
+ prev_value_ = state->contains_function_or_eval_;
+ state->contains_function_or_eval_ = false;
+ }
+ ~FunctionOrEvalRecordingScope() {
+ bool found = state_->contains_function_or_eval_;
+ if (!found) {
+ state_->contains_function_or_eval_ = prev_value_;
+ }
+ }
+
+ private:
+ FunctionState* state_;
+ bool prev_value_;
+ };
+
private:
void AddDestructuringAssignment(DestructuringAssignment pair) {
destructuring_assignments_to_rewrite_.Add(pair, scope_->zone());
@@ -482,6 +509,9 @@ class ParserBase {
bool next_function_is_likely_called_;
bool previous_function_was_likely_called_;
+ // Track if a function or eval occurs within this FunctionState
+ bool contains_function_or_eval_;
+
friend Impl;
};
@@ -601,7 +631,8 @@ class ParserBase {
constructor(parser->impl()->EmptyFunctionLiteral()),
has_seen_constructor(false),
has_name_static_property(false),
- has_static_computed_names(false) {}
+ has_static_computed_names(false),
+ is_anonymous(false) {}
VariableProxy* proxy;
ExpressionT extends;
typename Types::ClassPropertyList properties;
@@ -609,6 +640,7 @@ class ParserBase {
bool has_seen_constructor;
bool has_name_static_property;
bool has_static_computed_names;
+ bool is_anonymous;
};
DeclarationScope* NewScriptScope() const {
@@ -653,6 +685,10 @@ class ParserBase {
if (target_zone == nullptr) target_zone = zone();
DeclarationScope* result = new (target_zone)
DeclarationScope(zone(), scope(), FUNCTION_SCOPE, kind);
+
+ // Record presence of an inner function scope
+ function_state_->RecordFunctionOrEvalCall();
+
// TODO(verwaest): Move into the DeclarationScope constructor.
if (!IsArrowFunction(kind)) {
result->DeclareDefaultFunctionVariables(ast_value_factory());
@@ -1337,6 +1373,7 @@ class ParserBase {
if (impl()->IsIdentifier(expression) &&
impl()->IsEval(impl()->AsIdentifier(expression))) {
scope->RecordEvalCall();
+ function_state_->RecordFunctionOrEvalCall();
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.
@@ -1486,6 +1523,7 @@ class ParserBase {
bool parsing_on_main_thread_;
bool parsing_module_;
uintptr_t stack_limit_;
+ PreParsedScopeData* preparsed_scope_data_;
// Parser base's private field members.
@@ -1530,7 +1568,8 @@ ParserBase<Impl>::FunctionState::FunctionState(
non_patterns_to_rewrite_(0, scope->zone()),
reported_errors_(16, scope->zone()),
next_function_is_likely_called_(false),
- previous_function_was_likely_called_(false) {
+ previous_function_was_likely_called_(false),
+ contains_function_or_eval_(false) {
*function_state_stack = this;
if (outer_function_state_) {
outer_function_state_->previous_function_was_likely_called_ =
@@ -1933,6 +1972,11 @@ ParserBase<Impl>::ParseExpressionCoverGrammar(bool accept_IN, bool* ok) {
int ellipsis_pos = position();
int pattern_pos = peek_position();
ExpressionT pattern = ParsePrimaryExpression(CHECK_OK);
+ if (peek() == Token::ASSIGN) {
+ ReportMessage(MessageTemplate::kRestDefaultInitializer);
+ *ok = false;
+ return result;
+ }
ValidateBindingPattern(CHECK_OK);
right = factory()->NewSpread(pattern, ellipsis_pos, pattern_pos);
} else {
@@ -2222,12 +2266,12 @@ ParserBase<Impl>::ParseClassPropertyDefinition(
Token::Value name_token = peek();
- int function_token_position = scanner()->peek_location().beg_pos;
+ int name_token_position = scanner()->peek_location().beg_pos;
IdentifierT name = impl()->EmptyIdentifier();
ExpressionT name_expression;
if (name_token == Token::STATIC) {
Consume(Token::STATIC);
- function_token_position = scanner()->peek_location().beg_pos;
+ name_token_position = scanner()->peek_location().beg_pos;
if (peek() == Token::LPAREN) {
kind = PropertyKind::kMethodProperty;
name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static'
@@ -2305,7 +2349,7 @@ ParserBase<Impl>::ParseClassPropertyDefinition(
ExpressionT value = impl()->ParseFunctionLiteral(
name, scanner()->location(), kSkipFunctionNameCheck, kind,
- FLAG_harmony_function_tostring ? function_token_position
+ FLAG_harmony_function_tostring ? name_token_position
: kNoSourcePosition,
FunctionLiteral::kAccessorOrMethod, language_mode(),
CHECK_OK_CUSTOM(EmptyClassLiteralProperty));
@@ -2335,7 +2379,7 @@ ParserBase<Impl>::ParseClassPropertyDefinition(
FunctionLiteralT value = impl()->ParseFunctionLiteral(
name, scanner()->location(), kSkipFunctionNameCheck, kind,
- FLAG_harmony_function_tostring ? function_token_position
+ FLAG_harmony_function_tostring ? name_token_position
: kNoSourcePosition,
FunctionLiteral::kAccessorOrMethod, language_mode(),
CHECK_OK_CUSTOM(EmptyClassLiteralProperty));
@@ -2351,7 +2395,11 @@ ParserBase<Impl>::ParseClassPropertyDefinition(
*is_computed_name);
}
case PropertyKind::kSpreadProperty:
- UNREACHABLE();
+ ReportUnexpectedTokenAt(
+ Scanner::Location(name_token_position, name_expression->position()),
+ name_token);
+ *ok = false;
+ return impl()->EmptyClassLiteralProperty();
}
UNREACHABLE();
return impl()->EmptyClassLiteralProperty();
@@ -2672,6 +2720,10 @@ typename ParserBase<Impl>::ExpressionListT ParserBase<Impl>::ParseArguments(
spread_arg.beg_pos = start_pos;
spread_arg.end_pos = peek_position();
}
+ if (argument->IsAssignment()) {
+ classifier()->RecordAsyncArrowFormalParametersError(
+ scanner()->location(), MessageTemplate::kRestDefaultInitializer);
+ }
argument = factory()->NewSpread(argument, start_pos, expr_pos);
}
result->Add(argument, zone_);
@@ -2684,6 +2736,10 @@ typename ParserBase<Impl>::ExpressionListT ParserBase<Impl>::ParseArguments(
done = (peek() != Token::COMMA);
if (!done) {
Next();
+ if (argument->IsSpread()) {
+ classifier()->RecordAsyncArrowFormalParametersError(
+ scanner()->location(), MessageTemplate::kParamAfterRest);
+ }
if (allow_harmony_trailing_commas() && peek() == Token::RPAREN) {
// allow trailing comma
done = true;
@@ -3265,6 +3321,9 @@ ParserBase<Impl>::ParseLeftHandSideExpression(bool* ok) {
// Explicit calls to the super constructor using super() perform an
// implicit binding assignment to the 'this' variable.
if (is_super_call) {
+ classifier()->RecordAssignmentPatternError(
+ Scanner::Location(pos, scanner()->location().end_pos),
+ MessageTemplate::kInvalidDestructuringTarget);
ExpressionT this_expr = impl()->ThisExpression(pos);
result =
factory()->NewAssignment(Token::INIT, this_expr, result, pos);
@@ -3418,6 +3477,10 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseMemberExpression(
if (impl()->ParsingDynamicFunctionDeclaration()) {
// We don't want dynamic functions to actually declare their name
// "anonymous". We just want that name in the toString().
+ if (stack_overflow()) {
+ *ok = false;
+ return impl()->EmptyExpression();
+ }
Consume(Token::IDENTIFIER);
DCHECK(scanner()->CurrentMatchesContextual(Token::ANONYMOUS));
} else if (peek_any_identifier()) {
@@ -3506,6 +3569,10 @@ ParserBase<Impl>::ParseNewTargetExpression(bool* ok) {
int pos = position();
ExpectMetaProperty(Token::TARGET, "new.target", pos, CHECK_OK);
+ classifier()->RecordAssignmentPatternError(
+ Scanner::Location(pos, scanner()->location().end_pos),
+ MessageTemplate::kInvalidDestructuringTarget);
+
if (!GetReceiverScope()->is_function_scope()) {
impl()->ReportMessageAt(scanner()->location(),
MessageTemplate::kUnexpectedNewTarget);
@@ -3603,7 +3670,12 @@ void ParserBase<Impl>::ParseFormalParameter(FormalParametersT* parameters,
}
ExpressionT initializer = impl()->EmptyExpression();
- if (!is_rest && Check(Token::ASSIGN)) {
+ if (Check(Token::ASSIGN)) {
+ if (is_rest) {
+ ReportMessage(MessageTemplate::kRestDefaultInitializer);
+ *ok = false;
+ return;
+ }
ExpressionClassifier init_classifier(this);
initializer = ParseAssignmentExpression(true, CHECK_OK_CUSTOM(Void));
impl()->RewriteNonPattern(CHECK_OK_CUSTOM(Void));
@@ -4216,32 +4288,20 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
// FIXME(marja): Arrow function parameters will be parsed even if the
// body is preparsed; move relevant parts of parameter handling to
// simulate consistent parameter handling.
- Scanner::BookmarkScope bookmark(scanner());
- bookmark.Set();
+
// For arrow functions, we don't need to retrieve data about function
// parameters.
int dummy_num_parameters = -1;
- int dummy_function_length = -1;
DCHECK((kind & FunctionKind::kArrowFunction) != 0);
- LazyParsingResult result = impl()->SkipFunction(
- kind, formal_parameters.scope, &dummy_num_parameters,
- &dummy_function_length, false, true, CHECK_OK);
- formal_parameters.scope->ResetAfterPreparsing(
- ast_value_factory_, result == kLazyParsingAborted);
-
- if (result == kLazyParsingAborted) {
- bookmark.Apply();
- // Trigger eager (re-)parsing, just below this block.
- is_lazy_top_level_function = false;
-
- // This is probably an initialization function. Inform the compiler it
- // should also eager-compile this function, and that we expect it to
- // be used once.
- eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
- should_be_used_once_hint = true;
- }
- }
- if (!is_lazy_top_level_function) {
+ LazyParsingResult result =
+ impl()->SkipFunction(kind, formal_parameters.scope,
+ &dummy_num_parameters, false, false, CHECK_OK);
+ DCHECK_NE(result, kLazyParsingAborted);
+ USE(result);
+ formal_parameters.scope->ResetAfterPreparsing(ast_value_factory_,
+ false);
+
+ } else {
Consume(Token::LBRACE);
body = impl()->NewStatementList(8);
impl()->ParseFunctionBody(body, impl()->EmptyIdentifier(),
@@ -4339,24 +4399,30 @@ template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral(
IdentifierT name, Scanner::Location class_name_location,
bool name_is_strict_reserved, int class_token_pos, bool* ok) {
+ bool is_anonymous = impl()->IsEmptyIdentifier(name);
+
// All parts of a ClassDeclaration and ClassExpression are strict code.
- if (name_is_strict_reserved) {
- impl()->ReportMessageAt(class_name_location,
- MessageTemplate::kUnexpectedStrictReserved);
- *ok = false;
- return impl()->EmptyExpression();
- }
- if (impl()->IsEvalOrArguments(name)) {
- impl()->ReportMessageAt(class_name_location,
- MessageTemplate::kStrictEvalArguments);
- *ok = false;
- return impl()->EmptyExpression();
+ if (!is_anonymous) {
+ if (name_is_strict_reserved) {
+ impl()->ReportMessageAt(class_name_location,
+ MessageTemplate::kUnexpectedStrictReserved);
+ *ok = false;
+ return impl()->EmptyExpression();
+ }
+ if (impl()->IsEvalOrArguments(name)) {
+ impl()->ReportMessageAt(class_name_location,
+ MessageTemplate::kStrictEvalArguments);
+ *ok = false;
+ return impl()->EmptyExpression();
+ }
}
- BlockState block_state(zone(), &scope_);
+ Scope* block_scope = NewScope(BLOCK_SCOPE);
+ BlockState block_state(&scope_, block_scope);
RaiseLanguageMode(STRICT);
ClassInfo class_info(this);
+ class_info.is_anonymous = is_anonymous;
impl()->DeclareClassVariable(name, &class_info, class_token_pos, CHECK_OK);
scope()->set_start_position(scanner()->location().end_pos);
@@ -4401,7 +4467,10 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral(
}
Expect(Token::RBRACE, CHECK_OK);
- return impl()->RewriteClassLiteral(name, &class_info, class_token_pos, ok);
+ int end_pos = scanner()->location().end_pos;
+ block_scope->set_end_position(end_pos);
+ return impl()->RewriteClassLiteral(block_scope, name, &class_info,
+ class_token_pos, end_pos, ok);
}
template <typename Impl>
@@ -4452,6 +4521,10 @@ ParserBase<Impl>::ParseAsyncFunctionLiteral(bool* ok) {
if (impl()->ParsingDynamicFunctionDeclaration()) {
// We don't want dynamic functions to actually declare their name
// "anonymous". We just want that name in the toString().
+ if (stack_overflow()) {
+ *ok = false;
+ return impl()->EmptyExpression();
+ }
Consume(Token::IDENTIFIER);
DCHECK(scanner()->CurrentMatchesContextual(Token::ANONYMOUS));
} else if (peek_any_identifier()) {
@@ -5460,6 +5533,8 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseTryStatement(
template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForStatement(
ZoneList<const AstRawString*>* labels, bool* ok) {
+ typename FunctionState::FunctionOrEvalRecordingScope recording_scope(
+ function_state_);
int stmt_pos = peek_position();
ForInfo for_info(this);
bool bound_names_are_lexical = false;
@@ -5469,7 +5544,6 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForStatement(
Expect(Token::FOR, CHECK_OK);
Expect(Token::LPAREN, CHECK_OK);
scope()->set_start_position(scanner()->location().beg_pos);
- scope()->set_is_hidden();
StatementT init = impl()->NullStatement();
@@ -5527,6 +5601,7 @@ typename ParserBase<Impl>::StatementT
ParserBase<Impl>::ParseForEachStatementWithDeclarations(
int stmt_pos, ForInfo* for_info, ZoneList<const AstRawString*>* labels,
bool* ok) {
+ scope()->set_is_hidden();
// Just one declaration followed by in/of.
if (for_info->parsing_result.declarations.length() != 1) {
impl()->ReportMessageAt(for_info->parsing_result.bindings_loc,
@@ -5607,6 +5682,7 @@ typename ParserBase<Impl>::StatementT
ParserBase<Impl>::ParseForEachStatementWithoutDeclarations(
int stmt_pos, ExpressionT expression, int lhs_beg_pos, int lhs_end_pos,
ForInfo* for_info, ZoneList<const AstRawString*>* labels, bool* ok) {
+ scope()->set_is_hidden();
// Initializer is reference followed by in/of.
if (!expression->IsArrayLiteral() && !expression->IsObjectLiteral()) {
expression = impl()->CheckAndRewriteReferenceExpression(
@@ -5690,15 +5766,15 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseStandardForLoop(
body = ParseStatement(nullptr, CHECK_OK);
}
- if (bound_names_are_lexical && for_info->bound_names.length() > 0) {
- auto result = impl()->DesugarLexicalBindingsInForStatement(
+ scope()->set_end_position(scanner()->location().end_pos);
+ inner_scope->set_end_position(scanner()->location().end_pos);
+ if (bound_names_are_lexical && for_info->bound_names.length() > 0 &&
+ (is_resumable() || function_state_->contains_function_or_eval())) {
+ scope()->set_is_hidden();
+ return impl()->DesugarLexicalBindingsInForStatement(
loop, init, cond, next, body, inner_scope, *for_info, CHECK_OK);
- scope()->set_end_position(scanner()->location().end_pos);
- inner_scope->set_end_position(scanner()->location().end_pos);
- return result;
}
- scope()->set_end_position(scanner()->location().end_pos);
Scope* for_scope = scope()->FinalizeBlockScope();
if (for_scope != nullptr) {
// Rewrite a for statement of the form
@@ -5722,6 +5798,7 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseStandardForLoop(
BlockT block = factory()->NewBlock(nullptr, 2, false, kNoSourcePosition);
if (!impl()->IsNullStatement(init)) {
block->statements()->Add(init, zone());
+ init = impl()->NullStatement();
}
block->statements()->Add(loop, zone());
block->set_scope(for_scope);