~evarlast/ubuntu/utopic/mongodb/upstart-workaround-debian-bug-718702

« back to all changes in this revision

Viewing changes to src/third_party/v8/src/preparser.cc

  • Committer: Package Import Robot
  • Author(s): James Page, James Page, Robie Basak
  • Date: 2013-05-29 17:44:42 UTC
  • mfrom: (44.1.7 sid)
  • Revision ID: package-import@ubuntu.com-20130529174442-z0a4qmoww4y0t458
Tags: 1:2.4.3-1ubuntu1
[ James Page ]
* Merge from Debian unstable, remaining changes:
  - Enable SSL support:
    + d/control: Add libssl-dev to BD's.
    + d/rules: Enabled --ssl option.
    + d/mongodb.conf: Add example SSL configuration options.
  - d/mongodb-server.mongodb.upstart: Add upstart configuration.
  - d/rules: Don't strip binaries during scons build for Ubuntu.
  - d/control: Add armhf to target archs.
  - d/p/SConscript.client.patch: fixup install of client libraries.
  - d/p/0010-install-libs-to-usr-lib-not-usr-lib64-Closes-588557.patch:
    Install libraries to lib not lib64.
* Dropped changes:
  - d/p/arm-support.patch: Included in Debian.
  - d/p/double-alignment.patch: Included in Debian.
  - d/rules,control: Debian also builds with avaliable system libraries
    now.
* Fix FTBFS due to gcc and boost upgrades in saucy:
  - d/p/0008-ignore-unused-local-typedefs.patch: Add -Wno-unused-typedefs
    to unbreak building with g++-4.8.
  - d/p/0009-boost-1.53.patch: Fixup signed/unsigned casting issue.

[ Robie Basak ]
* d/p/0011-Use-a-signed-char-to-store-BSONType-enumerations.patch: Fixup
  build failure on ARM due to missing signed'ness of char cast.

Show diffs side-by-side

added added

removed removed

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