The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / src / preparser.cc @ f230a1cf

History | View | Annotate | Download (49.3 KB)

1
// Copyright 2011 the V8 project authors. All rights reserved.
2
// Redistribution and use in source and binary forms, with or without
3
// modification, are permitted provided that the following conditions are
4
// met:
5
//
6
//     * Redistributions of source code must retain the above copyright
7
//       notice, this list of conditions and the following disclaimer.
8
//     * Redistributions in binary form must reproduce the above
9
//       copyright notice, this list of conditions and the following
10
//       disclaimer in the documentation and/or other materials provided
11
//       with the distribution.
12
//     * Neither the name of Google Inc. nor the names of its
13
//       contributors may be used to endorse or promote products derived
14
//       from this software without specific prior written permission.
15
//
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27

    
28
#include <cmath>
29

    
30
#include "../include/v8stdint.h"
31

    
32
#include "allocation.h"
33
#include "checks.h"
34
#include "conversions.h"
35
#include "conversions-inl.h"
36
#include "globals.h"
37
#include "hashmap.h"
38
#include "list.h"
39
#include "preparse-data-format.h"
40
#include "preparse-data.h"
41
#include "preparser.h"
42
#include "unicode.h"
43
#include "utils.h"
44

    
45
#if V8_CC_MSVC && (_MSC_VER < 1800)
46
namespace std {
47

    
48
// Usually defined in math.h, but not in MSVC until VS2013+.
49
// Abstracted to work
50
int isfinite(double value);
51

    
52
}  // namespace std
53
#endif
54

    
55
namespace v8 {
56
namespace internal {
57

    
58
PreParser::PreParseResult PreParser::PreParseLazyFunction(
59
    LanguageMode mode, bool is_generator, ParserRecorder* log) {
60
  log_ = log;
61
  // Lazy functions always have trivial outer scopes (no with/catch scopes).
62
  Scope top_scope(&scope_, kTopLevelScope);
63
  set_language_mode(mode);
64
  Scope function_scope(&scope_, kFunctionScope);
65
  function_scope.set_is_generator(is_generator);
66
  ASSERT_EQ(Token::LBRACE, scanner()->current_token());
67
  bool ok = true;
68
  int start_position = peek_position();
69
  ParseLazyFunctionLiteralBody(&ok);
70
  if (stack_overflow()) return kPreParseStackOverflow;
71
  if (!ok) {
72
    ReportUnexpectedToken(scanner()->current_token());
73
  } else {
74
    ASSERT_EQ(Token::RBRACE, scanner()->peek());
75
    if (!is_classic_mode()) {
76
      int end_pos = scanner()->location().end_pos;
77
      CheckOctalLiteral(start_position, end_pos, &ok);
78
      if (ok) {
79
        CheckDelayedStrictModeViolation(start_position, end_pos, &ok);
80
      }
81
    }
82
  }
83
  return kPreParseSuccess;
84
}
85

    
86

    
87
// Preparsing checks a JavaScript program and emits preparse-data that helps
88
// a later parsing to be faster.
89
// See preparser-data.h for the data.
90

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

    
100
void PreParser::ReportUnexpectedToken(Token::Value token) {
101
  // We don't report stack overflows here, to avoid increasing the
102
  // stack depth even further.  Instead we report it after parsing is
103
  // over, in ParseProgram.
104
  if (token == Token::ILLEGAL && stack_overflow()) {
105
    return;
106
  }
107
  Scanner::Location source_location = scanner()->location();
108

    
109
  // Four of the tokens are treated specially
110
  switch (token) {
111
  case Token::EOS:
112
    return ReportMessageAt(source_location, "unexpected_eos", NULL);
113
  case Token::NUMBER:
114
    return ReportMessageAt(source_location, "unexpected_token_number", NULL);
115
  case Token::STRING:
116
    return ReportMessageAt(source_location, "unexpected_token_string", NULL);
117
  case Token::IDENTIFIER:
118
    return ReportMessageAt(source_location,
119
                           "unexpected_token_identifier", NULL);
120
  case Token::FUTURE_RESERVED_WORD:
121
    return ReportMessageAt(source_location, "unexpected_reserved", NULL);
122
  case Token::FUTURE_STRICT_RESERVED_WORD:
123
    return ReportMessageAt(source_location,
124
                           "unexpected_strict_reserved", NULL);
125
  default:
126
    const char* name = Token::String(token);
127
    ReportMessageAt(source_location, "unexpected_token", name);
128
  }
129
}
130

    
131

    
132
#define CHECK_OK  ok);                      \
133
  if (!*ok) return kUnknownSourceElements;  \
134
  ((void)0
135
#define DUMMY )  // to make indentation work
136
#undef DUMMY
137

    
138

    
139
PreParser::Statement PreParser::ParseSourceElement(bool* ok) {
140
  // (Ecma 262 5th Edition, clause 14):
141
  // SourceElement:
142
  //    Statement
143
  //    FunctionDeclaration
144
  //
145
  // In harmony mode we allow additionally the following productions
146
  // SourceElement:
147
  //    LetDeclaration
148
  //    ConstDeclaration
149
  //    GeneratorDeclaration
150

    
151
  switch (peek()) {
152
    case Token::FUNCTION:
153
      return ParseFunctionDeclaration(ok);
154
    case Token::LET:
155
    case Token::CONST:
156
      return ParseVariableStatement(kSourceElement, ok);
157
    default:
158
      return ParseStatement(ok);
159
  }
160
}
161

    
162

    
163
PreParser::SourceElements PreParser::ParseSourceElements(int end_token,
164
                                                         bool* ok) {
165
  // SourceElements ::
166
  //   (Statement)* <end_token>
167

    
168
  bool allow_directive_prologue = true;
169
  while (peek() != end_token) {
170
    Statement statement = ParseSourceElement(CHECK_OK);
171
    if (allow_directive_prologue) {
172
      if (statement.IsUseStrictLiteral()) {
173
        set_language_mode(allow_harmony_scoping() ?
174
                          EXTENDED_MODE : STRICT_MODE);
175
      } else if (!statement.IsStringLiteral()) {
176
        allow_directive_prologue = false;
177
      }
178
    }
179
  }
180
  return kUnknownSourceElements;
181
}
182

    
183

    
184
#undef CHECK_OK
185
#define CHECK_OK  ok);                   \
186
  if (!*ok) return Statement::Default();  \
187
  ((void)0
188
#define DUMMY )  // to make indentation work
189
#undef DUMMY
190

    
191

    
192
PreParser::Statement PreParser::ParseStatement(bool* ok) {
193
  // Statement ::
194
  //   Block
195
  //   VariableStatement
196
  //   EmptyStatement
197
  //   ExpressionStatement
198
  //   IfStatement
199
  //   IterationStatement
200
  //   ContinueStatement
201
  //   BreakStatement
202
  //   ReturnStatement
203
  //   WithStatement
204
  //   LabelledStatement
205
  //   SwitchStatement
206
  //   ThrowStatement
207
  //   TryStatement
208
  //   DebuggerStatement
209

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

    
217
  // Keep the source position of the statement
218
  switch (peek()) {
219
    case Token::LBRACE:
220
      return ParseBlock(ok);
221

    
222
    case Token::CONST:
223
    case Token::LET:
224
    case Token::VAR:
225
      return ParseVariableStatement(kStatement, ok);
226

    
227
    case Token::SEMICOLON:
228
      Next();
229
      return Statement::Default();
230

    
231
    case Token::IF:
232
      return ParseIfStatement(ok);
233

    
234
    case Token::DO:
235
      return ParseDoWhileStatement(ok);
236

    
237
    case Token::WHILE:
238
      return ParseWhileStatement(ok);
239

    
240
    case Token::FOR:
241
      return ParseForStatement(ok);
242

    
243
    case Token::CONTINUE:
244
      return ParseContinueStatement(ok);
245

    
246
    case Token::BREAK:
247
      return ParseBreakStatement(ok);
248

    
249
    case Token::RETURN:
250
      return ParseReturnStatement(ok);
251

    
252
    case Token::WITH:
253
      return ParseWithStatement(ok);
254

    
255
    case Token::SWITCH:
256
      return ParseSwitchStatement(ok);
257

    
258
    case Token::THROW:
259
      return ParseThrowStatement(ok);
260

    
261
    case Token::TRY:
262
      return ParseTryStatement(ok);
263

    
264
    case Token::FUNCTION: {
265
      Scanner::Location start_location = scanner()->peek_location();
266
      Statement statement = ParseFunctionDeclaration(CHECK_OK);
267
      Scanner::Location end_location = scanner()->location();
268
      if (!is_classic_mode()) {
269
        ReportMessageAt(start_location.beg_pos, end_location.end_pos,
270
                        "strict_function", NULL);
271
        *ok = false;
272
        return Statement::Default();
273
      } else {
274
        return statement;
275
      }
276
    }
277

    
278
    case Token::DEBUGGER:
279
      return ParseDebuggerStatement(ok);
280

    
281
    default:
282
      return ParseExpressionOrLabelledStatement(ok);
283
  }
284
}
285

    
286

    
287
PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
288
  // FunctionDeclaration ::
289
  //   'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
290
  // GeneratorDeclaration ::
291
  //   'function' '*' Identifier '(' FormalParameterListopt ')'
292
  //      '{' FunctionBody '}'
293
  Expect(Token::FUNCTION, CHECK_OK);
294

    
295
  bool is_generator = allow_generators() && Check(Token::MUL);
296
  Identifier identifier = ParseIdentifier(CHECK_OK);
297
  Scanner::Location location = scanner()->location();
298

    
299
  Expression function_value = ParseFunctionLiteral(is_generator, CHECK_OK);
300

    
301
  if (function_value.IsStrictFunction() &&
302
      !identifier.IsValidStrictVariable()) {
303
    // Strict mode violation, using either reserved word or eval/arguments
304
    // as name of strict function.
305
    const char* type = "strict_function_name";
306
    if (identifier.IsFutureStrictReserved() || identifier.IsYield()) {
307
      type = "strict_reserved_word";
308
    }
309
    ReportMessageAt(location, type, NULL);
310
    *ok = false;
311
  }
312
  return Statement::FunctionDeclaration();
313
}
314

    
315

    
316
PreParser::Statement PreParser::ParseBlock(bool* ok) {
317
  // Block ::
318
  //   '{' Statement* '}'
319

    
320
  // Note that a Block does not introduce a new execution scope!
321
  // (ECMA-262, 3rd, 12.2)
322
  //
323
  Expect(Token::LBRACE, CHECK_OK);
324
  while (peek() != Token::RBRACE) {
325
    if (is_extended_mode()) {
326
      ParseSourceElement(CHECK_OK);
327
    } else {
328
      ParseStatement(CHECK_OK);
329
    }
330
  }
331
  Expect(Token::RBRACE, ok);
332
  return Statement::Default();
333
}
334

    
335

    
336
PreParser::Statement PreParser::ParseVariableStatement(
337
    VariableDeclarationContext var_context,
338
    bool* ok) {
339
  // VariableStatement ::
340
  //   VariableDeclarations ';'
341

    
342
  Statement result = ParseVariableDeclarations(var_context,
343
                                               NULL,
344
                                               NULL,
345
                                               CHECK_OK);
346
  ExpectSemicolon(CHECK_OK);
347
  return result;
348
}
349

    
350

    
351
// If the variable declaration declares exactly one non-const
352
// variable, then *var is set to that variable. In all other cases,
353
// *var is untouched; in particular, it is the caller's responsibility
354
// to initialize it properly. This mechanism is also used for the parsing
355
// of 'for-in' loops.
356
PreParser::Statement PreParser::ParseVariableDeclarations(
357
    VariableDeclarationContext var_context,
358
    VariableDeclarationProperties* decl_props,
359
    int* num_decl,
360
    bool* ok) {
361
  // VariableDeclarations ::
362
  //   ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
363
  //
364
  // The ES6 Draft Rev3 specifies the following grammar for const declarations
365
  //
366
  // ConstDeclaration ::
367
  //   const ConstBinding (',' ConstBinding)* ';'
368
  // ConstBinding ::
369
  //   Identifier '=' AssignmentExpression
370
  //
371
  // TODO(ES6):
372
  // ConstBinding ::
373
  //   BindingPattern '=' AssignmentExpression
374
  bool require_initializer = false;
375
  if (peek() == Token::VAR) {
376
    Consume(Token::VAR);
377
  } else if (peek() == Token::CONST) {
378
    // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
379
    //
380
    // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
381
    //
382
    // * It is a Syntax Error if the code that matches this production is not
383
    //   contained in extended code.
384
    //
385
    // However disallowing const in classic mode will break compatibility with
386
    // existing pages. Therefore we keep allowing const with the old
387
    // non-harmony semantics in classic mode.
388
    Consume(Token::CONST);
389
    switch (language_mode()) {
390
      case CLASSIC_MODE:
391
        break;
392
      case STRICT_MODE: {
393
        Scanner::Location location = scanner()->peek_location();
394
        ReportMessageAt(location, "strict_const", NULL);
395
        *ok = false;
396
        return Statement::Default();
397
      }
398
      case EXTENDED_MODE:
399
        if (var_context != kSourceElement &&
400
            var_context != kForStatement) {
401
          Scanner::Location location = scanner()->peek_location();
402
          ReportMessageAt(location.beg_pos, location.end_pos,
403
                          "unprotected_const", NULL);
404
          *ok = false;
405
          return Statement::Default();
406
        }
407
        require_initializer = true;
408
        break;
409
    }
410
  } else if (peek() == Token::LET) {
411
    // ES6 Draft Rev4 section 12.2.1:
412
    //
413
    // LetDeclaration : let LetBindingList ;
414
    //
415
    // * It is a Syntax Error if the code that matches this production is not
416
    //   contained in extended code.
417
    if (!is_extended_mode()) {
418
      Scanner::Location location = scanner()->peek_location();
419
      ReportMessageAt(location.beg_pos, location.end_pos,
420
                      "illegal_let", NULL);
421
      *ok = false;
422
      return Statement::Default();
423
    }
424
    Consume(Token::LET);
425
    if (var_context != kSourceElement &&
426
        var_context != kForStatement) {
427
      Scanner::Location location = scanner()->peek_location();
428
      ReportMessageAt(location.beg_pos, location.end_pos,
429
                      "unprotected_let", NULL);
430
      *ok = false;
431
      return Statement::Default();
432
    }
433
  } else {
434
    *ok = false;
435
    return Statement::Default();
436
  }
437

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

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

    
466

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

    
472
  Expression expr = ParseExpression(true, CHECK_OK);
473
  if (expr.IsRawIdentifier()) {
474
    ASSERT(!expr.AsIdentifier().IsFutureReserved());
475
    ASSERT(is_classic_mode() ||
476
           (!expr.AsIdentifier().IsFutureStrictReserved() &&
477
            !expr.AsIdentifier().IsYield()));
478
    if (peek() == Token::COLON) {
479
      Consume(Token::COLON);
480
      return ParseStatement(ok);
481
    }
482
    // Preparsing is disabled for extensions (because the extension details
483
    // aren't passed to lazily compiled functions), so we don't
484
    // accept "native function" in the preparser.
485
  }
486
  // Parsed expression statement.
487
  ExpectSemicolon(CHECK_OK);
488
  return Statement::ExpressionStatement(expr);
489
}
490

    
491

    
492
PreParser::Statement PreParser::ParseIfStatement(bool* ok) {
493
  // IfStatement ::
494
  //   'if' '(' Expression ')' Statement ('else' Statement)?
495

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

    
508

    
509
PreParser::Statement PreParser::ParseContinueStatement(bool* ok) {
510
  // ContinueStatement ::
511
  //   'continue' [no line terminator] Identifier? ';'
512

    
513
  Expect(Token::CONTINUE, CHECK_OK);
514
  Token::Value tok = peek();
515
  if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
516
      tok != Token::SEMICOLON &&
517
      tok != Token::RBRACE &&
518
      tok != Token::EOS) {
519
    ParseIdentifier(CHECK_OK);
520
  }
521
  ExpectSemicolon(CHECK_OK);
522
  return Statement::Default();
523
}
524

    
525

    
526
PreParser::Statement PreParser::ParseBreakStatement(bool* ok) {
527
  // BreakStatement ::
528
  //   'break' [no line terminator] Identifier? ';'
529

    
530
  Expect(Token::BREAK, CHECK_OK);
531
  Token::Value tok = peek();
532
  if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
533
      tok != Token::SEMICOLON &&
534
      tok != Token::RBRACE &&
535
      tok != Token::EOS) {
536
    ParseIdentifier(CHECK_OK);
537
  }
538
  ExpectSemicolon(CHECK_OK);
539
  return Statement::Default();
540
}
541

    
542

    
543
PreParser::Statement PreParser::ParseReturnStatement(bool* ok) {
544
  // ReturnStatement ::
545
  //   'return' [no line terminator] Expression? ';'
546

    
547
  // Consume the return token. It is necessary to do the before
548
  // reporting any errors on it, because of the way errors are
549
  // reported (underlining).
550
  Expect(Token::RETURN, CHECK_OK);
551

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

    
557
  Token::Value tok = peek();
558
  if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
559
      tok != Token::SEMICOLON &&
560
      tok != Token::RBRACE &&
561
      tok != Token::EOS) {
562
    ParseExpression(true, CHECK_OK);
563
  }
564
  ExpectSemicolon(CHECK_OK);
565
  return Statement::Default();
566
}
567

    
568

    
569
PreParser::Statement PreParser::ParseWithStatement(bool* ok) {
570
  // WithStatement ::
571
  //   'with' '(' Expression ')' Statement
572
  Expect(Token::WITH, CHECK_OK);
573
  if (!is_classic_mode()) {
574
    Scanner::Location location = scanner()->location();
575
    ReportMessageAt(location, "strict_mode_with", NULL);
576
    *ok = false;
577
    return Statement::Default();
578
  }
579
  Expect(Token::LPAREN, CHECK_OK);
580
  ParseExpression(true, CHECK_OK);
581
  Expect(Token::RPAREN, CHECK_OK);
582

    
583
  Scope::InsideWith iw(scope_);
584
  ParseStatement(CHECK_OK);
585
  return Statement::Default();
586
}
587

    
588

    
589
PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) {
590
  // SwitchStatement ::
591
  //   'switch' '(' Expression ')' '{' CaseClause* '}'
592

    
593
  Expect(Token::SWITCH, CHECK_OK);
594
  Expect(Token::LPAREN, CHECK_OK);
595
  ParseExpression(true, CHECK_OK);
596
  Expect(Token::RPAREN, CHECK_OK);
597

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

    
620

    
621
PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) {
622
  // DoStatement ::
623
  //   'do' Statement 'while' '(' Expression ')' ';'
624

    
625
  Expect(Token::DO, CHECK_OK);
626
  ParseStatement(CHECK_OK);
627
  Expect(Token::WHILE, CHECK_OK);
628
  Expect(Token::LPAREN, CHECK_OK);
629
  ParseExpression(true, CHECK_OK);
630
  Expect(Token::RPAREN, ok);
631
  if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
632
  return Statement::Default();
633
}
634

    
635

    
636
PreParser::Statement PreParser::ParseWhileStatement(bool* ok) {
637
  // WhileStatement ::
638
  //   'while' '(' Expression ')' Statement
639

    
640
  Expect(Token::WHILE, CHECK_OK);
641
  Expect(Token::LPAREN, CHECK_OK);
642
  ParseExpression(true, CHECK_OK);
643
  Expect(Token::RPAREN, CHECK_OK);
644
  ParseStatement(ok);
645
  return Statement::Default();
646
}
647

    
648

    
649
bool PreParser::CheckInOrOf(bool accept_OF) {
650
  if (Check(Token::IN) ||
651
      (allow_for_of() && accept_OF &&
652
       CheckContextualKeyword(CStrVector("of")))) {
653
    return true;
654
  }
655
  return false;
656
}
657

    
658

    
659
PreParser::Statement PreParser::ParseForStatement(bool* ok) {
660
  // ForStatement ::
661
  //   'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
662

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

    
680
        ParseStatement(CHECK_OK);
681
        return Statement::Default();
682
      }
