a87c434558d0aed6018f19afa9b8f6d648c93e1c
[platform/framework/web/crosswalk.git] / src / v8 / src / preparser.cc
1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #include <cmath>
29
30 #include "../include/v8stdint.h"
31
32 #include "allocation.h"
33 #include "checks.h"
34 #include "conversions.h"
35 #include "conversions-inl.h"
36 #include "globals.h"
37 #include "hashmap.h"
38 #include "list.h"
39 #include "preparse-data-format.h"
40 #include "preparse-data.h"
41 #include "preparser.h"
42 #include "unicode.h"
43 #include "utils.h"
44
45 #if V8_CC_MSVC && (_MSC_VER < 1800)
46 namespace std {
47
48 // Usually defined in math.h, but not in MSVC until VS2013+.
49 // Abstracted to work
50 int isfinite(double value);
51
52 }  // namespace std
53 #endif
54
55 namespace v8 {
56 namespace internal {
57
58 PreParser::PreParseResult PreParser::PreParseLazyFunction(
59     LanguageMode mode, bool is_generator, ParserRecorder* log) {
60   log_ = log;
61   // Lazy functions always have trivial outer scopes (no with/catch scopes).
62   Scope top_scope(&scope_, kTopLevelScope);
63   set_language_mode(mode);
64   Scope function_scope(&scope_, kFunctionScope);
65   function_scope.set_is_generator(is_generator);
66   ASSERT_EQ(Token::LBRACE, scanner()->current_token());
67   bool ok = true;
68   int start_position = peek_position();
69   ParseLazyFunctionLiteralBody(&ok);
70   if (stack_overflow()) return kPreParseStackOverflow;
71   if (!ok) {
72     ReportUnexpectedToken(scanner()->current_token());
73   } else {
74     ASSERT_EQ(Token::RBRACE, scanner()->peek());
75     if (!is_classic_mode()) {
76       int end_pos = scanner()->location().end_pos;
77       CheckOctalLiteral(start_position, end_pos, &ok);
78       if (ok) {
79         CheckDelayedStrictModeViolation(start_position, end_pos, &ok);
80       }
81     }
82   }
83   return kPreParseSuccess;
84 }
85
86
87 // Preparsing checks a JavaScript program and emits preparse-data that helps
88 // a later parsing to be faster.
89 // See preparser-data.h for the data.
90
91 // The PreParser checks that the syntax follows the grammar for JavaScript,
92 // and collects some information about the program along the way.
93 // The grammar check is only performed in order to understand the program
94 // sufficiently to deduce some information about it, that can be used
95 // to speed up later parsing. Finding errors is not the goal of pre-parsing,
96 // rather it is to speed up properly written and correct programs.
97 // That means that contextual checks (like a label being declared where
98 // it is used) are generally omitted.
99
100 void PreParser::ReportUnexpectedToken(Token::Value token) {
101   // We don't report stack overflows here, to avoid increasing the
102   // stack depth even further.  Instead we report it after parsing is
103   // over, in ParseProgram.
104   if (token == Token::ILLEGAL && stack_overflow()) {
105     return;
106   }
107   Scanner::Location source_location = scanner()->location();
108
109   // Four of the tokens are treated specially
110   switch (token) {
111   case Token::EOS:
112     return ReportMessageAt(source_location, "unexpected_eos", NULL);
113   case Token::NUMBER:
114     return ReportMessageAt(source_location, "unexpected_token_number", NULL);
115   case Token::STRING:
116     return ReportMessageAt(source_location, "unexpected_token_string", NULL);
117   case Token::IDENTIFIER:
118     return ReportMessageAt(source_location,
119                            "unexpected_token_identifier", NULL);
120   case Token::FUTURE_RESERVED_WORD:
121     return ReportMessageAt(source_location, "unexpected_reserved", NULL);
122   case Token::FUTURE_STRICT_RESERVED_WORD:
123     return ReportMessageAt(source_location,
124                            "unexpected_strict_reserved", NULL);
125   default:
126     const char* name = Token::String(token);
127     ReportMessageAt(source_location, "unexpected_token", name);
128   }
129 }
130
131
132 #define CHECK_OK  ok);                      \
133   if (!*ok) return kUnknownSourceElements;  \
134   ((void)0
135 #define DUMMY )  // to make indentation work
136 #undef DUMMY
137
138
139 PreParser::Statement PreParser::ParseSourceElement(bool* ok) {
140   // (Ecma 262 5th Edition, clause 14):
141   // SourceElement:
142   //    Statement
143   //    FunctionDeclaration
144   //
145   // In harmony mode we allow additionally the following productions
146   // SourceElement:
147   //    LetDeclaration
148   //    ConstDeclaration
149   //    GeneratorDeclaration
150
151   switch (peek()) {
152     case Token::FUNCTION:
153       return ParseFunctionDeclaration(ok);
154     case Token::LET:
155     case Token::CONST:
156       return ParseVariableStatement(kSourceElement, ok);
157     default:
158       return ParseStatement(ok);
159   }
160 }
161
162
163 PreParser::SourceElements PreParser::ParseSourceElements(int end_token,
164                                                          bool* ok) {
165   // SourceElements ::
166   //   (Statement)* <end_token>
167
168   bool allow_directive_prologue = true;
169   while (peek() != end_token) {
170     Statement statement = ParseSourceElement(CHECK_OK);
171     if (allow_directive_prologue) {
172       if (statement.IsUseStrictLiteral()) {
173         set_language_mode(allow_harmony_scoping() ?
174                           EXTENDED_MODE : STRICT_MODE);
175       } else if (!statement.IsStringLiteral()) {
176         allow_directive_prologue = false;
177       }
178     }
179   }
180   return kUnknownSourceElements;
181 }
182
183
184 #undef CHECK_OK
185 #define CHECK_OK  ok);                   \
186   if (!*ok) return Statement::Default();  \
187   ((void)0
188 #define DUMMY )  // to make indentation work
189 #undef DUMMY
190
191
192 PreParser::Statement PreParser::ParseStatement(bool* ok) {
193   // Statement ::
194   //   Block
195   //   VariableStatement
196   //   EmptyStatement
197   //   ExpressionStatement
198   //   IfStatement
199   //   IterationStatement
200   //   ContinueStatement
201   //   BreakStatement
202   //   ReturnStatement
203   //   WithStatement
204   //   LabelledStatement
205   //   SwitchStatement
206   //   ThrowStatement
207   //   TryStatement
208   //   DebuggerStatement
209
210   // Note: Since labels can only be used by 'break' and 'continue'
211   // statements, which themselves are only valid within blocks,
212   // iterations or 'switch' statements (i.e., BreakableStatements),
213   // labels can be simply ignored in all other cases; except for
214   // trivial labeled break statements 'label: break label' which is
215   // parsed into an empty statement.
216
217   // Keep the source position of the statement
218   switch (peek()) {
219     case Token::LBRACE:
220       return ParseBlock(ok);
221
222     case Token::CONST:
223     case Token::LET:
224     case Token::VAR:
225       return ParseVariableStatement(kStatement, ok);
226
227     case Token::SEMICOLON:
228       Next();
229       return Statement::Default();
230
231     case Token::IF:
232       return ParseIfStatement(ok);
233
234     case Token::DO:
235       return ParseDoWhileStatement(ok);
236
237     case Token::WHILE:
238       return ParseWhileStatement(ok);
239
240     case Token::FOR:
241       return ParseForStatement(ok);
242
243     case Token::CONTINUE:
244       return ParseContinueStatement(ok);
245
246     case Token::BREAK:
247       return ParseBreakStatement(ok);
248
249     case Token::RETURN:
250       return ParseReturnStatement(ok);
251
252     case Token::WITH:
253       return ParseWithStatement(ok);
254
255     case Token::SWITCH:
256       return ParseSwitchStatement(ok);
257
258     case Token::THROW:
259       return ParseThrowStatement(ok);
260
261     case Token::TRY:
262       return ParseTryStatement(ok);
263
264     case Token::FUNCTION: {
265       Scanner::Location start_location = scanner()->peek_location();
266       Statement statement = ParseFunctionDeclaration(CHECK_OK);
267       Scanner::Location end_location = scanner()->location();
268       if (!is_classic_mode()) {
269         ReportMessageAt(start_location.beg_pos, end_location.end_pos,
270                         "strict_function", NULL);
271         *ok = false;
272         return Statement::Default();
273       } else {
274         return statement;
275       }
276     }
277
278     case Token::DEBUGGER:
279       return ParseDebuggerStatement(ok);
280
281     default:
282       return ParseExpressionOrLabelledStatement(ok);
283   }
284 }
285
286
287 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
288   // FunctionDeclaration ::
289   //   'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
290   // GeneratorDeclaration ::
291   //   'function' '*' Identifier '(' FormalParameterListopt ')'
292   //      '{' FunctionBody '}'
293   Expect(Token::FUNCTION, CHECK_OK);
294
295   bool is_generator = allow_generators() && Check(Token::MUL);
296   Identifier identifier = ParseIdentifier(CHECK_OK);
297   Scanner::Location location = scanner()->location();
298
299   Expression function_value = ParseFunctionLiteral(is_generator, CHECK_OK);
300
301   if (function_value.IsStrictFunction() &&
302       !identifier.IsValidStrictVariable()) {
303     // Strict mode violation, using either reserved word or eval/arguments
304     // as name of strict function.
305     const char* type = "strict_function_name";
306     if (identifier.IsFutureStrictReserved() || identifier.IsYield()) {
307       type = "strict_reserved_word";
308     }
309     ReportMessageAt(location, type, NULL);
310     *ok = false;
311   }
312   return Statement::FunctionDeclaration();
313 }
314
315
316 PreParser::Statement PreParser::ParseBlock(bool* ok) {
317   // Block ::
318   //   '{' Statement* '}'
319
320   // Note that a Block does not introduce a new execution scope!
321   // (ECMA-262, 3rd, 12.2)
322   //
323   Expect(Token::LBRACE, CHECK_OK);
324   while (peek() != Token::RBRACE) {
325     if (is_extended_mode()) {
326       ParseSourceElement(CHECK_OK);
327     } else {
328       ParseStatement(CHECK_OK);
329     }
330   }
331   Expect(Token::RBRACE, ok);
332   return Statement::Default();
333 }
334
335
336 PreParser::Statement PreParser::ParseVariableStatement(
337     VariableDeclarationContext var_context,
338     bool* ok) {
339   // VariableStatement ::
340   //   VariableDeclarations ';'
341
342   Statement result = ParseVariableDeclarations(var_context,
343                                                NULL,
344                                                NULL,
345                                                CHECK_OK);
346   ExpectSemicolon(CHECK_OK);
347   return result;
348 }
349
350
351 // If the variable declaration declares exactly one non-const
352 // variable, then *var is set to that variable. In all other cases,
353 // *var is untouched; in particular, it is the caller's responsibility
354 // to initialize it properly. This mechanism is also used for the parsing
355 // of 'for-in' loops.
356 PreParser::Statement PreParser::ParseVariableDeclarations(
357     VariableDeclarationContext var_context,
358     VariableDeclarationProperties* decl_props,
359     int* num_decl,
360     bool* ok) {
361   // VariableDeclarations ::
362   //   ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
363   //
364   // The ES6 Draft Rev3 specifies the following grammar for const declarations
365   //
366   // ConstDeclaration ::
367   //   const ConstBinding (',' ConstBinding)* ';'
368   // ConstBinding ::
369   //   Identifier '=' AssignmentExpression
370   //
371   // TODO(ES6):
372   // ConstBinding ::
373   //   BindingPattern '=' AssignmentExpression
374   bool require_initializer = false;
375   if (peek() == Token::VAR) {
376     Consume(Token::VAR);
377   } else if (peek() == Token::CONST) {
378     // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
379     //
380     // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
381     //
382     // * It is a Syntax Error if the code that matches this production is not
383     //   contained in extended code.
384     //
385     // However disallowing const in classic mode will break compatibility with
386     // existing pages. Therefore we keep allowing const with the old
387     // non-harmony semantics in classic mode.
388     Consume(Token::CONST);
389     switch (language_mode()) {
390       case CLASSIC_MODE:
391         break;
392       case STRICT_MODE: {
393         Scanner::Location location = scanner()->peek_location();
394         ReportMessageAt(location, "strict_const", NULL);
395         *ok = false;
396         return Statement::Default();
397       }
398       case EXTENDED_MODE:
399         if (var_context != kSourceElement &&
400             var_context != kForStatement) {
401           Scanner::Location location = scanner()->peek_location();
402           ReportMessageAt(location.beg_pos, location.end_pos,
403                           "unprotected_const", NULL);
404           *ok = false;
405           return Statement::Default();
406         }
407         require_initializer = true;
408         break;
409     }
410   } else if (peek() == Token::LET) {
411     // ES6 Draft Rev4 section 12.2.1:
412     //
413     // LetDeclaration : let LetBindingList ;
414     //
415     // * It is a Syntax Error if the code that matches this production is not
416     //   contained in extended code.
417     if (!is_extended_mode()) {
418       Scanner::Location location = scanner()->peek_location();
419       ReportMessageAt(location.beg_pos, location.end_pos,
420                       "illegal_let", NULL);
421       *ok = false;
422       return Statement::Default();
423     }
424     Consume(Token::LET);
425     if (var_context != kSourceElement &&
426         var_context != kForStatement) {
427       Scanner::Location location = scanner()->peek_location();
428       ReportMessageAt(location.beg_pos, location.end_pos,
429                       "unprotected_let", NULL);
430       *ok = false;
431       return Statement::Default();
432     }
433   } else {
434     *ok = false;
435     return Statement::Default();
436   }
437
438   // The scope of a var/const declared variable anywhere inside a function
439   // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope
440   // of a let declared variable is the scope of the immediately enclosing
441   // block.
442   int nvars = 0;  // the number of variables declared
443   do {
444     // Parse variable name.
445     if (nvars > 0) Consume(Token::COMMA);
446     Identifier identifier  = ParseIdentifier(CHECK_OK);
447     if (!is_classic_mode() && !identifier.IsValidStrictVariable()) {
448       StrictModeIdentifierViolation(scanner()->location(),
449                                     "strict_var_name",
450                                     identifier,
451                                     ok);
452       return Statement::Default();
453     }
454     nvars++;
455     if (peek() == Token::ASSIGN || require_initializer) {
456       Expect(Token::ASSIGN, CHECK_OK);
457       ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
458       if (decl_props != NULL) *decl_props = kHasInitializers;
459     }
460   } while (peek() == Token::COMMA);
461
462   if (num_decl != NULL) *num_decl = nvars;
463   return Statement::Default();
464 }
465
466
467 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
468   // ExpressionStatement | LabelledStatement ::
469   //   Expression ';'
470   //   Identifier ':' Statement
471
472   Expression expr = ParseExpression(true, CHECK_OK);
473   if (expr.IsRawIdentifier()) {
474     ASSERT(!expr.AsIdentifier().IsFutureReserved());
475     ASSERT(is_classic_mode() ||
476            (!expr.AsIdentifier().IsFutureStrictReserved() &&
477             !expr.AsIdentifier().IsYield()));
478     if (peek() == Token::COLON) {
479       Consume(Token::COLON);
480       return ParseStatement(ok);
481     }
482     // Preparsing is disabled for extensions (because the extension details
483     // aren't passed to lazily compiled functions), so we don't
484     // accept "native function" in the preparser.
485   }
486   // Parsed expression statement.
487   ExpectSemicolon(CHECK_OK);
488   return Statement::ExpressionStatement(expr);
489 }
490
491
492 PreParser::Statement PreParser::ParseIfStatement(bool* ok) {
493   // IfStatement ::
494   //   'if' '(' Expression ')' Statement ('else' Statement)?
495
496   Expect(Token::IF, CHECK_OK);
497   Expect(Token::LPAREN, CHECK_OK);
498   ParseExpression(true, CHECK_OK);
499   Expect(Token::RPAREN, CHECK_OK);
500   ParseStatement(CHECK_OK);
501   if (peek() == Token::ELSE) {
502     Next();
503     ParseStatement(CHECK_OK);
504   }
505   return Statement::Default();
506 }
507
508
509 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) {
510   // ContinueStatement ::
511   //   'continue' [no line terminator] Identifier? ';'
512
513   Expect(Token::CONTINUE, CHECK_OK);
514   Token::Value tok = peek();
515   if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
516       tok != Token::SEMICOLON &&
517       tok != Token::RBRACE &&
518       tok != Token::EOS) {
519     ParseIdentifier(CHECK_OK);
520   }
521   ExpectSemicolon(CHECK_OK);
522   return Statement::Default();
523 }
524
525
526 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) {
527   // BreakStatement ::
528   //   'break' [no line terminator] Identifier? ';'
529
530   Expect(Token::BREAK, CHECK_OK);
531   Token::Value tok = peek();
532   if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
533       tok != Token::SEMICOLON &&
534       tok != Token::RBRACE &&
535       tok != Token::EOS) {
536     ParseIdentifier(CHECK_OK);
537   }
538   ExpectSemicolon(CHECK_OK);
539   return Statement::Default();
540 }
541
542
543 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) {
544   // ReturnStatement ::
545   //   'return' [no line terminator] Expression? ';'
546
547   // Consume the return token. It is necessary to do the before
548   // reporting any errors on it, because of the way errors are
549   // reported (underlining).
550   Expect(Token::RETURN, CHECK_OK);
551
552   // An ECMAScript program is considered syntactically incorrect if it
553   // contains a return statement that is not within the body of a
554   // function. See ECMA-262, section 12.9, page 67.
555   // This is not handled during preparsing.
556
557   Token::Value tok = peek();
558   if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
559       tok != Token::SEMICOLON &&
560       tok != Token::RBRACE &&
561       tok != Token::EOS) {
562     ParseExpression(true, CHECK_OK);
563   }
564   ExpectSemicolon(CHECK_OK);
565   return Statement::Default();
566 }
567
568
569 PreParser::Statement PreParser::ParseWithStatement(bool* ok) {
570   // WithStatement ::
571   //   'with' '(' Expression ')' Statement
572   Expect(Token::WITH, CHECK_OK);
573   if (!is_classic_mode()) {
574     Scanner::Location location = scanner()->location();
575     ReportMessageAt(location, "strict_mode_with", NULL);
576     *ok = false;
577     return Statement::Default();
578   }
579   Expect(Token::LPAREN, CHECK_OK);
580   ParseExpression(true, CHECK_OK);
581   Expect(Token::RPAREN, CHECK_OK);
582
583   Scope::InsideWith iw(scope_);
584   ParseStatement(CHECK_OK);
585   return Statement::Default();
586 }
587
588
589 PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) {
590   // SwitchStatement ::
591   //   'switch' '(' Expression ')' '{' CaseClause* '}'
592
593   Expect(Token::SWITCH, CHECK_OK);
594   Expect(Token::LPAREN, CHECK_OK);
595   ParseExpression(true, CHECK_OK);
596   Expect(Token::RPAREN, CHECK_OK);
597
598   Expect(Token::LBRACE, CHECK_OK);
599   Token::Value token = peek();
600   while (token != Token::RBRACE) {
601     if (token == Token::CASE) {
602       Expect(Token::CASE, CHECK_OK);
603       ParseExpression(true, CHECK_OK);
604     } else {
605       Expect(Token::DEFAULT, CHECK_OK);
606     }
607     Expect(Token::COLON, CHECK_OK);
608     token = peek();
609     while (token != Token::CASE &&
610            token != Token::DEFAULT &&
611            token != Token::RBRACE) {
612       ParseStatement(CHECK_OK);
613       token = peek();
614     }
615   }
616   Expect(Token::RBRACE, ok);
617   return Statement::Default();
618 }
619
620
621 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) {
622   // DoStatement ::
623   //   'do' Statement 'while' '(' Expression ')' ';'
624
625   Expect(Token::DO, CHECK_OK);
626   ParseStatement(CHECK_OK);
627   Expect(Token::WHILE, CHECK_OK);
628   Expect(Token::LPAREN, CHECK_OK);
629   ParseExpression(true, CHECK_OK);
630   Expect(Token::RPAREN, ok);
631   if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
632   return Statement::Default();
633 }
634
635
636 PreParser::Statement PreParser::ParseWhileStatement(bool* ok) {
637   // WhileStatement ::
638   //   'while' '(' Expression ')' Statement
639
640   Expect(Token::WHILE, CHECK_OK);
641   Expect(Token::LPAREN, CHECK_OK);
642   ParseExpression(true, CHECK_OK);
643   Expect(Token::RPAREN, CHECK_OK);
644   ParseStatement(ok);
645   return Statement::Default();
646 }
647
648
649 bool PreParser::CheckInOrOf(bool accept_OF) {
650   if (Check(Token::IN) ||
651       (allow_for_of() && accept_OF &&
652        CheckContextualKeyword(CStrVector("of")))) {
653     return true;
654   }
655   return false;
656 }
657
658
659 PreParser::Statement PreParser::ParseForStatement(bool* ok) {
660   // ForStatement ::
661   //   'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
662
663   Expect(Token::FOR, CHECK_OK);
664   Expect(Token::LPAREN, CHECK_OK);
665   if (peek() != Token::SEMICOLON) {
666     if (peek() == Token::VAR || peek() == Token::CONST ||
667         peek() == Token::LET) {
668       bool is_let = peek() == Token::LET;
669       int decl_count;
670       VariableDeclarationProperties decl_props = kHasNoInitializers;
671       ParseVariableDeclarations(
672           kForStatement, &decl_props, &decl_count, CHECK_OK);
673       bool has_initializers = decl_props == kHasInitializers;
674       bool accept_IN = decl_count == 1 && !(is_let && has_initializers);
675       bool accept_OF = !has_initializers;
676       if (accept_IN && CheckInOrOf(accept_OF)) {
677         ParseExpression(true, CHECK_OK);
678         Expect(Token::RPAREN, CHECK_OK);
679
680         ParseStatement(CHECK_OK);
681         return Statement::Default();
682       }
683     } else {
684       Expression lhs = ParseExpression(false, CHECK_OK);
685       if (CheckInOrOf(lhs.IsIdentifier())) {
686         ParseExpression(true, CHECK_OK);
687         Expect(Token::RPAREN, CHECK_OK);
688
689         ParseStatement(CHECK_OK);
690         return Statement::Default();
691       }
692     }
693   }
694
695   // Parsed initializer at this point.
696   Expect(Token::SEMICOLON, CHECK_OK);
697
698   if (peek() != Token::SEMICOLON) {
699     ParseExpression(true, CHECK_OK);
700   }
701   Expect(Token::SEMICOLON, CHECK_OK);
702
703   if (peek() != Token::RPAREN) {
704     ParseExpression(true, CHECK_OK);
705   }
706   Expect(Token::RPAREN, CHECK_OK);
707
708   ParseStatement(ok);
709   return Statement::Default();
710 }
711
712
713 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) {
714   // ThrowStatement ::
715   //   'throw' [no line terminator] Expression ';'
716
717   Expect(Token::THROW, CHECK_OK);
718   if (scanner()->HasAnyLineTerminatorBeforeNext()) {
719     Scanner::Location pos = scanner()->location();
720     ReportMessageAt(pos, "newline_after_throw", NULL);
721     *ok = false;
722     return Statement::Default();
723   }
724   ParseExpression(true, CHECK_OK);
725   ExpectSemicolon(ok);
726   return Statement::Default();
727 }
728
729
730 PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
731   // TryStatement ::
732   //   'try' Block Catch
733   //   'try' Block Finally
734   //   'try' Block Catch Finally
735   //
736   // Catch ::
737   //   'catch' '(' Identifier ')' Block
738   //
739   // Finally ::
740   //   'finally' Block
741
742   // In preparsing, allow any number of catch/finally blocks, including zero
743   // of both.
744
745   Expect(Token::TRY, CHECK_OK);
746
747   ParseBlock(CHECK_OK);
748
749   bool catch_or_finally_seen = false;
750   if (peek() == Token::CATCH) {
751     Consume(Token::CATCH);
752     Expect(Token::LPAREN, CHECK_OK);
753     Identifier id = ParseIdentifier(CHECK_OK);
754     if (!is_classic_mode() && !id.IsValidStrictVariable()) {
755       StrictModeIdentifierViolation(scanner()->location(),
756                                     "strict_catch_variable",
757                                     id,
758                                     ok);
759       return Statement::Default();
760     }
761     Expect(Token::RPAREN, CHECK_OK);
762     { Scope::InsideWith iw(scope_);
763       ParseBlock(CHECK_OK);
764     }
765     catch_or_finally_seen = true;
766   }
767   if (peek() == Token::FINALLY) {
768     Consume(Token::FINALLY);
769     ParseBlock(CHECK_OK);
770     catch_or_finally_seen = true;
771   }
772   if (!catch_or_finally_seen) {
773     *ok = false;
774   }
775   return Statement::Default();
776 }
777
778
779 PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) {
780   // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
781   // contexts this is used as a statement which invokes the debugger as if a
782   // break point is present.
783   // DebuggerStatement ::
784   //   'debugger' ';'
785
786   Expect(Token::DEBUGGER, CHECK_OK);
787   ExpectSemicolon(ok);
788   return Statement::Default();
789 }
790
791
792 #undef CHECK_OK
793 #define CHECK_OK  ok);                     \
794   if (!*ok) return Expression::Default();  \
795   ((void)0
796 #define DUMMY )  // to make indentation work
797 #undef DUMMY
798
799
800 // Precedence = 1
801 PreParser::Expression PreParser::ParseExpression(bool accept_IN, bool* ok) {
802   // Expression ::
803   //   AssignmentExpression
804   //   Expression ',' AssignmentExpression
805
806   Expression result = ParseAssignmentExpression(accept_IN, CHECK_OK);
807   while (peek() == Token::COMMA) {
808     Expect(Token::COMMA, CHECK_OK);
809     ParseAssignmentExpression(accept_IN, CHECK_OK);
810     result = Expression::Default();
811   }
812   return result;
813 }
814
815
816 // Precedence = 2
817 PreParser::Expression PreParser::ParseAssignmentExpression(bool accept_IN,
818                                                            bool* ok) {
819   // AssignmentExpression ::
820   //   ConditionalExpression
821   //   YieldExpression
822   //   LeftHandSideExpression AssignmentOperator AssignmentExpression
823
824   if (scope_->is_generator() && peek() == Token::YIELD) {
825     return ParseYieldExpression(ok);
826   }
827
828   Scanner::Location before = scanner()->peek_location();
829   Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK);
830
831   if (!Token::IsAssignmentOp(peek())) {
832     // Parsed conditional expression only (no assignment).
833     return expression;
834   }
835
836   if (!is_classic_mode() &&
837       expression.IsIdentifier() &&
838       expression.AsIdentifier().IsEvalOrArguments()) {
839     Scanner::Location after = scanner()->location();
840     ReportMessageAt(before.beg_pos, after.end_pos,
841                     "strict_lhs_assignment", NULL);
842     *ok = false;
843     return Expression::Default();
844   }
845
846   Token::Value op = Next();  // Get assignment operator.
847   ParseAssignmentExpression(accept_IN, CHECK_OK);
848
849   if ((op == Token::ASSIGN) && expression.IsThisProperty()) {
850     scope_->AddProperty();
851   }
852
853   return Expression::Default();
854 }
855
856
857 // Precedence = 3
858 PreParser::Expression PreParser::ParseYieldExpression(bool* ok) {
859   // YieldExpression ::
860   //   'yield' '*'? AssignmentExpression
861   Consume(Token::YIELD);
862   Check(Token::MUL);
863
864   ParseAssignmentExpression(false, CHECK_OK);
865
866   return Expression::Default();
867 }
868
869
870 // Precedence = 3
871 PreParser::Expression PreParser::ParseConditionalExpression(bool accept_IN,
872                                                             bool* ok) {
873   // ConditionalExpression ::
874   //   LogicalOrExpression
875   //   LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
876
877   // We start using the binary expression parser for prec >= 4 only!
878   Expression expression = ParseBinaryExpression(4, accept_IN, CHECK_OK);
879   if (peek() != Token::CONDITIONAL) return expression;
880   Consume(Token::CONDITIONAL);
881   // In parsing the first assignment expression in conditional
882   // expressions we always accept the 'in' keyword; see ECMA-262,
883   // section 11.12, page 58.
884   ParseAssignmentExpression(true, CHECK_OK);
885   Expect(Token::COLON, CHECK_OK);
886   ParseAssignmentExpression(accept_IN, CHECK_OK);
887   return Expression::Default();
888 }
889
890
891 // Precedence >= 4
892 PreParser::Expression PreParser::ParseBinaryExpression(int prec,
893                                                        bool accept_IN,
894                                                        bool* ok) {
895   Expression result = ParseUnaryExpression(CHECK_OK);
896   for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
897     // prec1 >= 4
898     while (Precedence(peek(), accept_IN) == prec1) {
899       Next();
900       ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK);
901       result = Expression::Default();
902     }
903   }
904   return result;
905 }
906
907
908 PreParser::Expression PreParser::ParseUnaryExpression(bool* ok) {
909   // UnaryExpression ::
910   //   PostfixExpression
911   //   'delete' UnaryExpression
912   //   'void' UnaryExpression
913   //   'typeof' UnaryExpression
914   //   '++' UnaryExpression
915   //   '--' UnaryExpression
916   //   '+' UnaryExpression
917   //   '-' UnaryExpression
918   //   '~' UnaryExpression
919   //   '!' UnaryExpression
920
921   Token::Value op = peek();
922   if (Token::IsUnaryOp(op)) {
923     op = Next();
924     ParseUnaryExpression(ok);
925     return Expression::Default();
926   } else if (Token::IsCountOp(op)) {
927     op = Next();
928     Scanner::Location before = scanner()->peek_location();
929     Expression expression = ParseUnaryExpression(CHECK_OK);
930     if (!is_classic_mode() &&
931         expression.IsIdentifier() &&
932         expression.AsIdentifier().IsEvalOrArguments()) {
933       Scanner::Location after = scanner()->location();
934       ReportMessageAt(before.beg_pos, after.end_pos,
935                       "strict_lhs_prefix", NULL);
936       *ok = false;
937     }
938     return Expression::Default();
939   } else {
940     return ParsePostfixExpression(ok);
941   }
942 }
943
944
945 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) {
946   // PostfixExpression ::
947   //   LeftHandSideExpression ('++' | '--')?
948
949   Scanner::Location before = scanner()->peek_location();
950   Expression expression = ParseLeftHandSideExpression(CHECK_OK);
951   if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
952       Token::IsCountOp(peek())) {
953     if (!is_classic_mode() &&
954         expression.IsIdentifier() &&
955         expression.AsIdentifier().IsEvalOrArguments()) {
956       Scanner::Location after = scanner()->location();
957       ReportMessageAt(before.beg_pos, after.end_pos,
958                       "strict_lhs_postfix", NULL);
959       *ok = false;
960       return Expression::Default();
961     }
962     Next();
963     return Expression::Default();
964   }
965   return expression;
966 }
967
968
969 PreParser::Expression PreParser::ParseLeftHandSideExpression(bool* ok) {
970   // LeftHandSideExpression ::
971   //   (NewExpression | MemberExpression) ...
972
973   Expression result = Expression::Default();
974   if (peek() == Token::NEW) {
975     result = ParseNewExpression(CHECK_OK);
976   } else {
977     result = ParseMemberExpression(CHECK_OK);
978   }
979
980   while (true) {
981     switch (peek()) {
982       case Token::LBRACK: {
983         Consume(Token::LBRACK);
984         ParseExpression(true, CHECK_OK);
985         Expect(Token::RBRACK, CHECK_OK);
986         if (result.IsThis()) {
987           result = Expression::ThisProperty();
988         } else {
989           result = Expression::Default();
990         }
991         break;
992       }
993
994       case Token::LPAREN: {
995         ParseArguments(CHECK_OK);
996         result = Expression::Default();
997         break;
998       }
999
1000       case Token::PERIOD: {
1001         Consume(Token::PERIOD);
1002         ParseIdentifierName(CHECK_OK);
1003         if (result.IsThis()) {
1004           result = Expression::ThisProperty();
1005         } else {
1006           result = Expression::Default();
1007         }
1008         break;
1009       }
1010
1011       default:
1012         return result;
1013     }
1014   }
1015 }
1016
1017
1018 PreParser::Expression PreParser::ParseNewExpression(bool* ok) {
1019   // NewExpression ::
1020   //   ('new')+ MemberExpression
1021
1022   // The grammar for new expressions is pretty warped. The keyword
1023   // 'new' can either be a part of the new expression (where it isn't
1024   // followed by an argument list) or a part of the member expression,
1025   // where it must be followed by an argument list. To accommodate
1026   // this, we parse the 'new' keywords greedily and keep track of how
1027   // many we have parsed. This information is then passed on to the
1028   // member expression parser, which is only allowed to match argument
1029   // lists as long as it has 'new' prefixes left
1030   unsigned new_count = 0;
1031   do {
1032     Consume(Token::NEW);
1033     new_count++;
1034   } while (peek() == Token::NEW);
1035
1036   return ParseMemberWithNewPrefixesExpression(new_count, ok);
1037 }
1038
1039
1040 PreParser::Expression PreParser::ParseMemberExpression(bool* ok) {
1041   return ParseMemberWithNewPrefixesExpression(0, ok);
1042 }
1043
1044
1045 PreParser::Expression PreParser::ParseMemberWithNewPrefixesExpression(
1046     unsigned new_count, bool* ok) {
1047   // MemberExpression ::
1048   //   (PrimaryExpression | FunctionLiteral)
1049   //     ('[' Expression ']' | '.' Identifier | Arguments)*
1050
1051   // Parse the initial primary or function expression.
1052   Expression result = Expression::Default();
1053   if (peek() == Token::FUNCTION) {
1054     Consume(Token::FUNCTION);
1055
1056     bool is_generator = allow_generators() && Check(Token::MUL);
1057     Identifier identifier = Identifier::Default();
1058     if (peek_any_identifier()) {
1059       identifier = ParseIdentifier(CHECK_OK);
1060     }
1061     result = ParseFunctionLiteral(is_generator, CHECK_OK);
1062     if (result.IsStrictFunction() && !identifier.IsValidStrictVariable()) {
1063       StrictModeIdentifierViolation(scanner()->location(),
1064                                     "strict_function_name",
1065                                     identifier,
1066                                     ok);
1067       return Expression::Default();
1068     }
1069   } else {
1070     result = ParsePrimaryExpression(CHECK_OK);
1071   }
1072
1073   while (true) {
1074     switch (peek()) {
1075       case Token::LBRACK: {
1076         Consume(Token::LBRACK);
1077         ParseExpression(true, CHECK_OK);
1078         Expect(Token::RBRACK, CHECK_OK);
1079         if (result.IsThis()) {
1080           result = Expression::ThisProperty();
1081         } else {
1082           result = Expression::Default();
1083         }
1084         break;
1085       }
1086       case Token::PERIOD: {
1087         Consume(Token::PERIOD);
1088         ParseIdentifierName(CHECK_OK);
1089         if (result.IsThis()) {
1090           result = Expression::ThisProperty();
1091         } else {
1092           result = Expression::Default();
1093         }
1094         break;
1095       }
1096       case Token::LPAREN: {
1097         if (new_count == 0) return result;
1098         // Consume one of the new prefixes (already parsed).
1099         ParseArguments(CHECK_OK);
1100         new_count--;
1101         result = Expression::Default();
1102         break;
1103       }
1104       default:
1105         return result;
1106     }
1107   }
1108 }
1109
1110
1111 PreParser::Expression PreParser::ParsePrimaryExpression(bool* ok) {
1112   // PrimaryExpression ::
1113   //   'this'
1114   //   'null'
1115   //   'true'
1116   //   'false'
1117   //   Identifier
1118   //   Number
1119   //   String
1120   //   ArrayLiteral
1121   //   ObjectLiteral
1122   //   RegExpLiteral
1123   //   '(' Expression ')'
1124
1125   Expression result = Expression::Default();
1126   switch (peek()) {
1127     case Token::THIS: {
1128       Next();
1129       result = Expression::This();
1130       break;
1131     }
1132
1133     case Token::FUTURE_RESERVED_WORD:
1134     case Token::FUTURE_STRICT_RESERVED_WORD:
1135     case Token::YIELD:
1136     case Token::IDENTIFIER: {
1137       Identifier id = ParseIdentifier(CHECK_OK);
1138       result = Expression::FromIdentifier(id);
1139       break;
1140     }
1141
1142     case Token::NULL_LITERAL:
1143     case Token::TRUE_LITERAL:
1144     case Token::FALSE_LITERAL:
1145     case Token::NUMBER: {
1146       Next();
1147       break;
1148     }
1149     case Token::STRING: {
1150       Next();
1151       result = GetStringSymbol();
1152       break;
1153     }
1154
1155     case Token::ASSIGN_DIV:
1156       result = ParseRegExpLiteral(true, CHECK_OK);
1157       break;
1158
1159     case Token::DIV:
1160       result = ParseRegExpLiteral(false, CHECK_OK);
1161       break;
1162
1163     case Token::LBRACK:
1164       result = ParseArrayLiteral(CHECK_OK);
1165       break;
1166
1167     case Token::LBRACE:
1168       result = ParseObjectLiteral(CHECK_OK);
1169       break;
1170
1171     case Token::LPAREN:
1172       Consume(Token::LPAREN);
1173       parenthesized_function_ = (peek() == Token::FUNCTION);
1174       result = ParseExpression(true, CHECK_OK);
1175       Expect(Token::RPAREN, CHECK_OK);
1176       result = result.Parenthesize();
1177       break;
1178
1179     case Token::MOD:
1180       result = ParseV8Intrinsic(CHECK_OK);
1181       break;
1182
1183     default: {
1184       Next();
1185       *ok = false;
1186       return Expression::Default();
1187     }
1188   }
1189
1190   return result;
1191 }
1192
1193
1194 PreParser::Expression PreParser::ParseArrayLiteral(bool* ok) {
1195   // ArrayLiteral ::
1196   //   '[' Expression? (',' Expression?)* ']'
1197   Expect(Token::LBRACK, CHECK_OK);
1198   while (peek() != Token::RBRACK) {
1199     if (peek() != Token::COMMA) {
1200       ParseAssignmentExpression(true, CHECK_OK);
1201     }
1202     if (peek() != Token::RBRACK) {
1203       Expect(Token::COMMA, CHECK_OK);
1204     }
1205   }
1206   Expect(Token::RBRACK, CHECK_OK);
1207
1208   scope_->NextMaterializedLiteralIndex();
1209   return Expression::Default();
1210 }
1211
1212
1213 PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) {
1214   // ObjectLiteral ::
1215   //   '{' (
1216   //       ((IdentifierName | String | Number) ':' AssignmentExpression)
1217   //     | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
1218   //    )*[','] '}'
1219
1220   ObjectLiteralChecker checker(this, language_mode());
1221
1222   Expect(Token::LBRACE, CHECK_OK);
1223   while (peek() != Token::RBRACE) {
1224     Token::Value next = peek();
1225     switch (next) {
1226       case Token::IDENTIFIER:
1227       case Token::FUTURE_RESERVED_WORD:
1228       case Token::FUTURE_STRICT_RESERVED_WORD: {
1229         bool is_getter = false;
1230         bool is_setter = false;
1231         ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
1232         if ((is_getter || is_setter) && peek() != Token::COLON) {
1233             Token::Value name = Next();
1234             bool is_keyword = Token::IsKeyword(name);
1235             if (name != Token::IDENTIFIER &&
1236                 name != Token::FUTURE_RESERVED_WORD &&
1237                 name != Token::FUTURE_STRICT_RESERVED_WORD &&
1238                 name != Token::NUMBER &&
1239                 name != Token::STRING &&
1240                 !is_keyword) {
1241               *ok = false;
1242               return Expression::Default();
1243             }
1244             if (!is_keyword) {
1245               LogSymbol();
1246             }
1247             PropertyKind type = is_getter ? kGetterProperty : kSetterProperty;
1248             checker.CheckProperty(name, type, CHECK_OK);
1249             ParseFunctionLiteral(false, CHECK_OK);
1250             if (peek() != Token::RBRACE) {
1251               Expect(Token::COMMA, CHECK_OK);
1252             }
1253             continue;  // restart the while
1254         }
1255         checker.CheckProperty(next, kValueProperty, CHECK_OK);
1256         break;
1257       }
1258       case Token::STRING:
1259         Consume(next);
1260         checker.CheckProperty(next, kValueProperty, CHECK_OK);
1261         GetStringSymbol();
1262         break;
1263       case Token::NUMBER:
1264         Consume(next);
1265         checker.CheckProperty(next, kValueProperty, CHECK_OK);
1266         break;
1267       default:
1268         if (Token::IsKeyword(next)) {
1269           Consume(next);
1270           checker.CheckProperty(next, kValueProperty, CHECK_OK);
1271         } else {
1272           // Unexpected token.
1273           *ok = false;
1274           return Expression::Default();
1275         }
1276     }
1277
1278     Expect(Token::COLON, CHECK_OK);
1279     ParseAssignmentExpression(true, CHECK_OK);
1280
1281     // TODO(1240767): Consider allowing trailing comma.
1282     if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
1283   }
1284   Expect(Token::RBRACE, CHECK_OK);
1285
1286   scope_->NextMaterializedLiteralIndex();
1287   return Expression::Default();
1288 }
1289
1290
1291 PreParser::Expression PreParser::ParseRegExpLiteral(bool seen_equal,
1292                                                     bool* ok) {
1293   if (!scanner()->ScanRegExpPattern(seen_equal)) {
1294     Next();
1295     ReportMessageAt(scanner()->location(), "unterminated_regexp", NULL);
1296     *ok = false;
1297     return Expression::Default();
1298   }
1299
1300   scope_->NextMaterializedLiteralIndex();
1301
1302   if (!scanner()->ScanRegExpFlags()) {
1303     Next();
1304     ReportMessageAt(scanner()->location(), "invalid_regexp_flags", NULL);
1305     *ok = false;
1306     return Expression::Default();
1307   }
1308   Next();
1309   return Expression::Default();
1310 }
1311
1312
1313 PreParser::Arguments PreParser::ParseArguments(bool* ok) {
1314   // Arguments ::
1315   //   '(' (AssignmentExpression)*[','] ')'
1316
1317   Expect(Token::LPAREN, ok);
1318   if (!*ok) return -1;
1319   bool done = (peek() == Token::RPAREN);
1320   int argc = 0;
1321   while (!done) {
1322     ParseAssignmentExpression(true, ok);
1323     if (!*ok) return -1;
1324     argc++;
1325     done = (peek() == Token::RPAREN);
1326     if (!done) {
1327       Expect(Token::COMMA, ok);
1328       if (!*ok) return -1;
1329     }
1330   }
1331   Expect(Token::RPAREN, ok);
1332   return argc;
1333 }
1334
1335
1336 PreParser::Expression PreParser::ParseFunctionLiteral(bool is_generator,
1337                                                       bool* ok) {
1338   // Function ::
1339   //   '(' FormalParameterList? ')' '{' FunctionBody '}'
1340
1341   // Parse function body.
1342   ScopeType outer_scope_type = scope_->type();
1343   bool inside_with = scope_->IsInsideWith();
1344   Scope function_scope(&scope_, kFunctionScope);
1345   function_scope.set_is_generator(is_generator);
1346   //  FormalParameterList ::
1347   //    '(' (Identifier)*[','] ')'
1348   Expect(Token::LPAREN, CHECK_OK);
1349   int start_position = position();
1350   bool done = (peek() == Token::RPAREN);
1351   DuplicateFinder duplicate_finder(scanner()->unicode_cache());
1352   while (!done) {
1353     Identifier id = ParseIdentifier(CHECK_OK);
1354     if (!id.IsValidStrictVariable()) {
1355       StrictModeIdentifierViolation(scanner()->location(),
1356                                     "strict_param_name",
1357                                     id,
1358                                     CHECK_OK);
1359     }
1360     int prev_value;
1361     if (scanner()->is_literal_ascii()) {
1362       prev_value =
1363           duplicate_finder.AddAsciiSymbol(scanner()->literal_ascii_string(), 1);
1364     } else {
1365       prev_value =
1366           duplicate_finder.AddUtf16Symbol(scanner()->literal_utf16_string(), 1);
1367     }
1368
1369     if (prev_value != 0) {
1370       SetStrictModeViolation(scanner()->location(),
1371                              "strict_param_dupe",
1372                              CHECK_OK);
1373     }
1374     done = (peek() == Token::RPAREN);
1375     if (!done) {
1376       Expect(Token::COMMA, CHECK_OK);
1377     }
1378   }
1379   Expect(Token::RPAREN, CHECK_OK);
1380
1381   // Determine if the function will be lazily compiled.
1382   // Currently only happens to top-level functions.
1383   // Optimistically assume that all top-level functions are lazily compiled.
1384   bool is_lazily_compiled = (outer_scope_type == kTopLevelScope &&
1385                              !inside_with && allow_lazy() &&
1386                              !parenthesized_function_);
1387   parenthesized_function_ = false;
1388
1389   Expect(Token::LBRACE, CHECK_OK);
1390   if (is_lazily_compiled) {
1391     ParseLazyFunctionLiteralBody(CHECK_OK);
1392   } else {
1393     ParseSourceElements(Token::RBRACE, ok);
1394   }
1395   Expect(Token::RBRACE, CHECK_OK);
1396
1397   if (!is_classic_mode()) {
1398     int end_position = scanner()->location().end_pos;
1399     CheckOctalLiteral(start_position, end_position, CHECK_OK);
1400     CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK);
1401     return Expression::StrictFunction();
1402   }
1403
1404   return Expression::Default();
1405 }
1406
1407
1408 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) {
1409   int body_start = position();
1410   log_->PauseRecording();
1411   ParseSourceElements(Token::RBRACE, ok);
1412   log_->ResumeRecording();
1413   if (!*ok) return;
1414
1415   // Position right after terminal '}'.
1416   ASSERT_EQ(Token::RBRACE, scanner()->peek());
1417   int body_end = scanner()->peek_location().end_pos;
1418   log_->LogFunction(body_start, body_end,
1419                     scope_->materialized_literal_count(),
1420                     scope_->expected_properties(),
1421                     language_mode());
1422 }
1423
1424
1425 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
1426   // CallRuntime ::
1427   //   '%' Identifier Arguments
1428   Expect(Token::MOD, CHECK_OK);
1429   if (!allow_natives_syntax()) {
1430     *ok = false;
1431     return Expression::Default();
1432   }
1433   ParseIdentifier(CHECK_OK);
1434   ParseArguments(ok);
1435
1436   return Expression::Default();
1437 }
1438
1439 #undef CHECK_OK
1440
1441
1442 void PreParser::LogSymbol() {
1443   int identifier_pos = position();
1444   if (scanner()->is_literal_ascii()) {
1445     log_->LogAsciiSymbol(identifier_pos, scanner()->literal_ascii_string());
1446   } else {
1447     log_->LogUtf16Symbol(identifier_pos, scanner()->literal_utf16_string());
1448   }
1449 }
1450
1451
1452 PreParser::Expression PreParser::GetStringSymbol() {
1453   const int kUseStrictLength = 10;
1454   const char* kUseStrictChars = "use strict";
1455   LogSymbol();
1456   if (scanner()->is_literal_ascii() &&
1457       scanner()->literal_length() == kUseStrictLength &&
1458       !scanner()->literal_contains_escapes() &&
1459       !strncmp(scanner()->literal_ascii_string().start(), kUseStrictChars,
1460                kUseStrictLength)) {
1461     return Expression::UseStrictStringLiteral();
1462   }
1463   return Expression::StringLiteral();
1464 }
1465
1466
1467 PreParser::Identifier PreParser::GetIdentifierSymbol() {
1468   LogSymbol();
1469   if (scanner()->current_token() == Token::FUTURE_RESERVED_WORD) {
1470     return Identifier::FutureReserved();
1471   } else if (scanner()->current_token() ==
1472              Token::FUTURE_STRICT_RESERVED_WORD) {
1473     return Identifier::FutureStrictReserved();
1474   } else if (scanner()->current_token() == Token::YIELD) {
1475     return Identifier::Yield();
1476   }
1477   if (scanner()->is_literal_ascii()) {
1478     // Detect strict-mode poison words.
1479     if (scanner()->literal_length() == 4 &&
1480         !strncmp(scanner()->literal_ascii_string().start(), "eval", 4)) {
1481       return Identifier::Eval();
1482     }
1483     if (scanner()->literal_length() == 9 &&
1484         !strncmp(scanner()->literal_ascii_string().start(), "arguments", 9)) {
1485       return Identifier::Arguments();
1486     }
1487   }
1488   return Identifier::Default();
1489 }
1490
1491
1492 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) {
1493   Token::Value next = Next();
1494   switch (next) {
1495     case Token::FUTURE_RESERVED_WORD: {
1496       Scanner::Location location = scanner()->location();
1497       ReportMessageAt(location.beg_pos, location.end_pos,
1498                       "reserved_word", NULL);
1499       *ok = false;
1500       return GetIdentifierSymbol();
1501     }
1502     case Token::YIELD:
1503       if (scope_->is_generator()) {
1504         // 'yield' in a generator is only valid as part of a YieldExpression.
1505         ReportMessageAt(scanner()->location(), "unexpected_token", "yield");
1506         *ok = false;
1507         return Identifier::Yield();
1508       }
1509       // FALLTHROUGH
1510     case Token::FUTURE_STRICT_RESERVED_WORD:
1511       if (!is_classic_mode()) {
1512         Scanner::Location location = scanner()->location();
1513         ReportMessageAt(location.beg_pos, location.end_pos,
1514                         "strict_reserved_word", NULL);
1515         *ok = false;
1516       }
1517       // FALLTHROUGH
1518     case Token::IDENTIFIER:
1519       return GetIdentifierSymbol();
1520     default:
1521       *ok = false;
1522       return Identifier::Default();
1523   }
1524 }
1525
1526
1527 void PreParser::SetStrictModeViolation(Scanner::Location location,
1528                                        const char* type,
1529                                        bool* ok) {
1530   if (!is_classic_mode()) {
1531     ReportMessageAt(location, type, NULL);
1532     *ok = false;
1533     return;
1534   }
1535   // Delay report in case this later turns out to be strict code
1536   // (i.e., for function names and parameters prior to a "use strict"
1537   // directive).
1538   // It's safe to overwrite an existing violation.
1539   // It's either from a function that turned out to be non-strict,
1540   // or it's in the current function (and we just need to report
1541   // one error), or it's in a unclosed nesting function that wasn't
1542   // strict (otherwise we would already be in strict mode).
1543   strict_mode_violation_location_ = location;
1544   strict_mode_violation_type_ = type;
1545 }
1546
1547
1548 void PreParser::CheckDelayedStrictModeViolation(int beg_pos,
1549                                                 int end_pos,
1550                                                 bool* ok) {
1551   Scanner::Location location = strict_mode_violation_location_;
1552   if (location.IsValid() &&
1553       location.beg_pos > beg_pos && location.end_pos < end_pos) {
1554     ReportMessageAt(location, strict_mode_violation_type_, NULL);
1555     *ok = false;
1556   }
1557 }
1558
1559
1560 void PreParser::StrictModeIdentifierViolation(Scanner::Location location,
1561                                               const char* eval_args_type,
1562                                               Identifier identifier,
1563                                               bool* ok) {
1564   const char* type = eval_args_type;
1565   if (identifier.IsFutureReserved()) {
1566     type = "reserved_word";
1567   } else if (identifier.IsFutureStrictReserved() || identifier.IsYield()) {
1568     type = "strict_reserved_word";
1569   }
1570   if (!is_classic_mode()) {
1571     ReportMessageAt(location, type, NULL);
1572     *ok = false;
1573     return;
1574   }
1575   strict_mode_violation_location_ = location;
1576   strict_mode_violation_type_ = type;
1577 }
1578
1579
1580 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) {
1581   Token::Value next = Next();
1582   if (Token::IsKeyword(next)) {
1583     int pos = position();
1584     const char* keyword = Token::String(next);
1585     log_->LogAsciiSymbol(pos, Vector<const char>(keyword, StrLength(keyword)));
1586     return Identifier::Default();
1587   }
1588   if (next == Token::IDENTIFIER ||
1589       next == Token::FUTURE_RESERVED_WORD ||
1590       next == Token::FUTURE_STRICT_RESERVED_WORD) {
1591     return GetIdentifierSymbol();
1592   }
1593   *ok = false;
1594   return Identifier::Default();
1595 }
1596
1597 #undef CHECK_OK
1598
1599
1600 // This function reads an identifier and determines whether or not it
1601 // is 'get' or 'set'.
1602 PreParser::Identifier PreParser::ParseIdentifierNameOrGetOrSet(bool* is_get,
1603                                                                bool* is_set,
1604                                                                bool* ok) {
1605   Identifier result = ParseIdentifierName(ok);
1606   if (!*ok) return Identifier::Default();
1607   if (scanner()->is_literal_ascii() &&
1608       scanner()->literal_length() == 3) {
1609     const char* token = scanner()->literal_ascii_string().start();
1610     *is_get = strncmp(token, "get", 3) == 0;
1611     *is_set = !*is_get && strncmp(token, "set", 3) == 0;
1612   }
1613   return result;
1614 }
1615
1616
1617 void PreParser::ObjectLiteralChecker::CheckProperty(Token::Value property,
1618                                                     PropertyKind type,
1619                                                     bool* ok) {
1620   int old;
1621   if (property == Token::NUMBER) {
1622     old = finder_.AddNumber(scanner()->literal_ascii_string(), type);
1623   } else if (scanner()->is_literal_ascii()) {
1624     old = finder_.AddAsciiSymbol(scanner()->literal_ascii_string(), type);
1625   } else {
1626     old = finder_.AddUtf16Symbol(scanner()->literal_utf16_string(), type);
1627   }
1628   PropertyKind old_type = static_cast<PropertyKind>(old);
1629   if (HasConflict(old_type, type)) {
1630     if (IsDataDataConflict(old_type, type)) {
1631       // Both are data properties.
1632       if (language_mode_ == CLASSIC_MODE) return;
1633       parser()->ReportMessageAt(scanner()->location(),
1634                                "strict_duplicate_property");
1635     } else if (IsDataAccessorConflict(old_type, type)) {
1636       // Both a data and an accessor property with the same name.
1637       parser()->ReportMessageAt(scanner()->location(),
1638                                "accessor_data_property");
1639     } else {
1640       ASSERT(IsAccessorAccessorConflict(old_type, type));
1641       // Both accessors of the same type.
1642       parser()->ReportMessageAt(scanner()->location(),
1643                                "accessor_get_set");
1644     }
1645     *ok = false;
1646   }
1647 }
1648
1649 } }  // v8::internal