parser.h 35.7 KB
Newer Older
1
// Copyright 2012 the V8 project authors. All rights reserved.
2 3
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
4 5 6 7

#ifndef V8_PARSER_H_
#define V8_PARSER_H_

8 9 10 11
#include "src/allocation.h"
#include "src/ast.h"
#include "src/compiler.h"  // For CachedDataMode
#include "src/preparse-data.h"
12
#include "src/preparse-data-format.h"
13
#include "src/preparser.h"
14
#include "src/scopes.h"
15

16
namespace v8 {
17 18
class ScriptCompiler;

19
namespace internal {
20

21
class CompilationInfo;
22 23 24 25
class ParserLog;
class PositionStack;
class Target;

26 27 28

class FunctionEntry BASE_EMBEDDED {
 public:
29 30 31 32 33
  enum {
    kStartPositionIndex,
    kEndPositionIndex,
    kLiteralCountIndex,
    kPropertyCountIndex,
34
    kStrictModeIndex,
35 36 37
    kSize
  };

38 39 40 41
  explicit FunctionEntry(Vector<unsigned> backing)
    : backing_(backing) { }

  FunctionEntry() : backing_() { }
42

43 44 45 46
  int start_pos() { return backing_[kStartPositionIndex]; }
  int end_pos() { return backing_[kEndPositionIndex]; }
  int literal_count() { return backing_[kLiteralCountIndex]; }
  int property_count() { return backing_[kPropertyCountIndex]; }
47
  StrictMode strict_mode() {
48
    DCHECK(backing_[kStrictModeIndex] == SLOPPY ||
49 50
           backing_[kStrictModeIndex] == STRICT);
    return static_cast<StrictMode>(backing_[kStrictModeIndex]);
51
  }
52

53
  bool is_valid() { return !backing_.is_empty(); }
54 55 56 57 58 59

 private:
  Vector<unsigned> backing_;
};


60 61
// Wrapper around ScriptData to provide parser-specific functionality.
class ParseData {
62
 public:
63 64 65 66 67 68
  static ParseData* FromCachedData(ScriptData* cached_data) {
    ParseData* pd = new ParseData(cached_data);
    if (pd->IsSane()) return pd;
    cached_data->Reject();
    delete pd;
    return NULL;
69
  }
70

71
  void Initialize();
72
  FunctionEntry GetFunctionEntry(int start);
73 74 75 76 77 78
  int FunctionCount();

  bool HasError();

  unsigned* Data() {  // Writable data as unsigned int array.
    return reinterpret_cast<unsigned*>(const_cast<byte*>(script_data_->data()));
79
  }
80

81 82 83 84
  void Reject() { script_data_->Reject(); }

  bool rejected() const { return script_data_->rejected(); }

85
 private:
86 87
  explicit ParseData(ScriptData* script_data) : script_data_(script_data) {}

88 89 90 91 92 93 94 95
  bool IsSane();
  unsigned Magic();
  unsigned Version();
  int FunctionsSize();
  int Length() const {
    // Script data length is already checked to be a multiple of unsigned size.
    return script_data_->length() / sizeof(unsigned);
  }
96

97 98
  ScriptData* script_data_;
  int function_index_;
99

100
  DISALLOW_COPY_AND_ASSIGN(ParseData);
101 102
};

103 104
// ----------------------------------------------------------------------------
// REGEXP PARSING
105

106
// A BufferedZoneList is an automatically growing list, just like (and backed
107 108 109 110 111 112 113 114 115 116 117 118 119
// by) a ZoneList, that is optimized for the case of adding and removing
// a single element. The last element added is stored outside the backing list,
// and if no more than one element is ever added, the ZoneList isn't even
// allocated.
// Elements must not be NULL pointers.
template <typename T, int initial_size>
class BufferedZoneList {
 public:
  BufferedZoneList() : list_(NULL), last_(NULL) {}

  // Adds element at end of list. This element is buffered and can
  // be read using last() or removed using RemoveLast until a new Add or until
  // RemoveLast or GetList has been called.
120
  void Add(T* value, Zone* zone) {
121 122
    if (last_ != NULL) {
      if (list_ == NULL) {
123
        list_ = new(zone) ZoneList<T*>(initial_size, zone);
124
      }
125
      list_->Add(last_, zone);
126 127 128 129 130
    }
    last_ = value;
  }

  T* last() {
131
    DCHECK(last_ != NULL);
132 133 134 135
    return last_;
  }

  T* RemoveLast() {
136
    DCHECK(last_ != NULL);
137 138 139 140 141 142 143 144 145
    T* result = last_;
    if ((list_ != NULL) && (list_->length() > 0))
      last_ = list_->RemoveLast();
    else
      last_ = NULL;
    return result;
  }

  T* Get(int i) {
146
    DCHECK((0 <= i) && (i < length()));
147
    if (list_ == NULL) {
148
      DCHECK_EQ(0, i);
149 150 151
      return last_;
    } else {
      if (i == list_->length()) {
152
        DCHECK(last_ != NULL);
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
        return last_;
      } else {
        return list_->at(i);
      }
    }
  }

  void Clear() {
    list_ = NULL;
    last_ = NULL;
  }