683
    } else {
684
      Expression lhs = ParseExpression(false, CHECK_OK);
685
      if (CheckInOrOf(lhs.IsIdentifier())) {
686
        ParseExpression(true, CHECK_OK);
687
        Expect(Token::RPAREN, CHECK_OK);
688

    
689
        ParseStatement(CHECK_OK);
690
        return Statement::Default();
691
      }
692
    }
693
  }
694

    
695
  // Parsed initializer at this point.
696
  Expect(Token::SEMICOLON, CHECK_OK);
697

    
698
  if (peek() != Token::SEMICOLON) {
699
    ParseExpression(true, CHECK_OK);
700
  }
701
  Expect(Token::SEMICOLON, CHECK_OK);
702

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

    
708
  ParseStatement(ok);
709
  return Statement::Default();
710
}
711

    
712

    
713
PreParser::Statement PreParser::ParseThrowStatement(bool* ok) {
714
  // ThrowStatement ::
715
  //   'throw' [no line terminator] Expression ';'
716

    
717
  Expect(Token::THROW, CHECK_OK);
718
  if (scanner()->HasAnyLineTerminatorBeforeNext()) {
719
    Scanner::Location pos = scanner()->location();
720
    ReportMessageAt(pos, "newline_after_throw", NULL);
721
    *ok = false;
722
    return Statement::Default();
723
  }
724
  ParseExpression(true, CHECK_OK);
725
  ExpectSemicolon(ok);
726
  return Statement::Default();
727
}
728

    
729

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

    
742
  // In preparsing, allow any number of catch/finally blocks, including zero
