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
16namespace v8 {
17class ScriptCompiler;
18
19namespace internal {
20
21class CompilationInfo;
22class ParserLog;
23class PositionStack;
24class Target;
25
26template <typename T> class ZoneListWrapper;
27
28
29class 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.
63class 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.
104template <typename T, int initial_size>
105class 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.
180class 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
215class 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
342class Parser;
343class SingletonLogger;
344
345class 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
606class 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
856bool ParserTraits::IsFutureStrictReserved(
857    const AstRawString* identifier) const {
858  return identifier->IsOneByteEqualTo("yield") ||
859         parser_->scanner()->IdentifierIsFutureStrictReserved(identifier);
860}
861
862
863Scope* ParserTraits::NewScope(Scope* parent_scope, ScopeType scope_type) {
864  return parser_->NewScope(parent_scope, scope_type);
865}
866
867
868const AstRawString* ParserTraits::EmptyIdentifierString() {
869  return parser_->ast_value_factory()->empty_string();
870}
871
872
873void 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
882ZoneList<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
889void ParserTraits::CheckConflictingVarDeclarations(v8::internal::Scope* scope,
890                                                   bool* ok) {
891  parser_->CheckConflictingVarDeclarations(scope, ok);
892}
893
894
895AstValueFactory* 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.
902class 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