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
45namespace v8 {
46
47#ifdef _MSC_VER
48// Usually defined in math.h, but not in MSVC.
49// Abstracted to work
50int isfinite(double value);
51#endif
52
53namespace preparser {
54
55PreParser::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
96void 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.
130void 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
147PreParser::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
170PreParser::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
199PreParser::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
294PreParser::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
319PreParser::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
339PreParser::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.
359PreParser::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
470PreParser::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
493PreParser::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
510PreParser::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
527PreParser::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
544PreParser::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
570PreParser::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
591PreParser::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
620PreParser::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
635PreParser::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
648PreParser::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
703PreParser::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
720PreParser::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
770PreParser::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
792PreParser::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
808PreParser::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
844PreParser::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
864int 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
873PreParser::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
889PreParser::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
926PreParser::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
950PreParser::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
999PreParser::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
1021PreParser::Expression PreParser::ParseMemberExpression(bool* ok) {
1022  return ParseMemberWithNewPrefixesExpression(0, ok);
1023}
1024
1025
1026PreParser::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
1090PreParser::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
1188PreParser::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
1206void 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
1240PreParser::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
1317PreParser::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
1339PreParser::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
1362PreParser::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
1432void 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
1449PreParser::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
1466void 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
1483void 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
1493PreParser::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
1508PreParser::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
1531PreParser::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
1558void 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
1579void 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
1591void 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
1611PreParser::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'.
1634PreParser::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
1648bool 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
1656int DuplicateFinder::AddAsciiSymbol(i::Vector<const char> key, int value) {
1657  return AddSymbol(i::Vector<const byte>::cast(key), true, value);
1658}
1659
1660int DuplicateFinder::AddUtf16Symbol(i::Vector<const uint16_t> key, int value) {
1661  return AddSymbol(i::Vector<const byte>::cast(key), false, value);
1662}
1663
1664int 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
1677int 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
1701bool 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
1729uint32_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
1743bool 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
1765byte* 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
1789