  int length() {
    int length = (list_ == NULL) ? 0 : list_->length();
    return length + ((last_ == NULL) ? 0 : 1);
  }

170
  ZoneList<T*>* GetList(Zone* zone) {
171
    if (list_ == NULL) {
172
      list_ = new(zone) ZoneList<T*>(initial_size, zone);
173 174
    }
    if (last_ != NULL) {
175
      list_->Add(last_, zone);
176 177 178 179 180 181 182 183 184 185 186 187 188 189
      last_ = NULL;
    }
    return list_;
  }

 private:
  ZoneList<T*>* list_;
  T* last_;
};


// Accumulates RegExp atoms and assertions into lists of terms and alternatives.
class RegExpBuilder: public ZoneObject {
 public:
190
  explicit RegExpBuilder(Zone* zone);
191 192 193 194 195 196 197
  void AddCharacter(uc16 character);
  // "Adds" an empty expression. Does nothing except consume a
  // following quantifier
  void AddEmpty();
  void AddAtom(RegExpTree* tree);
  void AddAssertion(RegExpTree* tree);
  void NewAlternative();  // '|'
198 199
  void AddQuantifierToAtom(
      int min, int max, RegExpQuantifier::QuantifierType type);
200 201 202 203 204 205
  RegExpTree* ToRegExp();

 private:
  void FlushCharacters();
  void FlushText();
  void FlushTerms();
206
  Zone* zone() const { return zone_; }
207 208

  Zone* zone_;
209 210 211 212 213 214 215 216 217 218 219 220 221 222
  bool pending_empty_;
  ZoneList<uc16>* characters_;
  BufferedZoneList<RegExpTree, 2> terms_;
  BufferedZoneList<RegExpTree, 2> text_;
  BufferedZoneList<RegExpTree, 2> alternatives_;
#ifdef DEBUG
  enum {ADD_NONE, ADD_CHAR, ADD_TERM, ADD_ASSERT, ADD_ATOM} last_added_;
#define LAST(x) last_added_ = x;
#else
#define LAST(x)
#endif
};


223
class RegExpParser BASE_EMBEDDED {
224 225 226
 public:
  RegExpParser(FlatStringReader* in,
               Handle<String>* error,
227 228
               bool multiline_mode,
               Zone* zone);
229 230 231

  static bool ParseRegExp(FlatStringReader* input,
                          bool multiline,
232 233
                          RegExpCompileData* result,
                          Zone* zone);
234

235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
  RegExpTree* ParsePattern();
  RegExpTree* ParseDisjunction();
  RegExpTree* ParseGroup();
  RegExpTree* ParseCharacterClass();

  // Parses a {...,...} quantifier and stores the range in the given
  // out parameters.
  bool ParseIntervalQuantifier(int* min_out, int* max_out);

  // Parses and returns a single escaped character.  The character
  // must not be 'b' or 'B' since they are usually handle specially.
  uc32 ParseClassCharacterEscape();

  // Checks whether the following is a length-digit hexadecimal number,
  // and sets the value if it is.
  bool ParseHexEscape(int length, uc32* value);

  uc32 ParseOctalLiteral();

  // Tries to parse the input as a back reference.  If successful it
  // stores the result in the output parameter and returns true.  If
  // it fails it will push back the characters read so the same characters
  // can be reparsed.
  bool ParseBackReferenceIndex(int* index_out);

  CharacterRange ParseClassAtom(uc16* char_class);
  RegExpTree* ReportError(Vector<const char> message);
  void Advance();
  void Advance(int dist);
  void Reset(int pos);

  // Reports whether the pattern might be used as a literal search string.
  // Only use if the result of the parse is a single atom node.
  bool simple();
  bool contains_anchor() { return contains_anchor_; }
  void set_contains_anchor() { contains_anchor_ = true; }
  int captures_started() { return captures_ == NULL ? 0 : captures_->length(); }
  int position() { return next_pos_ - 1; }
  bool failed() { return failed_; }

  static const int kMaxCaptures = 1 << 16;
  static const uc32 kEndMarker = (1 << 21);

 private:
  enum SubexpressionType {
    INITIAL,
    CAPTURE,  // All positive values represent captures.
    POSITIVE_LOOKAHEAD,
    NEGATIVE_LOOKAHEAD,
    GROUPING
  };

  class RegExpParserState : public ZoneObject {
   public:
    RegExpParserState(RegExpParserState* previous_state,
                      SubexpressionType group_type,
291 292
                      int disjunction_capture_index,
                      Zone* zone)
293
        : previous_state_(previous_state),
294
          builder_(new(zone) RegExpBuilder(zone)),
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
          group_type_(group_type),
          disjunction_capture_index_(disjunction_capture_index) {}
    // Parser state of containing expression, if any.
    RegExpParserState* previous_state() { return previous_state_; }
    bool IsSubexpression() { return previous_state_ != NULL; }
    // RegExpBuilder building this regexp's AST.
    RegExpBuilder* builder() { return builder_; }
    // Type of regexp being parsed (parenthesized group or entire regexp).
    SubexpressionType group_type() { return group_type_; }
    // Index in captures array of first capture in this sub-expression, if any.
    // Also the capture index of this sub-expression itself, if group_type
    // is CAPTURE.
    int capture_index() { return disjunction_capture_index_; }

