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