Home | History | Annotate | Download | only in src
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef V8_PARSER_H_
      6 #define V8_PARSER_H_
      7 
      8 #include "src/allocation.h"
      9 #include "src/ast.h"
     10 #include "src/compiler.h"  // For CachedDataMode
     11 #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 class ScriptCompiler;
     18 
     19 namespace internal {
     20 
     21 class CompilationInfo;
     22 class ParserLog;
     23 class PositionStack;
     24 class Target;
     25 
     26 template <typename T> class ZoneListWrapper;
     27 
     28 
     29 class FunctionEntry BASE_EMBEDDED {
     30  public:
     31   enum {
     32     kStartPositionIndex,
     33     kEndPositionIndex,
     34     kLiteralCountIndex,
     35     kPropertyCountIndex,
     36     kStrictModeIndex,
     37     kSize
     38   };
     39 
     40   explicit FunctionEntry(Vector<unsigned> backing)
     41     : backing_(backing) { }
     42 
     43   FunctionEntry() : backing_() { }
     44 
     45   int start_pos() { return backing_[kStartPositionIndex]; }
     46   int end_pos() { return backing_[kEndPositionIndex]; }
     47   int literal_count() { return backing_[kLiteralCountIndex]; }
     48   int property_count() { return backing_[kPropertyCountIndex]; }
     49   StrictMode strict_mode() {
     50     DCHECK(backing_[kStrictModeIndex] == SLOPPY ||
     51            backing_[kStrictModeIndex] == STRICT);
     52     return static_cast<StrictMode>(backing_[kStrictModeIndex]);
     53   }
     54 
     55   bool is_valid() { return !backing_.is_empty(); }
     56 
     57  private:
     58   Vector<unsigned> backing_;
     59 };
     60 
     61 
     62 // Wrapper around ScriptData to provide parser-specific functionality.
     63 class ParseData {
     64  public:
     65   explicit ParseData(ScriptData* script_data) : script_data_(script_data) {
     66     CHECK(IsAligned(script_data->length(), sizeof(unsigned)));
     67     CHECK(IsSane());
     68   }
     69   void Initialize();
     70   FunctionEntry GetFunctionEntry(int start);
     71   int FunctionCount();
     72 
     73   bool HasError();
     74 
     75   unsigned* Data() {  // Writable data as unsigned int array.
     76     return reinterpret_cast<unsigned*>(const_cast<byte*>(script_data_->data()));
     77   }
     78 
     79  private:
     80   bool IsSane();
     81   unsigned Magic();
     82   unsigned Version();
     83   int FunctionsSize();
     84   int Length() const {
     85     // Script data length is already checked to be a multiple of unsigned size.
     86     return script_data_->length() / sizeof(unsigned);
     87   }
     88 
     89   ScriptData* script_data_;
     90   int function_index_;
     91 
     92   DISALLOW_COPY_AND_ASSIGN(ParseData);
     93 };
     94 
     95 // ----------------------------------------------------------------------------
     96 // REGEXP PARSING
     97 
     98 // A BufferedZoneList is an automatically growing list, just like (and backed
     99 // by) a ZoneList, that is optimized for the case of adding and removing
    100 // a single element. The last element added is stored outside the backing list,
    101 // and if no more than one element is ever added, the ZoneList isn't even
    102 // allocated.
    103 // Elements must not be NULL pointers.
    104 template <typename T, int initial_size>
    105 class BufferedZoneList {
    106  public:
    107   BufferedZoneList() : list_(NULL), last_(NULL) {}
    108 
    109   // Adds element at end of list. This element is buffered and can
    110   // be read using last() or removed using RemoveLast until a new Add or until
    111   // RemoveLast or GetList has been called.
    112   void Add(T* value, Zone* zone) {
    113     if (last_ != NULL) {
    114       if (list_ == NULL) {
    115         list_ = new(zone) ZoneList<T*>(initial_size, zone);
    116       }
    117       list_->Add(last_, zone);
    118     }
    119     last_ = value;
    120   }
    121 
    122   T* last() {
    123     DCHECK(last_ != NULL);
    124     return last_;
    125   }
    126 
    127   T* RemoveLast() {
    128     DCHECK(last_ != NULL);
    129     T* result = last_;
    130     if ((list_ != NULL) && (list_->length() > 0))
    131       last_ = list_->RemoveLast();
    132     else
    133       last_ = NULL;
    134     return result;
    135   }
    136 
    137   T* Get(int i) {
    138     DCHECK((0 <= i) && (i < length()));
    139     if (list_ == NULL) {
    140       DCHECK_EQ(0, i);
    141       return last_;
    142     } else {
    143       if (i == list_->length()) {
    144         DCHECK(last_ != NULL);
    145         return last_;
    146       } else {
    147         return list_->at(i);
    148       }
    149     }
    150   }
    151 
    152   void Clear() {
    153     list_ = NULL;
    154     last_ = NULL;
    155   }
    156 
    157   int length() {
    158     int length = (list_ == NULL) ? 0 : list_->length();
    159     return length + ((last_ == NULL) ? 0 : 1);
    160   }
    161 
    162   ZoneList<T*>* GetList(Zone* zone) {
    163     if (list_ == NULL) {
    164       list_ = new(zone) ZoneList<T*>(initial_size, zone);
    165     }
    166     if (last_ != NULL) {
    167       list_->Add(last_, zone);
    168       last_ = NULL;
    169     }
    170     return list_;
    171   }
    172 
    173  private:
    174   ZoneList<T*>* list_;
    175   T* last_;
    176 };
    177 
    178 
    179 // Accumulates RegExp atoms and assertions into lists of terms and alternatives.
    180 class RegExpBuilder: public ZoneObject {
    181  public:
    182   explicit RegExpBuilder(Zone* zone);
    183   void AddCharacter(uc16 character);
    184   // "Adds" an empty expression. Does nothing except consume a
    185   // following quantifier
    186   void AddEmpty();
    187   void AddAtom(RegExpTree* tree);
    188   void AddAssertion(RegExpTree* tree);
    189   void NewAlternative();  // '|'
    190   void AddQuantifierToAtom(
    191       int min, int max, RegExpQuantifier::QuantifierType type);
    192   RegExpTree* ToRegExp();
    193 
    194  private:
    195   void FlushCharacters();
    196   void FlushText();
    197   void FlushTerms();
    198   Zone* zone() const { return zone_; }
    199 
    200   Zone* zone_;
    201   bool pending_empty_;
    202   ZoneList<uc16>* characters_;
    203   BufferedZoneList<RegExpTree, 2> terms_;
    204   BufferedZoneList<RegExpTree, 2> text_;
    205   BufferedZoneList<RegExpTree, 2> alternatives_;
    206 #ifdef DEBUG
    207   enum {ADD_NONE, ADD_CHAR, ADD_TERM, ADD_ASSERT, ADD_ATOM} last_added_;
    208 #define LAST(x) last_added_ = x;
    209 #else
    210 #define LAST(x)
    211 #endif
    212 };
    213 
    214 
    215 class RegExpParser BASE_EMBEDDED {
    216  public:
    217   RegExpParser(FlatStringReader* in,
    218                Handle<String>* error,
    219                bool multiline_mode,
    220                Zone* zone);
    221 
    222   static bool ParseRegExp(FlatStringReader* input,
    223                           bool multiline,
    224                           RegExpCompileData* result,
    225                           Zone* zone);
    226 
    227   RegExpTree* ParsePattern();
    228   RegExpTree* ParseDisjunction();
    229   RegExpTree* ParseGroup();
    230   RegExpTree* ParseCharacterClass();
    231 
    232   // Parses a {...,...} quantifier and stores the range in the given
    233   // out parameters.
    234   bool ParseIntervalQuantifier(int* min_out, int* max_out);
    235 
    236   // Parses and returns a single escaped character.  The character
    237   // must not be 'b' or 'B' since they are usually handle specially.
    238   uc32 ParseClassCharacterEscape();
    239 
    240   // Checks whether the following is a length-digit hexadecimal number,
    241   // and sets the value if it is.
    242   bool ParseHexEscape(int length, uc32* value);
    243 
    244   uc32 ParseOctalLiteral();
    245 
    246   // Tries to parse the input as a back reference.  If successful it
    247   // stores the result in the output parameter and returns true.  If
    248   // it fails it will push back the characters read so the same characters
    249   // can be reparsed.
    250   bool ParseBackReferenceIndex(int* index_out);
    251 
    252   CharacterRange ParseClassAtom(uc16* char_class);
    253   RegExpTree* ReportError(Vector<const char> message);
    254   void Advance();
    255   void Advance(int dist);
    256   void Reset(int pos);
    257 
    258   // Reports whether the pattern might be used as a literal search string.
    259   // Only use if the result of the parse is a single atom node.
    260   bool simple();
    261   bool contains_anchor() { return contains_anchor_; }
    262   void set_contains_anchor() { contains_anchor_ = true; }
    263   int captures_started() { return captures_ == NULL ? 0 : captures_->length(); }
    264   int position() { return next_pos_ - 1; }
    265   bool failed() { return failed_; }
    266 
    267   static const int kMaxCaptures = 1 << 16;
    268   static const uc32 kEndMarker = (1 << 21);
    269 
    270  private:
    271   enum SubexpressionType {
    272     INITIAL,
    273     CAPTURE,  // All positive values represent captures.
    274     POSITIVE_LOOKAHEAD,
    275     NEGATIVE_LOOKAHEAD,
    276     GROUPING
    277   };
    278 
    279   class RegExpParserState : public ZoneObject {
    280    public:
    281     RegExpParserState(RegExpParserState* previous_state,
    282                       SubexpressionType group_type,
    283                       int disjunction_capture_index,
    284                       Zone* zone)
    285         : previous_state_(previous_state),
    286           builder_(new(zone) RegExpBuilder(zone)),
    287           group_type_(group_type),
    288           disjunction_capture_index_(disjunction_capture_index) {}
    289     // Parser state of containing expression, if any.
    290     RegExpParserState* previous_state() { return previous_state_; }
    291     bool IsSubexpression() { return previous_state_ != NULL; }
    292     // RegExpBuilder building this regexp's AST.
    293     RegExpBuilder* builder() { return builder_; }
    294     // Type of regexp being parsed (parenthesized group or entire regexp).
    295     SubexpressionType group_type() { return group_type_; }
    296     // Index in captures array of first capture in this sub-expression, if any.
    297     // Also the capture index of this sub-expression itself, if group_type
    298     // is CAPTURE.
    299     int capture_index() { return disjunction_capture_index_; }
    300 
    301    private:
    302     // Linked list implementation of stack of states.
    303     RegExpParserState* previous_state_;
    304     // Builder for the stored disjunction.
    305     RegExpBuilder* builder_;
    306     // Stored disjunction type (capture, look-ahead or grouping), if any.
    307     SubexpressionType group_type_;
    308     // Stored disjunction's capture index (if any).
    309     int disjunction_capture_index_;
    310   };
    311 
    312   Isolate* isolate() { return isolate_; }
    313   Zone* zone() const { return zone_; }
    314 
    315   uc32 current() { return current_; }
    316   bool has_more() { return has_more_; }
    317   bool has_next() { return next_pos_ < in()->length(); }
    318   uc32 Next();
    319   FlatStringReader* in() { return in_; }
    320   void ScanForCaptures();
    321 
    322   Isolate* isolate_;
    323   Zone* zone_;
    324   Handle<String>* error_;
    325   ZoneList<RegExpCapture*>* captures_;
    326   FlatStringReader* in_;
    327   uc32 current_;
    328   int next_pos_;
    329   // The capture count is only valid after we have scanned for captures.
    330   int capture_count_;
    331   bool has_more_;
    332   bool multiline_;
    333   bool simple_;
    334   bool contains_anchor_;
    335   bool is_scanned_for_captures_;
    336   bool failed_;
    337 };
    338 
    339 // ----------------------------------------------------------------------------
    340 // JAVASCRIPT PARSING
    341 
    342 class Parser;
    343 class SingletonLogger;
    344 
    345 class ParserTraits {
    346  public:
    347   struct Type {
    348     // TODO(marja): To be removed. The Traits object should contain all the data
    349     // it needs.
    350     typedef v8::internal::Parser* Parser;
    351 
    352     // Used by FunctionState and BlockState.
    353     typedef v8::internal::Scope Scope;
    354     typedef v8::internal::Scope* ScopePtr;
    355     typedef Variable GeneratorVariable;
    356     typedef v8::internal::Zone Zone;
    357 
    358     typedef v8::internal::AstProperties AstProperties;
    359     typedef Vector<VariableProxy*> ParameterIdentifierVector;
    360 
    361     // Return types for traversing functions.
    362     typedef const AstRawString* Identifier;
    363     typedef v8::internal::Expression* Expression;
    364     typedef Yield* YieldExpression;
    365     typedef v8::internal::FunctionLiteral* FunctionLiteral;
    366     typedef v8::internal::ClassLiteral* ClassLiteral;
    367     typedef v8::internal::Literal* Literal;
    368     typedef ObjectLiteral::Property* ObjectLiteralProperty;
    369     typedef ZoneList<v8::internal::Expression*>* ExpressionList;
    370     typedef ZoneList<ObjectLiteral::Property*>* PropertyList;
    371     typedef ZoneList<v8::internal::Statement*>* StatementList;
    372 
    373     // For constructing objects returned by the traversing functions.
    374     typedef AstNodeFactory<AstConstructionVisitor> Factory;
    375   };
    376 
    377   class Checkpoint;
    378 
    379   explicit ParserTraits(Parser* parser) : parser_(parser) {}
    380 
    381   // Custom operations executed when FunctionStates are created and destructed.
    382   template <typename FunctionState>
    383   static void SetUpFunctionState(FunctionState* function_state) {
    384     function_state->saved_id_gen_ = *function_state->ast_node_id_gen_;
    385     *function_state->ast_node_id_gen_ =
    386         AstNode::IdGen(BailoutId::FirstUsable().ToInt());
    387   }
    388 
    389   template <typename FunctionState>
    390   static void TearDownFunctionState(FunctionState* function_state) {
    391     if (function_state->outer_function_state_ != NULL) {
    392       *function_state->ast_node_id_gen_ = function_state->saved_id_gen_;
    393     }
    394   }
    395 
    396   // Helper functions for recursive descent.
    397   bool IsEvalOrArguments(const AstRawString* identifier) const;
    398   V8_INLINE bool IsFutureStrictReserved(const AstRawString* identifier) const;
    399 
    400   // Returns true if the expression is of type "this.foo".
    401   static bool IsThisProperty(Expression* expression);
    402 
    403   static bool IsIdentifier(Expression* expression);
    404 
    405   bool IsPrototype(const AstRawString* identifier) const;
    406 
    407   bool IsConstructor(const AstRawString* identifier) const;
    408 
    409   static const AstRawString* AsIdentifier(Expression* expression) {
    410     DCHECK(IsIdentifier(expression));
    411     return expression->AsVariableProxy()->raw_name();
    412   }
    413 
    414   static bool IsBoilerplateProperty(ObjectLiteral::Property* property) {
    415     return ObjectLiteral::IsBoilerplateProperty(property);
    416   }
    417 
    418   static bool IsArrayIndex(const AstRawString* string, uint32_t* index) {
    419     return string->AsArrayIndex(index);
    420   }
    421 
    422   // Functions for encapsulating the differences between parsing and preparsing;
    423   // operations interleaved with the recursive descent.
    424   static void PushLiteralName(FuncNameInferrer* fni, const AstRawString* id) {
    425     fni->PushLiteralName(id);
    426   }
    427   void PushPropertyName(FuncNameInferrer* fni, Expression* expression);
    428   static void InferFunctionName(FuncNameInferrer* fni,
    429                                 FunctionLiteral* func_to_infer) {
    430     fni->AddFunction(func_to_infer);
    431   }
    432 
    433   static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
    434       Scope* scope, ObjectLiteralProperty* property, bool* has_function) {
    435     Expression* value = property->value();
    436     if (scope->DeclarationScope()->is_global_scope() &&
    437         value->AsFunctionLiteral() != NULL) {
    438       *has_function = true;
    439       value->AsFunctionLiteral()->set_pretenure();
    440     }
    441   }
    442 
    443   // If we assign a function literal to a property we pretenure the
    444   // literal so it can be added as a constant function property.
    445   static void CheckAssigningFunctionLiteralToProperty(Expression* left,
    446                                                       Expression* right);
    447 
    448   // Keep track of eval() calls since they disable all local variable
    449   // optimizations. This checks if expression is an eval call, and if yes,
    450   // forwards the information to scope.
    451   void CheckPossibleEvalCall(Expression* expression, Scope* scope);
    452 
    453   // Determine if the expression is a variable proxy and mark it as being used
    454   // in an assignment or with a increment/decrement operator.
    455   static Expression* MarkExpressionAsAssigned(Expression* expression);
    456 
    457   // Returns true if we have a binary expression between two numeric
    458   // literals. In that case, *x will be changed to an expression which is the
    459   // computed value.
    460   bool ShortcutNumericLiteralBinaryExpression(
    461       Expression** x, Expression* y, Token::Value op, int pos,
    462       AstNodeFactory<AstConstructionVisitor>* factory);
    463 
    464   // Rewrites the following types of unary expressions:
    465   // not <literal> -> true / false
    466   // + <numeric literal> -> <numeric literal>
    467   // - <numeric literal> -> <numeric literal with value negated>
    468   // ! <literal> -> true / false
    469   // The following rewriting rules enable the collection of type feedback
    470   // without any special stub and the multiplication is removed later in
    471   // Crankshaft's canonicalization pass.
    472   // + foo -> foo * 1
    473   // - foo -> foo * (-1)
    474   // ~ foo -> foo ^(~0)
    475   Expression* BuildUnaryExpression(
    476       Expression* expression, Token::Value op, int pos,
    477       AstNodeFactory<AstConstructionVisitor>* factory);
    478 
    479   // Generate AST node that throws a ReferenceError with the given type.
    480   Expression* NewThrowReferenceError(const char* type, int pos);
    481 
    482   // Generate AST node that throws a SyntaxError with the given
    483   // type. The first argument may be null (in the handle sense) in
    484   // which case no arguments are passed to the constructor.
    485   Expression* NewThrowSyntaxError(
    486       const char* type, const AstRawString* arg, int pos);
    487 
    488   // Generate AST node that throws a TypeError with the given
    489   // type. Both arguments must be non-null (in the handle sense).
    490   Expression* NewThrowTypeError(const char* type, const AstRawString* arg,
    491                                 int pos);
    492 
    493   // Generic AST generator for throwing errors from compiled code.
    494   Expression* NewThrowError(
    495       const AstRawString* constructor, const char* type,
    496       const AstRawString* arg, int pos);
    497 
    498   // Reporting errors.
    499   void ReportMessageAt(Scanner::Location source_location,
    500                        const char* message,
    501                        const char* arg = NULL,
    502                        bool is_reference_error = false);
    503   void ReportMessage(const char* message,
    504                      const char* arg = NULL,
    505                      bool is_reference_error = false);
    506   void ReportMessage(const char* message,
    507                      const AstRawString* arg,
    508                      bool is_reference_error = false);
    509   void ReportMessageAt(Scanner::Location source_location,
    510                        const char* message,
    511                        const AstRawString* arg,
    512                        bool is_reference_error = false);
    513 
    514   // "null" return type creators.
    515   static const AstRawString* EmptyIdentifier() {
    516     return NULL;
    517   }
    518   static Expression* EmptyExpression() {
    519     return NULL;
    520   }
    521   static Expression* EmptyArrowParamList() { return NULL; }
    522   static Literal* EmptyLiteral() {
    523     return NULL;
    524   }
    525   static ObjectLiteralProperty* EmptyObjectLiteralProperty() { return NULL; }
    526   static FunctionLiteral* EmptyFunctionLiteral() { return NULL; }
    527 
    528   // Used in error return values.
    529   static ZoneList<Expression*>* NullExpressionList() {
    530     return NULL;
    531   }
    532 
    533   // Non-NULL empty string.
    534   V8_INLINE const AstRawString* EmptyIdentifierString();
    535 
    536   // Odd-ball literal creators.
    537   Literal* GetLiteralTheHole(int position,
    538                              AstNodeFactory<AstConstructionVisitor>* factory);
    539 
    540   // Producing data during the recursive descent.
    541   const AstRawString* GetSymbol(Scanner* scanner);
    542   const AstRawString* GetNextSymbol(Scanner* scanner);
    543   const AstRawString* GetNumberAsSymbol(Scanner* scanner);
    544 
    545   Expression* ThisExpression(Scope* scope,
    546                              AstNodeFactory<AstConstructionVisitor>* factory,
    547                              int pos = RelocInfo::kNoPosition);
    548   Expression* SuperReference(Scope* scope,
    549                              AstNodeFactory<AstConstructionVisitor>* factory,
    550                              int pos = RelocInfo::kNoPosition);
    551   Expression* ClassLiteral(const AstRawString* name, Expression* extends,
    552                            Expression* constructor,
    553                            ZoneList<ObjectLiteral::Property*>* properties,
    554                            int pos,
    555                            AstNodeFactory<AstConstructionVisitor>* factory);
    556 
    557   Literal* ExpressionFromLiteral(
    558       Token::Value token, int pos, Scanner* scanner,
    559       AstNodeFactory<AstConstructionVisitor>* factory);
    560   Expression* ExpressionFromIdentifier(
    561       const AstRawString* name, int pos, Scope* scope,
    562       AstNodeFactory<AstConstructionVisitor>* factory);
    563   Expression* ExpressionFromString(
    564       int pos, Scanner* scanner,
    565       AstNodeFactory<AstConstructionVisitor>* factory);
    566   Expression* GetIterator(Expression* iterable,
    567                           AstNodeFactory<AstConstructionVisitor>* factory);
    568   ZoneList<v8::internal::Expression*>* NewExpressionList(int size, Zone* zone) {
    569     return new(zone) ZoneList<v8::internal::Expression*>(size, zone);
    570   }
    571   ZoneList<ObjectLiteral::Property*>* NewPropertyList(int size, Zone* zone) {
    572     return new(zone) ZoneList<ObjectLiteral::Property*>(size, zone);
    573   }
    574   ZoneList<v8::internal::Statement*>* NewStatementList(int size, Zone* zone) {
    575     return new(zone) ZoneList<v8::internal::Statement*>(size, zone);
    576   }
    577   V8_INLINE Scope* NewScope(Scope* parent_scope, ScopeType scope_type);
    578 
    579   // Utility functions
    580   int DeclareArrowParametersFromExpression(Expression* expression, Scope* scope,
    581                                            Scanner::Location* dupe_loc,
    582                                            bool* ok);
    583   V8_INLINE AstValueFactory* ast_value_factory();
    584 
    585   // Temporary glue; these functions will move to ParserBase.
    586   Expression* ParseV8Intrinsic(bool* ok);
    587   FunctionLiteral* ParseFunctionLiteral(
    588       const AstRawString* name, Scanner::Location function_name_location,
    589       bool name_is_strict_reserved, FunctionKind kind,
    590       int function_token_position, FunctionLiteral::FunctionType type,
    591       FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
    592   V8_INLINE void SkipLazyFunctionBody(const AstRawString* name,
    593                                       int* materialized_literal_count,
    594                                       int* expected_property_count, bool* ok);
    595   V8_INLINE ZoneList<Statement*>* ParseEagerFunctionBody(
    596       const AstRawString* name, int pos, Variable* fvar,
    597       Token::Value fvar_init_op, bool is_generator, bool* ok);
    598   V8_INLINE void CheckConflictingVarDeclarations(v8::internal::Scope* scope,
    599                                                  bool* ok);
    600 
    601  private:
    602   Parser* parser_;
    603 };
    604 
    605 
    606 class Parser : public ParserBase<ParserTraits> {
    607  public:
    608   // Note that the hash seed in ParseInfo must be the hash seed from the
    609   // Isolate's heap, otherwise the heap will be in an inconsistent state once
    610   // the strings created by the Parser are internalized.
    611   struct ParseInfo {
    612     uintptr_t stack_limit;
    613     uint32_t hash_seed;
    614     UnicodeCache* unicode_cache;
    615   };
    616 
    617   Parser(CompilationInfo* info, ParseInfo* parse_info);
    618   ~Parser() {
    619     delete reusable_preparser_;
    620     reusable_preparser_ = NULL;
    621     delete cached_parse_data_;
    622     cached_parse_data_ = NULL;
    623   }
    624 
    625   // Parses the source code represented by the compilation info and sets its
    626   // function literal.  Returns false (and deallocates any allocated AST
    627   // nodes) if parsing failed.
    628   static bool Parse(CompilationInfo* info,
    629                     bool allow_lazy = false) {
    630     ParseInfo parse_info = {info->isolate()->stack_guard()->real_climit(),
    631                             info->isolate()->heap()->HashSeed(),
    632                             info->isolate()->unicode_cache()};
    633     Parser parser(info, &parse_info);
    634     parser.set_allow_lazy(allow_lazy);
    635     if (parser.Parse()) {
    636       info->SetStrictMode(info->function()->strict_mode());
    637       return true;
    638     }
    639     return false;
    640   }
    641   bool Parse();
    642   void ParseOnBackground();
    643 
    644   // Handle errors detected during parsing, move statistics to Isolate,
    645   // internalize strings (move them to the heap).
    646   void Internalize();
    647 
    648  private:
    649   friend class ParserTraits;
    650 
    651   // Limit the allowed number of local variables in a function. The hard limit
    652   // is that offsets computed by FullCodeGenerator::StackOperand and similar
    653   // functions are ints, and they should not overflow. In addition, accessing
    654   // local variables creates user-controlled constants in the generated code,
    655   // and we don't want too much user-controlled memory inside the code (this was
    656   // the reason why this limit was introduced in the first place; see
    657   // https://codereview.chromium.org/7003030/ ).
    658   static const int kMaxNumFunctionLocals = 4194303;  // 2^22-1
    659 
    660   enum VariableDeclarationContext {
    661     kModuleElement,
    662     kBlockElement,
    663     kStatement,
    664     kForStatement
    665   };
    666 
    667   // If a list of variable declarations includes any initializers.
    668   enum VariableDeclarationProperties {
    669     kHasInitializers,
    670     kHasNoInitializers
    671   };
    672 
    673   // Returns NULL if parsing failed.
    674   FunctionLiteral* ParseProgram();
    675 
    676   FunctionLiteral* ParseLazy();
    677   FunctionLiteral* ParseLazy(Utf16CharacterStream* source);
    678 
    679   Isolate* isolate() { return info_->isolate(); }
    680   CompilationInfo* info() const { return info_; }
    681   Handle<Script> script() const { return info_->script(); }
    682   AstValueFactory* ast_value_factory() const {
    683     return info_->ast_value_factory();
    684   }
    685 
    686   // Called by ParseProgram after setting up the scanner.
    687   FunctionLiteral* DoParseProgram(CompilationInfo* info, Scope** scope,
    688                                   Scope** ad_hoc_eval_scope);
    689 
    690   void SetCachedData();
    691 
    692   bool inside_with() const { return scope_->inside_with(); }
    693   ScriptCompiler::CompileOptions compile_options() const {
    694     return info_->compile_options();
    695   }
    696   Scope* DeclarationScope(VariableMode mode) {
    697     return IsLexicalVariableMode(mode)
    698         ? scope_ : scope_->DeclarationScope();
    699   }
    700 
    701   // All ParseXXX functions take as the last argument an *ok parameter
    702   // which is set to false if parsing failed; it is unchanged otherwise.
    703   // By making the 'exception handling' explicit, we are forced to check
    704   // for failure at the call sites.
    705   void* ParseSourceElements(ZoneList<Statement*>* processor, int end_token,
    706                             bool is_eval, bool is_global,
    707                             Scope** ad_hoc_eval_scope, bool* ok);
    708   Statement* ParseModuleElement(ZoneList<const AstRawString*>* labels,
    709                                 bool* ok);
    710   Statement* ParseModuleDeclaration(ZoneList<const AstRawString*>* names,
    711                                     bool* ok);
    712   Module* ParseModule(bool* ok);
    713   Module* ParseModuleLiteral(bool* ok);
    714   Module* ParseModulePath(bool* ok);
    715   Module* ParseModuleVariable(bool* ok);
    716   Module* ParseModuleUrl(bool* ok);
    717   Module* ParseModuleSpecifier(bool* ok);
    718   Block* ParseImportDeclaration(bool* ok);
    719   Statement* ParseExportDeclaration(bool* ok);
    720   Statement* ParseBlockElement(ZoneList<const AstRawString*>* labels, bool* ok);
    721   Statement* ParseStatement(ZoneList<const AstRawString*>* labels, bool* ok);
    722   Statement* ParseFunctionDeclaration(ZoneList<const AstRawString*>* names,
    723                                       bool* ok);
    724   Statement* ParseClassDeclaration(ZoneList<const AstRawString*>* names,
    725                                    bool* ok);
    726   Statement* ParseNativeDeclaration(bool* ok);
    727   Block* ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok);
    728   Block* ParseVariableStatement(VariableDeclarationContext var_context,
    729                                 ZoneList<const AstRawString*>* names,
    730                                 bool* ok);
    731   Block* ParseVariableDeclarations(VariableDeclarationContext var_context,
    732                                    VariableDeclarationProperties* decl_props,
    733                                    ZoneList<const AstRawString*>* names,
    734                                    const AstRawString** out,
    735                                    bool* ok);
    736   Statement* ParseExpressionOrLabelledStatement(
    737       ZoneList<const AstRawString*>* labels, bool* ok);
    738   IfStatement* ParseIfStatement(ZoneList<const AstRawString*>* labels,
    739                                 bool* ok);
    740   Statement* ParseContinueStatement(bool* ok);
    741   Statement* ParseBreakStatement(ZoneList<const AstRawString*>* labels,
    742                                  bool* ok);
    743   Statement* ParseReturnStatement(bool* ok);
    744   Statement* ParseWithStatement(ZoneList<const AstRawString*>* labels,
    745                                 bool* ok);
    746   CaseClause* ParseCaseClause(bool* default_seen_ptr, bool* ok);
    747   SwitchStatement* ParseSwitchStatement(ZoneList<const AstRawString*>* labels,
    748                                         bool* ok);
    749   DoWhileStatement* ParseDoWhileStatement(ZoneList<const AstRawString*>* labels,
    750                                           bool* ok);
    751   WhileStatement* ParseWhileStatement(ZoneList<const AstRawString*>* labels,
    752                                       bool* ok);
    753   Statement* ParseForStatement(ZoneList<const AstRawString*>* labels, bool* ok);
    754   Statement* ParseThrowStatement(bool* ok);
    755   Expression* MakeCatchContext(Handle<String> id, VariableProxy* value);
    756   TryStatement* ParseTryStatement(bool* ok);
    757   DebuggerStatement* ParseDebuggerStatement(bool* ok);
    758 
    759   // Support for hamony block scoped bindings.
    760   Block* ParseScopedBlock(ZoneList<const AstRawString*>* labels, bool* ok);
    761 
    762   // Initialize the components of a for-in / for-of statement.
    763   void InitializeForEachStatement(ForEachStatement* stmt,
    764                                   Expression* each,
    765                                   Expression* subject,
    766                                   Statement* body);
    767   Statement* DesugarLetBindingsInForStatement(
    768       Scope* inner_scope, ZoneList<const AstRawString*>* names,
    769       ForStatement* loop, Statement* init, Expression* cond, Statement* next,
    770       Statement* body, bool* ok);
    771 
    772   FunctionLiteral* ParseFunctionLiteral(
    773       const AstRawString* name, Scanner::Location function_name_location,
    774       bool name_is_strict_reserved, FunctionKind kind,
    775       int function_token_position, FunctionLiteral::FunctionType type,
    776       FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
    777 
    778   // Magical syntax support.
    779   Expression* ParseV8Intrinsic(bool* ok);
    780 
    781   bool CheckInOrOf(bool accept_OF, ForEachStatement::VisitMode* visit_mode);
    782 
    783   // Get odd-ball literals.
    784   Literal* GetLiteralUndefined(int position);
    785 
    786   // For harmony block scoping mode: Check if the scope has conflicting var/let
    787   // declarations from different scopes. It covers for example
    788   //
    789   // function f() { { { var x; } let x; } }
    790   // function g() { { var x; let x; } }
    791   //
    792   // The var declarations are hoisted to the function scope, but originate from
    793   // a scope where the name has also been let bound or the var declaration is
    794   // hoisted over such a scope.
    795   void CheckConflictingVarDeclarations(Scope* scope, bool* ok);
    796 
    797   // Parser support
    798   VariableProxy* NewUnresolved(const AstRawString* name,
    799                                VariableMode mode,
    800                                Interface* interface);
    801   void Declare(Declaration* declaration, bool resolve, bool* ok);
    802 
    803   bool TargetStackContainsLabel(const AstRawString* label);
    804   BreakableStatement* LookupBreakTarget(const AstRawString* label, bool* ok);
    805   IterationStatement* LookupContinueTarget(const AstRawString* label, bool* ok);
    806 
    807   void RegisterTargetUse(Label* target, Target* stop);
    808 
    809   // Factory methods.
    810 
    811   Scope* NewScope(Scope* parent, ScopeType type);
    812 
    813   // Skip over a lazy function, either using cached data if we have it, or
    814   // by parsing the function with PreParser. Consumes the ending }.
    815   void SkipLazyFunctionBody(const AstRawString* function_name,
    816                             int* materialized_literal_count,
    817                             int* expected_property_count,
    818                             bool* ok);
    819 
    820   PreParser::PreParseResult ParseLazyFunctionBodyWithPreParser(
    821       SingletonLogger* logger);
    822 
    823   // Consumes the ending }.
    824   ZoneList<Statement*>* ParseEagerFunctionBody(
    825       const AstRawString* function_name, int pos, Variable* fvar,
    826       Token::Value fvar_init_op, bool is_generator, bool* ok);
    827 
    828   void HandleSourceURLComments();
    829 
    830   void ThrowPendingError();
    831 
    832   Scanner scanner_;
    833   PreParser* reusable_preparser_;
    834   Scope* original_scope_;  // for ES5 function declarations in sloppy eval
    835   Target* target_stack_;  // for break, continue statements
    836   ParseData* cached_parse_data_;
    837 
    838   CompilationInfo* info_;
    839 
    840   // Pending errors.
    841   bool has_pending_error_;
    842   Scanner::Location pending_error_location_;
    843   const char* pending_error_message_;
    844   const AstRawString* pending_error_arg_;
    845   const char* pending_error_char_arg_;
    846   bool pending_error_is_reference_error_;
    847 
    848   // Other information which will be stored in Parser and moved to Isolate after
    849   // parsing.
    850   int use_counts_[v8::Isolate::kUseCounterFeatureCount];
    851   int total_preparse_skipped_;
    852   HistogramTimer* pre_parse_timer_;
    853 };
    854 
    855 
    856 bool ParserTraits::IsFutureStrictReserved(
    857     const AstRawString* identifier) const {
    858   return identifier->IsOneByteEqualTo("yield") ||
    859          parser_->scanner()->IdentifierIsFutureStrictReserved(identifier);
    860 }
    861 
    862 
    863 Scope* ParserTraits::NewScope(Scope* parent_scope, ScopeType scope_type) {
    864   return parser_->NewScope(parent_scope, scope_type);
    865 }
    866 
    867 
    868 const AstRawString* ParserTraits::EmptyIdentifierString() {
    869   return parser_->ast_value_factory()->empty_string();
    870 }
    871 
    872 
    873 void ParserTraits::SkipLazyFunctionBody(const AstRawString* function_name,
    874                                         int* materialized_literal_count,
    875                                         int* expected_property_count,
    876                                         bool* ok) {
    877   return parser_->SkipLazyFunctionBody(
    878       function_name, materialized_literal_count, expected_property_count, ok);
    879 }
    880 
    881 
    882 ZoneList<Statement*>* ParserTraits::ParseEagerFunctionBody(
    883     const AstRawString* name, int pos, Variable* fvar,
    884     Token::Value fvar_init_op, bool is_generator, bool* ok) {
    885   return parser_->ParseEagerFunctionBody(name, pos, fvar, fvar_init_op,
    886                                          is_generator, ok);
    887 }
    888 
    889 void ParserTraits::CheckConflictingVarDeclarations(v8::internal::Scope* scope,
    890                                                    bool* ok) {
    891   parser_->CheckConflictingVarDeclarations(scope, ok);
    892 }
    893 
    894 
    895 AstValueFactory* ParserTraits::ast_value_factory() {
    896   return parser_->ast_value_factory();
    897 }
    898 
    899 
    900 // Support for handling complex values (array and object literals) that
    901 // can be fully handled at compile time.
    902 class CompileTimeValue: public AllStatic {
    903  public:
    904   enum LiteralType {
    905     OBJECT_LITERAL_FAST_ELEMENTS,
    906     OBJECT_LITERAL_SLOW_ELEMENTS,
    907     ARRAY_LITERAL
    908   };
    909 
    910   static bool IsCompileTimeValue(Expression* expression);
    911 
    912   // Get the value as a compile time value.
    913   static Handle<FixedArray> GetValue(Isolate* isolate, Expression* expression);
    914 
    915   // Get the type of a compile time value returned by GetValue().
    916   static LiteralType GetLiteralType(Handle<FixedArray> value);
    917 
    918   // Get the elements array of a compile time value returned by GetValue().
    919   static Handle<FixedArray> GetElements(Handle<FixedArray> value);
    920 
    921  private:
    922   static const int kLiteralTypeSlot = 0;
    923   static const int kElementsSlot = 1;
    924 
    925   DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue);
    926 };
    927 
    928 } }  // namespace v8::internal
    929 
    930 #endif  // V8_PARSER_H_
    931