   private:
    // Linked list implementation of stack of states.
    RegExpParserState* previous_state_;
    // Builder for the stored disjunction.
    RegExpBuilder* builder_;
    // Stored disjunction type (capture, look-ahead or grouping), if any.
    SubexpressionType group_type_;
    // Stored disjunction's capture index (if any).
    int disjunction_capture_index_;
  };

320
  Isolate* isolate() { return isolate_; }
321
  Zone* zone() const { return zone_; }
322

323 324 325 326 327 328
  uc32 current() { return current_; }
  bool has_more() { return has_more_; }
  bool has_next() { return next_pos_ < in()->length(); }
  uc32 Next();
  FlatStringReader* in() { return in_; }
  void ScanForCaptures();
329

330
  Isolate* isolate_;
331
  Zone* zone_;
332 333 334
  Handle<String>* error_;
  ZoneList<RegExpCapture*>* captures_;
  FlatStringReader* in_;
335
  uc32 current_;
336 337 338
  int next_pos_;
  // The capture count is only valid after we have scanned for captures.
  int capture_count_;
339 340 341 342 343 344 345 346
  bool has_more_;
  bool multiline_;
  bool simple_;
  bool contains_anchor_;
  bool is_scanned_for_captures_;
  bool failed_;
};

347 348
// ----------------------------------------------------------------------------
// JAVASCRIPT PARSING
349

350
class Parser;
351 352
class SingletonLogger;

353 354
class ParserTraits {
 public:
355
  struct Type {
356 357
    // TODO(marja): To be removed. The Traits object should contain all the data
    // it needs.
358 359
    typedef v8::internal::Parser* Parser;

360
    // Used by FunctionState and BlockState.
361
    typedef v8::internal::Scope Scope;
362
    typedef v8::internal::Scope* ScopePtr;
363 364
    inline static Scope* ptr_to_scope(ScopePtr scope) { return scope; }

365 366 367
    typedef Variable GeneratorVariable;
    typedef v8::internal::Zone Zone;

368 369 370
    typedef v8::internal::AstProperties AstProperties;
    typedef Vector<VariableProxy*> ParameterIdentifierVector;

371
    // Return types for traversing functions.
372
    typedef const AstRawString* Identifier;
373
    typedef v8::internal::Expression* Expression;
374
    typedef Yield* YieldExpression;
375
    typedef v8::internal::FunctionLiteral* FunctionLiteral;
arv@chromium.org's avatar
arv@chromium.org committed
376
    typedef v8::internal::ClassLiteral* ClassLiteral;
377 378
    typedef v8::internal::Literal* Literal;
    typedef ObjectLiteral::Property* ObjectLiteralProperty;
379
    typedef ZoneList<v8::internal::Expression*>* ExpressionList;
380
    typedef ZoneList<ObjectLiteral::Property*>* PropertyList;
381
    typedef ZoneList<v8::internal::Statement*>* StatementList;
382 383

    // For constructing objects returned by the traversing functions.
384
    typedef AstNodeFactory Factory;
385
  };
386 387 388 389

  explicit ParserTraits(Parser* parser) : parser_(parser) {}

  // Helper functions for recursive descent.
390
  bool IsEvalOrArguments(const AstRawString* identifier) const;
391
  V8_INLINE bool IsFutureStrictReserved(const AstRawString* identifier) const;
392

393 394 395
  // Returns true if the expression is of type "this.foo".
  static bool IsThisProperty(Expression* expression);

396 397
  static bool IsIdentifier(Expression* expression);

arv@chromium.org's avatar
arv@chromium.org committed
398 399 400 401
  bool IsPrototype(const AstRawString* identifier) const;

  bool IsConstructor(const AstRawString* identifier) const;

402
  static const AstRawString* AsIdentifier(Expression* expression) {
403
    DCHECK(IsIdentifier(expression));
404
    return expression->AsVariableProxy()->raw_name();
405 406
  }

407 408 409 410
  static bool IsBoilerplateProperty(ObjectLiteral::Property* property) {
    return ObjectLiteral::IsBoilerplateProperty(property);
  }

411 412
  static bool IsArrayIndex(const AstRawString* string, uint32_t* index) {
    return string->AsArrayIndex(index);
413 414
  }

415 416 417 418 419
  bool IsConstructorProperty(ObjectLiteral::Property* property) {
    return property->key()->raw_value()->EqualsString(
        ast_value_factory()->constructor_string());
  }

420 421 422 423
  static Expression* GetPropertyValue(ObjectLiteral::Property* property) {
    return property->value();
  }

424 425
  // Functions for encapsulating the differences between parsing and preparsing;
  // operations interleaved with the recursive descent.
426
  static void PushLiteralName(FuncNameInferrer* fni, const AstRawString* id) {
427 428
    fni->PushLiteralName(id);
  }
429
  void PushPropertyName(FuncNameInferrer* fni, Expression* expression);
430 431 432 433
  static void InferFunctionName(FuncNameInferrer* fni,
                                FunctionLiteral* func_to_infer) {
    fni->AddFunction(func_to_infer);
  }
434 435

