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