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