  static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
436 437
      Scope* scope, ObjectLiteralProperty* property, bool* has_function) {
    Expression* value = property->value();
438
    if (scope->DeclarationScope()->is_script_scope() &&
439 440 441 442 443 444
        value->AsFunctionLiteral() != NULL) {
      *has_function = true;
      value->AsFunctionLiteral()->set_pretenure();
    }
  }

445 446 447 448 449
  // If we assign a function literal to a property we pretenure the
  // literal so it can be added as a constant function property.
  static void CheckAssigningFunctionLiteralToProperty(Expression* left,
                                                      Expression* right);

450 451 452 453 454
  // Keep track of eval() calls since they disable all local variable
  // optimizations. This checks if expression is an eval call, and if yes,
  // forwards the information to scope.
  void CheckPossibleEvalCall(Expression* expression, Scope* scope);

455
  // Determine if the expression is a variable proxy and mark it as being used
456 457
  // in an assignment or with a increment/decrement operator.
  static Expression* MarkExpressionAsAssigned(Expression* expression);
458

459 460 461
  // Returns true if we have a binary expression between two numeric
  // literals. In that case, *x will be changed to an expression which is the
  // computed value.
462 463 464
  bool ShortcutNumericLiteralBinaryExpression(Expression** x, Expression* y,
                                              Token::Value op, int pos,
                                              AstNodeFactory* factory);
465

466 467 468 469 470 471 472 473 474 475 476
  // Rewrites the following types of unary expressions:
  // not <literal> -> true / false
  // + <numeric literal> -> <numeric literal>
  // - <numeric literal> -> <numeric literal with value negated>
  // ! <literal> -> true / false
  // The following rewriting rules enable the collection of type feedback
  // without any special stub and the multiplication is removed later in
  // Crankshaft's canonicalization pass.
  // + foo -> foo * 1
  // - foo -> foo * (-1)
  // ~ foo -> foo ^(~0)
477 478
  Expression* BuildUnaryExpression(Expression* expression, Token::Value op,
                                   int pos, AstNodeFactory* factory);
479

480 481 482 483 484 485 486
  // Generate AST node that throws a ReferenceError with the given type.
  Expression* NewThrowReferenceError(const char* type, int pos);

  // Generate AST node that throws a SyntaxError with the given
  // type. The first argument may be null (in the handle sense) in
  // which case no arguments are passed to the constructor.
  Expression* NewThrowSyntaxError(
487
      const char* type, const AstRawString* arg, int pos);
488 489 490

  // Generate AST node that throws a TypeError with the given
  // type. Both arguments must be non-null (in the handle sense).
491 492
  Expression* NewThrowTypeError(const char* type, const AstRawString* arg,
                                int pos);
493 494 495

  // Generic AST generator for throwing errors from compiled code.
  Expression* NewThrowError(
496 497
      const AstRawString* constructor, const char* type,
      const AstRawString* arg, int pos);
498

499 500 501
  // Reporting errors.
  void ReportMessageAt(Scanner::Location source_location,
                       const char* message,
502
                       const char* arg = NULL,
503 504
                       bool is_reference_error = false);
  void ReportMessage(const char* message,
505 506 507 508
                     const char* arg = NULL,
                     bool is_reference_error = false);
  void ReportMessage(const char* message,
                     const AstRawString* arg,
509
                     bool is_reference_error = false);
510 511
  void ReportMessageAt(Scanner::Location source_location,
                       const char* message,
512
                       const AstRawString* arg,
513
                       bool is_reference_error = false);
514

515
  // "null" return type creators.
516 517
  static const AstRawString* EmptyIdentifier() {
    return NULL;
518
  }
519
  static Expression* EmptyExpression() {
520 521
    return NULL;
  }
522
  static Expression* EmptyArrowParamList() { return NULL; }
523 524 525
  static Literal* EmptyLiteral() {
    return NULL;
  }
526
  static ObjectLiteralProperty* EmptyObjectLiteralProperty() { return NULL; }
arv@chromium.org's avatar
arv@chromium.org committed
527
  static FunctionLiteral* EmptyFunctionLiteral() { return NULL; }
528

529
  // Used in error return values.
530 531 532
  static ZoneList<Expression*>* NullExpressionList() {
    return NULL;
  }
533

534 535 536
  // Non-NULL empty string.
  V8_INLINE const AstRawString* EmptyIdentifierString();

537
  // Odd-ball literal creators.
538
  Literal* GetLiteralTheHole(int position, AstNodeFactory* factory);
539

540
  // Producing data during the recursive descent.
541 542
  const AstRawString* GetSymbol(Scanner* scanner);
  const AstRawString* GetNextSymbol(Scanner* scanner);
543
  const AstRawString* GetNumberAsSymbol(Scanner* scanner);
544

545
  Expression* ThisExpression(Scope* scope, AstNodeFactory* factory,
546
                             int pos = RelocInfo::kNoPosition);
547
  Expression* SuperReference(Scope* scope, AstNodeFactory* factory,
548
                             int pos = RelocInfo::kNoPosition);
549 550
  Expression* DefaultConstructor(bool call_super, Scope* scope, int pos,
                                 int end_pos);
551 552 553 554 555 556 557
  Literal* ExpressionFromLiteral(Token::Value token, int pos, Scanner* scanner,
                                 AstNodeFactory* factory);
  Expression* ExpressionFromIdentifier(const AstRawString* name, int pos,
                                       Scope* scope, AstNodeFactory* factory);
  Expression* ExpressionFromString(int pos, Scanner* scanner,
                                   AstNodeFactory* factory);
  Expression* GetIterator(Expression* iterable, AstNodeFactory* factory);
558 559 560
  ZoneList<v8::internal::Expression*>* NewExpressionList(int size, Zone* zone) {
    return new(zone) ZoneList<v8::internal::Expression*>(size, zone);
  }
561 562 563
  ZoneList<ObjectLiteral::Property*>* NewPropertyList(int size, Zone* zone) {
    return new(zone) ZoneList<ObjectLiteral::Property*>(size, zone);
  }
564 565 566
  ZoneList<v8::internal::Statement*>* NewStatementList(int size, Zone* zone) {
    return new(zone) ZoneList<v8::internal::Statement*>(size, zone);
  }
567 568 569 570 571 572 573
  V8_INLINE Scope* NewScope(Scope* parent_scope, ScopeType scope_type);

