preparser.cc 28.5 KB
Newer Older
1
// Copyright 2011 the V8 project authors. All rights reserved.
2 3
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
4

5
#include <cmath>
6

7 8 9
#include "include/v8stdint.h"

#include "src/allocation.h"
10
#include "src/base/logging.h"
11
#include "src/conversions-inl.h"
12
#include "src/conversions.h"
13 14 15 16
#include "src/globals.h"
#include "src/hashmap.h"
#include "src/list.h"
#include "src/preparse-data.h"
17
#include "src/preparse-data-format.h"
18 19 20
#include "src/preparser.h"
#include "src/unicode.h"
#include "src/utils.h"
21

22
#if V8_LIBC_MSVCRT && (_MSC_VER < 1800)
23 24
namespace std {

25
// Usually defined in math.h, but not in MSVC until VS2013+.
26 27
// Abstracted to work
int isfinite(double value);
28 29

}  // namespace std
30 31
#endif

32
namespace v8 {
33
namespace internal {
34

35

36 37
void PreParserTraits::ReportMessageAt(Scanner::Location location,
                                      const char* message,
38
                                      const char* arg,
39
                                      bool is_reference_error) {
40 41 42
  ReportMessageAt(location.beg_pos,
                  location.end_pos,
                  message,
43
                  arg,
44
                  is_reference_error);
45 46 47 48 49
}


void PreParserTraits::ReportMessageAt(int start_pos,
                                      int end_pos,
50 51
                                      const char* message,
                                      const char* arg,
52
                                      bool is_reference_error) {
53
  pre_parser_->log_->LogMessage(start_pos, end_pos, message, arg,
54
                                is_reference_error);
55 56 57
}


58
PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) {
59 60 61 62 63
  if (scanner->current_token() == Token::FUTURE_RESERVED_WORD) {
    return PreParserIdentifier::FutureReserved();
  } else if (scanner->current_token() ==
             Token::FUTURE_STRICT_RESERVED_WORD) {
    return PreParserIdentifier::FutureStrictReserved();
64 65
  } else if (scanner->current_token() == Token::LET) {
    return PreParserIdentifier::Let();
66 67 68
  } else if (scanner->current_token() == Token::YIELD) {
    return PreParserIdentifier::Yield();
  }
69 70 71 72 73
  if (scanner->UnescapedLiteralMatches("eval", 4)) {
    return PreParserIdentifier::Eval();
  }
  if (scanner->UnescapedLiteralMatches("arguments", 9)) {
    return PreParserIdentifier::Arguments();
74 75 76 77 78
  }
  return PreParserIdentifier::Default();
}


79 80
PreParserExpression PreParserTraits::ExpressionFromString(
    int pos, Scanner* scanner, PreParserFactory* factory) {
81
  if (scanner->UnescapedLiteralMatches("use strict", 10)) {
82 83 84 85 86 87 88 89 90 91 92
    return PreParserExpression::UseStrictStringLiteral();
  }
  return PreParserExpression::StringLiteral();
}


PreParserExpression PreParserTraits::ParseV8Intrinsic(bool* ok) {
  return pre_parser_->ParseV8Intrinsic(ok);
}


93 94 95 96 97 98 99
PreParserExpression PreParserTraits::ParseFunctionLiteral(
    PreParserIdentifier name,
    Scanner::Location function_name_location,
    bool name_is_strict_reserved,
    bool is_generator,
    int function_token_position,
    FunctionLiteral::FunctionType type,
100
    FunctionLiteral::ArityRestriction arity_restriction,
101 102 103
    bool* ok) {
  return pre_parser_->ParseFunctionLiteral(
      name, function_name_location, name_is_strict_reserved, is_generator,
104
      function_token_position, type, arity_restriction, ok);
105 106 107
}


108
PreParser::PreParseResult PreParser::PreParseLazyFunction(
109
    StrictMode strict_mode, bool is_generator, ParserRecorder* log) {
110 111
  log_ = log;
  // Lazy functions always have trivial outer scopes (no with/catch scopes).
112
  PreParserScope top_scope(scope_, GLOBAL_SCOPE);
113 114
  FunctionState top_state(&function_state_, &scope_, &top_scope, NULL,
                          this->ast_value_factory());
115
  scope_->SetStrictMode(strict_mode);
116
  PreParserScope function_scope(scope_, FUNCTION_SCOPE);
117 118
  FunctionState function_state(&function_state_, &scope_, &function_scope, NULL,
                               this->ast_value_factory());
119
  function_state.set_is_generator(is_generator);
120
  DCHECK_EQ(Token::LBRACE, scanner()->current_token());
121
  bool ok = true;
122
  int start_position = peek_position();
123
  ParseLazyFunctionLiteralBody(&ok);
124
  if (stack_overflow()) return kPreParseStackOverflow;
125
  if (!ok) {
126
    ReportUnexpectedToken(scanner()->current_token());
127
  } else {
128
    DCHECK_EQ(Token::RBRACE, scanner()->peek());
129
    if (scope_->strict_mode() == STRICT) {
130
      int end_pos = scanner()->location().end_pos;
131 132 133 134 135 136 137
      CheckOctalLiteral(start_position, end_pos, &ok);
    }
  }
  return kPreParseSuccess;
}


138 139 140 141 142 143 144 145 146 147 148 149 150 151
// Preparsing checks a JavaScript program and emits preparse-data that helps
// a later parsing to be faster.
// See preparser-data.h for the data.

// The PreParser checks that the syntax follows the grammar for JavaScript,
// and collects some information about the program along the way.
// The grammar check is only performed in order to understand the program
// sufficiently to deduce some information about it, that can be used
// to speed up later parsing. Finding errors is not the goal of pre-parsing,
// rather it is to speed up properly written and correct programs.
// That means that contextual checks (like a label being declared where
// it is used) are generally omitted.


152 153 154 155 156 157 158
#define CHECK_OK  ok);                      \
  if (!*ok) return kUnknownSourceElements;  \
  ((void)0
#define DUMMY )  // to make indentation work
#undef DUMMY


159
PreParser::Statement PreParser::ParseSourceElement(bool* ok) {
160 161 162 163 164 165 166 167
  // (Ecma 262 5th Edition, clause 14):
  // SourceElement:
  //    Statement
  //    FunctionDeclaration
  //
  // In harmony mode we allow additionally the following productions
  // SourceElement:
  //    LetDeclaration
168
  //    ConstDeclaration
169
  //    GeneratorDeclaration
170

171
  switch (peek()) {
172
    case Token::FUNCTION:
173
      return ParseFunctionDeclaration(ok);
174
    case Token::CONST:
175
      return ParseVariableStatement(kSourceElement, ok);
176
    case Token::LET:
177
      DCHECK(allow_harmony_scoping());
178 179 180 181
      if (strict_mode() == STRICT) {
        return ParseVariableStatement(kSourceElement, ok);
      }
      // Fall through.
182 183 184 185 186 187
    default:
      return ParseStatement(ok);
  }
}


188 189
PreParser::SourceElements PreParser::ParseSourceElements(int end_token,
                                                         bool* ok) {
190 191 192
  // SourceElements ::
  //   (Statement)* <end_token>

193
  bool directive_prologue = true;
194
  while (peek() != end_token) {
195 196 197
    if (directive_prologue && peek() != Token::STRING) {
      directive_prologue = false;
    }
198
    Statement statement = ParseSourceElement(CHECK_OK);
199
    if (directive_prologue) {
200
      if (statement.IsUseStrictLiteral()) {
201
        scope_->SetStrictMode(STRICT);
202
      } else if (!statement.IsStringLiteral()) {
203
        directive_prologue = false;
204 205
      }
    }
206 207 208 209 210
  }
  return kUnknownSourceElements;
}


211 212 213 214 215 216 217 218
#undef CHECK_OK
#define CHECK_OK  ok);                   \
  if (!*ok) return Statement::Default();  \
  ((void)0
#define DUMMY )  // to make indentation work
#undef DUMMY


ager@chromium.org's avatar
ager@chromium.org committed
219
PreParser::Statement PreParser::ParseStatement(bool* ok) {
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
  // Statement ::
  //   Block
  //   VariableStatement
  //   EmptyStatement
  //   ExpressionStatement
  //   IfStatement
  //   IterationStatement
  //   ContinueStatement
  //   BreakStatement
  //   ReturnStatement
  //   WithStatement
  //   LabelledStatement
  //   SwitchStatement
  //   ThrowStatement
  //   TryStatement
  //   DebuggerStatement

  // Note: Since labels can only be used by 'break' and 'continue'
  // statements, which themselves are only valid within blocks,
  // iterations or 'switch' statements (i.e., BreakableStatements),
  // labels can be simply ignored in all other cases; except for
  // trivial labeled break statements 'label: break label' which is
  // parsed into an empty statement.

  // Keep the source position of the statement
  switch (peek()) {
246
    case Token::LBRACE:
247 248
      return ParseBlock(ok);

249
    case Token::SEMICOLON:
250
      Next();
251
      return Statement::Default();
252

253
    case Token::IF:
254
      return ParseIfStatement(ok);
255

256
    case Token::DO:
257 258
      return ParseDoWhileStatement(ok);

259
    case Token::WHILE:
260 261
      return ParseWhileStatement(ok);

262
    case Token::FOR:
263 264
      return ParseForStatement(ok);

265
    case Token::CONTINUE:
266 267
      return ParseContinueStatement(ok);

268
    case Token::BREAK:
269 270
      return ParseBreakStatement(ok);

271
    case Token::RETURN:
272 273
      return ParseReturnStatement(ok);

274
    case Token::WITH:
275 276
      return ParseWithStatement(ok);

277
    case Token::SWITCH:
278 279
      return ParseSwitchStatement(ok);

280
    case Token::THROW:
281 282
      return ParseThrowStatement(ok);

283
    case Token::TRY:
284 285
      return ParseTryStatement(ok);

286 287
    case Token::FUNCTION: {
      Scanner::Location start_location = scanner()->peek_location();
288
      Statement statement = ParseFunctionDeclaration(CHECK_OK);
289
      Scanner::Location end_location = scanner()->location();
290
      if (strict_mode() == STRICT) {
291 292
        PreParserTraits::ReportMessageAt(start_location.beg_pos,
                                         end_location.end_pos,
293
                                         "strict_function");
294 295 296 297 298 299
        *ok = false;
        return Statement::Default();
      } else {
        return statement;
      }
    }
300

301
    case Token::DEBUGGER:
302 303
      return ParseDebuggerStatement(ok);

304 305 306 307 308
    case Token::VAR:
    case Token::CONST:
      return ParseVariableStatement(kStatement, ok);

    case Token::LET:
309
      DCHECK(allow_harmony_scoping());
310 311 312 313
      if (strict_mode() == STRICT) {
        return ParseVariableStatement(kStatement, ok);
      }
      // Fall through.
314 315 316 317 318 319
    default:
      return ParseExpressionOrLabelledStatement(ok);
  }
}


320
PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
321 322
  // FunctionDeclaration ::
  //   'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
323 324 325
  // GeneratorDeclaration ::
  //   'function' '*' Identifier '(' FormalParameterListopt ')'
  //      '{' FunctionBody '}'
326
  Expect(Token::FUNCTION, CHECK_OK);
327
  int pos = position();
328
  bool is_generator = allow_generators() && Check(Token::MUL);
329 330 331 332 333 334 335
  bool is_strict_reserved = false;
  Identifier name = ParseIdentifierOrStrictReservedWord(
      &is_strict_reserved, CHECK_OK);
  ParseFunctionLiteral(name,
                       scanner()->location(),
                       is_strict_reserved,
                       is_generator,
336 337
                       pos,
                       FunctionLiteral::DECLARATION,
338
                       FunctionLiteral::NORMAL_ARITY,
339
                       CHECK_OK);
340
  return Statement::FunctionDeclaration();
341 342 343
}


344
PreParser::Statement PreParser::ParseBlock(bool* ok) {
345 346 347 348 349 350
  // Block ::
  //   '{' Statement* '}'

  // Note that a Block does not introduce a new execution scope!
  // (ECMA-262, 3rd, 12.2)
  //
351 352
  Expect(Token::LBRACE, CHECK_OK);
  while (peek() != Token::RBRACE) {
353
    if (allow_harmony_scoping() && strict_mode() == STRICT) {
354 355 356
      ParseSourceElement(CHECK_OK);
    } else {
      ParseStatement(CHECK_OK);
357
    }
358
  }
359
  Expect(Token::RBRACE, ok);
360
  return Statement::Default();
361 362 363
}


364 365 366
PreParser::Statement PreParser::ParseVariableStatement(
    VariableDeclarationContext var_context,
    bool* ok) {
367 368 369
  // VariableStatement ::
  //   VariableDeclarations ';'

370
  Statement result = ParseVariableDeclarations(var_context,
371
                                               NULL,
372 373
                                               NULL,
                                               CHECK_OK);
374 375 376 377 378 379 380 381 382 383
  ExpectSemicolon(CHECK_OK);
  return result;
}


// If the variable declaration declares exactly one non-const
// variable, then *var is set to that variable. In all other cases,
// *var is untouched; in particular, it is the caller's responsibility
// to initialize it properly. This mechanism is also used for the parsing
// of 'for-in' loops.
384 385
PreParser::Statement PreParser::ParseVariableDeclarations(
    VariableDeclarationContext var_context,
386
    VariableDeclarationProperties* decl_props,
387 388
    int* num_decl,
    bool* ok) {
389 390
  // VariableDeclarations ::
  //   ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
391 392 393 394 395 396 397 398 399 400 401 402
  //
  // The ES6 Draft Rev3 specifies the following grammar for const declarations
  //
  // ConstDeclaration ::
  //   const ConstBinding (',' ConstBinding)* ';'
  // ConstBinding ::
  //   Identifier '=' AssignmentExpression
  //
  // TODO(ES6):
  // ConstBinding ::
  //   BindingPattern '=' AssignmentExpression
  bool require_initializer = false;
403 404 405
  if (peek() == Token::VAR) {
    Consume(Token::VAR);
  } else if (peek() == Token::CONST) {
406 407 408 409 410 411 412
    // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
    //
    // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
    //
    // * It is a Syntax Error if the code that matches this production is not
    //   contained in extended code.
    //
413
    // However disallowing const in sloppy mode will break compatibility with
414
    // existing pages. Therefore we keep allowing const with the old
415
    // non-harmony semantics in sloppy mode.
416
    Consume(Token::CONST);
417
    if (strict_mode() == STRICT) {
418
      if (allow_harmony_scoping()) {
419
        if (var_context != kSourceElement && var_context != kForStatement) {
420
          ReportMessageAt(scanner()->peek_location(), "unprotected_const");
421 422 423 424
          *ok = false;
          return Statement::Default();
        }
        require_initializer = true;
425 426 427 428 429 430
      } else {
        Scanner::Location location = scanner()->peek_location();
        ReportMessageAt(location, "strict_const");
        *ok = false;
        return Statement::Default();
      }
431
    }
432
  } else if (peek() == Token::LET && strict_mode() == STRICT) {
433
    Consume(Token::LET);
434
    if (var_context != kSourceElement && var_context != kForStatement) {
435
      ReportMessageAt(scanner()->peek_location(), "unprotected_let");
436 437 438
      *ok = false;
      return Statement::Default();
    }
439 440
  } else {
    *ok = false;
441
    return Statement::Default();
442 443
  }

444 445 446 447
  // The scope of a var/const declared variable anywhere inside a function
  // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope
  // of a let declared variable is the scope of the immediately enclosing
  // block.
448 449 450
  int nvars = 0;  // the number of variables declared
  do {
    // Parse variable name.
451
    if (nvars > 0) Consume(Token::COMMA);
452
    ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
453
    nvars++;
454 455
    if (peek() == Token::ASSIGN || require_initializer) {
      Expect(Token::ASSIGN, CHECK_OK);
456
      ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
457
      if (decl_props != NULL) *decl_props = kHasInitializers;
458
    }
459
  } while (peek() == Token::COMMA);
460 461

  if (num_decl != NULL) *num_decl = nvars;
462
  return Statement::Default();
463 464 465
}


466
PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
467 468 469 470
  // ExpressionStatement | LabelledStatement ::
  //   Expression ';'
  //   Identifier ':' Statement

471
  bool starts_with_identifier = peek_any_identifier();
472
  Expression expr = ParseExpression(true, CHECK_OK);
473 474 475 476 477 478
  // Even if the expression starts with an identifier, it is not necessarily an
  // identifier. For example, "foo + bar" starts with an identifier but is not
  // an identifier.
  if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) {
    // Expression is a single identifier, and not, e.g., a parenthesized
    // identifier.
479 480
    DCHECK(!expr.AsIdentifier().IsFutureReserved());
    DCHECK(strict_mode() == SLOPPY ||
481 482
           (!expr.AsIdentifier().IsFutureStrictReserved() &&
            !expr.AsIdentifier().IsYield()));
483 484
    Consume(Token::COLON);
    return ParseStatement(ok);
485 486 487
    // Preparsing is disabled for extensions (because the extension details
    // aren't passed to lazily compiled functions), so we don't
    // accept "native function" in the preparser.
488 489 490
  }
  // Parsed expression statement.
  ExpectSemicolon(CHECK_OK);
491
  return Statement::ExpressionStatement(expr);
492 493 494
}