743
  // of both.
744

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

    
747
  ParseBlock(CHECK_OK);
748

    
749
  bool catch_or_finally_seen = false;
750
  if (peek() == Token::CATCH) {
751
    Consume(Token::CATCH);
752
    Expect(Token::LPAREN, CHECK_OK);
753
    Identifier id = ParseIdentifier(CHECK_OK);
754
    if (!is_classic_mode() && !id.IsValidStrictVariable()) {
755
      StrictModeIdentifierViolation(scanner()->location(),
756
                                    "strict_catch_variable",
757
                                    id,
758
                                    ok);
759
      return Statement::Default();
760
    }
761
    Expect(Token::RPAREN, CHECK_OK);
762
    { Scope::InsideWith iw(scope_);
763
      ParseBlock(CHECK_OK);
764
    }
765
    catch_or_finally_seen = true;
766
  }
767
  if (peek() == Token::FINALLY) {
768
    Consume(Token::FINALLY);
769
    ParseBlock(CHECK_OK);
770
    catch_or_finally_seen = true;
771
  }
772
  if (!catch_or_finally_seen) {
773
    *ok = false;
774
  }
775
  return Statement::Default();
776
}
777

    
778

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

    
786
  Expect(Token::DEBUGGER, CHECK_OK);
787
  ExpectSemicolon(ok);