  // Utility functions
  int DeclareArrowParametersFromExpression(Expression* expression, Scope* scope,
                                           Scanner::Location* dupe_loc,
                                           bool* ok);
  V8_INLINE AstValueFactory* ast_value_factory();
574 575 576

  // Temporary glue; these functions will move to ParserBase.
  Expression* ParseV8Intrinsic(bool* ok);
577
  FunctionLiteral* ParseFunctionLiteral(
578 579 580 581
      const AstRawString* name, Scanner::Location function_name_location,
      bool name_is_strict_reserved, FunctionKind kind,
      int function_token_position, FunctionLiteral::FunctionType type,
      FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
582 583 584 585 586 587
  V8_INLINE void SkipLazyFunctionBody(const AstRawString* name,
                                      int* materialized_literal_count,
                                      int* expected_property_count, bool* ok);
  V8_INLINE ZoneList<Statement*>* ParseEagerFunctionBody(
      const AstRawString* name, int pos, Variable* fvar,
      Token::Value fvar_init_op, bool is_generator, bool* ok);
588 589 590 591 592 593

  ClassLiteral* ParseClassLiteral(const AstRawString* name,
                                  Scanner::Location class_name_location,
                                  bool name_is_strict_reserved, int pos,
                                  bool* ok);

594 595
  V8_INLINE void CheckConflictingVarDeclarations(v8::internal::Scope* scope,
                                                 bool* ok);
596

597 598 599
  class TemplateLiteral : public ZoneObject {
   public:
    TemplateLiteral(Zone* zone, int pos)
600
        : cooked_(8, zone), raw_(8, zone), expressions_(8, zone), pos_(pos) {}
601 602

    const ZoneList<Expression*>* cooked() const { return &cooked_; }
603
    const ZoneList<Expression*>* raw() const { return &raw_; }
604 605 606
    const ZoneList<Expression*>* expressions() const { return &expressions_; }
    int position() const { return pos_; }

607
    void AddTemplateSpan(Literal* cooked, Literal* raw, int end, Zone* zone) {
608
      DCHECK_NOT_NULL(cooked);
609
      DCHECK_NOT_NULL(raw);
610
      cooked_.Add(cooked, zone);
611
      raw_.Add(raw, zone);
612 613 614 615 616 617 618 619 620
    }

    void AddExpression(Expression* expression, Zone* zone) {
      DCHECK_NOT_NULL(expression);
      expressions_.Add(expression, zone);
    }

   private:
    ZoneList<Expression*> cooked_;
621
    ZoneList<Expression*> raw_;
622 623 624 625 626 627 628 629 630 631 632 633 634
    ZoneList<Expression*> expressions_;
    int pos_;
  };

  typedef TemplateLiteral* TemplateLiteralState;

  V8_INLINE TemplateLiteralState OpenTemplateLiteral(int pos);
  V8_INLINE void AddTemplateSpan(TemplateLiteralState* state, bool tail);
  V8_INLINE void AddTemplateExpression(TemplateLiteralState* state,
                                       Expression* expression);
  V8_INLINE Expression* CloseTemplateLiteral(TemplateLiteralState* state,
                                             int start, Expression* tag);
  V8_INLINE Expression* NoTemplateTag() { return NULL; }
635 636 637
  V8_INLINE static bool IsTaggedTemplate(const Expression* tag) {
    return tag != NULL;
  }
638

639 640 641 642 643 644
 private:
  Parser* parser_;
};


class Parser : public ParserBase<ParserTraits> {
645
 public:
646 647 648 649 650 651 652 653 654 655
  // Note that the hash seed in ParseInfo must be the hash seed from the
  // Isolate's heap, otherwise the heap will be in an inconsistent state once
  // the strings created by the Parser are internalized.
  struct ParseInfo {
    uintptr_t stack_limit;
    uint32_t hash_seed;
    UnicodeCache* unicode_cache;
  };