495
PreParser::Statement PreParser::ParseIfStatement(bool* ok) {
496 497 498
  // IfStatement ::
  //   'if' '(' Expression ')' Statement ('else' Statement)?

499 500
  Expect(Token::IF, CHECK_OK);
  Expect(Token::LPAREN, CHECK_OK);
501
  ParseExpression(true, CHECK_OK);
502
  Expect(Token::RPAREN, CHECK_OK);
503
  ParseStatement(CHECK_OK);
504
  if (peek() == Token::ELSE) {
505 506 507
    Next();
    ParseStatement(CHECK_OK);
  }
508
  return Statement::Default();
509 510 511
}


512
PreParser::Statement PreParser::ParseContinueStatement(bool* ok) {
513 514 515
  // ContinueStatement ::
  //   'continue' [no line terminator] Identifier? ';'

516 517
  Expect(Token::CONTINUE, CHECK_OK);
  Token::Value tok = peek();
518
  if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
519 520 521
      tok != Token::SEMICOLON &&
      tok != Token::RBRACE &&
      tok != Token::EOS) {
522 523
    // ECMA allows "eval" or "arguments" as labels even in strict mode.
    ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
524 525
  }
  ExpectSemicolon(CHECK_OK);
526
  return Statement::Default();
527 528 529
}