788
  return Statement::Default();
789
}
790

    
791

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

    
799

    
800
// Precedence = 1
801
PreParser::Expression PreParser::ParseExpression(bool accept_IN, bool* ok) {
802
  // Expression ::
803
  //   AssignmentExpression
804
  //   Expression ',' AssignmentExpression
805

    
806
  Expression result = ParseAssignmentExpression(accept_IN, CHECK_OK);
807
  while (peek() == Token::COMMA) {
808
    Expect(Token::COMMA, CHECK_OK);
809
    ParseAssignmentExpression(accept_IN, CHECK_OK);
810
    result = Expression::Default();
811
  }
812
  return result;
813
}
814

    
815

    
816
// Precedence = 2
817
PreParser::Expression PreParser::ParseAssignmentExpression(bool accept_IN,
818
                                                           bool* ok) {
819
  // AssignmentExpression ::
820
  //   ConditionalExpression
821
  //   YieldExpression
822
  //   LeftHandSideExpression AssignmentOperator AssignmentExpression
823

    
824
  if (scope_->is_generator() && peek() == Token::YIELD) {
825
    return ParseYieldExpression(ok);
826
  }
827

    
828
  Scanner::Location before = scanner()->peek_location();
829
  Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK);
830

    
831
  if (!Token::IsAssignmentOp(peek())) {
832
    // Parsed conditional expression only (no assignment).
833
    return expression;
834
  }
835

    
836
  if (!is_classic_mode() &&
837
      expression.IsIdentifier() &&
838
      expression.AsIdentifier().IsEvalOrArguments()) {
839
    Scanner::Location after = scanner()->location();
840
    ReportMessageAt(before.beg_pos, after.end_pos,
841
                    "strict_lhs_assignment", NULL);
842
    *ok = false;
843
    return Expression::Default();
844
  }
845

    
846
  Token::Value op = Next();  // Get assignment operator.
847
  ParseAssignmentExpression(accept_IN, CHECK_OK);
848

    
849
  if ((op == Token::ASSIGN) && expression.IsThisProperty()) {
850
    scope_->AddProperty();
851
  }
852

    
853
  return Expression::Default();
854
}
855

    
856

    
857
// Precedence = 3
858
PreParser::Expression PreParser::ParseYieldExpression(bool* ok) {
859
  // YieldExpression ::
860
  //   'yield' '*'? AssignmentExpression
861
  Consume(Token::YIELD);
862
  Check(Token::MUL);
863

    
864
  ParseAssignmentExpression(false, CHECK_OK);
865

    
866
  return Expression::Default();
867
}
868

    
869

    
870
// Precedence = 3
871
PreParser::Expression PreParser::ParseConditionalExpression(bool accept_IN,
872
                                                            bool* ok) {
873
  // ConditionalExpression ::
874
  //   LogicalOrExpression
875
  //   LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
876

    
877
  // We start using the binary expression parser for prec >= 4 only!
878
  Expression expression = ParseBinaryExpression(4, accept_IN, CHECK_OK);
879
  if (peek() != Token::CONDITIONAL) return expression;
880
  Consume(Token::CONDITIONAL);
881
  // In parsing the first assignment expression in conditional
882
  // expressions we always accept the 'in' keyword; see ECMA-262,
883
  // section 11.12, page 58.
884
  ParseAssignmentExpression(true, CHECK_OK);
885
  Expect(Token::COLON, CHECK_OK);
886
  ParseAssignmentExpression(accept_IN, CHECK_OK);
887
  return Expression::Default();
888
}
889

    
890

    
891
// Precedence >= 4
892
PreParser::Expression PreParser::ParseBinaryExpression(int prec,
893
                                                       bool accept_IN,
894
                                                       bool* ok) {
895
  Expression result = ParseUnaryExpression(CHECK_OK);
896
  for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
897
    // prec1 >= 4
898
    while (Precedence(peek(), accept_IN) == prec1) {
899
      Next();
900
      ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK);
901
      result = Expression::Default();
902
    }
903
  }
904
  return result;