  Parser(CompilationInfo* info, ParseInfo* parse_info);
656
  ~Parser() {
657 658
    delete reusable_preparser_;
    reusable_preparser_ = NULL;
659 660
    delete cached_parse_data_;
    cached_parse_data_ = NULL;
661
  }
662

663 664 665
  // Parses the source code represented by the compilation info and sets its
  // function literal.  Returns false (and deallocates any allocated AST
  // nodes) if parsing failed.
666 667
  static bool Parse(CompilationInfo* info,
                    bool allow_lazy = false) {
668 669 670 671
    ParseInfo parse_info = {info->isolate()->stack_guard()->real_climit(),
                            info->isolate()->heap()->HashSeed(),
                            info->isolate()->unicode_cache()};
    Parser parser(info, &parse_info);
672
    parser.set_allow_lazy(allow_lazy);
673 674 675 676 677
    if (parser.Parse()) {
      info->SetStrictMode(info->function()->strict_mode());
      return true;
    }
    return false;
678
  }
679
  bool Parse();
680 681 682 683 684
  void ParseOnBackground();

  // Handle errors detected during parsing, move statistics to Isolate,
  // internalize strings (move them to the heap).
  void Internalize();
685

686
 private:
687 688
  friend class ParserTraits;

689 690 691 692 693 694 695 696
  // Limit the allowed number of local variables in a function. The hard limit
  // is that offsets computed by FullCodeGenerator::StackOperand and similar
  // functions are ints, and they should not overflow. In addition, accessing
  // local variables creates user-controlled constants in the generated code,
  // and we don't want too much user-controlled memory inside the code (this was
  // the reason why this limit was introduced in the first place; see
  // https://codereview.chromium.org/7003030/ ).
  static const int kMaxNumFunctionLocals = 4194303;  // 2^22-1
697

698
  enum VariableDeclarationContext {
699 700
    kModuleElement,
    kBlockElement,
701 702 703 704
    kStatement,
    kForStatement
  };

705 706 707 708 709 710
  // If a list of variable declarations includes any initializers.
  enum VariableDeclarationProperties {
    kHasInitializers,
    kHasNoInitializers
  };

711 712 713
  // Returns NULL if parsing failed.
  FunctionLiteral* ParseProgram();

714
  FunctionLiteral* ParseLazy();
715
  FunctionLiteral* ParseLazy(Utf16CharacterStream* source);
716

717
  Isolate* isolate() { return info_->isolate(); }
718
  CompilationInfo* info() const { return info_; }
719 720 721 722
  Handle<Script> script() const { return info_->script(); }
  AstValueFactory* ast_value_factory() const {
    return info_->ast_value_factory();
  }
723

724
  // Called by ParseProgram after setting up the scanner.
725 726
  FunctionLiteral* DoParseProgram(CompilationInfo* info, Scope** scope,
                                  Scope** ad_hoc_eval_scope);
727

728
  void SetCachedData();
729

730
  bool inside_with() const { return scope_->inside_with(); }
731 732 733
  ScriptCompiler::CompileOptions compile_options() const {
    return info_->compile_options();
  }
734 735 736 737 738 739 740
  bool consume_cached_parse_data() const {
    return compile_options() == ScriptCompiler::kConsumeParserCache &&
           cached_parse_data_ != NULL;
  }
  bool produce_cached_parse_data() const {
    return compile_options() == ScriptCompiler::kProduceParserCache;
  }
741
  Scope* DeclarationScope(VariableMode mode) {
742
    return IsLexicalVariableMode(mode)
743
        ? scope_ : scope_->DeclarationScope();
744
  }
745 746 747 748 749

