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