905
}
906

    
907

    
908
PreParser::Expression PreParser::ParseUnaryExpression(bool* ok) {
909
  // UnaryExpression ::
910
  //   PostfixExpression
911
  //   'delete' UnaryExpression
912
  //   'void' UnaryExpression
913
  //   'typeof' UnaryExpression
914
  //   '++' UnaryExpression
915
  //   '--' UnaryExpression
916
  //   '+' UnaryExpression
917
  //   '-' UnaryExpression
918
  //   '~' UnaryExpression
919
  //   '!' UnaryExpression
920

    
921
  Token::Value op = peek();
922
  if (Token::IsUnaryOp(op)) {
923
    op = Next();
924
    ParseUnaryExpression(ok);
925
    return Expression::Default();
926
  } else if (Token::IsCountOp(op)) {
927
    op = Next();
928
    Scanner::Location before = scanner()->peek_location();
929
    Expression expression = ParseUnaryExpression(CHECK_OK);
930
    if (!is_classic_mode() &&
931
        expression.IsIdentifier() &&
932
        expression.AsIdentifier().IsEvalOrArguments()) {
933
      Scanner::Location after = scanner()->location();
934
      ReportMessageAt(before.beg_pos, after.end_pos,
935
                      "strict_lhs_prefix", NULL);
936
      *ok = false;
937
    }
938
    return Expression::Default();
939
  } else {
940
    return ParsePostfixExpression(ok);
941
  }
942
}
943

    
944

    
945
PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) {
946
  // PostfixExpression ::
947
  //   LeftHandSideExpression ('++' | '--')?
948

    
949
  Scanner::Location before = scanner()->peek_location();
950
  Expression expression = ParseLeftHandSideExpression(CHECK_OK);
951
  if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
952
      Token::IsCountOp(peek())) {
953
    if (!is_classic_mode() &&
954
        expression.IsIdentifier() &&
955
        expression.AsIdentifier().IsEvalOrArguments()) {
956
      Scanner::Location after = scanner()->location();
957
      ReportMessageAt(before.beg_pos, after.end_pos,
958
                      "strict_lhs_postfix", NULL);
959
      *ok = false;
960
      return Expression::Default();
961
    }
962
    Next();
963
    return Expression::Default();
964
  }
965
  return expression;