  // All ParseXXX functions take as the last argument an *ok parameter
  // which is set to false if parsing failed; it is unchanged otherwise.
  // By making the 'exception handling' explicit, we are forced to check
  // for failure at the call sites.
750
  void* ParseSourceElements(ZoneList<Statement*>* processor, int end_token,
751 752
                            bool is_eval, bool is_global,
                            Scope** ad_hoc_eval_scope, bool* ok);
753 754 755 756
  Statement* ParseModuleElement(ZoneList<const AstRawString*>* labels,
                                bool* ok);
  Statement* ParseModuleDeclaration(ZoneList<const AstRawString*>* names,
                                    bool* ok);
757 758 759 760 761
  Module* ParseModule(bool* ok);
  Module* ParseModuleLiteral(bool* ok);
  Module* ParseModulePath(bool* ok);
  Module* ParseModuleVariable(bool* ok);
  Module* ParseModuleUrl(bool* ok);
762
  Module* ParseModuleSpecifier(bool* ok);
763
  Block* ParseImportDeclaration(bool* ok);
764
  Statement* ParseExportDeclaration(bool* ok);
765 766 767 768
  Statement* ParseBlockElement(ZoneList<const AstRawString*>* labels, bool* ok);
  Statement* ParseStatement(ZoneList<const AstRawString*>* labels, bool* ok);
  Statement* ParseFunctionDeclaration(ZoneList<const AstRawString*>* names,
                                      bool* ok);
arv@chromium.org's avatar
arv@chromium.org committed
769 770
  Statement* ParseClassDeclaration(ZoneList<const AstRawString*>* names,
                                   bool* ok);
771
  Statement* ParseNativeDeclaration(bool* ok);
772
  Block* ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok);
773
  Block* ParseVariableStatement(VariableDeclarationContext var_context,
774
                                ZoneList<const AstRawString*>* names,
775 776
                                bool* ok);
  Block* ParseVariableDeclarations(VariableDeclarationContext var_context,
777
                                   VariableDeclarationProperties* decl_props,
778 779
                                   ZoneList<const AstRawString*>* names,
                                   const AstRawString** out,
780
                                   bool* ok);
781 782 783 784
  Statement* ParseExpressionOrLabelledStatement(
      ZoneList<const AstRawString*>* labels, bool* ok);
  IfStatement* ParseIfStatement(ZoneList<const AstRawString*>* labels,
                                bool* ok);
785
  Statement* ParseContinueStatement(bool* ok);
786 787
  Statement* ParseBreakStatement(ZoneList<const AstRawString*>* labels,
                                 bool* ok);
788
  Statement* ParseReturnStatement(bool* ok);
789 790
  Statement* ParseWithStatement(ZoneList<const AstRawString*>* labels,
                                bool* ok);
791
  CaseClause* ParseCaseClause(bool* default_seen_ptr, bool* ok);
792 793 794 795 796 797 798
  SwitchStatement* ParseSwitchStatement(ZoneList<const AstRawString*>* labels,
                                        bool* ok);
  DoWhileStatement* ParseDoWhileStatement(ZoneList<const AstRawString*>* labels,
                                          bool* ok);
  WhileStatement* ParseWhileStatement(ZoneList<const AstRawString*>* labels,
                                      bool* ok);
  Statement* ParseForStatement(ZoneList<const AstRawString*>* labels, bool* ok);
799 800 801 802
  Statement* ParseThrowStatement(bool* ok);
  Expression* MakeCatchContext(Handle<String> id, VariableProxy* value);
  TryStatement* ParseTryStatement(bool* ok);
  DebuggerStatement* ParseDebuggerStatement(bool* ok);
803 804