530
PreParser::Statement PreParser::ParseBreakStatement(bool* ok) {
531 532 533
  // BreakStatement ::
  //   'break' [no line terminator] Identifier? ';'

534 535
  Expect(Token::BREAK, CHECK_OK);
  Token::Value tok = peek();
536
  if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
537 538 539
      tok != Token::SEMICOLON &&
      tok != Token::RBRACE &&
      tok != Token::EOS) {
540 541
    // ECMA allows "eval" or "arguments" as labels even in strict mode.
    ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
542 543
  }
  ExpectSemicolon(CHECK_OK);
544
  return Statement::Default();
545 546 547
}


548
PreParser::Statement PreParser::ParseReturnStatement(bool* ok) {
549 550 551
  // ReturnStatement ::
  //   'return' [no line terminator] Expression? ';'

552
  // Consume the return token. It is necessary to do before
553 554
  // reporting any errors on it, because of the way errors are
  // reported (underlining).
555
  Expect(Token::RETURN, CHECK_OK);
556 557 558 559 560 561

  // An ECMAScript program is considered syntactically incorrect if it
  // contains a return statement that is not within the body of a
  // function. See ECMA-262, section 12.9, page 67.
  // This is not handled during preparsing.

562
  Token::Value tok = peek();
563
  if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
564 565 566
      tok != Token::SEMICOLON &&
      tok != Token::RBRACE &&
      tok != Token::EOS) {
567 568 569
    ParseExpression(true, CHECK_OK);
  }
  ExpectSemicolon(CHECK_OK);