966
}
967

    
968

    
969
PreParser::Expression PreParser::ParseLeftHandSideExpression(bool* ok) {
970
  // LeftHandSideExpression ::
971
  //   (NewExpression | MemberExpression) ...
972

    
973
  Expression result = Expression::Default();
974
  if (peek() == Token::NEW) {
975
    result = ParseNewExpression(CHECK_OK);
976
  } else {
977
    result = ParseMemberExpression(CHECK_OK);
978
  }
979

    
980
  while (true) {
981
    switch (peek()) {
982
      case Token::LBRACK: {
983
        Consume(Token::LBRACK);
984
        ParseExpression(true, CHECK_OK);
985
        Expect(Token::RBRACK, CHECK_OK);
986
        if (result.IsThis()) {
987
          result = Expression::ThisProperty();
988
        } else {
989
          result = Expression::Default();
990
        }
991
        break;
992
      }
993

    
994
      case Token::LPAREN: {
995
        ParseArguments(CHECK_OK);
996
        result = Expression::Default();
997
        break;
998
      }
999

    
1000
      case Token::PERIOD: {
1001
        Consume(Token::PERIOD);
1002
        ParseIdentifierName(CHECK_OK);
1003
        if (result.IsThis()) {
1004
          result = Expression::ThisProperty();
1005
        } else {
1006
          result = Expression::Default();
1007
        }
1008
        break;
1009
      }
1010

    
1011
      default:
1012
        return result;
1013
    }
1014
  }
1015
}
1016

    
1017

    
1018
PreParser::Expression PreParser::ParseNewExpression(bool* ok) {
1019
  // NewExpression ::
1020
  //   ('new')+ MemberExpression
1021

    
1022
  // The grammar for new expressions is pretty warped. The keyword
1023
  // 'new' can either be a part of the new expression (where it isn't
1024
  // followed by an argument list) or a part of the member expression,
1025
  // where it must be followed by an argument list. To accommodate
1026
  // this, we parse the 'new' keywords greedily and keep track of how
1027
  // many we have parsed. This information is then passed on to the
1028
  // member expression parser, which is only allowed to match argument
1029
  // lists as long as it has 'new' prefixes left
1030
  unsigned new_count = 0;
1031
  do {
1032
    Consume(Token::NEW);
1033
    new_count++;
1034
  } while (peek() == Token::NEW);
1035

    
1036
  return ParseMemberWithNewPrefixesExpression(new_count, ok);
1037
}
1038

    
1039

    
1040
PreParser::Expression PreParser::ParseMemberExpression(bool* ok) {
1041
  return ParseMemberWithNewPrefixesExpression(0, ok);
1042
}
1043

    
1044

    
1045
PreParser::Expression PreParser::ParseMemberWithNewPrefixesExpression(
1046
    unsigned new_count, bool* ok) {
1047
  // MemberExpression ::
1048
  //   (PrimaryExpression | FunctionLiteral)
1049
  //     ('[' Expression ']' | '.' Identifier | Arguments)*
1050

    
1051
  // Parse the initial primary or function expression.
1052
  Expression result = Expression::Default();
1053
  if (peek() == Token::FUNCTION) {
1054
    Consume(Token::FUNCTION);
1055

    
1056
    bool is_generator = allow_generators() && Check(Token::MUL);
1057
    Identifier identifier = Identifier::Default();
1058
    if (peek_any_identifier()) {
1059
      identifier = ParseIdentifier(CHECK_OK);
1060
    }
1061
    result = ParseFunctionLiteral(is_generator, CHECK_OK);
1062
    if (result.IsStrictFunction() && !identifier.IsValidStrictVariable()) {
1063
      StrictModeIdentifierViolation(scanner()->location(),
1064
                                    "strict_function_name",
1065
                                    identifier,
1066
                                    ok);
1067
      return Expression::Default();
1068
    }
1069
  } else {
1070
    result = ParsePrimaryExpression(CHECK_OK);
1071
  }
1072

    
1073
  while (true) {
1074
    switch (peek()) {
1075
      case Token::LBRACK: {
1076
        Consume(Token::LBRACK);
1077
        ParseExpression(true, CHECK_OK);
1078
        Expect(Token::RBRACK, CHECK_OK);
1079
        if (result.IsThis()) {
1080
          result = Expression::ThisProperty();
1081
        } else {
1082
          result = Expression::Default();
1083
        }
1084
        break;
1085
      }
1086
      case Token::PERIOD: {
1087
        Consume(Token::PERIOD);
1088
        ParseIdentifierName(CHECK_OK);
1089
        if (result.IsThis()) {
1090
          result = Expression::ThisProperty();
1091
        } else {
1092
          result = Expression::Default();
1093
        }
1094
        break;
1095
      }
1096
      case Token::LPAREN: {
1097
        if (new_count == 0) return result;
1098
        // Consume one of the new prefixes (already parsed).
1099
        ParseArguments(CHECK_OK);
1100
        new_count--;
1101
        result = Expression::Default();
1102
        break;
1103
      }
1104
      default:
1105
        return result;
1106
    }
1107
  }
1108
}
1109

    
1110

    
1111
PreParser::Expression PreParser::ParsePrimaryExpression(bool* ok) {
1112
  // PrimaryExpression ::
1113
  //   'this'
1114
  //   'null'
1115
  //   'true'
1116
  //   'false'
1117
  //   Identifier
1118
  //   Number
1119
  //   String
1120
  //   ArrayLiteral
1121
  //   ObjectLiteral
1122
  //   RegExpLiteral
1123
  //   '(' Expression ')'
1124

    
1125
  Expression result = Expression::Default();
1126
  switch (peek()) {
1127
    case Token::THIS: {
1128
      Next();
1129
      result = Expression::This();
1130
      break;
1131
    }
1132

    
1133
    case Token::FUTURE_RESERVED_WORD:
1134
    case Token::FUTURE_STRICT_RESERVED_WORD:
1135
    case Token::YIELD:
1136
    case Token::IDENTIFIER: {
1137
      Identifier id = ParseIdentifier(CHECK_OK);
1138
      result = Expression::FromIdentifier(id);
1139
      break;
1140
    }
1141

    
1142
    case Token::NULL_LITERAL:
1143
    case Token::TRUE_LITERAL:
1144
    case Token::FALSE_LITERAL:
1145
    case Token::NUMBER: {
1146
      Next();
1147
      break;
1148
    }
1149
    case Token::STRING: {
1150
      Next();
1151
      result = GetStringSymbol();
1152
      break;
1153
    }
1154

    
1155
    case Token::ASSIGN_DIV:
1156
      result = ParseRegExpLiteral(true, CHECK_OK);
1157
      break;
1158

    
1159
    case Token::DIV:
1160
      result = ParseRegExpLiteral(false, CHECK_OK);
1161
      break;
1162

    
1163
    case Token::LBRACK:
1164
      result = ParseArrayLiteral(CHECK_OK);
1165
      break;
1166

    
1167
    case Token::LBRACE:
1168
      result = ParseObjectLiteral(CHECK_OK);
1169
      break;
1170

    
1171
    case Token::LPAREN:
1172
      Consume(Token::LPAREN);
1173
      parenthesized_function_ = (peek() == Token::FUNCTION);
1174
      result = ParseExpression(true, CHECK_OK);
1175
      Expect(Token::RPAREN, CHECK_OK);
1176
      result = result.Parenthesize();
1177
      break;
1178

    
1179
    case Token::MOD:
1180
      result = ParseV8Intrinsic(CHECK_OK);
1181
      break;
1182

    
1183
    default: {
1184
      Next();
1185
      *ok = false;
1186
      return Expression::Default();
1187
    }
1188
  }
1189

    
1190
  return result;
1191
}
1192

    
1193

    
1194
PreParser::Expression PreParser::ParseArrayLiteral(bool* ok) {
1195
  // ArrayLiteral ::
1196
  //   '[' Expression? (',' Expression?)* ']'
1197
  Expect(Token::LBRACK, CHECK_OK);
1198
  while (peek() != Token::RBRACK) {
1199
    if (peek() != Token::COMMA) {
1200
      ParseAssignmentExpression(true, CHECK_OK);
1201
    }
1202
    if (peek() != Token::RBRACK) {
1203
      Expect(Token::COMMA, CHECK_OK);
1204
    }
1205
  }
1206
  Expect(Token::RBRACK, CHECK_OK);
1207

    
1208
  scope_->NextMaterializedLiteralIndex();
1209
  return Expression::Default();
1210
}
1211

    
1212

    
1213
PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) {
1214
  // ObjectLiteral ::
1215
  //   '{' (
1216
  //       ((IdentifierName | String | Number) ':' AssignmentExpression)
1217
  //     | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
1218
  //    )*[','] '}'
1219

    
1220
  ObjectLiteralChecker checker(this, language_mode());
1221

    
1222
  Expect(Token::LBRACE, CHECK_OK);
1223
  while (peek() != Token::RBRACE) {
1224
    Token::Value next = peek();
1225
    switch (next) {
1226
      case Token::IDENTIFIER:
1227
      case Token::FUTURE_RESERVED_WORD:
1228
      case Token::FUTURE_STRICT_RESERVED_WORD: {
1229
        bool is_getter = false;
1230
        bool is_setter = false;
1231
        ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
1232
        if ((is_getter || is_setter) && peek() != Token::COLON) {
1233
            Token::Value name = Next();
1234
            bool is_keyword = Token::IsKeyword(name);
1235
            if (name != Token::IDENTIFIER &&
1236
                name != Token::FUTURE_RESERVED_WORD &&
1237
                name != Token::FUTURE_STRICT_RESERVED_WORD &&
1238
                name != Token::NUMBER &&
1239
                name != Token::STRING &&
1240
                !is_keyword) {
1241
              *ok = false;
1242
              return Expression::Default();
1243
            }
1244
            if (!is_keyword) {
1245
              LogSymbol();
1246
            }
1247
            PropertyKind type = is_getter ? kGetterProperty : kSetterProperty;
1248
            checker.CheckProperty(name, type, CHECK_OK);
1249
            ParseFunctionLiteral(false, CHECK_OK);
1250
            if (peek() != Token::RBRACE) {
1251
              Expect(Token::COMMA, CHECK_OK);
1252
            }
1253
            continue;  // restart the while
1254
        }
1255
        checker.CheckProperty(next, kValueProperty, CHECK_OK);
1256
        break;
1257
      }
1258
      case Token::STRING:
1259
        Consume(next);
1260
        checker.CheckProperty(next, kValueProperty, CHECK_OK);
1261
        GetStringSymbol();
1262
        break;
1263
      case Token::NUMBER:
1264
        Consume(next);
1265
        checker.CheckProperty(next, kValueProperty, CHECK_OK);
1266
        break;
1267
      default:
1268
        if (Token::IsKeyword(next)) {
1269
          Consume(next);
1270
          checker.CheckProperty(next, kValueProperty, CHECK_OK);
1271
        } else {
1272
          // Unexpected token.
1273
          *ok = false;
1274
          return Expression::Default();
1275
        }
1276
    }
1277

    
1278
    Expect(Token::COLON, CHECK_OK);
1279
    ParseAssignmentExpression(true, CHECK_OK);
1280

    
1281
    // TODO(1240767): Consider allowing trailing comma.
1282
    if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
1283
  }
1284
  Expect(Token::RBRACE, CHECK_OK);
1285

    
1286
  scope_->NextMaterializedLiteralIndex();
1287
  return Expression::Default();
1288
}
1289

    
1290

    
1291
PreParser::Expression PreParser::ParseRegExpLiteral(bool seen_equal,
1292
                                                    bool* ok) {
1293
  if (!scanner()->ScanRegExpPattern(seen_equal)) {
1294
    Next();
1295
    ReportMessageAt(scanner()->location(), "unterminated_regexp", NULL);
1296
    *ok = false;
1297
    return Expression::Default();
1298
  }
1299

    
1300
  scope_->NextMaterializedLiteralIndex();
1301

    
1302
  if (!scanner()->ScanRegExpFlags()) {
1303
    Next();
1304
    ReportMessageAt(scanner()->location(), "invalid_regexp_flags", NULL);
1305
    *ok = false;
1306
    return Expression::Default();
1307
  }
1308
  Next();
1309
  return Expression::Default();
1310
}
1311

    
1312

    
1313
PreParser::Arguments PreParser::ParseArguments(bool* ok) {
1314
  // Arguments ::
1315
  //   '(' (AssignmentExpression)*[','] ')'
1316

    
1317
  Expect(Token::LPAREN, ok);
1318
  if (!*ok) return -1;
1319
  bool done = (peek() == Token::RPAREN);
1320
  int argc = 0;
1321
  while (!done) {
1322
    ParseAssignmentExpression(true, ok);
1323
    if (!*ok) return -1;
1324
    argc++;
1325
    done = (peek() == Token::RPAREN);
1326
    if (!done) {
1327
      Expect(Token::COMMA, ok);
1328
      if (!*ok) return -1;
1329
    }
1330
  }
1331
  Expect(Token::RPAREN, ok);
1332
  return argc;
1333
}
1334

    
1335

    
1336
PreParser::Expression PreParser::ParseFunctionLiteral(bool is_generator,
1337
                                                      bool* ok) {
1338
  // Function ::
1339
  //   '(' FormalParameterList? ')' '{' FunctionBody '}'
1340

    
1341
  // Parse function body.
1342
  ScopeType outer_scope_type = scope_->type();
1343
  bool inside_with = scope_->IsInsideWith();
1344
  Scope function_scope(&scope_, kFunctionScope);
1345
  function_scope.set_is_generator(is_generator);
1346
  //  FormalParameterList ::
1347
  //    '(' (Identifier)*[','] ')'
1348
  Expect(Token::LPAREN, CHECK_OK);
1349
  int start_position = position();
1350
  bool done = (peek() == Token::RPAREN);
1351
  DuplicateFinder duplicate_finder(scanner()->unicode_cache());
1352
  while (!done) {
1353
    Identifier id = ParseIdentifier(CHECK_OK);
1354
    if (!id.IsValidStrictVariable()) {
1355
      StrictModeIdentifierViolation(scanner()->location(),
1356
                                    "strict_param_name",
1357
                                    id,
1358
                                    CHECK_OK);
1359
    }
1360
    int prev_value;
1361
    if (scanner()->is_literal_ascii()) {
1362
      prev_value =
1363
          duplicate_finder.AddAsciiSymbol(scanner()->literal_ascii_string(), 1);
1364
    } else {
1365
      prev_value =
1366
          duplicate_finder.AddUtf16Symbol(scanner()->literal_utf16_string(), 1);
1367
    }
1368

    
1369
    if (prev_value != 0) {
1370
      SetStrictModeViolation(scanner()->location(),
1371
                             "strict_param_dupe",
1372
                             CHECK_OK);
1373
    }
1374
    done = (peek() == Token::RPAREN);
1375
    if (!done) {
1376
      Expect(Token::COMMA, CHECK_OK);
1377
    }
1378
  }
1379
  Expect(Token::RPAREN, CHECK_OK);
1380

    
1381
  // Determine if the function will be lazily compiled.
1382
  // Currently only happens to top-level functions.
1383
  // Optimistically assume that all top-level functions are lazily compiled.
1384
  bool is_lazily_compiled = (outer_scope_type == kTopLevelScope &&
1385
                             !inside_with && allow_lazy() &&
1386
                             !parenthesized_function_);
1387
  parenthesized_function_ = false;
1388

    
1389
  Expect(Token::LBRACE, CHECK_OK);
1390
  if (is_lazily_compiled) {
1391
    ParseLazyFunctionLiteralBody(CHECK_OK);
1392
  } else {
1393
    ParseSourceElements(Token::RBRACE, ok);
1394
  }
1395
  Expect(Token::RBRACE, CHECK_OK);
1396

    
1397
  if (!is_classic_mode()) {
1398
    int end_position = scanner()->location().end_pos;
1399
    CheckOctalLiteral(start_position, end_position, CHECK_OK);
1400
    CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK);
1401
    return Expression::StrictFunction();
1402
  }
