Updated V8 from git://github.com/v8/v8.git to 57f8959fb264354ba1a2e5118db512f588917061
[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_->EnterWith();
585   ParseStatement(CHECK_OK);
586   scope_->LeaveWith();
587   return Statement::Default();
588 }
589
590
591 PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) {
592   // SwitchStatement ::
593   //   'switch' '(' Expression ')' '{' CaseClause* '}'
594
595   Expect(i::Token::SWITCH, CHECK_OK);
596   Expect(i::Token::LPAREN, CHECK_OK);
597   ParseExpression(true, CHECK_OK);
598   Expect(i::Token::RPAREN, CHECK_OK);
599
600   Expect(i::Token::LBRACE, CHECK_OK);
601   i::Token::Value token = peek();
602   while (token != i::Token::RBRACE) {
603     if (token == i::Token::CASE) {
604       Expect(i::Token::CASE, CHECK_OK);
605       ParseExpression(true, CHECK_OK);
606       Expect(i::Token::COLON, CHECK_OK);
607     } else if (token == i::Token::DEFAULT) {
608       Expect(i::Token::DEFAULT, CHECK_OK);
609       Expect(i::Token::COLON, CHECK_OK);
610     } else {
611       ParseStatement(CHECK_OK);
612     }
613     token = peek();
614   }
615   Expect(i::Token::RBRACE, ok);
616   return Statement::Default();
617 }
618
619
620 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) {
621   // DoStatement ::
622   //   'do' Statement 'while' '(' Expression ')' ';'
623
624   Expect(i::Token::DO, CHECK_OK);
625   ParseStatement(CHECK_OK);
626   Expect(i::Token::WHILE, CHECK_OK);
627   Expect(i::Token::LPAREN, CHECK_OK);
628   ParseExpression(true, CHECK_OK);
629   Expect(i::Token::RPAREN, ok);
630   if (peek() == i::Token::SEMICOLON) Consume(i::Token::SEMICOLON);
631   return Statement::Default();
632 }
633
634
635 PreParser::Statement PreParser::ParseWhileStatement(bool* ok) {
636   // WhileStatement ::
637   //   'while' '(' Expression ')' Statement
638
639   Expect(i::Token::WHILE, CHECK_OK);
640   Expect(i::Token::LPAREN, CHECK_OK);
641   ParseExpression(true, CHECK_OK);
642   Expect(i::Token::RPAREN, CHECK_OK);
643   ParseStatement(ok);
644   return Statement::Default();
645 }
646
647
648 PreParser::Statement PreParser::ParseForStatement(bool* ok) {
649   // ForStatement ::
650   //   'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
651
652   Expect(i::Token::FOR, CHECK_OK);
653   Expect(i::Token::LPAREN, CHECK_OK);
654   if (peek() != i::Token::SEMICOLON) {
655     if (peek() == i::Token::VAR || peek() == i::Token::CONST ||
656         peek() == i::Token::LET) {
657       bool is_let = peek() == i::Token::LET;
658       int decl_count;
659       VariableDeclarationProperties decl_props = kHasNoInitializers;
660       ParseVariableDeclarations(
661           kForStatement, &decl_props, &decl_count, CHECK_OK);
662       bool accept_IN = decl_count == 1 &&
663           !(is_let && decl_props == kHasInitializers);
664       if (peek() == i::Token::IN && accept_IN) {
665         Expect(i::Token::IN, CHECK_OK);
666         ParseExpression(true, CHECK_OK);
667         Expect(i::Token::RPAREN, CHECK_OK);
668
669         ParseStatement(CHECK_OK);
670         return Statement::Default();
671       }
672     } else {
673       ParseExpression(false, CHECK_OK);
674       if (peek() == i::Token::IN) {
675         Expect(i::Token::IN, CHECK_OK);
676         ParseExpression(true, CHECK_OK);
677         Expect(i::Token::RPAREN, CHECK_OK);
678
679         ParseStatement(CHECK_OK);
680         return Statement::Default();
681       }
682     }
683   }
684
685   // Parsed initializer at this point.
686   Expect(i::Token::SEMICOLON, CHECK_OK);
687
688   if (peek() != i::Token::SEMICOLON) {
689     ParseExpression(true, CHECK_OK);
690   }
691   Expect(i::Token::SEMICOLON, CHECK_OK);
692
693   if (peek() != i::Token::RPAREN) {
694     ParseExpression(true, CHECK_OK);
695   }
696   Expect(i::Token::RPAREN, CHECK_OK);
697
698   ParseStatement(ok);
699   return Statement::Default();
700 }
701
702
703 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) {
704   // ThrowStatement ::
705   //   'throw' [no line terminator] Expression ';'
706
707   Expect(i::Token::THROW, CHECK_OK);
708   if (scanner_->HasAnyLineTerminatorBeforeNext()) {
709     i::Scanner::Location pos = scanner_->location();
710     ReportMessageAt(pos, "newline_after_throw", NULL);
711     *ok = false;
712     return Statement::Default();
713   }
714   ParseExpression(true, CHECK_OK);
715   ExpectSemicolon(ok);
716   return Statement::Default();
717 }
718
719
720 PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
721   // TryStatement ::
722   //   'try' Block Catch
723   //   'try' Block Finally
724   //   'try' Block Catch Finally
725   //
726   // Catch ::
727   //   'catch' '(' Identifier ')' Block
728   //
729   // Finally ::
730   //   'finally' Block
731
732   // In preparsing, allow any number of catch/finally blocks, including zero
733   // of both.
734
735   Expect(i::Token::TRY, CHECK_OK);
736
737   ParseBlock(CHECK_OK);
738
739   bool catch_or_finally_seen = false;
740   if (peek() == i::Token::CATCH) {
741     Consume(i::Token::CATCH);
742     Expect(i::Token::LPAREN, CHECK_OK);
743     Identifier id = ParseIdentifier(CHECK_OK);
744     if (!is_classic_mode() && !id.IsValidStrictVariable()) {
745       StrictModeIdentifierViolation(scanner_->location(),
746                                     "strict_catch_variable",
747                                     id,
748                                     ok);
749       return Statement::Default();
750     }
751     Expect(i::Token::RPAREN, CHECK_OK);
752     scope_->EnterWith();
753     ParseBlock(ok);
754     scope_->LeaveWith();
755     if (!*ok) Statement::Default();
756     catch_or_finally_seen = true;
757   }
758   if (peek() == i::Token::FINALLY) {
759     Consume(i::Token::FINALLY);
760     ParseBlock(CHECK_OK);
761     catch_or_finally_seen = true;
762   }
763   if (!catch_or_finally_seen) {
764     *ok = false;
765   }
766   return Statement::Default();
767 }
768
769
770 PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) {
771   // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
772   // contexts this is used as a statement which invokes the debugger as if a
773   // break point is present.
774   // DebuggerStatement ::
775   //   'debugger' ';'
776
777   Expect(i::Token::DEBUGGER, CHECK_OK);
778   ExpectSemicolon(ok);
779   return Statement::Default();
780 }
781
782
783 #undef CHECK_OK
784 #define CHECK_OK  ok);                     \
785   if (!*ok) return Expression::Default();  \
786   ((void)0
787 #define DUMMY )  // to make indentation work
788 #undef DUMMY
789
790
791 // Precedence = 1
792 PreParser::Expression PreParser::ParseExpression(bool accept_IN, bool* ok) {
793   // Expression ::
794   //   AssignmentExpression
795   //   Expression ',' AssignmentExpression
796
797   Expression result = ParseAssignmentExpression(accept_IN, CHECK_OK);
798   while (peek() == i::Token::COMMA) {
799     Expect(i::Token::COMMA, CHECK_OK);
800     ParseAssignmentExpression(accept_IN, CHECK_OK);
801     result = Expression::Default();
802   }
803   return result;
804 }
805
806
807 // Precedence = 2
808 PreParser::Expression PreParser::ParseAssignmentExpression(bool accept_IN,
809                                                            bool* ok) {
810   // AssignmentExpression ::
811   //   ConditionalExpression
812   //   LeftHandSideExpression AssignmentOperator AssignmentExpression
813
814   i::Scanner::Location before = scanner_->peek_location();
815   Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK);
816
817   if (!i::Token::IsAssignmentOp(peek())) {
818     // Parsed conditional expression only (no assignment).
819     return expression;
820   }
821
822   if (!is_classic_mode() &&
823       expression.IsIdentifier() &&
824       expression.AsIdentifier().IsEvalOrArguments()) {
825     i::Scanner::Location after = scanner_->location();
826     ReportMessageAt(before.beg_pos, after.end_pos,
827                     "strict_lhs_assignment", NULL);
828     *ok = false;
829     return Expression::Default();
830   }
831
832   i::Token::Value op = Next();  // Get assignment operator.
833   ParseAssignmentExpression(accept_IN, CHECK_OK);
834
835   if ((op == i::Token::ASSIGN) && expression.IsThisProperty()) {
836     scope_->AddProperty();
837   }
838
839   return Expression::Default();
840 }
841
842
843 // Precedence = 3
844 PreParser::Expression PreParser::ParseConditionalExpression(bool accept_IN,
845                                                             bool* ok) {
846   // ConditionalExpression ::
847   //   LogicalOrExpression
848   //   LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
849
850   // We start using the binary expression parser for prec >= 4 only!
851   Expression expression = ParseBinaryExpression(4, accept_IN, CHECK_OK);
852   if (peek() != i::Token::CONDITIONAL) return expression;
853   Consume(i::Token::CONDITIONAL);
854   // In parsing the first assignment expression in conditional
855   // expressions we always accept the 'in' keyword; see ECMA-262,
856   // section 11.12, page 58.
857   ParseAssignmentExpression(true, CHECK_OK);
858   Expect(i::Token::COLON, CHECK_OK);
859   ParseAssignmentExpression(accept_IN, CHECK_OK);
860   return Expression::Default();
861 }
862
863
864 int PreParser::Precedence(i::Token::Value tok, bool accept_IN) {
865   if (tok == i::Token::IN && !accept_IN)
866     return 0;  // 0 precedence will terminate binary expression parsing
867
868   return i::Token::Precedence(tok);
869 }
870
871
872 // Precedence >= 4
873 PreParser::Expression PreParser::ParseBinaryExpression(int prec,
874                                                        bool accept_IN,
875                                                        bool* ok) {
876   Expression result = ParseUnaryExpression(CHECK_OK);
877   for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
878     // prec1 >= 4
879     while (Precedence(peek(), accept_IN) == prec1) {
880       Next();
881       ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK);
882       result = Expression::Default();
883     }
884   }
885   return result;
886 }
887
888
889 PreParser::Expression PreParser::ParseUnaryExpression(bool* ok) {
890   // UnaryExpression ::
891   //   PostfixExpression
892   //   'delete' UnaryExpression
893   //   'void' UnaryExpression
894   //   'typeof' UnaryExpression
895   //   '++' UnaryExpression
896   //   '--' UnaryExpression
897   //   '+' UnaryExpression
898   //   '-' UnaryExpression
899   //   '~' UnaryExpression
900   //   '!' UnaryExpression
901
902   i::Token::Value op = peek();
903   if (i::Token::IsUnaryOp(op)) {
904     op = Next();
905     ParseUnaryExpression(ok);
906     return Expression::Default();
907   } else if (i::Token::IsCountOp(op)) {
908     op = Next();
909     i::Scanner::Location before = scanner_->peek_location();
910     Expression expression = ParseUnaryExpression(CHECK_OK);
911     if (!is_classic_mode() &&
912         expression.IsIdentifier() &&
913         expression.AsIdentifier().IsEvalOrArguments()) {
914       i::Scanner::Location after = scanner_->location();
915       ReportMessageAt(before.beg_pos, after.end_pos,
916                       "strict_lhs_prefix", NULL);
917       *ok = false;
918     }
919     return Expression::Default();
920   } else {
921     return ParsePostfixExpression(ok);
922   }
923 }
924
925
926 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) {
927   // PostfixExpression ::
928   //   LeftHandSideExpression ('++' | '--')?
929
930   i::Scanner::Location before = scanner_->peek_location();
931   Expression expression = ParseLeftHandSideExpression(CHECK_OK);
932   if (!scanner_->HasAnyLineTerminatorBeforeNext() &&
933       i::Token::IsCountOp(peek())) {
934     if (!is_classic_mode() &&
935         expression.IsIdentifier() &&
936         expression.AsIdentifier().IsEvalOrArguments()) {
937       i::Scanner::Location after = scanner_->location();
938       ReportMessageAt(before.beg_pos, after.end_pos,
939                       "strict_lhs_postfix", NULL);
940       *ok = false;
941       return Expression::Default();
942     }
943     Next();
944     return Expression::Default();
945   }
946   return expression;
947 }
948
949
950 PreParser::Expression PreParser::ParseLeftHandSideExpression(bool* ok) {
951   // LeftHandSideExpression ::
952   //   (NewExpression | MemberExpression) ...
953
954   Expression result = Expression::Default();
955   if (peek() == i::Token::NEW) {
956     result = ParseNewExpression(CHECK_OK);
957   } else {
958     result = ParseMemberExpression(CHECK_OK);
959   }
960
961   while (true) {
962     switch (peek()) {
963       case i::Token::LBRACK: {
964         Consume(i::Token::LBRACK);
965         ParseExpression(true, CHECK_OK);
966         Expect(i::Token::RBRACK, CHECK_OK);
967         if (result.IsThis()) {
968           result = Expression::ThisProperty();
969         } else {
970           result = Expression::Default();
971         }
972         break;
973       }
974
975       case i::Token::LPAREN: {
976         ParseArguments(CHECK_OK);
977         result = Expression::Default();
978         break;
979       }
980
981       case i::Token::PERIOD: {
982         Consume(i::Token::PERIOD);
983         ParseIdentifierName(CHECK_OK);
984         if (result.IsThis()) {
985           result = Expression::ThisProperty();
986         } else {
987           result = Expression::Default();
988         }
989         break;
990       }
991
992       default:
993         return result;
994     }
995   }
996 }
997
998
999 PreParser::Expression PreParser::ParseNewExpression(bool* ok) {
1000   // NewExpression ::
1001   //   ('new')+ MemberExpression
1002
1003   // The grammar for new expressions is pretty warped. The keyword
1004   // 'new' can either be a part of the new expression (where it isn't
1005   // followed by an argument list) or a part of the member expression,
1006   // where it must be followed by an argument list. To accommodate
1007   // this, we parse the 'new' keywords greedily and keep track of how
1008   // many we have parsed. This information is then passed on to the
1009   // member expression parser, which is only allowed to match argument
1010   // lists as long as it has 'new' prefixes left
1011   unsigned new_count = 0;
1012   do {
1013     Consume(i::Token::NEW);
1014     new_count++;
1015   } while (peek() == i::Token::NEW);
1016
1017   return ParseMemberWithNewPrefixesExpression(new_count, ok);
1018 }
1019
1020
1021 PreParser::Expression PreParser::ParseMemberExpression(bool* ok) {
1022   return ParseMemberWithNewPrefixesExpression(0, ok);
1023 }
1024
1025
1026 PreParser::Expression PreParser::ParseMemberWithNewPrefixesExpression(
1027     unsigned new_count, bool* ok) {
1028   // MemberExpression ::
1029   //   (PrimaryExpression | FunctionLiteral)
1030   //     ('[' Expression ']' | '.' Identifier | Arguments)*
1031
1032   // Parse the initial primary or function expression.
1033   Expression result = Expression::Default();
1034   if (peek() == i::Token::FUNCTION) {
1035     Consume(i::Token::FUNCTION);
1036     Identifier identifier = Identifier::Default();
1037     if (peek_any_identifier()) {
1038       identifier = ParseIdentifier(CHECK_OK);
1039     }
1040     result = ParseFunctionLiteral(CHECK_OK);
1041     if (result.IsStrictFunction() && !identifier.IsValidStrictVariable()) {
1042       StrictModeIdentifierViolation(scanner_->location(),
1043                                     "strict_function_name",
1044                                     identifier,
1045                                     ok);
1046       return Expression::Default();
1047     }
1048   } else {
1049     result = ParsePrimaryExpression(CHECK_OK);
1050   }
1051
1052   while (true) {
1053     switch (peek()) {
1054       case i::Token::LBRACK: {
1055         Consume(i::Token::LBRACK);
1056         ParseExpression(true, CHECK_OK);
1057         Expect(i::Token::RBRACK, CHECK_OK);
1058         if (result.IsThis()) {
1059           result = Expression::ThisProperty();
1060         } else {
1061           result = Expression::Default();
1062         }
1063         break;
1064       }
1065       case i::Token::PERIOD: {
1066         Consume(i::Token::PERIOD);
1067         ParseIdentifierName(CHECK_OK);
1068         if (result.IsThis()) {
1069           result = Expression::ThisProperty();
1070         } else {
1071           result = Expression::Default();
1072         }
1073         break;
1074       }
1075       case i::Token::LPAREN: {
1076         if (new_count == 0) return result;
1077         // Consume one of the new prefixes (already parsed).
1078         ParseArguments(CHECK_OK);
1079         new_count--;
1080         result = Expression::Default();
1081         break;
1082       }
1083       default:
1084         return result;
1085     }
1086   }
1087 }
1088
1089
1090 PreParser::Expression PreParser::ParsePrimaryExpression(bool* ok) {
1091   // PrimaryExpression ::
1092   //   'this'
1093   //   'null'
1094   //   'true'
1095   //   'false'
1096   //   Identifier
1097   //   Number
1098   //   String
1099   //   ArrayLiteral
1100   //   ObjectLiteral
1101   //   RegExpLiteral
1102   //   '(' Expression ')'
1103
1104   Expression result = Expression::Default();
1105   switch (peek()) {
1106     case i::Token::THIS: {
1107       Next();
1108       result = Expression::This();
1109       break;
1110     }
1111
1112     case i::Token::FUTURE_RESERVED_WORD: {
1113       Next();
1114       i::Scanner::Location location = scanner_->location();
1115       ReportMessageAt(location.beg_pos, location.end_pos,
1116                       "reserved_word", NULL);
1117       *ok = false;
1118       return Expression::Default();
1119     }
1120
1121     case i::Token::FUTURE_STRICT_RESERVED_WORD:
1122       if (!is_classic_mode()) {
1123         Next();
1124         i::Scanner::Location location = scanner_->location();
1125         ReportMessageAt(location, "strict_reserved_word", NULL);
1126         *ok = false;
1127         return Expression::Default();
1128       }
1129       // FALLTHROUGH
1130     case i::Token::IDENTIFIER: {
1131       Identifier id = ParseIdentifier(CHECK_OK);
1132       result = Expression::FromIdentifier(id);
1133       break;
1134     }
1135
1136     case i::Token::NULL_LITERAL:
1137     case i::Token::TRUE_LITERAL:
1138     case i::Token::FALSE_LITERAL:
1139     case i::Token::NUMBER: {
1140       Next();
1141       break;
1142     }
1143     case i::Token::STRING: {
1144       Next();
1145       result = GetStringSymbol();
1146       break;
1147     }
1148
1149     case i::Token::ASSIGN_DIV:
1150       result = ParseRegExpLiteral(true, CHECK_OK);
1151       break;
1152
1153     case i::Token::DIV:
1154       result = ParseRegExpLiteral(false, CHECK_OK);
1155       break;
1156
1157     case i::Token::LBRACK:
1158       result = ParseArrayLiteral(CHECK_OK);
1159       break;
1160
1161     case i::Token::LBRACE:
1162       result = ParseObjectLiteral(CHECK_OK);
1163       break;
1164
1165     case i::Token::LPAREN:
1166       Consume(i::Token::LPAREN);
1167       parenthesized_function_ = (peek() == i::Token::FUNCTION);
1168       result = ParseExpression(true, CHECK_OK);
1169       Expect(i::Token::RPAREN, CHECK_OK);
1170       result = result.Parenthesize();
1171       break;
1172
1173     case i::Token::MOD:
1174       result = ParseV8Intrinsic(CHECK_OK);
1175       break;
1176
1177     default: {
1178       Next();
1179       *ok = false;
1180       return Expression::Default();
1181     }
1182   }
1183
1184   return result;
1185 }
1186
1187
1188 PreParser::Expression PreParser::ParseArrayLiteral(bool* ok) {
1189   // ArrayLiteral ::
1190   //   '[' Expression? (',' Expression?)* ']'
1191   Expect(i::Token::LBRACK, CHECK_OK);
1192   while (peek() != i::Token::RBRACK) {
1193     if (peek() != i::Token::COMMA) {
1194       ParseAssignmentExpression(true, CHECK_OK);
1195     }
1196     if (peek() != i::Token::RBRACK) {
1197       Expect(i::Token::COMMA, CHECK_OK);
1198     }
1199   }
1200   Expect(i::Token::RBRACK, CHECK_OK);
1201
1202   scope_->NextMaterializedLiteralIndex();
1203   return Expression::Default();
1204 }
1205
1206 void PreParser::CheckDuplicate(DuplicateFinder* finder,
1207                                i::Token::Value property,
1208                                int type,
1209                                bool* ok) {
1210   int old_type;
1211   if (property == i::Token::NUMBER) {
1212     old_type = finder->AddNumber(scanner_->literal_ascii_string(), type);
1213   } else if (scanner_->is_literal_ascii()) {
1214     old_type = finder->AddAsciiSymbol(scanner_->literal_ascii_string(),
1215                                       type);
1216   } else {
1217     old_type = finder->AddUtf16Symbol(scanner_->literal_utf16_string(), type);
1218   }
1219   if (HasConflict(old_type, type)) {
1220     if (IsDataDataConflict(old_type, type)) {
1221       // Both are data properties.
1222       if (is_classic_mode()) return;
1223       ReportMessageAt(scanner_->location(),
1224                       "strict_duplicate_property", NULL);
1225     } else if (IsDataAccessorConflict(old_type, type)) {
1226       // Both a data and an accessor property with the same name.
1227       ReportMessageAt(scanner_->location(),
1228                       "accessor_data_property", NULL);
1229     } else {
1230       ASSERT(IsAccessorAccessorConflict(old_type, type));
1231       // Both accessors of the same type.
1232       ReportMessageAt(scanner_->location(),
1233                       "accessor_get_set", NULL);
1234     }
1235     *ok = false;
1236   }
1237 }
1238
1239
1240 PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) {
1241   // ObjectLiteral ::
1242   //   '{' (
1243   //       ((IdentifierName | String | Number) ':' AssignmentExpression)
1244   //     | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
1245   //    )*[','] '}'
1246
1247   Expect(i::Token::LBRACE, CHECK_OK);
1248   DuplicateFinder duplicate_finder(scanner_->unicode_cache());
1249   while (peek() != i::Token::RBRACE) {
1250     i::Token::Value next = peek();
1251     switch (next) {
1252       case i::Token::IDENTIFIER:
1253       case i::Token::FUTURE_RESERVED_WORD:
1254       case i::Token::FUTURE_STRICT_RESERVED_WORD: {
1255         bool is_getter = false;
1256         bool is_setter = false;
1257         ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
1258         if ((is_getter || is_setter) && peek() != i::Token::COLON) {
1259             i::Token::Value name = Next();
1260             bool is_keyword = i::Token::IsKeyword(name);
1261             if (name != i::Token::IDENTIFIER &&
1262                 name != i::Token::FUTURE_RESERVED_WORD &&
1263                 name != i::Token::FUTURE_STRICT_RESERVED_WORD &&
1264                 name != i::Token::NUMBER &&
1265                 name != i::Token::STRING &&
1266                 !is_keyword) {
1267               *ok = false;
1268               return Expression::Default();
1269             }
1270             if (!is_keyword) {
1271               LogSymbol();
1272             }
1273             PropertyType type = is_getter ? kGetterProperty : kSetterProperty;
1274             CheckDuplicate(&duplicate_finder, name, type, CHECK_OK);
1275             ParseFunctionLiteral(CHECK_OK);
1276             if (peek() != i::Token::RBRACE) {
1277               Expect(i::Token::COMMA, CHECK_OK);
1278             }
1279             continue;  // restart the while
1280         }
1281         CheckDuplicate(&duplicate_finder, next, kValueProperty, CHECK_OK);
1282         break;
1283       }
1284       case i::Token::STRING:
1285         Consume(next);
1286         CheckDuplicate(&duplicate_finder, next, kValueProperty, CHECK_OK);
1287         GetStringSymbol();
1288         break;
1289       case i::Token::NUMBER:
1290         Consume(next);
1291         CheckDuplicate(&duplicate_finder, next, kValueProperty, CHECK_OK);
1292         break;
1293       default:
1294         if (i::Token::IsKeyword(next)) {
1295           Consume(next);
1296           CheckDuplicate(&duplicate_finder, next, kValueProperty, CHECK_OK);
1297         } else {
1298           // Unexpected token.
1299           *ok = false;
1300           return Expression::Default();
1301         }
1302     }
1303
1304     Expect(i::Token::COLON, CHECK_OK);
1305     ParseAssignmentExpression(true, CHECK_OK);
1306
1307     // TODO(1240767): Consider allowing trailing comma.
1308     if (peek() != i::Token::RBRACE) Expect(i::Token::COMMA, CHECK_OK);
1309   }
1310   Expect(i::Token::RBRACE, CHECK_OK);
1311
1312   scope_->NextMaterializedLiteralIndex();
1313   return Expression::Default();
1314 }
1315
1316
1317 PreParser::Expression PreParser::ParseRegExpLiteral(bool seen_equal,
1318                                                     bool* ok) {
1319   if (!scanner_->ScanRegExpPattern(seen_equal)) {
1320     Next();
1321     ReportMessageAt(scanner_->location(), "unterminated_regexp", NULL);
1322     *ok = false;
1323     return Expression::Default();
1324   }
1325
1326   scope_->NextMaterializedLiteralIndex();
1327
1328   if (!scanner_->ScanRegExpFlags()) {
1329     Next();
1330     ReportMessageAt(scanner_->location(), "invalid_regexp_flags", NULL);
1331     *ok = false;
1332     return Expression::Default();
1333   }
1334   Next();
1335   return Expression::Default();
1336 }
1337
1338
1339 PreParser::Arguments PreParser::ParseArguments(bool* ok) {
1340   // Arguments ::
1341   //   '(' (AssignmentExpression)*[','] ')'
1342
1343   Expect(i::Token::LPAREN, ok);
1344   if (!*ok) return -1;
1345   bool done = (peek() == i::Token::RPAREN);
1346   int argc = 0;
1347   while (!done) {
1348     ParseAssignmentExpression(true, ok);
1349     if (!*ok) return -1;
1350     argc++;
1351     done = (peek() == i::Token::RPAREN);
1352     if (!done) {
1353       Expect(i::Token::COMMA, ok);
1354       if (!*ok) return -1;
1355     }
1356   }
1357   Expect(i::Token::RPAREN, ok);
1358   return argc;
1359 }
1360
1361
1362 PreParser::Expression PreParser::ParseFunctionLiteral(bool* ok) {
1363   // Function ::
1364   //   '(' FormalParameterList? ')' '{' FunctionBody '}'
1365
1366   // Parse function body.
1367   ScopeType outer_scope_type = scope_->type();
1368   bool inside_with = scope_->IsInsideWith();
1369   Scope function_scope(&scope_, kFunctionScope);
1370   //  FormalParameterList ::
1371   //    '(' (Identifier)*[','] ')'
1372   Expect(i::Token::LPAREN, CHECK_OK);
1373   int start_position = scanner_->location().beg_pos;
1374   bool done = (peek() == i::Token::RPAREN);
1375   DuplicateFinder duplicate_finder(scanner_->unicode_cache());
1376   while (!done) {
1377     Identifier id = ParseIdentifier(CHECK_OK);
1378     if (!id.IsValidStrictVariable()) {
1379       StrictModeIdentifierViolation(scanner_->location(),
1380                                     "strict_param_name",
1381                                     id,
1382                                     CHECK_OK);
1383     }
1384     int prev_value;
1385     if (scanner_->is_literal_ascii()) {
1386       prev_value =
1387           duplicate_finder.AddAsciiSymbol(scanner_->literal_ascii_string(), 1);
1388     } else {
1389       prev_value =
1390           duplicate_finder.AddUtf16Symbol(scanner_->literal_utf16_string(), 1);
1391     }
1392
1393     if (prev_value != 0) {
1394       SetStrictModeViolation(scanner_->location(),
1395                              "strict_param_dupe",
1396                              CHECK_OK);
1397     }
1398     done = (peek() == i::Token::RPAREN);
1399     if (!done) {
1400       Expect(i::Token::COMMA, CHECK_OK);
1401     }
1402   }
1403   Expect(i::Token::RPAREN, CHECK_OK);
1404
1405   // Determine if the function will be lazily compiled.
1406   // Currently only happens to top-level functions.
1407   // Optimistically assume that all top-level functions are lazily compiled.
1408   bool is_lazily_compiled = (outer_scope_type == kTopLevelScope &&
1409                              !inside_with && allow_lazy_ &&
1410                              !parenthesized_function_);
1411   parenthesized_function_ = false;
1412
1413   Expect(i::Token::LBRACE, CHECK_OK);
1414   if (is_lazily_compiled) {
1415     ParseLazyFunctionLiteralBody(CHECK_OK);
1416   } else {
1417     ParseSourceElements(i::Token::RBRACE, ok);
1418   }
1419   Expect(i::Token::RBRACE, CHECK_OK);
1420
1421   if (!is_classic_mode()) {
1422     int end_position = scanner_->location().end_pos;
1423     CheckOctalLiteral(start_position, end_position, CHECK_OK);
1424     CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK);
1425     return Expression::StrictFunction();
1426   }
1427
1428   return Expression::Default();
1429 }
1430
1431
1432 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) {
1433   int body_start = scanner_->location().beg_pos;
1434   log_->PauseRecording();
1435   ParseSourceElements(i::Token::RBRACE, ok);
1436   log_->ResumeRecording();
1437   if (!*ok) return;
1438
1439   // Position right after terminal '}'.
1440   ASSERT_EQ(i::Token::RBRACE, scanner_->peek());
1441   int body_end = scanner_->peek_location().end_pos;
1442   log_->LogFunction(body_start, body_end,
1443                     scope_->materialized_literal_count(),
1444                     scope_->expected_properties(),
1445                     language_mode());
1446 }
1447
1448
1449 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
1450   // CallRuntime ::
1451   //   '%' Identifier Arguments
1452   Expect(i::Token::MOD, CHECK_OK);
1453   if (!allow_natives_syntax_) {
1454     *ok = false;
1455     return Expression::Default();
1456   }
1457   ParseIdentifier(CHECK_OK);
1458   ParseArguments(ok);
1459
1460   return Expression::Default();
1461 }
1462
1463 #undef CHECK_OK
1464
1465
1466 void PreParser::ExpectSemicolon(bool* ok) {
1467   // Check for automatic semicolon insertion according to
1468   // the rules given in ECMA-262, section 7.9, page 21.
1469   i::Token::Value tok = peek();
1470   if (tok == i::Token::SEMICOLON) {
1471     Next();
1472     return;
1473   }
1474   if (scanner_->HasAnyLineTerminatorBeforeNext() ||
1475       tok == i::Token::RBRACE ||
1476       tok == i::Token::EOS) {
1477     return;
1478   }
1479   Expect(i::Token::SEMICOLON, ok);
1480 }
1481
1482
1483 void PreParser::LogSymbol() {
1484   int identifier_pos = scanner_->location().beg_pos;
1485   if (scanner_->is_literal_ascii()) {
1486     log_->LogAsciiSymbol(identifier_pos, scanner_->literal_ascii_string());
1487   } else {
1488     log_->LogUtf16Symbol(identifier_pos, scanner_->literal_utf16_string());
1489   }
1490 }
1491
1492
1493 PreParser::Expression PreParser::GetStringSymbol() {
1494   const int kUseStrictLength = 10;
1495   const char* kUseStrictChars = "use strict";
1496   LogSymbol();
1497   if (scanner_->is_literal_ascii() &&
1498       scanner_->literal_length() == kUseStrictLength &&
1499       !scanner_->literal_contains_escapes() &&
1500       !strncmp(scanner_->literal_ascii_string().start(), kUseStrictChars,
1501                kUseStrictLength)) {
1502     return Expression::UseStrictStringLiteral();
1503   }
1504   return Expression::StringLiteral();
1505 }
1506
1507
1508 PreParser::Identifier PreParser::GetIdentifierSymbol() {
1509   LogSymbol();
1510   if (scanner_->current_token() == i::Token::FUTURE_RESERVED_WORD) {
1511     return Identifier::FutureReserved();
1512   } else if (scanner_->current_token() ==
1513              i::Token::FUTURE_STRICT_RESERVED_WORD) {
1514     return Identifier::FutureStrictReserved();
1515   }
1516   if (scanner_->is_literal_ascii()) {
1517     // Detect strict-mode poison words.
1518     if (scanner_->literal_length() == 4 &&
1519         !strncmp(scanner_->literal_ascii_string().start(), "eval", 4)) {
1520       return Identifier::Eval();
1521     }
1522     if (scanner_->literal_length() == 9 &&
1523         !strncmp(scanner_->literal_ascii_string().start(), "arguments", 9)) {
1524       return Identifier::Arguments();
1525     }
1526   }
1527   return Identifier::Default();
1528 }
1529
1530
1531 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) {
1532   i::Token::Value next = Next();
1533   switch (next) {
1534     case i::Token::FUTURE_RESERVED_WORD: {
1535       i::Scanner::Location location = scanner_->location();
1536       ReportMessageAt(location.beg_pos, location.end_pos,
1537                       "reserved_word", NULL);
1538       *ok = false;
1539       return GetIdentifierSymbol();
1540     }
1541     case i::Token::FUTURE_STRICT_RESERVED_WORD:
1542       if (!is_classic_mode()) {
1543         i::Scanner::Location location = scanner_->location();
1544         ReportMessageAt(location.beg_pos, location.end_pos,
1545                         "strict_reserved_word", NULL);
1546         *ok = false;
1547       }
1548       // FALLTHROUGH
1549     case i::Token::IDENTIFIER:
1550       return GetIdentifierSymbol();
1551     default:
1552       *ok = false;
1553       return Identifier::Default();
1554   }
1555 }
1556
1557
1558 void PreParser::SetStrictModeViolation(i::Scanner::Location location,
1559                                        const char* type,
1560                                        bool* ok) {
1561   if (!is_classic_mode()) {
1562     ReportMessageAt(location, type, NULL);
1563     *ok = false;
1564     return;
1565   }
1566   // Delay report in case this later turns out to be strict code
1567   // (i.e., for function names and parameters prior to a "use strict"
1568   // directive).
1569   // It's safe to overwrite an existing violation.
1570   // It's either from a function that turned out to be non-strict,
1571   // or it's in the current function (and we just need to report
1572   // one error), or it's in a unclosed nesting function that wasn't
1573   // strict (otherwise we would already be in strict mode).
1574   strict_mode_violation_location_ = location;
1575   strict_mode_violation_type_ = type;
1576 }
1577
1578
1579 void PreParser::CheckDelayedStrictModeViolation(int beg_pos,
1580                                                 int end_pos,
1581                                                 bool* ok) {
1582   i::Scanner::Location location = strict_mode_violation_location_;
1583   if (location.IsValid() &&
1584       location.beg_pos > beg_pos && location.end_pos < end_pos) {
1585     ReportMessageAt(location, strict_mode_violation_type_, NULL);
1586     *ok = false;
1587   }
1588 }
1589
1590
1591 void PreParser::StrictModeIdentifierViolation(i::Scanner::Location location,
1592                                               const char* eval_args_type,
1593                                               Identifier identifier,
1594                                               bool* ok) {
1595   const char* type = eval_args_type;
1596   if (identifier.IsFutureReserved()) {
1597     type = "reserved_word";
1598   } else if (identifier.IsFutureStrictReserved()) {
1599     type = "strict_reserved_word";
1600   }
1601   if (!is_classic_mode()) {
1602     ReportMessageAt(location, type, NULL);
1603     *ok = false;
1604     return;
1605   }
1606   strict_mode_violation_location_ = location;
1607   strict_mode_violation_type_ = type;
1608 }
1609
1610
1611 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) {
1612   i::Token::Value next = Next();
1613   if (i::Token::IsKeyword(next)) {
1614     int pos = scanner_->location().beg_pos;
1615     const char* keyword = i::Token::String(next);
1616     log_->LogAsciiSymbol(pos, i::Vector<const char>(keyword,
1617                                                     i::StrLength(keyword)));
1618     return Identifier::Default();
1619   }
1620   if (next == i::Token::IDENTIFIER ||
1621       next == i::Token::FUTURE_RESERVED_WORD ||
1622       next == i::Token::FUTURE_STRICT_RESERVED_WORD) {
1623     return GetIdentifierSymbol();
1624   }
1625   *ok = false;
1626   return Identifier::Default();
1627 }
1628
1629 #undef CHECK_OK
1630
1631
1632 // This function reads an identifier and determines whether or not it
1633 // is 'get' or 'set'.
1634 PreParser::Identifier PreParser::ParseIdentifierNameOrGetOrSet(bool* is_get,
1635                                                                bool* is_set,
1636                                                                bool* ok) {
1637   Identifier result = ParseIdentifierName(ok);
1638   if (!*ok) return Identifier::Default();
1639   if (scanner_->is_literal_ascii() &&
1640       scanner_->literal_length() == 3) {
1641     const char* token = scanner_->literal_ascii_string().start();
1642     *is_get = strncmp(token, "get", 3) == 0;
1643     *is_set = !*is_get && strncmp(token, "set", 3) == 0;
1644   }
1645   return result;
1646 }
1647
1648 bool PreParser::peek_any_identifier() {
1649   i::Token::Value next = peek();
1650   return next == i::Token::IDENTIFIER ||
1651          next == i::Token::FUTURE_RESERVED_WORD ||
1652          next == i::Token::FUTURE_STRICT_RESERVED_WORD;
1653 }
1654
1655
1656 int DuplicateFinder::AddAsciiSymbol(i::Vector<const char> key, int value) {
1657   return AddSymbol(i::Vector<const byte>::cast(key), true, value);
1658 }
1659
1660 int DuplicateFinder::AddUtf16Symbol(i::Vector<const uint16_t> key, int value) {
1661   return AddSymbol(i::Vector<const byte>::cast(key), false, value);
1662 }
1663
1664 int DuplicateFinder::AddSymbol(i::Vector<const byte> key,
1665                                bool is_ascii,
1666                                int value) {
1667   uint32_t hash = Hash(key, is_ascii);
1668   byte* encoding = BackupKey(key, is_ascii);
1669   i::HashMap::Entry* entry = map_.Lookup(encoding, hash, true);
1670   int old_value = static_cast<int>(reinterpret_cast<intptr_t>(entry->value));
1671   entry->value =
1672     reinterpret_cast<void*>(static_cast<intptr_t>(value | old_value));
1673   return old_value;
1674 }
1675
1676
1677 int DuplicateFinder::AddNumber(i::Vector<const char> key, int value) {
1678   ASSERT(key.length() > 0);
1679   // Quick check for already being in canonical form.
1680   if (IsNumberCanonical(key)) {
1681     return AddAsciiSymbol(key, value);
1682   }
1683
1684   int flags = i::ALLOW_HEX | i::ALLOW_OCTALS;
1685   double double_value = StringToDouble(unicode_constants_, key, flags, 0.0);
1686   int length;
1687   const char* string;
1688   if (!isfinite(double_value)) {
1689     string = "Infinity";
1690     length = 8;  // strlen("Infinity");
1691   } else {
1692     string = DoubleToCString(double_value,
1693                              i::Vector<char>(number_buffer_, kBufferSize));
1694     length = i::StrLength(string);
1695   }
1696   return AddSymbol(i::Vector<const byte>(reinterpret_cast<const byte*>(string),
1697                                          length), true, value);
1698 }
1699
1700
1701 bool DuplicateFinder::IsNumberCanonical(i::Vector<const char> number) {
1702   // Test for a safe approximation of number literals that are already
1703   // in canonical form: max 15 digits, no leading zeroes, except an
1704   // integer part that is a single zero, and no trailing zeros below
1705   // the decimal point.
1706   int pos = 0;
1707   int length = number.length();
1708   if (number.length() > 15) return false;
1709   if (number[pos] == '0') {
1710     pos++;
1711   } else {
1712     while (pos < length &&
1713            static_cast<unsigned>(number[pos] - '0') <= ('9' - '0')) pos++;
1714   }
1715   if (length == pos) return true;
1716   if (number[pos] != '.') return false;
1717   pos++;
1718   bool invalid_last_digit = true;
1719   while (pos < length) {
1720     byte digit = number[pos] - '0';
1721     if (digit > '9' - '0') return false;
1722     invalid_last_digit = (digit == 0);
1723     pos++;
1724   }
1725   return !invalid_last_digit;
1726 }
1727
1728
1729 uint32_t DuplicateFinder::Hash(i::Vector<const byte> key, bool is_ascii) {
1730   // Primitive hash function, almost identical to the one used
1731   // for strings (except that it's seeded by the length and ASCII-ness).
1732   int length = key.length();
1733   uint32_t hash = (length << 1) | (is_ascii ? 1 : 0) ;
1734   for (int i = 0; i < length; i++) {
1735     uint32_t c = key[i];
1736     hash = (hash + c) * 1025;
1737     hash ^= (hash >> 6);
1738   }
1739   return hash;
1740 }
1741
1742
1743 bool DuplicateFinder::Match(void* first, void* second) {
1744   // Decode lengths.
1745   // Length + ASCII-bit is encoded as base 128, most significant heptet first,
1746   // with a 8th bit being non-zero while there are more heptets.
1747   // The value encodes the number of bytes following, and whether the original
1748   // was ASCII.
1749   byte* s1 = reinterpret_cast<byte*>(first);
1750   byte* s2 = reinterpret_cast<byte*>(second);
1751   uint32_t length_ascii_field = 0;
1752   byte c1;
1753   do {
1754     c1 = *s1;
1755     if (c1 != *s2) return false;
1756     length_ascii_field = (length_ascii_field << 7) | (c1 & 0x7f);
1757     s1++;
1758     s2++;
1759   } while ((c1 & 0x80) != 0);
1760   int length = static_cast<int>(length_ascii_field >> 1);
1761   return memcmp(s1, s2, length) == 0;
1762 }
1763
1764
1765 byte* DuplicateFinder::BackupKey(i::Vector<const byte> bytes,
1766                                  bool is_ascii) {
1767   uint32_t ascii_length = (bytes.length() << 1) | (is_ascii ? 1 : 0);
1768   backing_store_.StartSequence();
1769   // Emit ascii_length as base-128 encoded number, with the 7th bit set
1770   // on the byte of every heptet except the last, least significant, one.
1771   if (ascii_length >= (1 << 7)) {
1772     if (ascii_length >= (1 << 14)) {
1773       if (ascii_length >= (1 << 21)) {
1774         if (ascii_length >= (1 << 28)) {
1775           backing_store_.Add(static_cast<byte>((ascii_length >> 28) | 0x80));
1776         }
1777         backing_store_.Add(static_cast<byte>((ascii_length >> 21) | 0x80u));
1778       }
1779       backing_store_.Add(static_cast<byte>((ascii_length >> 14) | 0x80u));
1780     }
1781     backing_store_.Add(static_cast<byte>((ascii_length >> 7) | 0x80u));
1782   }
1783   backing_store_.Add(static_cast<byte>(ascii_length & 0x7f));
1784
1785   backing_store_.AddBlock(bytes);
1786   return backing_store_.EndSequence().start();
1787 }
1788 } }  // v8::preparser