570
  return Statement::Default();
571 572 573
}


574
PreParser::Statement PreParser::ParseWithStatement(bool* ok) {
575 576
  // WithStatement ::
  //   'with' '(' Expression ')' Statement
577
  Expect(Token::WITH, CHECK_OK);
578
  if (strict_mode() == STRICT) {
579
    ReportMessageAt(scanner()->location(), "strict_mode_with");
580 581 582
    *ok = false;
    return Statement::Default();
  }
583
  Expect(Token::LPAREN, CHECK_OK);
584
  ParseExpression(true, CHECK_OK);
585
  Expect(Token::RPAREN, CHECK_OK);
586

587 588
  PreParserScope with_scope(scope_, WITH_SCOPE);
  BlockState block_state(&scope_, &with_scope);
589
  ParseStatement(CHECK_OK);
590
  return Statement::Default();
591 592 593
}


594
PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) {
595 596 597
  // SwitchStatement ::
  //   'switch' '(' Expression ')' '{' CaseClause* '}'

598 599
  Expect(Token::SWITCH, CHECK_OK);
  Expect(Token::LPAREN, CHECK_OK);
600
  ParseExpression(true, CHECK_OK);
601
  Expect(Token::RPAREN, CHECK_OK);
602

603 604 605 606 607
  Expect(Token::LBRACE, CHECK_OK);
  Token::Value token = peek();
  while (token != Token::RBRACE) {
    if (token == Token::CASE) {
      Expect(Token::CASE, CHECK_OK);
608 609
      ParseExpression(true, CHECK_OK);
    } else {
610
      Expect(Token::DEFAULT, CHECK_OK);
611
    }
612
    Expect(Token::COLON, CHECK_OK);
613
    token = peek();
614 615 616
    while (token != Token::CASE &&
           token != Token::DEFAULT &&
           token != Token::RBRACE) {
617 618 619
      ParseStatement(CHECK_OK);
      token = peek();
    }
620
  }
621
  Expect(Token::RBRACE, ok);
622
  return Statement::Default();
623 624 625
}


