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