  // Support for hamony block scoped bindings.
805
  Block* ParseScopedBlock(ZoneList<const AstRawString*>* labels, bool* ok);
806

807 808 809 810 811
  // Initialize the components of a for-in / for-of statement.
  void InitializeForEachStatement(ForEachStatement* stmt,
                                  Expression* each,
                                  Expression* subject,
                                  Statement* body);
812
  Statement* DesugarLetBindingsInForStatement(
813 814 815
      Scope* inner_scope, ZoneList<const AstRawString*>* names,
      ForStatement* loop, Statement* init, Expression* cond, Statement* next,
      Statement* body, bool* ok);
816

817
  FunctionLiteral* ParseFunctionLiteral(
818 819 820 821
      const AstRawString* name, Scanner::Location function_name_location,
      bool name_is_strict_reserved, FunctionKind kind,
      int function_token_position, FunctionLiteral::FunctionType type,
      FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
822

823 824 825 826 827 828

  ClassLiteral* ParseClassLiteral(const AstRawString* name,
                                  Scanner::Location class_name_location,
                                  bool name_is_strict_reserved, int pos,
                                  bool* ok);

829 830 831
  // Magical syntax support.
  Expression* ParseV8Intrinsic(bool* ok);

832
  bool CheckInOrOf(bool accept_OF, ForEachStatement::VisitMode* visit_mode);
833

834
  // Get odd-ball literals.
835
  Literal* GetLiteralUndefined(int position);
836

837 838 839 840 841 842 843 844 845 846 847
  // For harmony block scoping mode: Check if the scope has conflicting var/let
  // declarations from different scopes. It covers for example
  //
  // function f() { { { var x; } let x; } }
  // function g() { { var x; let x; } }
  //
  // The var declarations are hoisted to the function scope, but originate from
  // a scope where the name has also been let bound or the var declaration is
  // hoisted over such a scope.
  void CheckConflictingVarDeclarations(Scope* scope, bool* ok);

848
  // Parser support
849
  VariableProxy* NewUnresolved(const AstRawString* name,
850
                               VariableMode mode,
851
                               Interface* interface);
852
  void Declare(Declaration* declaration, bool resolve, bool* ok);
853

854 855 856
  bool TargetStackContainsLabel(const AstRawString* label);
  BreakableStatement* LookupBreakTarget(const AstRawString* label, bool* ok);
  IterationStatement* LookupContinueTarget(const AstRawString* label, bool* ok);
857

858
  void RegisterTargetUse(Label* target, Target* stop);
859

860 861
  // Factory methods.

862
  Scope* NewScope(Scope* parent, ScopeType type);
863

864 865 866
  FunctionLiteral* DefaultConstructor(bool call_super, Scope* scope, int pos,
                                      int end_pos);

867 868
  // Skip over a lazy function, either using cached data if we have it, or
  // by parsing the function with PreParser. Consumes the ending }.
869
  void SkipLazyFunctionBody(const AstRawString* function_name,
870 871 872 873 874 875 876 877
                            int* materialized_literal_count,
                            int* expected_property_count,
                            bool* ok);

  PreParser::PreParseResult ParseLazyFunctionBodyWithPreParser(
      SingletonLogger* logger);

  // Consumes the ending }.
878 879 880
  ZoneList<Statement*>* ParseEagerFunctionBody(
      const AstRawString* function_name, int pos, Variable* fvar,
      Token::Value fvar_init_op, bool is_generator, bool* ok);
881

882 883
  void HandleSourceURLComments();

884 885
  void ThrowPendingError();

886 887 888 889 890 891
  TemplateLiteralState OpenTemplateLiteral(int pos);
  void AddTemplateSpan(TemplateLiteralState* state, bool tail);
  void AddTemplateExpression(TemplateLiteralState* state,
                             Expression* expression);
  Expression* CloseTemplateLiteral(TemplateLiteralState* state, int start,
                                   Expression* tag);
892 893
  uint32_t ComputeTemplateLiteralHash(const TemplateLiteral* lit);

894
  Scanner scanner_;
895
  PreParser* reusable_preparser_;
896
  Scope* original_scope_;  // for ES5 function declarations in sloppy eval
897
  Target* target_stack_;  // for break, continue statements
898
  ParseData* cached_parse_data_;
899

900
  CompilationInfo* info_;
901 902 903 904 905

  // Pending errors.
  bool has_pending_error_;
  Scanner::Location pending_error_location_;
  const char* pending_error_message_;
906
  const AstRawString* pending_error_arg_;
907 908
  const char* pending_error_char_arg_;
  bool pending_error_is_reference_error_;
909

910 911
  // Other information which will be stored in Parser and moved to Isolate after
  // parsing.
912
  int use_counts_[v8::Isolate::kUseCounterFeatureCount];
913 914
  int total_preparse_skipped_;
  HistogramTimer* pre_parse_timer_;
915
};
916

917

918 919
bool ParserTraits::IsFutureStrictReserved(
    const AstRawString* identifier) const {
920
  return parser_->scanner()->IdentifierIsFutureStrictReserved(identifier);
921 922 923 924 925 926 927 928 929
}


Scope* ParserTraits::NewScope(Scope* parent_scope, ScopeType scope_type) {
  return parser_->NewScope(parent_scope, scope_type);
}


const AstRawString* ParserTraits::EmptyIdentifierString() {
930
  return parser_->ast_value_factory()->empty_string();
931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956
}


void ParserTraits::SkipLazyFunctionBody(const AstRawString* function_name,
                                        int* materialized_literal_count,
                                        int* expected_property_count,
                                        bool* ok) {
  return parser_->SkipLazyFunctionBody(
      function_name, materialized_literal_count, expected_property_count, ok);
}


ZoneList<Statement*>* ParserTraits::ParseEagerFunctionBody(
    const AstRawString* name, int pos, Variable* fvar,
    Token::Value fvar_init_op, bool is_generator, bool* ok) {
  return parser_->ParseEagerFunctionBody(name, pos, fvar, fvar_init_op,
                                         is_generator, ok);
}

void ParserTraits::CheckConflictingVarDeclarations(v8::internal::Scope* scope,
                                                   bool* ok) {
  parser_->CheckConflictingVarDeclarations(scope, ok);
}


AstValueFactory* ParserTraits::ast_value_factory() {
957
  return parser_->ast_value_factory();
958 959 960
}


961 962 963 964
// Support for handling complex values (array and object literals) that
// can be fully handled at compile time.
class CompileTimeValue: public AllStatic {
 public:
965
  enum LiteralType {
966 967
    OBJECT_LITERAL_FAST_ELEMENTS,
    OBJECT_LITERAL_SLOW_ELEMENTS,
968 969 970 971 972 973
    ARRAY_LITERAL
  };

  static bool IsCompileTimeValue(Expression* expression);

  // Get the value as a compile time value.
974
  static Handle<FixedArray> GetValue(Isolate* isolate, Expression* expression);
975 976

  // Get the type of a compile time value returned by GetValue().
977
  static LiteralType GetLiteralType(Handle<FixedArray> value);
978 979 980 981 982

  // Get the elements array of a compile time value returned by GetValue().
  static Handle<FixedArray> GetElements(Handle<FixedArray> value);

 private:
983
  static const int kLiteralTypeSlot = 0;
984 985 986 987 988
  static const int kElementsSlot = 1;

  DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue);
};

989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009

ParserTraits::TemplateLiteralState ParserTraits::OpenTemplateLiteral(int pos) {
  return parser_->OpenTemplateLiteral(pos);
}


void ParserTraits::AddTemplateSpan(TemplateLiteralState* state, bool tail) {
  parser_->AddTemplateSpan(state, tail);
}


void ParserTraits::AddTemplateExpression(TemplateLiteralState* state,
                                         Expression* expression) {
  parser_->AddTemplateExpression(state, expression);
}


Expression* ParserTraits::CloseTemplateLiteral(TemplateLiteralState* state,
                                               int start, Expression* tag) {
  return parser_->CloseTemplateLiteral(state, start, tag);
}
1010 1011 1012
} }  // namespace v8::internal

#endif  // V8_PARSER_H_