626
PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) {
627 628 629
  // DoStatement ::
  //   'do' Statement 'while' '(' Expression ')' ';'

630
  Expect(Token::DO, CHECK_OK);
631
  ParseStatement(CHECK_OK);
632 633
  Expect(Token::WHILE, CHECK_OK);
  Expect(Token::LPAREN, CHECK_OK);
634
  ParseExpression(true, CHECK_OK);
635 636
  Expect(Token::RPAREN, ok);
  if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
637
  return Statement::Default();
638 639 640
}


641
PreParser::Statement PreParser::ParseWhileStatement(bool* ok) {
642 643 644
  // WhileStatement ::
  //   'while' '(' Expression ')' Statement

645 646
  Expect(Token::WHILE, CHECK_OK);
  Expect(Token::LPAREN, CHECK_OK);
647
  ParseExpression(true, CHECK_OK);
648
  Expect(Token::RPAREN, CHECK_OK);
649 650
  ParseStatement(ok);
  return Statement::Default();
651 652 653
}


654
bool PreParser::CheckInOrOf(bool accept_OF) {
655
  if (Check(Token::IN) ||
656
      (accept_OF && CheckContextualKeyword(CStrVector("of")))) {
657 658 659 660 661 662
    return true;
  }
  return false;
}


663
PreParser::Statement PreParser::ParseForStatement(bool* ok) {
664 665 666
  // ForStatement ::
  //   'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement

667 668 669 670
  Expect(Token::FOR, CHECK_OK);
  Expect(Token::LPAREN, CHECK_OK);
  if (peek() != Token::SEMICOLON) {
    if (peek() == Token::VAR || peek() == Token::CONST ||
671
        (peek() == Token::LET && strict_mode() == STRICT)) {
672
      bool is_let = peek() == Token::LET;
673
      int decl_count;
674 675 676
      VariableDeclarationProperties decl_props = kHasNoInitializers;
      ParseVariableDeclarations(
          kForStatement, &decl_props, &decl_count, CHECK_OK);
677 678 679 680
      bool has_initializers = decl_props == kHasInitializers;
      bool accept_IN = decl_count == 1 && !(is_let && has_initializers);
      bool accept_OF = !has_initializers;
      if (accept_IN && CheckInOrOf(accept_OF)) {
681
        ParseExpression(true, CHECK_OK);
682
        Expect(Token::RPAREN, CHECK_OK);
683 684

        ParseStatement(CHECK_OK);
685
        return Statement::Default();
686 687
      }
    } else {
688 689
      Expression lhs = ParseExpression(false, CHECK_OK);
      if (CheckInOrOf(lhs.IsIdentifier())) {
690
        ParseExpression(true, CHECK_OK);
691
        Expect(Token::RPAREN, CHECK_OK);
692 693

        ParseStatement(CHECK_OK);
694
        return Statement::Default();
695 696 697 698 699
      }
    }
  }

  // Parsed initializer at this point.
700
  Expect(Token::SEMICOLON, CHECK_OK);
701

702
  if (peek() != Token::SEMICOLON) {
703 704
    ParseExpression(true, CHECK_OK);
  }
705
  Expect(Token::SEMICOLON, CHECK_OK);
706

707
  if (peek() != Token::RPAREN) {
708 709
    ParseExpression(true, CHECK_OK);
  }
710
  Expect(Token::RPAREN, CHECK_OK);
711

712 713
  ParseStatement(ok);
  return Statement::Default();
714 715 716
}


