deps: update v8 to 4.3.61.21
[platform/upstream/nodejs.git] / deps / v8 / 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                                       const char* message, const char* arg,
25                                       ParseErrorType error_type) {
26   ReportMessageAt(location.beg_pos, location.end_pos, message, arg, error_type);
27 }
28
29
30 void PreParserTraits::ReportMessageAt(int start_pos, int end_pos,
31                                       const char* message, const char* arg,
32                                       ParseErrorType error_type) {
33   pre_parser_->log_->LogMessage(start_pos, end_pos, message, arg, error_type);
34 }
35
36
37 PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) {
38   if (scanner->current_token() == Token::FUTURE_RESERVED_WORD) {
39     return PreParserIdentifier::FutureReserved();
40   } else if (scanner->current_token() ==
41              Token::FUTURE_STRICT_RESERVED_WORD) {
42     return PreParserIdentifier::FutureStrictReserved();
43   } else if (scanner->current_token() == Token::LET) {
44     return PreParserIdentifier::Let();
45   } else if (scanner->current_token() == Token::STATIC) {
46     return PreParserIdentifier::Static();
47   } else if (scanner->current_token() == Token::YIELD) {
48     return PreParserIdentifier::Yield();
49   }
50   if (scanner->UnescapedLiteralMatches("eval", 4)) {
51     return PreParserIdentifier::Eval();
52   }
53   if (scanner->UnescapedLiteralMatches("arguments", 9)) {
54     return PreParserIdentifier::Arguments();
55   }
56   if (scanner->LiteralMatches("prototype", 9)) {
57     return PreParserIdentifier::Prototype();
58   }
59   if (scanner->LiteralMatches("constructor", 11)) {
60     return PreParserIdentifier::Constructor();
61   }
62   return PreParserIdentifier::Default();
63 }
64
65
66 PreParserIdentifier PreParserTraits::GetNumberAsSymbol(Scanner* scanner) {
67   return PreParserIdentifier::Default();
68 }
69
70
71 PreParserExpression PreParserTraits::ExpressionFromString(
72     int pos, Scanner* scanner, PreParserFactory* factory) {
73   if (scanner->UnescapedLiteralMatches("use strict", 10)) {
74     return PreParserExpression::UseStrictStringLiteral();
75   } else if (scanner->UnescapedLiteralMatches("use strong", 10)) {
76     return PreParserExpression::UseStrongStringLiteral();
77   }
78   return PreParserExpression::StringLiteral();
79 }
80
81
82 PreParserExpression PreParserTraits::ParseV8Intrinsic(bool* ok) {
83   return pre_parser_->ParseV8Intrinsic(ok);
84 }
85
86
87 PreParserExpression PreParserTraits::ParseFunctionLiteral(
88     PreParserIdentifier name, Scanner::Location function_name_location,
89     bool name_is_strict_reserved, FunctionKind kind,
90     int function_token_position, FunctionLiteral::FunctionType type,
91     FunctionLiteral::ArityRestriction arity_restriction, bool* ok) {
92   return pre_parser_->ParseFunctionLiteral(
93       name, function_name_location, name_is_strict_reserved, kind,
94       function_token_position, type, arity_restriction, ok);
95 }
96
97
98 PreParser::PreParseResult PreParser::PreParseLazyFunction(
99     LanguageMode language_mode, FunctionKind kind, ParserRecorder* log) {
100   log_ = log;
101   // Lazy functions always have trivial outer scopes (no with/catch scopes).
102   Scope* top_scope = NewScope(scope_, SCRIPT_SCOPE);
103   PreParserFactory top_factory(NULL);
104   FunctionState top_state(&function_state_, &scope_, top_scope, kNormalFunction,
105                           &top_factory);
106   scope_->SetLanguageMode(language_mode);
107   Scope* function_scope = NewScope(scope_, FUNCTION_SCOPE);
108   PreParserFactory function_factory(NULL);
109   FunctionState function_state(&function_state_, &scope_, function_scope, kind,
110                                &function_factory);
111   DCHECK_EQ(Token::LBRACE, scanner()->current_token());
112   bool ok = true;
113   int start_position = peek_position();
114   ParseLazyFunctionLiteralBody(&ok);
115   if (stack_overflow()) return kPreParseStackOverflow;
116   if (!ok) {
117     ReportUnexpectedToken(scanner()->current_token());
118   } else {
119     DCHECK_EQ(Token::RBRACE, scanner()->peek());
120     if (is_strict(scope_->language_mode())) {
121       int end_pos = scanner()->location().end_pos;
122       CheckStrictOctalLiteral(start_position, end_pos, &ok);
123     }
124   }
125   return kPreParseSuccess;
126 }
127
128
129 PreParserExpression PreParserTraits::ParseClassLiteral(
130     PreParserIdentifier name, Scanner::Location class_name_location,
131     bool name_is_strict_reserved, int pos, bool* ok) {
132   return pre_parser_->ParseClassLiteral(name, class_name_location,
133                                         name_is_strict_reserved, pos, ok);
134 }
135
136
137 // Preparsing checks a JavaScript program and emits preparse-data that helps
138 // a later parsing to be faster.
139 // See preparser-data.h for the data.
140
141 // The PreParser checks that the syntax follows the grammar for JavaScript,
142 // and collects some information about the program along the way.
143 // The grammar check is only performed in order to understand the program
144 // sufficiently to deduce some information about it, that can be used
145 // to speed up later parsing. Finding errors is not the goal of pre-parsing,
146 // rather it is to speed up properly written and correct programs.
147 // That means that contextual checks (like a label being declared where
148 // it is used) are generally omitted.
149
150
151 PreParser::Statement PreParser::ParseStatementListItem(bool* ok) {
152   // ECMA 262 6th Edition
153   // StatementListItem[Yield, Return] :
154   //   Statement[?Yield, ?Return]
155   //   Declaration[?Yield]
156   //
157   // Declaration[Yield] :
158   //   HoistableDeclaration[?Yield]
159   //   ClassDeclaration[?Yield]
160   //   LexicalDeclaration[In, ?Yield]
161   //
162   // HoistableDeclaration[Yield, Default] :
163   //   FunctionDeclaration[?Yield, ?Default]
164   //   GeneratorDeclaration[?Yield, ?Default]
165   //
166   // LexicalDeclaration[In, Yield] :
167   //   LetOrConst BindingList[?In, ?Yield] ;
168
169   switch (peek()) {
170     case Token::FUNCTION:
171       return ParseFunctionDeclaration(ok);
172     case Token::CLASS:
173       return ParseClassDeclaration(ok);
174     case Token::CONST:
175       return ParseVariableStatement(kStatementListItem, ok);
176     case Token::LET:
177       if (is_strict(language_mode())) {
178         return ParseVariableStatement(kStatementListItem, ok);
179       }
180       // Fall through.
181     default:
182       return ParseStatement(ok);
183   }
184 }
185
186
187 void PreParser::ParseStatementList(int end_token, bool* ok) {
188   // SourceElements ::
189   //   (Statement)* <end_token>
190
191   bool directive_prologue = true;
192   while (peek() != end_token) {
193     if (directive_prologue && peek() != Token::STRING) {
194       directive_prologue = false;
195     }
196     Token::Value token = peek();
197     Scanner::Location old_super_loc = function_state_->super_call_location();
198     Statement statement = ParseStatementListItem(ok);
199     if (!*ok) return;
200     Scanner::Location super_loc = function_state_->super_call_location();
201     if (is_strong(language_mode()) &&
202         i::IsConstructor(function_state_->kind()) &&
203         !old_super_loc.IsValid() && super_loc.IsValid() &&
204         token != Token::SUPER) {
205       ReportMessageAt(super_loc, "strong_super_call_nested");
206       *ok = false;
207       return;
208     }
209     if (directive_prologue) {
210       if (statement.IsUseStrictLiteral()) {
211         scope_->SetLanguageMode(
212             static_cast<LanguageMode>(scope_->language_mode() | STRICT_BIT));
213       } else if (statement.IsUseStrongLiteral() && allow_strong_mode()) {
214         scope_->SetLanguageMode(static_cast<LanguageMode>(
215             scope_->language_mode() | STRICT_BIT | STRONG_BIT));
216       } else if (!statement.IsStringLiteral()) {
217         directive_prologue = false;
218       }
219     }
220   }
221 }
222
223
224 #define CHECK_OK  ok);                   \
225   if (!*ok) return Statement::Default();  \
226   ((void)0
227 #define DUMMY )  // to make indentation work
228 #undef DUMMY
229
230
231 PreParser::Statement PreParser::ParseStatement(bool* ok) {
232   // Statement ::
233   //   EmptyStatement
234   //   ...
235   return ParseSubStatement(ok);
236 }
237
238
239 PreParser::Statement PreParser::ParseSubStatement(bool* ok) {
240   // Statement ::
241   //   Block
242   //   VariableStatement
243   //   EmptyStatement
244   //   ExpressionStatement
245   //   IfStatement
246   //   IterationStatement
247   //   ContinueStatement
248   //   BreakStatement
249   //   ReturnStatement
250   //   WithStatement
251   //   LabelledStatement
252   //   SwitchStatement
253   //   ThrowStatement
254   //   TryStatement
255   //   DebuggerStatement
256
257   // Note: Since labels can only be used by 'break' and 'continue'
258   // statements, which themselves are only valid within blocks,
259   // iterations or 'switch' statements (i.e., BreakableStatements),
260   // labels can be simply ignored in all other cases; except for
261   // trivial labeled break statements 'label: break label' which is
262   // parsed into an empty statement.
263
264   // Keep the source position of the statement
265   switch (peek()) {
266     case Token::LBRACE:
267       return ParseBlock(ok);
268
269     case Token::SEMICOLON:
270       if (is_strong(language_mode())) {
271         PreParserTraits::ReportMessageAt(scanner()->peek_location(),
272                                          "strong_empty");
273         *ok = false;
274         return Statement::Default();
275       }
276       Next();
277       return Statement::Default();
278
279     case Token::IF:
280       return ParseIfStatement(ok);
281
282     case Token::DO:
283       return ParseDoWhileStatement(ok);
284
285     case Token::WHILE:
286       return ParseWhileStatement(ok);
287
288     case Token::FOR:
289       return ParseForStatement(ok);
290
291     case Token::CONTINUE:
292       return ParseContinueStatement(ok);
293
294     case Token::BREAK:
295       return ParseBreakStatement(ok);
296
297     case Token::RETURN:
298       return ParseReturnStatement(ok);
299
300     case Token::WITH:
301       return ParseWithStatement(ok);
302
303     case Token::SWITCH:
304       return ParseSwitchStatement(ok);
305
306     case Token::THROW:
307       return ParseThrowStatement(ok);
308
309     case Token::TRY:
310       return ParseTryStatement(ok);
311
312     case Token::FUNCTION: {
313       Scanner::Location start_location = scanner()->peek_location();
314       Statement statement = ParseFunctionDeclaration(CHECK_OK);
315       Scanner::Location end_location = scanner()->location();
316       if (is_strict(language_mode())) {
317         PreParserTraits::ReportMessageAt(start_location.beg_pos,
318                                          end_location.end_pos,
319                                          "strict_function");
320         *ok = false;
321         return Statement::Default();
322       } else {
323         return statement;
324       }
325     }
326
327     case Token::DEBUGGER:
328       return ParseDebuggerStatement(ok);
329
330     case Token::VAR:
331       return ParseVariableStatement(kStatement, ok);
332
333     case Token::CONST:
334       // In ES6 CONST is not allowed as a Statement, only as a
335       // LexicalDeclaration, however we continue to allow it in sloppy mode for
336       // backwards compatibility.
337       if (is_sloppy(language_mode())) {
338         return ParseVariableStatement(kStatement, ok);
339       }
340
341     // Fall through.
342     default:
343       return ParseExpressionOrLabelledStatement(ok);
344   }
345 }
346
347
348 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
349   // FunctionDeclaration ::
350   //   'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
351   // GeneratorDeclaration ::
352   //   'function' '*' Identifier '(' FormalParameterListopt ')'
353   //      '{' FunctionBody '}'
354   Expect(Token::FUNCTION, CHECK_OK);
355   int pos = position();
356   bool is_generator = Check(Token::MUL);
357   bool is_strict_reserved = false;
358   Identifier name = ParseIdentifierOrStrictReservedWord(
359       &is_strict_reserved, CHECK_OK);
360   ParseFunctionLiteral(name, scanner()->location(), is_strict_reserved,
361                        is_generator ? FunctionKind::kGeneratorFunction
362                                     : FunctionKind::kNormalFunction,
363                        pos, FunctionLiteral::DECLARATION,
364                        FunctionLiteral::NORMAL_ARITY, CHECK_OK);
365   return Statement::FunctionDeclaration();
366 }
367
368
369 PreParser::Statement PreParser::ParseClassDeclaration(bool* ok) {
370   Expect(Token::CLASS, CHECK_OK);
371   if (!allow_harmony_sloppy() && is_sloppy(language_mode())) {
372     ReportMessage("sloppy_lexical");
373     *ok = false;
374     return Statement::Default();
375   }
376
377   int pos = position();
378   bool is_strict_reserved = false;
379   Identifier name =
380       ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
381   ParseClassLiteral(name, scanner()->location(), is_strict_reserved, pos,
382                     CHECK_OK);
383   return Statement::Default();
384 }
385
386
387 PreParser::Statement PreParser::ParseBlock(bool* ok) {
388   // Block ::
389   //   '{' Statement* '}'
390
391   // Note that a Block does not introduce a new execution scope!
392   // (ECMA-262, 3rd, 12.2)
393   //
394   Expect(Token::LBRACE, CHECK_OK);
395   while (peek() != Token::RBRACE) {
396     if (is_strict(language_mode())) {
397       ParseStatementListItem(CHECK_OK);
398     } else {
399       ParseStatement(CHECK_OK);
400     }
401   }
402   Expect(Token::RBRACE, ok);
403   return Statement::Default();
404 }
405
406
407 PreParser::Statement PreParser::ParseVariableStatement(
408     VariableDeclarationContext var_context,
409     bool* ok) {
410   // VariableStatement ::
411   //   VariableDeclarations ';'
412
413   Statement result = ParseVariableDeclarations(var_context,
414                                                NULL,
415                                                NULL,
416                                                CHECK_OK);
417   ExpectSemicolon(CHECK_OK);
418   return result;
419 }
420
421
422 // If the variable declaration declares exactly one non-const
423 // variable, then *var is set to that variable. In all other cases,
424 // *var is untouched; in particular, it is the caller's responsibility
425 // to initialize it properly. This mechanism is also used for the parsing
426 // of 'for-in' loops.
427 PreParser::Statement PreParser::ParseVariableDeclarations(
428     VariableDeclarationContext var_context,
429     VariableDeclarationProperties* decl_props,
430     int* num_decl,
431     bool* ok) {
432   // VariableDeclarations ::
433   //   ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
434   //
435   // The ES6 Draft Rev3 specifies the following grammar for const declarations
436   //
437   // ConstDeclaration ::
438   //   const ConstBinding (',' ConstBinding)* ';'
439   // ConstBinding ::
440   //   Identifier '=' AssignmentExpression
441   //
442   // TODO(ES6):
443   // ConstBinding ::
444   //   BindingPattern '=' AssignmentExpression
445   bool require_initializer = false;
446   bool is_strict_const = false;
447   if (peek() == Token::VAR) {
448     if (is_strong(language_mode())) {
449       Scanner::Location location = scanner()->peek_location();
450       ReportMessageAt(location, "strong_var");
451       *ok = false;
452       return Statement::Default();
453     }
454     Consume(Token::VAR);
455   } else if (peek() == Token::CONST) {
456     // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
457     //
458     // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
459     //
460     // * It is a Syntax Error if the code that matches this production is not
461     //   contained in extended code.
462     //
463     // However disallowing const in sloppy mode will break compatibility with
464     // existing pages. Therefore we keep allowing const with the old
465     // non-harmony semantics in sloppy mode.
466     Consume(Token::CONST);
467     if (is_strict(language_mode())) {
468       DCHECK(var_context != kStatement);
469       is_strict_const = true;
470       require_initializer = var_context != kForStatement;
471     }
472   } else if (peek() == Token::LET && is_strict(language_mode())) {
473     Consume(Token::LET);
474     DCHECK(var_context != kStatement);
475   } else {
476     *ok = false;
477     return Statement::Default();
478   }
479
480   // The scope of a var/const declared variable anywhere inside a function
481   // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope
482   // of a let declared variable is the scope of the immediately enclosing
483   // block.
484   int nvars = 0;  // the number of variables declared
485   do {
486     // Parse variable name.
487     if (nvars > 0) Consume(Token::COMMA);
488     ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
489     nvars++;
490     if (peek() == Token::ASSIGN || require_initializer ||
491         // require initializers for multiple consts.
492         (is_strict_const && peek() == Token::COMMA)) {
493       Expect(Token::ASSIGN, CHECK_OK);
494       ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
495       if (decl_props != NULL) *decl_props = kHasInitializers;
496     }
497   } while (peek() == Token::COMMA);
498
499   if (num_decl != NULL) *num_decl = nvars;
500   return Statement::Default();
501 }
502
503
504 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
505   // ExpressionStatement | LabelledStatement ::
506   //   Expression ';'
507   //   Identifier ':' Statement
508
509   switch (peek()) {
510     case Token::FUNCTION:
511     case Token::LBRACE:
512       UNREACHABLE();  // Always handled by the callers.
513     case Token::CLASS:
514       ReportUnexpectedToken(Next());
515       *ok = false;
516       return Statement::Default();
517
518     // TODO(arv): Handle `let [`
519     // https://code.google.com/p/v8/issues/detail?id=3847
520
521     default:
522       break;
523   }
524
525   bool starts_with_identifier = peek_any_identifier();
526   Expression expr = ParseExpression(true, CHECK_OK);
527   // Even if the expression starts with an identifier, it is not necessarily an
528   // identifier. For example, "foo + bar" starts with an identifier but is not
529   // an identifier.
530   if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) {
531     // Expression is a single identifier, and not, e.g., a parenthesized
532     // identifier.
533     DCHECK(!expr.AsIdentifier().IsFutureReserved());
534     DCHECK(is_sloppy(language_mode()) ||
535            !IsFutureStrictReserved(expr.AsIdentifier()));
536     Consume(Token::COLON);
537     return ParseStatement(ok);
538     // Preparsing is disabled for extensions (because the extension details
539     // aren't passed to lazily compiled functions), so we don't
540     // accept "native function" in the preparser.
541   }
542   // Parsed expression statement.
543   // Detect attempts at 'let' declarations in sloppy mode.
544   if (peek() == Token::IDENTIFIER && is_sloppy(language_mode()) &&
545       expr.IsIdentifier() && expr.AsIdentifier().IsLet()) {
546     ReportMessage("sloppy_lexical", NULL);
547     *ok = false;
548     return Statement::Default();
549   }
550   ExpectSemicolon(CHECK_OK);
551   return Statement::ExpressionStatement(expr);
552 }
553
554
555 PreParser::Statement PreParser::ParseIfStatement(bool* ok) {
556   // IfStatement ::
557   //   'if' '(' Expression ')' Statement ('else' Statement)?
558
559   Expect(Token::IF, CHECK_OK);
560   Expect(Token::LPAREN, CHECK_OK);
561   ParseExpression(true, CHECK_OK);
562   Expect(Token::RPAREN, CHECK_OK);
563   ParseSubStatement(CHECK_OK);
564   if (peek() == Token::ELSE) {
565     Next();
566     ParseSubStatement(CHECK_OK);
567   }
568   return Statement::Default();
569 }
570
571
572 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) {
573   // ContinueStatement ::
574   //   'continue' [no line terminator] Identifier? ';'
575
576   Expect(Token::CONTINUE, CHECK_OK);
577   Token::Value tok = peek();
578   if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
579       tok != Token::SEMICOLON &&
580       tok != Token::RBRACE &&
581       tok != Token::EOS) {
582     // ECMA allows "eval" or "arguments" as labels even in strict mode.
583     ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
584   }
585   ExpectSemicolon(CHECK_OK);
586   return Statement::Default();
587 }
588
589
590 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) {
591   // BreakStatement ::
592   //   'break' [no line terminator] Identifier? ';'
593
594   Expect(Token::BREAK, CHECK_OK);
595   Token::Value tok = peek();
596   if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
597       tok != Token::SEMICOLON &&
598       tok != Token::RBRACE &&
599       tok != Token::EOS) {
600     // ECMA allows "eval" or "arguments" as labels even in strict mode.
601     ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
602   }
603   ExpectSemicolon(CHECK_OK);
604   return Statement::Default();
605 }
606
607
608 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) {
609   // ReturnStatement ::
610   //   'return' [no line terminator] Expression? ';'
611
612   // Consume the return token. It is necessary to do before
613   // reporting any errors on it, because of the way errors are
614   // reported (underlining).
615   Expect(Token::RETURN, CHECK_OK);
616   function_state_->set_return_location(scanner()->location());
617
618   // An ECMAScript program is considered syntactically incorrect if it
619   // contains a return statement that is not within the body of a
620   // function. See ECMA-262, section 12.9, page 67.
621   // This is not handled during preparsing.
622
623   Token::Value tok = peek();
624   if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
625       tok != Token::SEMICOLON &&
626       tok != Token::RBRACE &&
627       tok != Token::EOS) {
628     if (is_strong(language_mode()) &&
629         i::IsConstructor(function_state_->kind())) {
630       int pos = peek_position();
631       ReportMessageAt(Scanner::Location(pos, pos + 1),
632                       "strong_constructor_return_value");
633       *ok = false;
634       return Statement::Default();
635     }
636     ParseExpression(true, CHECK_OK);
637   }
638   ExpectSemicolon(CHECK_OK);
639   return Statement::Default();
640 }
641
642
643 PreParser::Statement PreParser::ParseWithStatement(bool* ok) {
644   // WithStatement ::
645   //   'with' '(' Expression ')' Statement
646   Expect(Token::WITH, CHECK_OK);
647   if (is_strict(language_mode())) {
648     ReportMessageAt(scanner()->location(), "strict_mode_with");
649     *ok = false;
650     return Statement::Default();
651   }
652   Expect(Token::LPAREN, CHECK_OK);
653   ParseExpression(true, CHECK_OK);
654   Expect(Token::RPAREN, CHECK_OK);
655
656   Scope* with_scope = NewScope(scope_, WITH_SCOPE);
657   BlockState block_state(&scope_, with_scope);
658   ParseSubStatement(CHECK_OK);
659   return Statement::Default();
660 }
661
662
663 PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) {
664   // SwitchStatement ::
665   //   'switch' '(' Expression ')' '{' CaseClause* '}'
666
667   Expect(Token::SWITCH, CHECK_OK);
668   Expect(Token::LPAREN, CHECK_OK);
669   ParseExpression(true, CHECK_OK);
670   Expect(Token::RPAREN, CHECK_OK);
671
672   Expect(Token::LBRACE, CHECK_OK);
673   Token::Value token = peek();
674   while (token != Token::RBRACE) {
675     if (token == Token::CASE) {
676       Expect(Token::CASE, CHECK_OK);
677       ParseExpression(true, CHECK_OK);
678     } else {
679       Expect(Token::DEFAULT, CHECK_OK);
680     }
681     Expect(Token::COLON, CHECK_OK);
682     token = peek();
683     while (token != Token::CASE &&
684            token != Token::DEFAULT &&
685            token != Token::RBRACE) {
686       ParseStatementListItem(CHECK_OK);
687       token = peek();
688     }
689   }
690   Expect(Token::RBRACE, ok);
691   return Statement::Default();
692 }
693
694
695 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) {
696   // DoStatement ::
697   //   'do' Statement 'while' '(' Expression ')' ';'
698
699   Expect(Token::DO, CHECK_OK);
700   ParseSubStatement(CHECK_OK);
701   Expect(Token::WHILE, CHECK_OK);
702   Expect(Token::LPAREN, CHECK_OK);
703   ParseExpression(true, CHECK_OK);
704   Expect(Token::RPAREN, ok);
705   if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
706   return Statement::Default();
707 }
708
709
710 PreParser::Statement PreParser::ParseWhileStatement(bool* ok) {
711   // WhileStatement ::
712   //   'while' '(' Expression ')' Statement
713
714   Expect(Token::WHILE, CHECK_OK);
715   Expect(Token::LPAREN, CHECK_OK);
716   ParseExpression(true, CHECK_OK);
717   Expect(Token::RPAREN, CHECK_OK);
718   ParseSubStatement(ok);
719   return Statement::Default();
720 }
721
722
723 PreParser::Statement PreParser::ParseForStatement(bool* ok) {
724   // ForStatement ::
725   //   'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
726
727   Expect(Token::FOR, CHECK_OK);
728   Expect(Token::LPAREN, CHECK_OK);
729   bool is_let_identifier_expression = false;
730   if (peek() != Token::SEMICOLON) {
731     ForEachStatement::VisitMode visit_mode;
732     if (peek() == Token::VAR || peek() == Token::CONST ||
733         (peek() == Token::LET && is_strict(language_mode()))) {
734       bool is_lexical = peek() == Token::LET ||
735                         (peek() == Token::CONST && is_strict(language_mode()));
736       int decl_count;
737       VariableDeclarationProperties decl_props = kHasNoInitializers;
738       ParseVariableDeclarations(
739           kForStatement, &decl_props, &decl_count, CHECK_OK);
740       bool has_initializers = decl_props == kHasInitializers;
741       bool accept_IN = decl_count == 1 && !(is_lexical && has_initializers);
742       bool accept_OF = !has_initializers;
743       if (accept_IN && CheckInOrOf(accept_OF, &visit_mode, ok)) {
744         if (!*ok) return Statement::Default();
745         ParseExpression(true, CHECK_OK);
746         Expect(Token::RPAREN, CHECK_OK);
747         ParseSubStatement(CHECK_OK);
748         return Statement::Default();
749       }
750     } else {
751       Expression lhs = ParseExpression(false, CHECK_OK);
752       is_let_identifier_expression =
753           lhs.IsIdentifier() && lhs.AsIdentifier().IsLet();
754       if (CheckInOrOf(lhs.IsIdentifier(), &visit_mode, ok)) {
755         if (!*ok) return Statement::Default();
756         ParseExpression(true, CHECK_OK);
757         Expect(Token::RPAREN, CHECK_OK);
758         ParseSubStatement(CHECK_OK);
759         return Statement::Default();
760       }
761     }
762   }
763
764   // Parsed initializer at this point.
765   // Detect attempts at 'let' declarations in sloppy mode.
766   if (peek() == Token::IDENTIFIER && is_sloppy(language_mode()) &&
767       is_let_identifier_expression) {
768     ReportMessage("sloppy_lexical", NULL);
769     *ok = false;
770     return Statement::Default();
771   }
772   Expect(Token::SEMICOLON, CHECK_OK);
773
774   if (peek() != Token::SEMICOLON) {
775     ParseExpression(true, CHECK_OK);
776   }
777   Expect(Token::SEMICOLON, CHECK_OK);
778
779   if (peek() != Token::RPAREN) {
780     ParseExpression(true, CHECK_OK);
781   }
782   Expect(Token::RPAREN, CHECK_OK);
783
784   ParseSubStatement(ok);
785   return Statement::Default();
786 }
787
788
789 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) {
790   // ThrowStatement ::
791   //   'throw' [no line terminator] Expression ';'
792
793   Expect(Token::THROW, CHECK_OK);
794   if (scanner()->HasAnyLineTerminatorBeforeNext()) {
795     ReportMessageAt(scanner()->location(), "newline_after_throw");
796     *ok = false;
797     return Statement::Default();
798   }
799   ParseExpression(true, CHECK_OK);
800   ExpectSemicolon(ok);
801   return Statement::Default();
802 }
803
804
805 PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
806   // TryStatement ::
807   //   'try' Block Catch
808   //   'try' Block Finally
809   //   'try' Block Catch Finally
810   //
811   // Catch ::
812   //   'catch' '(' Identifier ')' Block
813   //
814   // Finally ::
815   //   'finally' Block
816
817   Expect(Token::TRY, CHECK_OK);
818
819   ParseBlock(CHECK_OK);
820
821   Token::Value tok = peek();
822   if (tok != Token::CATCH && tok != Token::FINALLY) {
823     ReportMessageAt(scanner()->location(), "no_catch_or_finally");
824     *ok = false;
825     return Statement::Default();
826   }
827   if (tok == Token::CATCH) {
828     Consume(Token::CATCH);
829     Expect(Token::LPAREN, CHECK_OK);
830     ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
831     Expect(Token::RPAREN, CHECK_OK);
832     {
833       Scope* with_scope = NewScope(scope_, WITH_SCOPE);
834       BlockState block_state(&scope_, with_scope);
835       ParseBlock(CHECK_OK);
836     }
837     tok = peek();
838   }
839   if (tok == Token::FINALLY) {
840     Consume(Token::FINALLY);
841     ParseBlock(CHECK_OK);
842   }
843   return Statement::Default();
844 }
845
846
847 PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) {
848   // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
849   // contexts this is used as a statement which invokes the debugger as if a
850   // break point is present.
851   // DebuggerStatement ::
852   //   'debugger' ';'
853
854   Expect(Token::DEBUGGER, CHECK_OK);
855   ExpectSemicolon(ok);
856   return Statement::Default();
857 }
858
859
860 #undef CHECK_OK
861 #define CHECK_OK  ok);                     \
862   if (!*ok) return Expression::Default();  \
863   ((void)0
864 #define DUMMY )  // to make indentation work
865 #undef DUMMY
866
867
868 PreParser::Expression PreParser::ParseFunctionLiteral(
869     Identifier function_name, Scanner::Location function_name_location,
870     bool name_is_strict_reserved, FunctionKind kind, int function_token_pos,
871     FunctionLiteral::FunctionType function_type,
872     FunctionLiteral::ArityRestriction arity_restriction, bool* ok) {
873   // Function ::
874   //   '(' FormalParameterList? ')' '{' FunctionBody '}'
875
876   // Parse function body.
877   bool outer_is_script_scope = scope_->is_script_scope();
878   Scope* function_scope = NewScope(scope_, FUNCTION_SCOPE);
879   PreParserFactory factory(NULL);
880   FunctionState function_state(&function_state_, &scope_, function_scope, kind,
881                                &factory);
882   //  FormalParameterList ::
883   //    '(' (Identifier)*[','] ')'
884   Expect(Token::LPAREN, CHECK_OK);
885   int start_position = position();
886   DuplicateFinder duplicate_finder(scanner()->unicode_cache());
887   // We don't yet know if the function will be strict, so we cannot yet produce
888   // errors for parameter names or duplicates. However, we remember the
889   // locations of these errors if they occur and produce the errors later.
890   Scanner::Location eval_args_error_loc = Scanner::Location::invalid();
891   Scanner::Location dupe_error_loc = Scanner::Location::invalid();
892   Scanner::Location reserved_error_loc = Scanner::Location::invalid();
893
894   bool is_rest = false;
895   bool done = arity_restriction == FunctionLiteral::GETTER_ARITY ||
896       (peek() == Token::RPAREN &&
897        arity_restriction != FunctionLiteral::SETTER_ARITY);
898   while (!done) {
899     bool is_strict_reserved = false;
900     is_rest = peek() == Token::ELLIPSIS && allow_harmony_rest_params();
901     if (is_rest) {
902       Consume(Token::ELLIPSIS);
903     }
904
905     Identifier param_name =
906         ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
907     if (!eval_args_error_loc.IsValid() && param_name.IsEvalOrArguments()) {
908       eval_args_error_loc = scanner()->location();
909     }
910     if (!reserved_error_loc.IsValid() && is_strict_reserved) {
911       reserved_error_loc = scanner()->location();
912     }
913
914     int prev_value = scanner()->FindSymbol(&duplicate_finder, 1);
915
916     if (!dupe_error_loc.IsValid() && prev_value != 0) {
917       dupe_error_loc = scanner()->location();
918     }
919
920     if (arity_restriction == FunctionLiteral::SETTER_ARITY) break;
921     done = (peek() == Token::RPAREN);
922     if (!done) {
923       if (is_rest) {
924         ReportMessageAt(scanner()->peek_location(), "param_after_rest");
925         *ok = false;
926         return Expression::Default();
927       }
928       Expect(Token::COMMA, CHECK_OK);
929     }
930   }
931   Expect(Token::RPAREN, CHECK_OK);
932
933   // See Parser::ParseFunctionLiteral for more information about lazy parsing
934   // and lazy compilation.
935   bool is_lazily_parsed =
936       (outer_is_script_scope && allow_lazy() && !parenthesized_function_);
937   parenthesized_function_ = false;
938
939   Expect(Token::LBRACE, CHECK_OK);
940   if (is_lazily_parsed) {
941     ParseLazyFunctionLiteralBody(CHECK_OK);
942   } else {
943     ParseStatementList(Token::RBRACE, CHECK_OK);
944   }
945   Expect(Token::RBRACE, CHECK_OK);
946
947   // Validate name and parameter names. We can do this only after parsing the
948   // function, since the function can declare itself strict.
949   CheckFunctionName(language_mode(), kind, function_name,
950                     name_is_strict_reserved, function_name_location, CHECK_OK);
951   const bool use_strict_params = is_rest || IsConciseMethod(kind);
952   CheckFunctionParameterNames(language_mode(), use_strict_params,
953                               eval_args_error_loc, dupe_error_loc,
954                               reserved_error_loc, CHECK_OK);
955
956   if (is_strict(language_mode())) {
957     int end_position = scanner()->location().end_pos;
958     CheckStrictOctalLiteral(start_position, end_position, CHECK_OK);
959   }
960
961   if (is_strong(language_mode()) && IsSubclassConstructor(kind)) {
962     if (!function_state.super_call_location().IsValid()) {
963       ReportMessageAt(function_name_location, "strong_super_call_missing",
964                       kReferenceError);
965       *ok = false;
966       return Expression::Default();
967     }
968   }
969
970   return Expression::Default();
971 }
972
973
974 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) {
975   int body_start = position();
976   ParseStatementList(Token::RBRACE, ok);
977   if (!*ok) return;
978
979   // Position right after terminal '}'.
980   DCHECK_EQ(Token::RBRACE, scanner()->peek());
981   int body_end = scanner()->peek_location().end_pos;
982   log_->LogFunction(body_start, body_end,
983                     function_state_->materialized_literal_count(),
984                     function_state_->expected_property_count(), language_mode(),
985                     scope_->uses_super_property());
986 }
987
988
989 PreParserExpression PreParser::ParseClassLiteral(
990     PreParserIdentifier name, Scanner::Location class_name_location,
991     bool name_is_strict_reserved, int pos, bool* ok) {
992   // All parts of a ClassDeclaration and ClassExpression are strict code.
993   if (name_is_strict_reserved) {
994     ReportMessageAt(class_name_location, "unexpected_strict_reserved");
995     *ok = false;
996     return EmptyExpression();
997   }
998   if (IsEvalOrArguments(name)) {
999     ReportMessageAt(class_name_location, "strict_eval_arguments");
1000     *ok = false;
1001     return EmptyExpression();
1002   }
1003
1004   Scope* scope = NewScope(scope_, BLOCK_SCOPE);
1005   BlockState block_state(&scope_, scope);
1006   scope_->SetLanguageMode(
1007       static_cast<LanguageMode>(scope_->language_mode() | STRICT_BIT));
1008   // TODO(marja): Make PreParser use scope names too.
1009   // scope_->SetScopeName(name);
1010
1011   bool has_extends = Check(Token::EXTENDS);
1012   if (has_extends) {
1013     ParseLeftHandSideExpression(CHECK_OK);
1014   }
1015
1016   ClassLiteralChecker checker(this);
1017   bool has_seen_constructor = false;
1018
1019   Expect(Token::LBRACE, CHECK_OK);
1020   while (peek() != Token::RBRACE) {
1021     if (Check(Token::SEMICOLON)) continue;
1022     const bool in_class = true;
1023     const bool is_static = false;
1024     bool is_computed_name = false;  // Classes do not care about computed
1025                                     // property names here.
1026     ParsePropertyDefinition(&checker, in_class, has_extends, is_static,
1027                             &is_computed_name, &has_seen_constructor, CHECK_OK);
1028   }
1029
1030   Expect(Token::RBRACE, CHECK_OK);
1031
1032   return Expression::Default();
1033 }
1034
1035
1036 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
1037   // CallRuntime ::
1038   //   '%' Identifier Arguments
1039   Expect(Token::MOD, CHECK_OK);
1040   if (!allow_natives()) {
1041     *ok = false;
1042     return Expression::Default();
1043   }
1044   // Allow "eval" or "arguments" for backward compatibility.
1045   ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
1046   ParseArguments(ok);
1047
1048   return Expression::Default();
1049 }
1050
1051 #undef CHECK_OK
1052
1053
1054 } }  // v8::internal