1403

    
1404
  return Expression::Default();
1405
}
1406

    
1407

    
1408
void PreParser::ParseLazyFunctionLiteralBody(bool* ok) {
1409
  int body_start = position();
1410
  log_->PauseRecording();
1411
  ParseSourceElements(Token::RBRACE, ok);
1412
  log_->ResumeRecording();
1413
  if (!*ok) return;
1414

    
1415
  // Position right after terminal '}'.
1416
  ASSERT_EQ(Token::RBRACE, scanner()->peek());
1417
  int body_end = scanner()->peek_location().end_pos;
1418
  log_->LogFunction(body_start, body_end,
1419
                    scope_->materialized_literal_count(),
1420
                    scope_->expected_properties(),
1421
                    language_mode());
1422
}
1423

    
1424

    
1425
PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
1426
  // CallRuntime ::
1427
  //   '%' Identifier Arguments
1428
  Expect(Token::MOD, CHECK_OK);
1429
  if (!allow_natives_syntax()) {
1430
    *ok = false;
1431
    return Expression::Default();
1432
  }
1433
  ParseIdentifier(CHECK_OK);
1434
  ParseArguments(ok);
1435

    
1436
  return Expression::Default();
1437
}
1438

    
1439
#undef CHECK_OK
1440

    
1441

    
1442
void PreParser::LogSymbol() {
1443
  int identifier_pos = position();
1444
  if (scanner()->is_literal_ascii()) {
1445
    log_->LogAsciiSymbol(identifier_pos, scanner()->literal_ascii_string());
1446
  } else {
1447
    log_->LogUtf16Symbol(identifier_pos, scanner()->literal_utf16_string());
1448
  }
1449
}
1450

    
1451

    
1452
PreParser::Expression PreParser::GetStringSymbol() {
1453
  const int kUseStrictLength = 10;
1454
  const char* kUseStrictChars = "use strict";
1455
  LogSymbol();
1456
  if (scanner()->is_literal_ascii() &&
1457
      scanner()->literal_length() == kUseStrictLength &&
1458
      !scanner()->literal_contains_escapes() &&
1459
      !strncmp(scanner()->literal_ascii_string().start(), kUseStrictChars,
1460
               kUseStrictLength)) {
1461
    return Expression::UseStrictStringLiteral();
1462
  }
1463
  return Expression::StringLiteral();
1464
}
1465

    
1466

    
1467
PreParser::Identifier PreParser::GetIdentifierSymbol() {
1468
  LogSymbol();
1469
  if (scanner()->current_token() == Token::FUTURE_RESERVED_WORD) {
1470
    return Identifier::FutureReserved();
1471
  } else if (scanner()->current_token() ==
1472
             Token::FUTURE_STRICT_RESERVED_WORD) {
1473
    return Identifier::FutureStrictReserved();
1474
  } else if (scanner()->current_token() == Token::YIELD) {
1475
    return Identifier::Yield();
1476
  }
1477
  if (scanner()->is_literal_ascii()) {
1478
    // Detect strict-mode poison words.
1479
    if (scanner()->literal_length() == 4 &&
1480
        !strncmp(scanner()->literal_ascii_string().start(), "eval", 4)) {
1481
      return Identifier::Eval();
1482
    }
1483
    if (scanner()->literal_length() == 9 &&
1484
        !strncmp(scanner()->literal_ascii_string().start(), "arguments", 9)) {
1485
      return Identifier::Arguments();
1486
    }
1487
  }
1488
  return Identifier::Default();
1489
}
1490

    
1491

    
1492
PreParser::Identifier PreParser::ParseIdentifier(bool* ok) {
1493
  Token::Value next = Next();
1494
  switch (next) {
1495
    case Token::FUTURE_RESERVED_WORD: {
1496
      Scanner::Location location = scanner()->location();
1497
      ReportMessageAt(location.beg_pos, location.end_pos,
1498
                      "reserved_word", NULL);
1499
      *ok = false;
1500
      return GetIdentifierSymbol();
1501
    }
1502
    case Token::YIELD:
1503
      if (scope_->is_generator()) {
1504
        // 'yield' in a generator is only valid as part of a YieldExpression.
1505
        ReportMessageAt(scanner()->location(), "unexpected_token", "yield");
1506
        *ok = false;
1507
        return Identifier::Yield();
1508
      }
1509
      // FALLTHROUGH
1510
    case Token::FUTURE_STRICT_RESERVED_WORD:
1511
      if (!is_classic_mode()) {
1512
        Scanner::Location location = scanner()->location();
1513
        ReportMessageAt(location.beg_pos, location.end_pos,
1514
                        "strict_reserved_word", NULL);
1515
        *ok = false;
1516
      }
1517
      // FALLTHROUGH
1518
    case Token::IDENTIFIER:
1519
      return GetIdentifierSymbol();
1520
    default:
1521
      *ok = false;
1522
      return Identifier::Default();
1523
  }
1524
}
1525

    
1526

    
1527
void PreParser::SetStrictModeViolation(Scanner::Location location,
1528
                                       const char* type,
1529
                                       bool* ok) {
1530
  if (!is_classic_mode()) {
1531
    ReportMessageAt(location, type, NULL);
1532
    *ok = false;
1533
    return;
1534
  }
1535
  // Delay report in case this later turns out to be strict code
1536
  // (i.e., for function names and parameters prior to a "use strict"
1537
  // directive).
1538
  // It's safe to overwrite an existing violation.
1539
  // It's either from a function that turned out to be non-strict,
1540
  // or it's in the current function (and we just need to report
1541
  // one error), or it's in a unclosed nesting function that wasn't
1542
  // strict (otherwise we would already be in strict mode).
1543
  strict_mode_violation_location_ = location;
1544
  strict_mode_violation_type_ = type;
1545
}
1546

    
1547

    
1548
void PreParser::CheckDelayedStrictModeViolation(int beg_pos,
1549
                                                int end_pos,
1550
                                                bool* ok) {
1551
  Scanner::Location location = strict_mode_violation_location_;
1552
  if (location.IsValid() &&
1553
      location.beg_pos > beg_pos && location.end_pos < end_pos) {
1554
    ReportMessageAt(location, strict_mode_violation_type_, NULL);
1555
    *ok = false;
1556
  }
1557
}
1558

    
1559

    
1560
void PreParser::StrictModeIdentifierViolation(Scanner::Location location,
1561
                                              const char* eval_args_type,
1562
                                              Identifier identifier,
1563
                                              bool* ok) {
1564
  const char* type = eval_args_type;
1565
  if (identifier.IsFutureReserved()) {
1566
    type = "reserved_word";
1567
  } else if (identifier.IsFutureStrictReserved() || identifier.IsYield()) {
1568
    type = "strict_reserved_word";
1569
  }
1570
  if (!is_classic_mode()) {
1571
    ReportMessageAt(location, type, NULL);
1572
    *ok = false;
1573
    return;
1574
  }
1575
  strict_mode_violation_location_ = location;
1576
  strict_mode_violation_type_ = type;
1577
}
1578

    
1579

    
1580
PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) {
1581
  Token::Value next = Next();
1582
  if (Token::IsKeyword(next)) {
1583
    int pos = position();
1584
    const char* keyword = Token::String(next);
1585
    log_->LogAsciiSymbol(pos, Vector<const char>(keyword, StrLength(keyword)));
1586
    return Identifier::Default();
1587
  }
1588
  if (next == Token::IDENTIFIER ||
1589
      next == Token::FUTURE_RESERVED_WORD ||
1590
      next == Token::FUTURE_STRICT_RESERVED_WORD) {
1591
    return GetIdentifierSymbol();
1592
  }
1593
  *ok = false;
1594
  return Identifier::Default();
1595
}
1596

    
1597
#undef CHECK_OK
1598

    
1599

    
1600
// This function reads an identifier and determines whether or not it
1601
// is 'get' or 'set'.
1602
PreParser::Identifier PreParser::ParseIdentifierNameOrGetOrSet(bool* is_get,
1603
                                                               bool* is_set,
1604
                                                               bool* ok) {
1605
  Identifier result = ParseIdentifierName(ok);
1606
  if (!*ok) return Identifier::Default();
1607
  if (scanner()->is_literal_ascii() &&
1608
      scanner()->literal_length() == 3) {
1609
    const char* token = scanner()->literal_ascii_string().start();
1610
    *is_get = strncmp(token, "get", 3) == 0;
1611
    *is_set = !*is_get && strncmp(token, "set", 3) == 0;
1612
  }
1613
  return result;
1614
}
1615

    
1616

    
1617
void PreParser::ObjectLiteralChecker::CheckProperty(Token::Value property,
1618
                                                    PropertyKind type,
1619
                                                    bool* ok) {
1620
  int old;
1621
  if (property == Token::NUMBER) {
1622
    old = finder_.AddNumber(scanner()->literal_ascii_string(), type);
1623
  } else if (scanner()->is_literal_ascii()) {
1624
    old = finder_.AddAsciiSymbol(scanner()->literal_ascii_string(), type);
1625
  } else {
1626
    old = finder_.AddUtf16Symbol(scanner()->literal_utf16_string(), type);
1627
  }
1628
  PropertyKind old_type = static_cast<PropertyKind>(old);
1629
  if (HasConflict(old_type, type)) {
1630
    if (IsDataDataConflict(old_type, type)) {
1631
      // Both are data properties.
1632
      if (language_mode_ == CLASSIC_MODE) return;
1633
      parser()->ReportMessageAt(scanner()->location(),
1634
                               "strict_duplicate_property");
1635
    } else if (IsDataAccessorConflict(old_type, type)) {
1636
      // Both a data and an accessor property with the same name.
1637
      parser()->ReportMessageAt(scanner()->location(),
1638
                               "accessor_data_property");
1639
    } else {
1640
      ASSERT(IsAccessorAccessorConflict(old_type, type));
1641
      // Both accessors of the same type.
1642
      parser()->ReportMessageAt(scanner()->location(),
1643
                               "accessor_get_set");
1644
    }
1645
    *ok = false;
1646
  }
1647
}
1648

    
1649
} }  // v8::internal