717
PreParser::Statement PreParser::ParseThrowStatement(bool* ok) {
718 719 720
  // ThrowStatement ::
  //   'throw' [no line terminator] Expression ';'

721
  Expect(Token::THROW, CHECK_OK);
722
  if (scanner()->HasAnyLineTerminatorBeforeNext()) {
723
    ReportMessageAt(scanner()->location(), "newline_after_throw");
724
    *ok = false;
725
    return Statement::Default();
726 727
  }
  ParseExpression(true, CHECK_OK);
728 729
  ExpectSemicolon(ok);
  return Statement::Default();
730 731 732
}


733
PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
734 735 736 737 738 739 740 741 742 743 744
  // TryStatement ::
  //   'try' Block Catch
  //   'try' Block Finally
  //   'try' Block Catch Finally
  //
  // Catch ::
  //   'catch' '(' Identifier ')' Block
  //
  // Finally ::
  //   'finally' Block

745
  Expect(Token::TRY, CHECK_OK);
746 747 748

  ParseBlock(CHECK_OK);

749 750
  Token::Value tok = peek();
  if (tok != Token::CATCH && tok != Token::FINALLY) {
751
    ReportMessageAt(scanner()->location(), "no_catch_or_finally");
752 753 754 755
    *ok = false;
    return Statement::Default();
  }
  if (tok == Token::CATCH) {
756 757
    Consume(Token::CATCH);
    Expect(Token::LPAREN, CHECK_OK);
758
    ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
759
    Expect(Token::RPAREN, CHECK_OK);
760
    {
761 762
      PreParserScope with_scope(scope_, WITH_SCOPE);
      BlockState block_state(&scope_, &with_scope);
763 764
      ParseBlock(CHECK_OK);
    }
765
    tok = peek();
766
  }
