• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <cmath>
6 
7 #include "src/allocation.h"
8 #include "src/base/logging.h"
9 #include "src/conversions-inl.h"
10 #include "src/conversions.h"
11 #include "src/globals.h"
12 #include "src/list.h"
13 #include "src/parsing/parser-base.h"
14 #include "src/parsing/preparse-data-format.h"
15 #include "src/parsing/preparse-data.h"
16 #include "src/parsing/preparser.h"
17 #include "src/unicode.h"
18 #include "src/utils.h"
19 
20 namespace v8 {
21 namespace internal {
22 
ReportMessageAt(Scanner::Location location,MessageTemplate::Template message,const char * arg,ParseErrorType error_type)23 void PreParserTraits::ReportMessageAt(Scanner::Location location,
24                                       MessageTemplate::Template message,
25                                       const char* arg,
26                                       ParseErrorType error_type) {
27   ReportMessageAt(location.beg_pos, location.end_pos, message, arg, error_type);
28 }
29 
30 
ReportMessageAt(int start_pos,int end_pos,MessageTemplate::Template message,const char * arg,ParseErrorType error_type)31 void PreParserTraits::ReportMessageAt(int start_pos, int end_pos,
32                                       MessageTemplate::Template message,
33                                       const char* arg,
34                                       ParseErrorType error_type) {
35   pre_parser_->log_->LogMessage(start_pos, end_pos, message, arg, error_type);
36 }
37 
38 
GetSymbol(Scanner * scanner)39 PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) {
40   if (scanner->current_token() == Token::ENUM) {
41     return PreParserIdentifier::Enum();
42   } else if (scanner->current_token() == Token::AWAIT) {
43     return PreParserIdentifier::Await();
44   } else if (scanner->current_token() ==
45              Token::FUTURE_STRICT_RESERVED_WORD) {
46     return PreParserIdentifier::FutureStrictReserved();
47   } else if (scanner->current_token() == Token::LET) {
48     return PreParserIdentifier::Let();
49   } else if (scanner->current_token() == Token::STATIC) {
50     return PreParserIdentifier::Static();
51   } else if (scanner->current_token() == Token::YIELD) {
52     return PreParserIdentifier::Yield();
53   } else if (scanner->current_token() == Token::ASYNC) {
54     return PreParserIdentifier::Async();
55   }
56   if (scanner->UnescapedLiteralMatches("eval", 4)) {
57     return PreParserIdentifier::Eval();
58   }
59   if (scanner->UnescapedLiteralMatches("arguments", 9)) {
60     return PreParserIdentifier::Arguments();
61   }
62   if (scanner->UnescapedLiteralMatches("undefined", 9)) {
63     return PreParserIdentifier::Undefined();
64   }
65   if (scanner->LiteralMatches("prototype", 9)) {
66     return PreParserIdentifier::Prototype();
67   }
68   if (scanner->LiteralMatches("constructor", 11)) {
69     return PreParserIdentifier::Constructor();
70   }
71   return PreParserIdentifier::Default();
72 }
73 
74 
GetNumberAsSymbol(Scanner * scanner)75 PreParserIdentifier PreParserTraits::GetNumberAsSymbol(Scanner* scanner) {
76   return PreParserIdentifier::Default();
77 }
78 
79 
ExpressionFromString(int pos,Scanner * scanner,PreParserFactory * factory)80 PreParserExpression PreParserTraits::ExpressionFromString(
81     int pos, Scanner* scanner, PreParserFactory* factory) {
82   if (scanner->UnescapedLiteralMatches("use strict", 10)) {
83     return PreParserExpression::UseStrictStringLiteral();
84   }
85   return PreParserExpression::StringLiteral();
86 }
87 
88 
ParseV8Intrinsic(bool * ok)89 PreParserExpression PreParserTraits::ParseV8Intrinsic(bool* ok) {
90   return pre_parser_->ParseV8Intrinsic(ok);
91 }
92 
93 
ParseFunctionLiteral(PreParserIdentifier name,Scanner::Location function_name_location,FunctionNameValidity function_name_validity,FunctionKind kind,int function_token_position,FunctionLiteral::FunctionType type,LanguageMode language_mode,bool * ok)94 PreParserExpression PreParserTraits::ParseFunctionLiteral(
95     PreParserIdentifier name, Scanner::Location function_name_location,
96     FunctionNameValidity function_name_validity, FunctionKind kind,
97     int function_token_position, FunctionLiteral::FunctionType type,
98     LanguageMode language_mode, bool* ok) {
99   return pre_parser_->ParseFunctionLiteral(
100       name, function_name_location, function_name_validity, kind,
101       function_token_position, type, language_mode, ok);
102 }
103 
PreParseLazyFunction(LanguageMode language_mode,FunctionKind kind,bool has_simple_parameters,bool parsing_module,ParserRecorder * log,Scanner::BookmarkScope * bookmark,int * use_counts)104 PreParser::PreParseResult PreParser::PreParseLazyFunction(
105     LanguageMode language_mode, FunctionKind kind, bool has_simple_parameters,
106     bool parsing_module, ParserRecorder* log, Scanner::BookmarkScope* bookmark,
107     int* use_counts) {
108   parsing_module_ = parsing_module;
109   log_ = log;
110   use_counts_ = use_counts;
111   // Lazy functions always have trivial outer scopes (no with/catch scopes).
112   Scope* top_scope = NewScope(scope_, SCRIPT_SCOPE);
113   PreParserFactory top_factory(NULL);
114   FunctionState top_state(&function_state_, &scope_, top_scope, kNormalFunction,
115                           &top_factory);
116   scope_->SetLanguageMode(language_mode);
117   Scope* function_scope = NewScope(scope_, FUNCTION_SCOPE, kind);
118   if (!has_simple_parameters) function_scope->SetHasNonSimpleParameters();
119   PreParserFactory function_factory(NULL);
120   FunctionState function_state(&function_state_, &scope_, function_scope, kind,
121                                &function_factory);
122   DCHECK_EQ(Token::LBRACE, scanner()->current_token());
123   bool ok = true;
124   int start_position = peek_position();
125   ParseLazyFunctionLiteralBody(&ok, bookmark);
126   use_counts_ = nullptr;
127   if (bookmark && bookmark->HasBeenReset()) {
128     // Do nothing, as we've just aborted scanning this function.
129   } else if (stack_overflow()) {
130     return kPreParseStackOverflow;
131   } else if (!ok) {
132     ReportUnexpectedToken(scanner()->current_token());
133   } else {
134     DCHECK_EQ(Token::RBRACE, scanner()->peek());
135     if (is_strict(scope_->language_mode())) {
136       int end_pos = scanner()->location().end_pos;
137       CheckStrictOctalLiteral(start_position, end_pos, &ok);
138       CheckDecimalLiteralWithLeadingZero(use_counts, start_position, end_pos);
139       if (!ok) return kPreParseSuccess;
140     }
141   }
142   return kPreParseSuccess;
143 }
144 
ParseClassLiteral(Type::ExpressionClassifier * classifier,PreParserIdentifier name,Scanner::Location class_name_location,bool name_is_strict_reserved,int pos,bool * ok)145 PreParserExpression PreParserTraits::ParseClassLiteral(
146     Type::ExpressionClassifier* classifier, PreParserIdentifier name,
147     Scanner::Location class_name_location, bool name_is_strict_reserved,
148     int pos, bool* ok) {
149   return pre_parser_->ParseClassLiteral(classifier, name, class_name_location,
150                                         name_is_strict_reserved, pos, ok);
151 }
152 
153 
154 // Preparsing checks a JavaScript program and emits preparse-data that helps
155 // a later parsing to be faster.
156 // See preparser-data.h for the data.
157 
158 // The PreParser checks that the syntax follows the grammar for JavaScript,
159 // and collects some information about the program along the way.
160 // The grammar check is only performed in order to understand the program
161 // sufficiently to deduce some information about it, that can be used
162 // to speed up later parsing. Finding errors is not the goal of pre-parsing,
163 // rather it is to speed up properly written and correct programs.
164 // That means that contextual checks (like a label being declared where
165 // it is used) are generally omitted.
166 
167 
ParseStatementListItem(bool * ok)168 PreParser::Statement PreParser::ParseStatementListItem(bool* ok) {
169   // ECMA 262 6th Edition
170   // StatementListItem[Yield, Return] :
171   //   Statement[?Yield, ?Return]
172   //   Declaration[?Yield]
173   //
174   // Declaration[Yield] :
175   //   HoistableDeclaration[?Yield]
176   //   ClassDeclaration[?Yield]
177   //   LexicalDeclaration[In, ?Yield]
178   //
179   // HoistableDeclaration[Yield, Default] :
180   //   FunctionDeclaration[?Yield, ?Default]
181   //   GeneratorDeclaration[?Yield, ?Default]
182   //
183   // LexicalDeclaration[In, Yield] :
184   //   LetOrConst BindingList[?In, ?Yield] ;
185 
186   switch (peek()) {
187     case Token::FUNCTION:
188       return ParseHoistableDeclaration(ok);
189     case Token::CLASS:
190       return ParseClassDeclaration(ok);
191     case Token::CONST:
192       return ParseVariableStatement(kStatementListItem, ok);
193     case Token::LET:
194       if (IsNextLetKeyword()) {
195         return ParseVariableStatement(kStatementListItem, ok);
196       }
197       break;
198     case Token::ASYNC:
199       if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION &&
200           !scanner()->HasAnyLineTerminatorAfterNext()) {
201         Consume(Token::ASYNC);
202         return ParseAsyncFunctionDeclaration(ok);
203       }
204     /* falls through */
205     default:
206       break;
207   }
208   return ParseStatement(kAllowLabelledFunctionStatement, ok);
209 }
210 
211 
ParseStatementList(int end_token,bool * ok,Scanner::BookmarkScope * bookmark)212 void PreParser::ParseStatementList(int end_token, bool* ok,
213                                    Scanner::BookmarkScope* bookmark) {
214   // SourceElements ::
215   //   (Statement)* <end_token>
216 
217   // Bookkeeping for trial parse if bookmark is set:
218   DCHECK_IMPLIES(bookmark, bookmark->HasBeenSet());
219   bool maybe_reset = bookmark != nullptr;
220   int count_statements = 0;
221 
222   bool directive_prologue = true;
223   while (peek() != end_token) {
224     if (directive_prologue && peek() != Token::STRING) {
225       directive_prologue = false;
226     }
227     bool starts_with_identifier = peek() == Token::IDENTIFIER;
228     Scanner::Location token_loc = scanner()->peek_location();
229     Statement statement = ParseStatementListItem(ok);
230     if (!*ok) return;
231 
232     if (directive_prologue) {
233       bool use_strict_found = statement.IsUseStrictLiteral();
234 
235       if (use_strict_found) {
236         scope_->SetLanguageMode(
237             static_cast<LanguageMode>(scope_->language_mode() | STRICT));
238       } else if (!statement.IsStringLiteral()) {
239         directive_prologue = false;
240       }
241 
242       if (use_strict_found && !scope_->HasSimpleParameters()) {
243         // TC39 deemed "use strict" directives to be an error when occurring
244         // in the body of a function with non-simple parameter list, on
245         // 29/7/2015. https://goo.gl/ueA7Ln
246         PreParserTraits::ReportMessageAt(
247             token_loc, MessageTemplate::kIllegalLanguageModeDirective,
248             "use strict");
249         *ok = false;
250         return;
251       }
252     }
253 
254     // If we're allowed to reset to a bookmark, we will do so when we see a long
255     // and trivial function.
256     // Our current definition of 'long and trivial' is:
257     // - over 200 statements
258     // - all starting with an identifier (i.e., no if, for, while, etc.)
259     if (maybe_reset && (!starts_with_identifier ||
260                         ++count_statements > kLazyParseTrialLimit)) {
261       if (count_statements > kLazyParseTrialLimit) {
262         bookmark->Reset();
263         return;
264       }
265       maybe_reset = false;
266     }
267   }
268 }
269 
270 
271 #define CHECK_OK  ok);                   \
272   if (!*ok) return Statement::Default();  \
273   ((void)0
274 #define DUMMY )  // to make indentation work
275 #undef DUMMY
276 
ParseStatement(AllowLabelledFunctionStatement allow_function,bool * ok)277 PreParser::Statement PreParser::ParseStatement(
278     AllowLabelledFunctionStatement allow_function, bool* ok) {
279   // Statement ::
280   //   EmptyStatement
281   //   ...
282 
283   if (peek() == Token::SEMICOLON) {
284     Next();
285     return Statement::Default();
286   }
287   return ParseSubStatement(allow_function, ok);
288 }
289 
ParseScopedStatement(bool legacy,bool * ok)290 PreParser::Statement PreParser::ParseScopedStatement(bool legacy, bool* ok) {
291   if (is_strict(language_mode()) || peek() != Token::FUNCTION ||
292       (legacy && allow_harmony_restrictive_declarations())) {
293     return ParseSubStatement(kDisallowLabelledFunctionStatement, ok);
294   } else {
295     Scope* body_scope = NewScope(scope_, BLOCK_SCOPE);
296     BlockState block_state(&scope_, body_scope);
297     return ParseFunctionDeclaration(ok);
298   }
299 }
300 
ParseSubStatement(AllowLabelledFunctionStatement allow_function,bool * ok)301 PreParser::Statement PreParser::ParseSubStatement(
302     AllowLabelledFunctionStatement allow_function, bool* ok) {
303   // Statement ::
304   //   Block
305   //   VariableStatement
306   //   EmptyStatement
307   //   ExpressionStatement
308   //   IfStatement
309   //   IterationStatement
310   //   ContinueStatement
311   //   BreakStatement
312   //   ReturnStatement
313   //   WithStatement
314   //   LabelledStatement
315   //   SwitchStatement
316   //   ThrowStatement
317   //   TryStatement
318   //   DebuggerStatement
319 
320   // Note: Since labels can only be used by 'break' and 'continue'
321   // statements, which themselves are only valid within blocks,
322   // iterations or 'switch' statements (i.e., BreakableStatements),
323   // labels can be simply ignored in all other cases; except for
324   // trivial labeled break statements 'label: break label' which is
325   // parsed into an empty statement.
326 
327   // Keep the source position of the statement
328   switch (peek()) {
329     case Token::LBRACE:
330       return ParseBlock(ok);
331 
332     case Token::SEMICOLON:
333       Next();
334       return Statement::Default();
335 
336     case Token::IF:
337       return ParseIfStatement(ok);
338 
339     case Token::DO:
340       return ParseDoWhileStatement(ok);
341 
342     case Token::WHILE:
343       return ParseWhileStatement(ok);
344 
345     case Token::FOR:
346       return ParseForStatement(ok);
347 
348     case Token::CONTINUE:
349       return ParseContinueStatement(ok);
350 
351     case Token::BREAK:
352       return ParseBreakStatement(ok);
353 
354     case Token::RETURN:
355       return ParseReturnStatement(ok);
356 
357     case Token::WITH:
358       return ParseWithStatement(ok);
359 
360     case Token::SWITCH:
361       return ParseSwitchStatement(ok);
362 
363     case Token::THROW:
364       return ParseThrowStatement(ok);
365 
366     case Token::TRY:
367       return ParseTryStatement(ok);
368 
369     case Token::FUNCTION:
370       // FunctionDeclaration only allowed as a StatementListItem, not in
371       // an arbitrary Statement position. Exceptions such as
372       // ES#sec-functiondeclarations-in-ifstatement-statement-clauses
373       // are handled by calling ParseScopedStatement rather than
374       // ParseSubStatement directly.
375       ReportMessageAt(scanner()->peek_location(),
376                       is_strict(language_mode())
377                           ? MessageTemplate::kStrictFunction
378                           : MessageTemplate::kSloppyFunction);
379       *ok = false;
380       return Statement::Default();
381 
382     case Token::DEBUGGER:
383       return ParseDebuggerStatement(ok);
384 
385     case Token::VAR:
386       return ParseVariableStatement(kStatement, ok);
387 
388     default:
389       return ParseExpressionOrLabelledStatement(allow_function, ok);
390   }
391 }
392 
ParseHoistableDeclaration(int pos,ParseFunctionFlags flags,bool * ok)393 PreParser::Statement PreParser::ParseHoistableDeclaration(
394     int pos, ParseFunctionFlags flags, bool* ok) {
395   const bool is_generator = flags & ParseFunctionFlags::kIsGenerator;
396   const bool is_async = flags & ParseFunctionFlags::kIsAsync;
397   DCHECK(!is_generator || !is_async);
398 
399   bool is_strict_reserved = false;
400   Identifier name = ParseIdentifierOrStrictReservedWord(
401       &is_strict_reserved, CHECK_OK);
402 
403   if (V8_UNLIKELY(is_async_function() && this->IsAwait(name))) {
404     ReportMessageAt(scanner()->location(),
405                     MessageTemplate::kAwaitBindingIdentifier);
406     *ok = false;
407     return Statement::Default();
408   }
409 
410   ParseFunctionLiteral(name, scanner()->location(),
411                        is_strict_reserved ? kFunctionNameIsStrictReserved
412                                           : kFunctionNameValidityUnknown,
413                        is_generator ? FunctionKind::kGeneratorFunction
414                                     : is_async ? FunctionKind::kAsyncFunction
415                                                : FunctionKind::kNormalFunction,
416                        pos, FunctionLiteral::kDeclaration, language_mode(),
417                        CHECK_OK);
418   return Statement::FunctionDeclaration();
419 }
420 
ParseAsyncFunctionDeclaration(bool * ok)421 PreParser::Statement PreParser::ParseAsyncFunctionDeclaration(bool* ok) {
422   // AsyncFunctionDeclaration ::
423   //   async [no LineTerminator here] function BindingIdentifier[Await]
424   //       ( FormalParameters[Await] ) { AsyncFunctionBody }
425   DCHECK_EQ(scanner()->current_token(), Token::ASYNC);
426   int pos = position();
427   Expect(Token::FUNCTION, CHECK_OK);
428   ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync;
429   return ParseHoistableDeclaration(pos, flags, ok);
430 }
431 
ParseHoistableDeclaration(bool * ok)432 PreParser::Statement PreParser::ParseHoistableDeclaration(bool* ok) {
433   // FunctionDeclaration ::
434   //   'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
435   // GeneratorDeclaration ::
436   //   'function' '*' Identifier '(' FormalParameterListopt ')'
437   //      '{' FunctionBody '}'
438 
439   Expect(Token::FUNCTION, CHECK_OK);
440   int pos = position();
441   ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal;
442   if (Check(Token::MUL)) {
443     flags |= ParseFunctionFlags::kIsGenerator;
444   }
445   return ParseHoistableDeclaration(pos, flags, ok);
446 }
447 
448 
ParseClassDeclaration(bool * ok)449 PreParser::Statement PreParser::ParseClassDeclaration(bool* ok) {
450   Expect(Token::CLASS, CHECK_OK);
451 
452   int pos = position();
453   bool is_strict_reserved = false;
454   Identifier name =
455       ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
456   ParseClassLiteral(nullptr, name, scanner()->location(), is_strict_reserved,
457                     pos, CHECK_OK);
458   return Statement::Default();
459 }
460 
461 
ParseBlock(bool * ok)462 PreParser::Statement PreParser::ParseBlock(bool* ok) {
463   // Block ::
464   //   '{' StatementList '}'
465 
466   Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
467   Expect(Token::LBRACE, CHECK_OK);
468   Statement final = Statement::Default();
469   {
470     BlockState block_state(&scope_, block_scope);
471     while (peek() != Token::RBRACE) {
472       final = ParseStatementListItem(CHECK_OK);
473     }
474   }
475   Expect(Token::RBRACE, ok);
476   return final;
477 }
478 
479 
ParseVariableStatement(VariableDeclarationContext var_context,bool * ok)480 PreParser::Statement PreParser::ParseVariableStatement(
481     VariableDeclarationContext var_context,
482     bool* ok) {
483   // VariableStatement ::
484   //   VariableDeclarations ';'
485 
486   Statement result = ParseVariableDeclarations(
487       var_context, nullptr, nullptr, nullptr, nullptr, nullptr, CHECK_OK);
488   ExpectSemicolon(CHECK_OK);
489   return result;
490 }
491 
492 
493 // If the variable declaration declares exactly one non-const
494 // variable, then *var is set to that variable. In all other cases,
495 // *var is untouched; in particular, it is the caller's responsibility
496 // to initialize it properly. This mechanism is also used for the parsing
497 // of 'for-in' loops.
ParseVariableDeclarations(VariableDeclarationContext var_context,int * num_decl,bool * is_lexical,bool * is_binding_pattern,Scanner::Location * first_initializer_loc,Scanner::Location * bindings_loc,bool * ok)498 PreParser::Statement PreParser::ParseVariableDeclarations(
499     VariableDeclarationContext var_context, int* num_decl, bool* is_lexical,
500     bool* is_binding_pattern, Scanner::Location* first_initializer_loc,
501     Scanner::Location* bindings_loc, bool* ok) {
502   // VariableDeclarations ::
503   //   ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
504   //
505   // The ES6 Draft Rev3 specifies the following grammar for const declarations
506   //
507   // ConstDeclaration ::
508   //   const ConstBinding (',' ConstBinding)* ';'
509   // ConstBinding ::
510   //   Identifier '=' AssignmentExpression
511   //
512   // TODO(ES6):
513   // ConstBinding ::
514   //   BindingPattern '=' AssignmentExpression
515   bool require_initializer = false;
516   bool lexical = false;
517   bool is_pattern = false;
518   if (peek() == Token::VAR) {
519     Consume(Token::VAR);
520   } else if (peek() == Token::CONST) {
521     // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
522     //
523     // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
524     //
525     // * It is a Syntax Error if the code that matches this production is not
526     //   contained in extended code.
527     //
528     // However disallowing const in sloppy mode will break compatibility with
529     // existing pages. Therefore we keep allowing const with the old
530     // non-harmony semantics in sloppy mode.
531     Consume(Token::CONST);
532     DCHECK(var_context != kStatement);
533     require_initializer = true;
534     lexical = true;
535   } else if (peek() == Token::LET) {
536     Consume(Token::LET);
537     DCHECK(var_context != kStatement);
538     lexical = true;
539   } else {
540     *ok = false;
541     return Statement::Default();
542   }
543 
544   // The scope of a var/const declared variable anywhere inside a function
545   // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope
546   // of a let declared variable is the scope of the immediately enclosing
547   // block.
548   int nvars = 0;  // the number of variables declared
549   int bindings_start = peek_position();
550   do {
551     // Parse binding pattern.
552     if (nvars > 0) Consume(Token::COMMA);
553     int decl_pos = peek_position();
554     PreParserExpression pattern = PreParserExpression::Default();
555     {
556       ExpressionClassifier pattern_classifier(this);
557       pattern = ParsePrimaryExpression(&pattern_classifier, CHECK_OK);
558 
559       ValidateBindingPattern(&pattern_classifier, CHECK_OK);
560       if (lexical) {
561         ValidateLetPattern(&pattern_classifier, CHECK_OK);
562       }
563     }
564 
565     is_pattern = pattern.IsObjectLiteral() || pattern.IsArrayLiteral();
566 
567     Scanner::Location variable_loc = scanner()->location();
568     nvars++;
569     if (Check(Token::ASSIGN)) {
570       ExpressionClassifier classifier(this);
571       ParseAssignmentExpression(var_context != kForStatement, &classifier,
572                                 CHECK_OK);
573       ValidateExpression(&classifier, CHECK_OK);
574 
575       variable_loc.end_pos = scanner()->location().end_pos;
576       if (first_initializer_loc && !first_initializer_loc->IsValid()) {
577         *first_initializer_loc = variable_loc;
578       }
579     } else if ((require_initializer || is_pattern) &&
580                (var_context != kForStatement || !PeekInOrOf())) {
581       PreParserTraits::ReportMessageAt(
582           Scanner::Location(decl_pos, scanner()->location().end_pos),
583           MessageTemplate::kDeclarationMissingInitializer,
584           is_pattern ? "destructuring" : "const");
585       *ok = false;
586       return Statement::Default();
587     }
588   } while (peek() == Token::COMMA);
589 
590   if (bindings_loc) {
591     *bindings_loc =
592         Scanner::Location(bindings_start, scanner()->location().end_pos);
593   }
594 
595   if (num_decl != nullptr) *num_decl = nvars;
596   if (is_lexical != nullptr) *is_lexical = lexical;
597   if (is_binding_pattern != nullptr) *is_binding_pattern = is_pattern;
598   return Statement::Default();
599 }
600 
ParseFunctionDeclaration(bool * ok)601 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
602   Consume(Token::FUNCTION);
603   int pos = position();
604   ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal;
605   if (Check(Token::MUL)) {
606     flags |= ParseFunctionFlags::kIsGenerator;
607     if (allow_harmony_restrictive_declarations()) {
608       PreParserTraits::ReportMessageAt(
609           scanner()->location(), MessageTemplate::kGeneratorInLegacyContext);
610       *ok = false;
611       return Statement::Default();
612     }
613   }
614   return ParseHoistableDeclaration(pos, flags, ok);
615 }
616 
ParseExpressionOrLabelledStatement(AllowLabelledFunctionStatement allow_function,bool * ok)617 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(
618     AllowLabelledFunctionStatement allow_function, bool* ok) {
619   // ExpressionStatement | LabelledStatement ::
620   //   Expression ';'
621   //   Identifier ':' Statement
622 
623   switch (peek()) {
624     case Token::FUNCTION:
625     case Token::LBRACE:
626       UNREACHABLE();  // Always handled by the callers.
627     case Token::CLASS:
628       ReportUnexpectedToken(Next());
629       *ok = false;
630       return Statement::Default();
631 
632     default:
633       break;
634   }
635 
636   bool starts_with_identifier = peek_any_identifier();
637   ExpressionClassifier classifier(this);
638   Expression expr = ParseExpression(true, &classifier, CHECK_OK);
639   ValidateExpression(&classifier, CHECK_OK);
640 
641   // Even if the expression starts with an identifier, it is not necessarily an
642   // identifier. For example, "foo + bar" starts with an identifier but is not
643   // an identifier.
644   if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) {
645     // Expression is a single identifier, and not, e.g., a parenthesized
646     // identifier.
647     DCHECK(!expr.AsIdentifier().IsEnum());
648     DCHECK(!parsing_module_ || !expr.AsIdentifier().IsAwait());
649     DCHECK(is_sloppy(language_mode()) ||
650            !IsFutureStrictReserved(expr.AsIdentifier()));
651     Consume(Token::COLON);
652     // ES#sec-labelled-function-declarations Labelled Function Declarations
653     if (peek() == Token::FUNCTION && is_sloppy(language_mode())) {
654       if (allow_function == kAllowLabelledFunctionStatement) {
655         return ParseFunctionDeclaration(ok);
656       } else {
657         return ParseScopedStatement(true, ok);
658       }
659     }
660     Statement statement =
661         ParseStatement(kDisallowLabelledFunctionStatement, ok);
662     return statement.IsJumpStatement() ? Statement::Default() : statement;
663     // Preparsing is disabled for extensions (because the extension details
664     // aren't passed to lazily compiled functions), so we don't
665     // accept "native function" in the preparser.
666   }
667   // Parsed expression statement.
668   ExpectSemicolon(CHECK_OK);
669   return Statement::ExpressionStatement(expr);
670 }
671 
672 
ParseIfStatement(bool * ok)673 PreParser::Statement PreParser::ParseIfStatement(bool* ok) {
674   // IfStatement ::
675   //   'if' '(' Expression ')' Statement ('else' Statement)?
676 
677   Expect(Token::IF, CHECK_OK);
678   Expect(Token::LPAREN, CHECK_OK);
679   ParseExpression(true, CHECK_OK);
680   Expect(Token::RPAREN, CHECK_OK);
681   Statement stat = ParseScopedStatement(false, CHECK_OK);
682   if (peek() == Token::ELSE) {
683     Next();
684     Statement else_stat = ParseScopedStatement(false, CHECK_OK);
685     stat = (stat.IsJumpStatement() && else_stat.IsJumpStatement()) ?
686         Statement::Jump() : Statement::Default();
687   } else {
688     stat = Statement::Default();
689   }
690   return stat;
691 }
692 
693 
ParseContinueStatement(bool * ok)694 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) {
695   // ContinueStatement ::
696   //   'continue' [no line terminator] Identifier? ';'
697 
698   Expect(Token::CONTINUE, CHECK_OK);
699   Token::Value tok = peek();
700   if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
701       tok != Token::SEMICOLON &&
702       tok != Token::RBRACE &&
703       tok != Token::EOS) {
704     // ECMA allows "eval" or "arguments" as labels even in strict mode.
705     ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
706   }
707   ExpectSemicolon(CHECK_OK);
708   return Statement::Jump();
709 }
710 
711 
ParseBreakStatement(bool * ok)712 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) {
713   // BreakStatement ::
714   //   'break' [no line terminator] Identifier? ';'
715 
716   Expect(Token::BREAK, CHECK_OK);
717   Token::Value tok = peek();
718   if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
719       tok != Token::SEMICOLON &&
720       tok != Token::RBRACE &&
721       tok != Token::EOS) {
722     // ECMA allows "eval" or "arguments" as labels even in strict mode.
723     ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
724   }
725   ExpectSemicolon(CHECK_OK);
726   return Statement::Jump();
727 }
728 
729 
ParseReturnStatement(bool * ok)730 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) {
731   // ReturnStatement ::
732   //   'return' [no line terminator] Expression? ';'
733 
734   // Consume the return token. It is necessary to do before
735   // reporting any errors on it, because of the way errors are
736   // reported (underlining).
737   Expect(Token::RETURN, CHECK_OK);
738   function_state_->set_return_location(scanner()->location());
739 
740   // An ECMAScript program is considered syntactically incorrect if it
741   // contains a return statement that is not within the body of a
742   // function. See ECMA-262, section 12.9, page 67.
743   // This is not handled during preparsing.
744 
745   Token::Value tok = peek();
746   if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
747       tok != Token::SEMICOLON &&
748       tok != Token::RBRACE &&
749       tok != Token::EOS) {
750     // Because of the return code rewriting that happens in case of a subclass
751     // constructor we don't want to accept tail calls, therefore we don't set
752     // ReturnExprScope to kInsideValidReturnStatement here.
753     ReturnExprContext return_expr_context =
754         IsSubclassConstructor(function_state_->kind())
755             ? function_state_->return_expr_context()
756             : ReturnExprContext::kInsideValidReturnStatement;
757 
758     ReturnExprScope maybe_allow_tail_calls(function_state_,
759                                            return_expr_context);
760     ParseExpression(true, CHECK_OK);
761   }
762   ExpectSemicolon(CHECK_OK);
763   return Statement::Jump();
764 }
765 
766 
ParseWithStatement(bool * ok)767 PreParser::Statement PreParser::ParseWithStatement(bool* ok) {
768   // WithStatement ::
769   //   'with' '(' Expression ')' Statement
770   Expect(Token::WITH, CHECK_OK);
771   if (is_strict(language_mode())) {
772     ReportMessageAt(scanner()->location(), MessageTemplate::kStrictWith);
773     *ok = false;
774     return Statement::Default();
775   }
776   Expect(Token::LPAREN, CHECK_OK);
777   ParseExpression(true, CHECK_OK);
778   Expect(Token::RPAREN, CHECK_OK);
779 
780   Scope* with_scope = NewScope(scope_, WITH_SCOPE);
781   BlockState block_state(&scope_, with_scope);
782   ParseScopedStatement(true, CHECK_OK);
783   return Statement::Default();
784 }
785 
786 
ParseSwitchStatement(bool * ok)787 PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) {
788   // SwitchStatement ::
789   //   'switch' '(' Expression ')' '{' CaseClause* '}'
790 
791   Expect(Token::SWITCH, CHECK_OK);
792   Expect(Token::LPAREN, CHECK_OK);
793   ParseExpression(true, CHECK_OK);
794   Expect(Token::RPAREN, CHECK_OK);
795 
796   Scope* cases_scope = NewScope(scope_, BLOCK_SCOPE);
797   {
798     BlockState cases_block_state(&scope_, cases_scope);
799     Expect(Token::LBRACE, CHECK_OK);
800     Token::Value token = peek();
801     while (token != Token::RBRACE) {
802       if (token == Token::CASE) {
803         Expect(Token::CASE, CHECK_OK);
804         ParseExpression(true, CHECK_OK);
805       } else {
806         Expect(Token::DEFAULT, CHECK_OK);
807       }
808       Expect(Token::COLON, CHECK_OK);
809       token = peek();
810       Statement statement = Statement::Jump();
811       while (token != Token::CASE &&
812              token != Token::DEFAULT &&
813              token != Token::RBRACE) {
814         statement = ParseStatementListItem(CHECK_OK);
815         token = peek();
816       }
817     }
818   }
819   Expect(Token::RBRACE, ok);
820   return Statement::Default();
821 }
822 
823 
ParseDoWhileStatement(bool * ok)824 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) {
825   // DoStatement ::
826   //   'do' Statement 'while' '(' Expression ')' ';'
827 
828   Expect(Token::DO, CHECK_OK);
829   ParseScopedStatement(true, CHECK_OK);
830   Expect(Token::WHILE, CHECK_OK);
831   Expect(Token::LPAREN, CHECK_OK);
832   ParseExpression(true, CHECK_OK);
833   Expect(Token::RPAREN, ok);
834   if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
835   return Statement::Default();
836 }
837 
838 
ParseWhileStatement(bool * ok)839 PreParser::Statement PreParser::ParseWhileStatement(bool* ok) {
840   // WhileStatement ::
841   //   'while' '(' Expression ')' Statement
842 
843   Expect(Token::WHILE, CHECK_OK);
844   Expect(Token::LPAREN, CHECK_OK);
845   ParseExpression(true, CHECK_OK);
846   Expect(Token::RPAREN, CHECK_OK);
847   ParseScopedStatement(true, ok);
848   return Statement::Default();
849 }
850 
851 
ParseForStatement(bool * ok)852 PreParser::Statement PreParser::ParseForStatement(bool* ok) {
853   // ForStatement ::
854   //   'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
855 
856   // Create an in-between scope for let-bound iteration variables.
857   Scope* for_scope = NewScope(scope_, BLOCK_SCOPE);
858   bool has_lexical = false;
859 
860   BlockState block_state(&scope_, for_scope);
861   Expect(Token::FOR, CHECK_OK);
862   Expect(Token::LPAREN, CHECK_OK);
863   if (peek() != Token::SEMICOLON) {
864     ForEachStatement::VisitMode mode;
865     if (peek() == Token::VAR || peek() == Token::CONST ||
866         (peek() == Token::LET && IsNextLetKeyword())) {
867       int decl_count;
868       bool is_lexical;
869       bool is_binding_pattern;
870       Scanner::Location first_initializer_loc = Scanner::Location::invalid();
871       Scanner::Location bindings_loc = Scanner::Location::invalid();
872       ParseVariableDeclarations(kForStatement, &decl_count, &is_lexical,
873                                 &is_binding_pattern, &first_initializer_loc,
874                                 &bindings_loc, CHECK_OK);
875       if (is_lexical) has_lexical = true;
876       if (CheckInOrOf(&mode, ok)) {
877         if (!*ok) return Statement::Default();
878         if (decl_count != 1) {
879           PreParserTraits::ReportMessageAt(
880               bindings_loc, MessageTemplate::kForInOfLoopMultiBindings,
881               ForEachStatement::VisitModeString(mode));
882           *ok = false;
883           return Statement::Default();
884         }
885         if (first_initializer_loc.IsValid() &&
886             (is_strict(language_mode()) || mode == ForEachStatement::ITERATE ||
887              is_lexical || is_binding_pattern || allow_harmony_for_in())) {
888           // Only increment the use count if we would have let this through
889           // without the flag.
890           if (use_counts_ != nullptr && allow_harmony_for_in()) {
891             ++use_counts_[v8::Isolate::kForInInitializer];
892           }
893           PreParserTraits::ReportMessageAt(
894               first_initializer_loc, MessageTemplate::kForInOfLoopInitializer,
895               ForEachStatement::VisitModeString(mode));
896           *ok = false;
897           return Statement::Default();
898         }
899 
900         if (mode == ForEachStatement::ITERATE) {
901           ExpressionClassifier classifier(this);
902           ParseAssignmentExpression(true, &classifier, CHECK_OK);
903           RewriteNonPattern(&classifier, CHECK_OK);
904         } else {
905           ParseExpression(true, CHECK_OK);
906         }
907 
908         Expect(Token::RPAREN, CHECK_OK);
909         {
910           ReturnExprScope no_tail_calls(function_state_,
911                                         ReturnExprContext::kInsideForInOfBody);
912           ParseScopedStatement(true, CHECK_OK);
913         }
914         return Statement::Default();
915       }
916     } else {
917       int lhs_beg_pos = peek_position();
918       ExpressionClassifier classifier(this);
919       Expression lhs = ParseExpression(false, &classifier, CHECK_OK);
920       int lhs_end_pos = scanner()->location().end_pos;
921       bool is_for_each = CheckInOrOf(&mode, ok);
922       if (!*ok) return Statement::Default();
923       bool is_destructuring = is_for_each &&
924                               (lhs->IsArrayLiteral() || lhs->IsObjectLiteral());
925 
926       if (is_destructuring) {
927         ValidateAssignmentPattern(&classifier, CHECK_OK);
928       } else {
929         ValidateExpression(&classifier, CHECK_OK);
930       }
931 
932       if (is_for_each) {
933         if (!is_destructuring) {
934           lhs = CheckAndRewriteReferenceExpression(
935               lhs, lhs_beg_pos, lhs_end_pos, MessageTemplate::kInvalidLhsInFor,
936               kSyntaxError, CHECK_OK);
937         }
938 
939         if (mode == ForEachStatement::ITERATE) {
940           ExpressionClassifier classifier(this);
941           ParseAssignmentExpression(true, &classifier, CHECK_OK);
942           RewriteNonPattern(&classifier, CHECK_OK);
943         } else {
944           ParseExpression(true, CHECK_OK);
945         }
946 
947         Expect(Token::RPAREN, CHECK_OK);
948         Scope* body_scope = NewScope(scope_, BLOCK_SCOPE);
949         {
950           BlockState block_state(&scope_, body_scope);
951           ParseScopedStatement(true, CHECK_OK);
952         }
953         return Statement::Default();
954       }
955     }
956   }
957 
958   // Parsed initializer at this point.
959   Expect(Token::SEMICOLON, CHECK_OK);
960 
961   // If there are let bindings, then condition and the next statement of the
962   // for loop must be parsed in a new scope.
963   Scope* inner_scope = scope_;
964   if (has_lexical) inner_scope = NewScope(for_scope, BLOCK_SCOPE);
965 
966   {
967     BlockState block_state(&scope_, inner_scope);
968 
969     if (peek() != Token::SEMICOLON) {
970       ParseExpression(true, CHECK_OK);
971     }
972     Expect(Token::SEMICOLON, CHECK_OK);
973 
974     if (peek() != Token::RPAREN) {
975       ParseExpression(true, CHECK_OK);
976     }
977     Expect(Token::RPAREN, CHECK_OK);
978 
979     ParseScopedStatement(true, ok);
980   }
981   return Statement::Default();
982 }
983 
984 
ParseThrowStatement(bool * ok)985 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) {
986   // ThrowStatement ::
987   //   'throw' [no line terminator] Expression ';'
988 
989   Expect(Token::THROW, CHECK_OK);
990   if (scanner()->HasAnyLineTerminatorBeforeNext()) {
991     ReportMessageAt(scanner()->location(), MessageTemplate::kNewlineAfterThrow);
992     *ok = false;
993     return Statement::Default();
994   }
995   ParseExpression(true, CHECK_OK);
996   ExpectSemicolon(ok);
997   return Statement::Jump();
998 }
999 
1000 
ParseTryStatement(bool * ok)1001 PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
1002   // TryStatement ::
1003   //   'try' Block Catch
1004   //   'try' Block Finally
1005   //   'try' Block Catch Finally
1006   //
1007   // Catch ::
1008   //   'catch' '(' Identifier ')' Block
1009   //
1010   // Finally ::
1011   //   'finally' Block
1012 
1013   Expect(Token::TRY, CHECK_OK);
1014 
1015   {
1016     ReturnExprScope no_tail_calls(function_state_,
1017                                   ReturnExprContext::kInsideTryBlock);
1018     ParseBlock(CHECK_OK);
1019   }
1020 
1021   Token::Value tok = peek();
1022   if (tok != Token::CATCH && tok != Token::FINALLY) {
1023     ReportMessageAt(scanner()->location(), MessageTemplate::kNoCatchOrFinally);
1024     *ok = false;
1025     return Statement::Default();
1026   }
1027   TailCallExpressionList tail_call_expressions_in_catch_block(zone());
1028   bool catch_block_exists = false;
1029   if (tok == Token::CATCH) {
1030     Consume(Token::CATCH);
1031     Expect(Token::LPAREN, CHECK_OK);
1032     Scope* catch_scope = NewScope(scope_, CATCH_SCOPE);
1033     ExpressionClassifier pattern_classifier(this);
1034     ParsePrimaryExpression(&pattern_classifier, CHECK_OK);
1035     ValidateBindingPattern(&pattern_classifier, CHECK_OK);
1036     Expect(Token::RPAREN, CHECK_OK);
1037     {
1038       CollectExpressionsInTailPositionToListScope
1039           collect_tail_call_expressions_scope(
1040               function_state_, &tail_call_expressions_in_catch_block);
1041       BlockState block_state(&scope_, catch_scope);
1042       Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
1043       {
1044         BlockState block_state(&scope_, block_scope);
1045         ParseBlock(CHECK_OK);
1046       }
1047     }
1048     catch_block_exists = true;
1049     tok = peek();
1050   }
1051   if (tok == Token::FINALLY) {
1052     Consume(Token::FINALLY);
1053     ParseBlock(CHECK_OK);
1054     if (FLAG_harmony_explicit_tailcalls && catch_block_exists &&
1055         tail_call_expressions_in_catch_block.has_explicit_tail_calls()) {
1056       // TODO(ishell): update chapter number.
1057       // ES8 XX.YY.ZZ
1058       ReportMessageAt(tail_call_expressions_in_catch_block.location(),
1059                       MessageTemplate::kUnexpectedTailCallInCatchBlock);
1060       *ok = false;
1061       return Statement::Default();
1062     }
1063   }
1064   return Statement::Default();
1065 }
1066 
1067 
ParseDebuggerStatement(bool * ok)1068 PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) {
1069   // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
1070   // contexts this is used as a statement which invokes the debugger as if a
1071   // break point is present.
1072   // DebuggerStatement ::
1073   //   'debugger' ';'
1074 
1075   Expect(Token::DEBUGGER, CHECK_OK);
1076   ExpectSemicolon(ok);
1077   return Statement::Default();
1078 }
1079 
1080 
1081 #undef CHECK_OK
1082 #define CHECK_OK  ok);                     \
1083   if (!*ok) return Expression::Default();  \
1084   ((void)0
1085 #define DUMMY )  // to make indentation work
1086 #undef DUMMY
1087 
1088 
ParseFunctionLiteral(Identifier function_name,Scanner::Location function_name_location,FunctionNameValidity function_name_validity,FunctionKind kind,int function_token_pos,FunctionLiteral::FunctionType function_type,LanguageMode language_mode,bool * ok)1089 PreParser::Expression PreParser::ParseFunctionLiteral(
1090     Identifier function_name, Scanner::Location function_name_location,
1091     FunctionNameValidity function_name_validity, FunctionKind kind,
1092     int function_token_pos, FunctionLiteral::FunctionType function_type,
1093     LanguageMode language_mode, bool* ok) {
1094   // Function ::
1095   //   '(' FormalParameterList? ')' '{' FunctionBody '}'
1096 
1097   // Parse function body.
1098   bool outer_is_script_scope = scope_->is_script_scope();
1099   Scope* function_scope = NewScope(scope_, FUNCTION_SCOPE, kind);
1100   function_scope->SetLanguageMode(language_mode);
1101   PreParserFactory factory(NULL);
1102   FunctionState function_state(&function_state_, &scope_, function_scope, kind,
1103                                &factory);
1104   DuplicateFinder duplicate_finder(scanner()->unicode_cache());
1105   ExpressionClassifier formals_classifier(this, &duplicate_finder);
1106 
1107   Expect(Token::LPAREN, CHECK_OK);
1108   int start_position = scanner()->location().beg_pos;
1109   function_scope->set_start_position(start_position);
1110   PreParserFormalParameters formals(function_scope);
1111   ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK);
1112   Expect(Token::RPAREN, CHECK_OK);
1113   int formals_end_position = scanner()->location().end_pos;
1114 
1115   CheckArityRestrictions(formals.arity, kind, formals.has_rest, start_position,
1116                          formals_end_position, CHECK_OK);
1117 
1118   // See Parser::ParseFunctionLiteral for more information about lazy parsing
1119   // and lazy compilation.
1120   bool is_lazily_parsed = (outer_is_script_scope && allow_lazy() &&
1121                            !function_state_->this_function_is_parenthesized());
1122 
1123   Expect(Token::LBRACE, CHECK_OK);
1124   if (is_lazily_parsed) {
1125     ParseLazyFunctionLiteralBody(CHECK_OK);
1126   } else {
1127     ParseStatementList(Token::RBRACE, CHECK_OK);
1128   }
1129   Expect(Token::RBRACE, CHECK_OK);
1130 
1131   // Parsing the body may change the language mode in our scope.
1132   language_mode = function_scope->language_mode();
1133 
1134   // Validate name and parameter names. We can do this only after parsing the
1135   // function, since the function can declare itself strict.
1136   CheckFunctionName(language_mode, function_name, function_name_validity,
1137                     function_name_location, CHECK_OK);
1138   const bool allow_duplicate_parameters =
1139       is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind);
1140   ValidateFormalParameters(&formals_classifier, language_mode,
1141                            allow_duplicate_parameters, CHECK_OK);
1142 
1143   if (is_strict(language_mode)) {
1144     int end_position = scanner()->location().end_pos;
1145     CheckStrictOctalLiteral(start_position, end_position, CHECK_OK);
1146     CheckDecimalLiteralWithLeadingZero(use_counts_, start_position,
1147                                        end_position);
1148   }
1149 
1150   return Expression::Default();
1151 }
1152 
ParseAsyncFunctionExpression(bool * ok)1153 PreParser::Expression PreParser::ParseAsyncFunctionExpression(bool* ok) {
1154   // AsyncFunctionDeclaration ::
1155   //   async [no LineTerminator here] function ( FormalParameters[Await] )
1156   //       { AsyncFunctionBody }
1157   //
1158   //   async [no LineTerminator here] function BindingIdentifier[Await]
1159   //       ( FormalParameters[Await] ) { AsyncFunctionBody }
1160   int pos = position();
1161   Expect(Token::FUNCTION, CHECK_OK);
1162   bool is_strict_reserved = false;
1163   Identifier name;
1164   FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression;
1165 
1166   if (peek_any_identifier()) {
1167     type = FunctionLiteral::kNamedExpression;
1168     name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
1169     if (this->IsAwait(name)) {
1170       ReportMessageAt(scanner()->location(),
1171                       MessageTemplate::kAwaitBindingIdentifier);
1172       *ok = false;
1173       return Expression::Default();
1174     }
1175   }
1176 
1177   ParseFunctionLiteral(name, scanner()->location(),
1178                        is_strict_reserved ? kFunctionNameIsStrictReserved
1179                                           : kFunctionNameValidityUnknown,
1180                        FunctionKind::kAsyncFunction, pos, type, language_mode(),
1181                        CHECK_OK);
1182   return Expression::Default();
1183 }
1184 
ParseLazyFunctionLiteralBody(bool * ok,Scanner::BookmarkScope * bookmark)1185 void PreParser::ParseLazyFunctionLiteralBody(bool* ok,
1186                                              Scanner::BookmarkScope* bookmark) {
1187   int body_start = position();
1188   ParseStatementList(Token::RBRACE, ok, bookmark);
1189   if (!*ok) return;
1190   if (bookmark && bookmark->HasBeenReset()) return;
1191 
1192   // Position right after terminal '}'.
1193   DCHECK_EQ(Token::RBRACE, scanner()->peek());
1194   int body_end = scanner()->peek_location().end_pos;
1195   log_->LogFunction(body_start, body_end,
1196                     function_state_->materialized_literal_count(),
1197                     function_state_->expected_property_count(), language_mode(),
1198                     scope_->uses_super_property(), scope_->calls_eval());
1199 }
1200 
ParseClassLiteral(ExpressionClassifier * classifier,PreParserIdentifier name,Scanner::Location class_name_location,bool name_is_strict_reserved,int pos,bool * ok)1201 PreParserExpression PreParser::ParseClassLiteral(
1202     ExpressionClassifier* classifier, PreParserIdentifier name,
1203     Scanner::Location class_name_location, bool name_is_strict_reserved,
1204     int pos, bool* ok) {
1205   // All parts of a ClassDeclaration and ClassExpression are strict code.
1206   if (name_is_strict_reserved) {
1207     ReportMessageAt(class_name_location,
1208                     MessageTemplate::kUnexpectedStrictReserved);
1209     *ok = false;
1210     return EmptyExpression();
1211   }
1212   if (IsEvalOrArguments(name)) {
1213     ReportMessageAt(class_name_location, MessageTemplate::kStrictEvalArguments);
1214     *ok = false;
1215     return EmptyExpression();
1216   }
1217 
1218   LanguageMode class_language_mode = language_mode();
1219   Scope* scope = NewScope(scope_, BLOCK_SCOPE);
1220   BlockState block_state(&scope_, scope);
1221   scope_->SetLanguageMode(
1222       static_cast<LanguageMode>(class_language_mode | STRICT));
1223   // TODO(marja): Make PreParser use scope names too.
1224   // scope_->SetScopeName(name);
1225 
1226   bool has_extends = Check(Token::EXTENDS);
1227   if (has_extends) {
1228     ExpressionClassifier extends_classifier(this);
1229     ParseLeftHandSideExpression(&extends_classifier, CHECK_OK);
1230     CheckNoTailCallExpressions(&extends_classifier, CHECK_OK);
1231     ValidateExpression(&extends_classifier, CHECK_OK);
1232     if (classifier != nullptr) {
1233       classifier->Accumulate(&extends_classifier,
1234                              ExpressionClassifier::ExpressionProductions);
1235     }
1236   }
1237 
1238   ClassLiteralChecker checker(this);
1239   bool has_seen_constructor = false;
1240 
1241   Expect(Token::LBRACE, CHECK_OK);
1242   while (peek() != Token::RBRACE) {
1243     if (Check(Token::SEMICOLON)) continue;
1244     const bool in_class = true;
1245     bool is_computed_name = false;  // Classes do not care about computed
1246                                     // property names here.
1247     Identifier name;
1248     ExpressionClassifier property_classifier(this);
1249     ParsePropertyDefinition(&checker, in_class, has_extends, MethodKind::Normal,
1250                             &is_computed_name, &has_seen_constructor,
1251                             &property_classifier, &name, CHECK_OK);
1252     ValidateExpression(&property_classifier, CHECK_OK);
1253     if (classifier != nullptr) {
1254       classifier->Accumulate(&property_classifier,
1255                              ExpressionClassifier::ExpressionProductions);
1256     }
1257   }
1258 
1259   Expect(Token::RBRACE, CHECK_OK);
1260 
1261   return Expression::Default();
1262 }
1263 
1264 
ParseV8Intrinsic(bool * ok)1265 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
1266   // CallRuntime ::
1267   //   '%' Identifier Arguments
1268   Expect(Token::MOD, CHECK_OK);
1269   if (!allow_natives()) {
1270     *ok = false;
1271     return Expression::Default();
1272   }
1273   // Allow "eval" or "arguments" for backward compatibility.
1274   ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
1275   Scanner::Location spread_pos;
1276   ExpressionClassifier classifier(this);
1277   ParseArguments(&spread_pos, &classifier, ok);
1278   ValidateExpression(&classifier, CHECK_OK);
1279 
1280   DCHECK(!spread_pos.IsValid());
1281 
1282   return Expression::Default();
1283 }
1284 
1285 
ParseDoExpression(bool * ok)1286 PreParserExpression PreParser::ParseDoExpression(bool* ok) {
1287   // AssignmentExpression ::
1288   //     do '{' StatementList '}'
1289   Expect(Token::DO, CHECK_OK);
1290   Expect(Token::LBRACE, CHECK_OK);
1291   while (peek() != Token::RBRACE) {
1292     ParseStatementListItem(CHECK_OK);
1293   }
1294   Expect(Token::RBRACE, CHECK_OK);
1295   return PreParserExpression::Default();
1296 }
1297 
ParseAsyncArrowSingleExpressionBody(PreParserStatementList body,bool accept_IN,Type::ExpressionClassifier * classifier,int pos,bool * ok)1298 void PreParserTraits::ParseAsyncArrowSingleExpressionBody(
1299     PreParserStatementList body, bool accept_IN,
1300     Type::ExpressionClassifier* classifier, int pos, bool* ok) {
1301   Scope* scope = pre_parser_->scope_;
1302   scope->ForceContextAllocation();
1303 
1304   PreParserExpression return_value =
1305       pre_parser_->ParseAssignmentExpression(accept_IN, classifier, ok);
1306   if (!*ok) return;
1307 
1308   body->Add(PreParserStatement::ExpressionStatement(return_value), zone());
1309 }
1310 
1311 #undef CHECK_OK
1312 
1313 
1314 }  // namespace internal
1315 }  // namespace v8
1316