diff options
author | Myles Borins <mylesborins@google.com> | 2017-08-01 11:36:44 -0500 |
---|---|---|
committer | Myles Borins <mylesborins@google.com> | 2017-08-01 15:23:15 -0500 |
commit | 0a66b223e149a841669bfad5598e4254589730cb (patch) | |
tree | 5ec050f7f78aafbf5b1e0e50d639fb843141e162 /deps/v8/src/parsing/parser-base.h | |
parent | 1782b3836ba58ef0da6b687f2bb970c0bd8199ad (diff) | |
download | android-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.h | 179 |
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); |