767
  if (tok == Token::FINALLY) {
768
    Consume(Token::FINALLY);
769 770
    ParseBlock(CHECK_OK);
  }
771
  return Statement::Default();
772 773 774
}


775
PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) {
776 777 778 779 780 781
  // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
  // contexts this is used as a statement which invokes the debugger as if a
  // break point is present.
  // DebuggerStatement ::
  //   'debugger' ';'

782
  Expect(Token::DEBUGGER, CHECK_OK);
783 784
  ExpectSemicolon(ok);
  return Statement::Default();
785 786 787
}


788 789 790 791 792 793 794 795
#undef CHECK_OK
#define CHECK_OK  ok);                     \
  if (!*ok) return Expression::Default();  \
  ((void)0
#define DUMMY )  // to make indentation work
#undef DUMMY


796
PreParser::Expression PreParser::ParseFunctionLiteral(
797
    Identifier function_name,
798 799 800
    Scanner::Location function_name_location,
    bool name_is_strict_reserved,
    bool is_generator,
801 802
    int function_token_pos,
    FunctionLiteral::FunctionType function_type,
803
    FunctionLiteral::ArityRestriction arity_restriction,
804
    bool* ok) {
805 806 807 808 809
  // Function ::
  //   '(' FormalParameterList? ')' '{' FunctionBody '}'

  // Parse function body.
  ScopeType outer_scope_type = scope_->type();
810
  PreParserScope function_scope(scope_, FUNCTION_SCOPE);
811 812
  FunctionState function_state(&function_state_, &scope_, &function_scope, NULL,
                               this->ast_value_factory());
813
  function_state.set_is_generator(is_generator);
814 815
  //  FormalParameterList ::
  //    '(' (Identifier)*[','] ')'
816
  Expect(Token::LPAREN, CHECK_OK);
817
  int start_position = position();
818
  DuplicateFinder duplicate_finder(scanner()->unicode_cache());
819 820 821 822 823 824
  // We don't yet know if the function will be strict, so we cannot yet produce
  // errors for parameter names or duplicates. However, we remember the
  // locations of these errors if they occur and produce the errors later.
  Scanner::Location eval_args_error_loc = Scanner::Location::invalid();
  Scanner::Location dupe_error_loc = Scanner::Location::invalid();
  Scanner::Location reserved_error_loc = Scanner::Location::invalid();
825 826 827 828

  bool done = arity_restriction == FunctionLiteral::GETTER_ARITY ||
      (peek() == Token::RPAREN &&
       arity_restriction != FunctionLiteral::SETTER_ARITY);
829
  while (!done) {
830 831 832 833 834 835 836 837 838 839
    bool is_strict_reserved = false;
    Identifier param_name =
        ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
    if (!eval_args_error_loc.IsValid() && param_name.IsEvalOrArguments()) {
      eval_args_error_loc = scanner()->location();
    }
    if (!reserved_error_loc.IsValid() && is_strict_reserved) {
      reserved_error_loc = scanner()->location();
    }

840
    int prev_value = scanner()->FindSymbol(&duplicate_finder, 1);
841

842 843
    if (!dupe_error_loc.IsValid() && prev_value != 0) {
      dupe_error_loc = scanner()->location();
844
    }
845

846
    if (arity_restriction == FunctionLiteral::SETTER_ARITY) break;
847
    done = (peek() == Token::RPAREN);
848
    if (!done) Expect(Token::COMMA, CHECK_OK);
849
  }
850
  Expect(Token::RPAREN, CHECK_OK);
851

852 853
  // See Parser::ParseFunctionLiteral for more information about lazy parsing
  // and lazy compilation.
854
  bool is_lazily_parsed = (outer_scope_type == GLOBAL_SCOPE && allow_lazy() &&
855
                           !parenthesized_function_);
856
  parenthesized_function_ = false;
857

858
  Expect(Token::LBRACE, CHECK_OK);
859
  if (is_lazily_parsed) {
860
    ParseLazyFunctionLiteralBody(CHECK_OK);
861
  } else {
862
    ParseSourceElements(Token::RBRACE, ok);
863
  }
864
  Expect(Token::RBRACE, CHECK_OK);
865

866 867
  // Validate strict mode. We can do this only after parsing the function,
  // since the function can declare itself strict.
868
  if (strict_mode() == STRICT) {
869
    if (function_name.IsEvalOrArguments()) {
870
      ReportMessageAt(function_name_location, "strict_eval_arguments");
871 872 873 874
      *ok = false;
      return Expression::Default();
    }
    if (name_is_strict_reserved) {
875
      ReportMessageAt(function_name_location, "unexpected_strict_reserved");
876 877 878
      *ok = false;
      return Expression::Default();
    }
879
    if (eval_args_error_loc.IsValid()) {
880
      ReportMessageAt(eval_args_error_loc, "strict_eval_arguments");
881 882 883 884
      *ok = false;
      return Expression::Default();
    }
    if (dupe_error_loc.IsValid()) {
885
      ReportMessageAt(dupe_error_loc, "strict_param_dupe");
886 887 888 889
      *ok = false;
      return Expression::Default();
    }
    if (reserved_error_loc.IsValid()) {
890
      ReportMessageAt(reserved_error_loc, "unexpected_strict_reserved");
891 892 893
      *ok = false;
      return Expression::Default();
    }
894

895
    int end_position = scanner()->location().end_pos;
896 897 898
    CheckOctalLiteral(start_position, end_position, CHECK_OK);
  }

899
  return Expression::Default();
900 901 902
}


903
void PreParser::ParseLazyFunctionLiteralBody(bool* ok) {
904
  int body_start = position();
905
  ParseSourceElements(Token::RBRACE, ok);
906 907 908
  if (!*ok) return;

  // Position right after terminal '}'.
909
  DCHECK_EQ(Token::RBRACE, scanner()->peek());
910
  int body_end = scanner()->peek_location().end_pos;
911
  log_->LogFunction(body_start, body_end,
912
                    function_state_->materialized_literal_count(),
913
                    function_state_->expected_property_count(),
914
                    strict_mode());
915 916 917
}


918
PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
919 920
  // CallRuntime ::
  //   '%' Identifier Arguments
921
  Expect(Token::MOD, CHECK_OK);
922
  if (!allow_natives_syntax()) {
923 924 925
    *ok = false;
    return Expression::Default();
  }
926 927
  // Allow "eval" or "arguments" for backward compatibility.
  ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
928
  ParseArguments(ok);
929

930
  return Expression::Default();
931 932
}

933 934
#undef CHECK_OK

935

936
} }  // v8::internal