The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / src / parser.h @ f230a1cf

History | View | Annotate | Download (28.8 KB)

1
// Copyright 2012 the V8 project authors. All rights reserved.
2
// Redistribution and use in source and binary forms, with or without
3
// modification, are permitted provided that the following conditions are
4
// met:
5
//
6
//     * Redistributions of source code must retain the above copyright
7
//       notice, this list of conditions and the following disclaimer.
8
//     * Redistributions in binary form must reproduce the above
9
//       copyright notice, this list of conditions and the following
10
//       disclaimer in the documentation and/or other materials provided
11
//       with the distribution.
12
//     * Neither the name of Google Inc. nor the names of its
13
//       contributors may be used to endorse or promote products derived
14
//       from this software without specific prior written permission.
15
//
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27

    
28
#ifndef V8_PARSER_H_
29
#define V8_PARSER_H_
30

    
31
#include "allocation.h"
32
#include "ast.h"
33
#include "preparse-data-format.h"
34
#include "preparse-data.h"
35
#include "scopes.h"
36
#include "preparser.h"
37

    
38
namespace v8 {
39
namespace internal {
40

    
41
class CompilationInfo;
42
class FuncNameInferrer;
43
class ParserLog;
44
class PositionStack;
45
class Target;
46

    
47
template <typename T> class ZoneListWrapper;
48

    
49

    
50
class ParserMessage : public Malloced {
51
 public:
52
  ParserMessage(Scanner::Location loc, const char* message,
53
                Vector<const char*> args)
54
      : loc_(loc),
55
        message_(message),
56
        args_(args) { }
57
  ~ParserMessage();
58
  Scanner::Location location() { return loc_; }
59
  const char* message() { return message_; }
60
  Vector<const char*> args() { return args_; }
61
 private:
62
  Scanner::Location loc_;
63
  const char* message_;
64
  Vector<const char*> args_;
65
};
66

    
67

    
68
class FunctionEntry BASE_EMBEDDED {
69
 public:
70
  enum {
71
    kStartPositionIndex,
72
    kEndPositionIndex,
73
    kLiteralCountIndex,
74
    kPropertyCountIndex,
75
    kLanguageModeIndex,
76
    kSize
77
  };
78

    
79
  explicit FunctionEntry(Vector<unsigned> backing)
80
    : backing_(backing) { }
81

    
82
  FunctionEntry() : backing_() { }
83

    
84
  int start_pos() { return backing_[kStartPositionIndex]; }
85
  int end_pos() { return backing_[kEndPositionIndex]; }
86
  int literal_count() { return backing_[kLiteralCountIndex]; }
87
  int property_count() { return backing_[kPropertyCountIndex]; }
88
  LanguageMode language_mode() {
89
    ASSERT(backing_[kLanguageModeIndex] == CLASSIC_MODE ||
90
           backing_[kLanguageModeIndex] == STRICT_MODE ||
91
           backing_[kLanguageModeIndex] == EXTENDED_MODE);
92
    return static_cast<LanguageMode>(backing_[kLanguageModeIndex]);
93
  }
94

    
95
  bool is_valid() { return !backing_.is_empty(); }
96

    
97
 private:
98
  Vector<unsigned> backing_;
99
};
100

    
101

    
102
class ScriptDataImpl : public ScriptData {
103
 public:
104
  explicit ScriptDataImpl(Vector<unsigned> store)
105
      : store_(store),
106
        owns_store_(true) { }
107

    
108
  // Create an empty ScriptDataImpl that is guaranteed to not satisfy
109
  // a SanityCheck.
110
  ScriptDataImpl() : owns_store_(false) { }
111

    
112
  virtual ~ScriptDataImpl();
113
  virtual int Length();
114
  virtual const char* Data();
115
  virtual bool HasError();
116

    
117
  void Initialize();
118
  void ReadNextSymbolPosition();
119

    
120
  FunctionEntry GetFunctionEntry(int start);
121
  int GetSymbolIdentifier();
122
  bool SanityCheck();
123

    
124
  Scanner::Location MessageLocation();
125
  const char* BuildMessage();
126
  Vector<const char*> BuildArgs();
127

    
128
  int symbol_count() {
129
    return (store_.length() > PreparseDataConstants::kHeaderSize)
130
        ? store_[PreparseDataConstants::kSymbolCountOffset]
131
        : 0;
132
  }
133
  // The following functions should only be called if SanityCheck has
134
  // returned true.
135
  bool has_error() { return store_[PreparseDataConstants::kHasErrorOffset]; }
136
  unsigned magic() { return store_[PreparseDataConstants::kMagicOffset]; }
137
  unsigned version() { return store_[PreparseDataConstants::kVersionOffset]; }
138

    
139
 private:
140
  Vector<unsigned> store_;
141
  unsigned char* symbol_data_;
142
  unsigned char* symbol_data_end_;
143
  int function_index_;
144
  bool owns_store_;
145

    
146
  unsigned Read(int position);
147
  unsigned* ReadAddress(int position);
148
  // Reads a number from the current symbols
149
  int ReadNumber(byte** source);
150

    
151
  ScriptDataImpl(const char* backing_store, int length)
152
      : store_(reinterpret_cast<unsigned*>(const_cast<char*>(backing_store)),
153
               length / static_cast<int>(sizeof(unsigned))),
154
        owns_store_(false) {
155
    ASSERT_EQ(0, static_cast<int>(
156
        reinterpret_cast<intptr_t>(backing_store) % sizeof(unsigned)));
157
  }
158

    
159
  // Read strings written by ParserRecorder::WriteString.
160
  static const char* ReadString(unsigned* start, int* chars);
161

    
162
  friend class ScriptData;
163
};
164

    
165

    
166
class PreParserApi {
167
 public:
168
  // Pre-parse a character stream and return full preparse data.
169
  //
170
  // This interface is here instead of in preparser.h because it instantiates a
171
  // preparser recorder object that is suited to the parser's purposes.  Also,
172
  // the preparser doesn't know about ScriptDataImpl.
173
  static ScriptDataImpl* PreParse(Isolate* isolate,
174
                                  Utf16CharacterStream* source);
175
};
176

    
177

    
178
// ----------------------------------------------------------------------------
179
// REGEXP PARSING
180

    
181
// A BufferedZoneList is an automatically growing list, just like (and backed
182
// by) a ZoneList, that is optimized for the case of adding and removing
183
// a single element. The last element added is stored outside the backing list,
184
// and if no more than one element is ever added, the ZoneList isn't even
185
// allocated.
186
// Elements must not be NULL pointers.
187
template <typename T, int initial_size>
188
class BufferedZoneList {
189
 public:
190
  BufferedZoneList() : list_(NULL), last_(NULL) {}
191

    
192
  // Adds element at end of list. This element is buffered and can
193
  // be read using last() or removed using RemoveLast until a new Add or until
194
  // RemoveLast or GetList has been called.
195
  void Add(T* value, Zone* zone) {
196
    if (last_ != NULL) {
197
      if (list_ == NULL) {
198
        list_ = new(zone) ZoneList<T*>(initial_size, zone);
199
      }
200
      list_->Add(last_, zone);
201
    }
202
    last_ = value;
203
  }
204

    
205
  T* last() {
206
    ASSERT(last_ != NULL);
207
    return last_;
208
  }
209

    
210
  T* RemoveLast() {
211
    ASSERT(last_ != NULL);
212
    T* result = last_;
213
    if ((list_ != NULL) && (list_->length() > 0))
214
      last_ = list_->RemoveLast();
215
    else
216
      last_ = NULL;
217
    return result;
218
  }
219

    
220
  T* Get(int i) {
221
    ASSERT((0 <= i) && (i < length()));
222
    if (list_ == NULL) {
223
      ASSERT_EQ(0, i);
224
      return last_;
225
    } else {
226
      if (i == list_->length()) {
227
        ASSERT(last_ != NULL);
228
        return last_;
229
      } else {
230
        return list_->at(i);
231
      }
232
    }
233
  }
234

    
235
  void Clear() {
236
    list_ = NULL;
237
    last_ = NULL;
238
  }
239

    
240
  int length() {
241
    int length = (list_ == NULL) ? 0 : list_->length();
242
    return length + ((last_ == NULL) ? 0 : 1);
243
  }
244

    
245
  ZoneList<T*>* GetList(Zone* zone) {
246
    if (list_ == NULL) {
247
      list_ = new(zone) ZoneList<T*>(initial_size, zone);
248
    }
249
    if (last_ != NULL) {
250
      list_->Add(last_, zone);
251
      last_ = NULL;
252
    }
253
    return list_;
254
  }
255

    
256
 private:
257
  ZoneList<T*>* list_;
258
  T* last_;
259
};
260

    
261

    
262
// Accumulates RegExp atoms and assertions into lists of terms and alternatives.
263
class RegExpBuilder: public ZoneObject {
264
 public:
265
  explicit RegExpBuilder(Zone* zone);
266
  void AddCharacter(uc16 character);
267
  // "Adds" an empty expression. Does nothing except consume a
268
  // following quantifier
269
  void AddEmpty();
270
  void AddAtom(RegExpTree* tree);
271
  void AddAssertion(RegExpTree* tree);
272
  void NewAlternative();  // '|'
273
  void AddQuantifierToAtom(
274
      int min, int max, RegExpQuantifier::QuantifierType type);
275
  RegExpTree* ToRegExp();
276

    
277
 private:
278
  void FlushCharacters();
279
  void FlushText();
280
  void FlushTerms();
281
  Zone* zone() const { return zone_; }
282

    
283
  Zone* zone_;
284
  bool pending_empty_;
285
  ZoneList<uc16>* characters_;
286
  BufferedZoneList<RegExpTree, 2> terms_;
287
  BufferedZoneList<RegExpTree, 2> text_;
288
  BufferedZoneList<RegExpTree, 2> alternatives_;
289
#ifdef DEBUG
290
  enum {ADD_NONE, ADD_CHAR, ADD_TERM, ADD_ASSERT, ADD_ATOM} last_added_;
291
#define LAST(x) last_added_ = x;
292
#else
293
#define LAST(x)
294
#endif
295
};
296

    
297

    
298
class RegExpParser BASE_EMBEDDED {
299
 public:
300
  RegExpParser(FlatStringReader* in,
301
               Handle<String>* error,
302
               bool multiline_mode,
303
               Zone* zone);
304

    
305
  static bool ParseRegExp(FlatStringReader* input,
306
                          bool multiline,
307
                          RegExpCompileData* result,
308
                          Zone* zone);
309

    
310
  RegExpTree* ParsePattern();
311
  RegExpTree* ParseDisjunction();
312
  RegExpTree* ParseGroup();
313
  RegExpTree* ParseCharacterClass();
314

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

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

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

    
327
  uc32 ParseOctalLiteral();
328

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

    
335
  CharacterRange ParseClassAtom(uc16* char_class);
336
  RegExpTree* ReportError(Vector<const char> message);
337
  void Advance();
338
  void Advance(int dist);
339
  void Reset(int pos);
340

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

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

    
353
 private:
354
  enum SubexpressionType {
355
    INITIAL,
356
    CAPTURE,  // All positive values represent captures.
357
    POSITIVE_LOOKAHEAD,
358
    NEGATIVE_LOOKAHEAD,
359
    GROUPING
360
  };
361

    
362
  class RegExpParserState : public ZoneObject {
363
   public:
364
    RegExpParserState(RegExpParserState* previous_state,
365
                      SubexpressionType group_type,
366
                      int disjunction_capture_index,
367
                      Zone* zone)
368
        : previous_state_(previous_state),
369
          builder_(new(zone) RegExpBuilder(zone)),
370
          group_type_(group_type),
371
          disjunction_capture_index_(disjunction_capture_index) {}
372
    // Parser state of containing expression, if any.
373
    RegExpParserState* previous_state() { return previous_state_; }
374
    bool IsSubexpression() { return previous_state_ != NULL; }
375
    // RegExpBuilder building this regexp's AST.
376
    RegExpBuilder* builder() { return builder_; }
377
    // Type of regexp being parsed (parenthesized group or entire regexp).
378
    SubexpressionType group_type() { return group_type_; }
379
    // Index in captures array of first capture in this sub-expression, if any.
380
    // Also the capture index of this sub-expression itself, if group_type
381
    // is CAPTURE.
382
    int capture_index() { return disjunction_capture_index_; }
383

    
384
   private:
385
    // Linked list implementation of stack of states.
386
    RegExpParserState* previous_state_;
387
    // Builder for the stored disjunction.
388
    RegExpBuilder* builder_;
389
    // Stored disjunction type (capture, look-ahead or grouping), if any.
390
    SubexpressionType group_type_;
391
    // Stored disjunction's capture index (if any).
392
    int disjunction_capture_index_;
393
  };
394

    
395
  Isolate* isolate() { return isolate_; }
396
  Zone* zone() const { return zone_; }
397

    
398
  uc32 current() { return current_; }
399
  bool has_more() { return has_more_; }
400
  bool has_next() { return next_pos_ < in()->length(); }
401
  uc32 Next();
402
  FlatStringReader* in() { return in_; }
403
  void ScanForCaptures();
404

    
405
  Isolate* isolate_;
406
  Zone* zone_;
407
  Handle<String>* error_;
408
  ZoneList<RegExpCapture*>* captures_;
409
  FlatStringReader* in_;
410
  uc32 current_;
411
  int next_pos_;
412
  // The capture count is only valid after we have scanned for captures.
413
  int capture_count_;
414
  bool has_more_;
415
  bool multiline_;
416
  bool simple_;
417
  bool contains_anchor_;
418
  bool is_scanned_for_captures_;
419
  bool failed_;
420
};
421

    
422
// ----------------------------------------------------------------------------
423
// JAVASCRIPT PARSING
424

    
425
// Forward declaration.
426
class SingletonLogger;
427

    
428
class Parser : public ParserBase {
429
 public:
430
  explicit Parser(CompilationInfo* info);
431
  ~Parser() {
432
    delete reusable_preparser_;
433
    reusable_preparser_ = NULL;
434
  }
435

    
436
  // Parses the source code represented by the compilation info and sets its
437
  // function literal.  Returns false (and deallocates any allocated AST
438
  // nodes) if parsing failed.
439
  static bool Parse(CompilationInfo* info) { return Parser(info).Parse(); }
440
  bool Parse();
441

    
442
 private:
443
  static const int kMaxNumFunctionLocals = 131071;  // 2^17-1
444

    
445
  enum Mode {
446
    PARSE_LAZILY,
447
    PARSE_EAGERLY
448
  };
449

    
450
  enum VariableDeclarationContext {
451
    kModuleElement,
452
    kBlockElement,
453
    kStatement,
454
    kForStatement
455
  };
456

    
457
  // If a list of variable declarations includes any initializers.
458
  enum VariableDeclarationProperties {
459
    kHasInitializers,
460
    kHasNoInitializers
461
  };
462

    
463
  class BlockState;
464

    
465
  class FunctionState BASE_EMBEDDED {
466
   public:
467
    FunctionState(Parser* parser,
468
                  Scope* scope,
469
                  Isolate* isolate);
470
    ~FunctionState();
471

    
472
    int NextMaterializedLiteralIndex() {
473
      return next_materialized_literal_index_++;
474
    }
475
    int materialized_literal_count() {
476
      return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize;
477
    }
478

    
479
    int NextHandlerIndex() { return next_handler_index_++; }
480
    int handler_count() { return next_handler_index_; }
481

    
482
    void AddProperty() { expected_property_count_++; }
483
    int expected_property_count() { return expected_property_count_; }
484

    
485
    void set_generator_object_variable(Variable *variable) {
486
      ASSERT(variable != NULL);
487
      ASSERT(!is_generator());
488
      generator_object_variable_ = variable;
489
    }
490
    Variable* generator_object_variable() const {
491
      return generator_object_variable_;
492
    }
493
    bool is_generator() const {
494
      return generator_object_variable_ != NULL;
495
    }
496

    
497
    AstNodeFactory<AstConstructionVisitor>* factory() { return &factory_; }
498

    
499
   private:
500
    // Used to assign an index to each literal that needs materialization in
501
    // the function.  Includes regexp literals, and boilerplate for object and
502
    // array literals.
503
    int next_materialized_literal_index_;
504

    
505
    // Used to assign a per-function index to try and catch handlers.
506
    int next_handler_index_;
507

    
508
    // Properties count estimation.
509
    int expected_property_count_;
510

    
511
    // For generators, the variable that holds the generator object.  This
512
    // variable is used by yield expressions and return statements.  NULL
513
    // indicates that this function is not a generator.
514
    Variable* generator_object_variable_;
515

    
516
    Parser* parser_;
517
    FunctionState* outer_function_state_;
518
    Scope* outer_scope_;
519
    int saved_ast_node_id_;
520
    AstNodeFactory<AstConstructionVisitor> factory_;
521
  };
522

    
523
  class ParsingModeScope BASE_EMBEDDED {
524
   public:
525
    ParsingModeScope(Parser* parser, Mode mode)
526
        : parser_(parser),
527
          old_mode_(parser->mode()) {
528
      parser_->mode_ = mode;
529
    }
530
    ~ParsingModeScope() {
531
      parser_->mode_ = old_mode_;
532
    }
533

    
534
   private:
535
    Parser* parser_;
536
    Mode old_mode_;
537
  };
538

    
539
  // Returns NULL if parsing failed.
540
  FunctionLiteral* ParseProgram();
541

    
542
  FunctionLiteral* ParseLazy();
543
  FunctionLiteral* ParseLazy(Utf16CharacterStream* source);
544

    
545
  Isolate* isolate() { return isolate_; }
546
  Zone* zone() const { return zone_; }
547
  CompilationInfo* info() const { return info_; }
548

    
549
  // Called by ParseProgram after setting up the scanner.
550
  FunctionLiteral* DoParseProgram(CompilationInfo* info,
551
                                  Handle<String> source);
552

    
553
  // Report syntax error
554
  void ReportUnexpectedToken(Token::Value token);
555
  void ReportInvalidPreparseData(Handle<String> name, bool* ok);
556
  void ReportMessage(const char* message, Vector<const char*> args);
557
  void ReportMessage(const char* message, Vector<Handle<String> > args);
558
  void ReportMessageAt(Scanner::Location location, const char* type) {
559
    ReportMessageAt(location, type, Vector<const char*>::empty());
560
  }
561
  void ReportMessageAt(Scanner::Location loc,
562
                       const char* message,
563
                       Vector<const char*> args);
564
  void ReportMessageAt(Scanner::Location loc,
565
                       const char* message,
566
                       Vector<Handle<String> > args);
567

    
568
  void set_pre_parse_data(ScriptDataImpl *data) {
569
    pre_parse_data_ = data;
570
    symbol_cache_.Initialize(data ? data->symbol_count() : 0, zone());
571
  }
572

    
573
  bool inside_with() const { return top_scope_->inside_with(); }
574
  Scanner& scanner()  { return scanner_; }
575
  Mode mode() const { return mode_; }
576
  ScriptDataImpl* pre_parse_data() const { return pre_parse_data_; }
577
  bool is_extended_mode() {
578
    ASSERT(top_scope_ != NULL);
579
    return top_scope_->is_extended_mode();
580
  }
581
  Scope* DeclarationScope(VariableMode mode) {
582
    return IsLexicalVariableMode(mode)
583
        ? top_scope_ : top_scope_->DeclarationScope();
584
  }
585

    
586
  // Check if the given string is 'eval' or 'arguments'.
587
  bool IsEvalOrArguments(Handle<String> string);
588

    
589
  // All ParseXXX functions take as the last argument an *ok parameter
590
  // which is set to false if parsing failed; it is unchanged otherwise.
591
  // By making the 'exception handling' explicit, we are forced to check
592
  // for failure at the call sites.
593
  void* ParseSourceElements(ZoneList<Statement*>* processor, int end_token,
594
                            bool is_eval, bool is_global, bool* ok);
595
  Statement* ParseModuleElement(ZoneStringList* labels, bool* ok);
596
  Statement* ParseModuleDeclaration(ZoneStringList* names, bool* ok);
597
  Module* ParseModule(bool* ok);
598
  Module* ParseModuleLiteral(bool* ok);
599
  Module* ParseModulePath(bool* ok);
600
  Module* ParseModuleVariable(bool* ok);
601
  Module* ParseModuleUrl(bool* ok);
602
  Module* ParseModuleSpecifier(bool* ok);
603
  Block* ParseImportDeclaration(bool* ok);
604
  Statement* ParseExportDeclaration(bool* ok);
605
  Statement* ParseBlockElement(ZoneStringList* labels, bool* ok);
606
  Statement* ParseStatement(ZoneStringList* labels, bool* ok);
607
  Statement* ParseFunctionDeclaration(ZoneStringList* names, bool* ok);
608
  Statement* ParseNativeDeclaration(bool* ok);
609
  Block* ParseBlock(ZoneStringList* labels, bool* ok);
610
  Block* ParseVariableStatement(VariableDeclarationContext var_context,
611
                                ZoneStringList* names,
612
                                bool* ok);
613
  Block* ParseVariableDeclarations(VariableDeclarationContext var_context,
614
                                   VariableDeclarationProperties* decl_props,
615
                                   ZoneStringList* names,
616
                                   Handle<String>* out,
617
                                   bool* ok);
618
  Statement* ParseExpressionOrLabelledStatement(ZoneStringList* labels,
619
                                                bool* ok);
620
  IfStatement* ParseIfStatement(ZoneStringList* labels, bool* ok);
621
  Statement* ParseContinueStatement(bool* ok);
622
  Statement* ParseBreakStatement(ZoneStringList* labels, bool* ok);
623
  Statement* ParseReturnStatement(bool* ok);
624
  Statement* ParseWithStatement(ZoneStringList* labels, bool* ok);
625
  CaseClause* ParseCaseClause(bool* default_seen_ptr, bool* ok);
626
  SwitchStatement* ParseSwitchStatement(ZoneStringList* labels, bool* ok);
627
  DoWhileStatement* ParseDoWhileStatement(ZoneStringList* labels, bool* ok);
628
  WhileStatement* ParseWhileStatement(ZoneStringList* labels, bool* ok);
629
  Statement* ParseForStatement(ZoneStringList* labels, bool* ok);
630
  Statement* ParseThrowStatement(bool* ok);
631
  Expression* MakeCatchContext(Handle<String> id, VariableProxy* value);
632
  TryStatement* ParseTryStatement(bool* ok);
633
  DebuggerStatement* ParseDebuggerStatement(bool* ok);
634

    
635
  // Support for hamony block scoped bindings.
636
  Block* ParseScopedBlock(ZoneStringList* labels, bool* ok);
637

    
638
  Expression* ParseExpression(bool accept_IN, bool* ok);
639
  Expression* ParseAssignmentExpression(bool accept_IN, bool* ok);
640
  Expression* ParseYieldExpression(bool* ok);
641
  Expression* ParseConditionalExpression(bool accept_IN, bool* ok);
642
  Expression* ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
643
  Expression* ParseUnaryExpression(bool* ok);
644
  Expression* ParsePostfixExpression(bool* ok);
645
  Expression* ParseLeftHandSideExpression(bool* ok);
646
  Expression* ParseNewExpression(bool* ok);
647
  Expression* ParseMemberExpression(bool* ok);
648
  Expression* ParseNewPrefix(PositionStack* stack, bool* ok);
649
  Expression* ParseMemberWithNewPrefixesExpression(PositionStack* stack,
650
                                                   bool* ok);
651
  Expression* ParsePrimaryExpression(bool* ok);
652
  Expression* ParseArrayLiteral(bool* ok);
653
  Expression* ParseObjectLiteral(bool* ok);
654
  Expression* ParseRegExpLiteral(bool seen_equal, bool* ok);
655

    
656
  // Populate the constant properties fixed array for a materialized object
657
  // literal.
658
  void BuildObjectLiteralConstantProperties(
659
      ZoneList<ObjectLiteral::Property*>* properties,
660
      Handle<FixedArray> constants,
661
      bool* is_simple,
662
      bool* fast_elements,
663
      int* depth,
664
      bool* may_store_doubles);
665

    
666
  // Decide if a property should be in the object boilerplate.
667
  bool IsBoilerplateProperty(ObjectLiteral::Property* property);
668
  // If the expression is a literal, return the literal value;
669
  // if the expression is a materialized literal and is simple return a
670
  // compile time value as encoded by CompileTimeValue::GetValue().
671
  // Otherwise, return undefined literal as the placeholder
672
  // in the object literal boilerplate.
673
  Handle<Object> GetBoilerplateValue(Expression* expression);
674

    
675
  // Initialize the components of a for-in / for-of statement.
676
  void InitializeForEachStatement(ForEachStatement* stmt,
677
                                  Expression* each,
678
                                  Expression* subject,
679
                                  Statement* body);
680

    
681
  ZoneList<Expression*>* ParseArguments(bool* ok);
682
  FunctionLiteral* ParseFunctionLiteral(Handle<String> var_name,
683
                                        bool name_is_reserved,
684
                                        bool is_generator,
685
                                        int function_token_position,
686
                                        FunctionLiteral::FunctionType type,
687
                                        bool* ok);
688

    
689

    
690
  // Magical syntax support.
691
  Expression* ParseV8Intrinsic(bool* ok);
692

    
693
  bool is_generator() const { return current_function_state_->is_generator(); }
694

    
695
  bool CheckInOrOf(bool accept_OF, ForEachStatement::VisitMode* visit_mode);
696

    
697
  Handle<String> LiteralString(PretenureFlag tenured) {
698
    if (scanner().is_literal_ascii()) {
699
      return isolate_->factory()->NewStringFromAscii(
700
          scanner().literal_ascii_string(), tenured);
701
    } else {
702
      return isolate_->factory()->NewStringFromTwoByte(
703
            scanner().literal_utf16_string(), tenured);
704
    }
705
  }
706

    
707
  Handle<String> NextLiteralString(PretenureFlag tenured) {
708
    if (scanner().is_next_literal_ascii()) {
709
      return isolate_->factory()->NewStringFromAscii(
710
          scanner().next_literal_ascii_string(), tenured);
711
    } else {
712
      return isolate_->factory()->NewStringFromTwoByte(
713
          scanner().next_literal_utf16_string(), tenured);
714
    }
715
  }
716

    
717
  Handle<String> GetSymbol();
718

    
719
  // Get odd-ball literals.
720
  Literal* GetLiteralUndefined(int position);
721
  Literal* GetLiteralTheHole(int position);
722

    
723
  Handle<String> ParseIdentifier(bool* ok);
724
  Handle<String> ParseIdentifierOrStrictReservedWord(
725
      bool* is_strict_reserved, bool* ok);
726
  Handle<String> ParseIdentifierName(bool* ok);
727
  Handle<String> ParseIdentifierNameOrGetOrSet(bool* is_get,
728
                                               bool* is_set,
729
                                               bool* ok);
730

    
731
  // Determine if the expression is a variable proxy and mark it as being used
732
  // in an assignment or with a increment/decrement operator. This is currently
733
  // used on for the statically checking assignments to harmony const bindings.
734
  void MarkAsLValue(Expression* expression);
735

    
736
  // Strict mode validation of LValue expressions
737
  void CheckStrictModeLValue(Expression* expression,
738
                             const char* error,
739
                             bool* ok);
740

    
741
  // For harmony block scoping mode: Check if the scope has conflicting var/let
742
  // declarations from different scopes. It covers for example
743
  //
744
  // function f() { { { var x; } let x; } }
745
  // function g() { { var x; let x; } }
746
  //
747
  // The var declarations are hoisted to the function scope, but originate from
748
  // a scope where the name has also been let bound or the var declaration is
749
  // hoisted over such a scope.
750
  void CheckConflictingVarDeclarations(Scope* scope, bool* ok);
751

    
752
  // Parser support
753
  VariableProxy* NewUnresolved(Handle<String> name,
754
                               VariableMode mode,
755
                               Interface* interface);
756
  void Declare(Declaration* declaration, bool resolve, bool* ok);
757

    
758
  bool TargetStackContainsLabel(Handle<String> label);
759
  BreakableStatement* LookupBreakTarget(Handle<String> label, bool* ok);
760
  IterationStatement* LookupContinueTarget(Handle<String> label, bool* ok);
761

    
762
  void RegisterTargetUse(Label* target, Target* stop);
763

    
764
  // Factory methods.
765

    
766
  Scope* NewScope(Scope* parent, ScopeType type);
767

    
768
  Handle<String> LookupSymbol(int symbol_id);
769

    
770
  Handle<String> LookupCachedSymbol(int symbol_id);
771

    
772
  // Generate AST node that throw a ReferenceError with the given type.
773
  Expression* NewThrowReferenceError(Handle<String> type);
774

    
775
  // Generate AST node that throw a SyntaxError with the given
776
  // type. The first argument may be null (in the handle sense) in
777
  // which case no arguments are passed to the constructor.
778
  Expression* NewThrowSyntaxError(Handle<String> type, Handle<Object> first);
779

    
780
  // Generate AST node that throw a TypeError with the given
781
  // type. Both arguments must be non-null (in the handle sense).
782
  Expression* NewThrowTypeError(Handle<String> type,
783
                                Handle<Object> first,
784
                                Handle<Object> second);
785

    
786
  // Generic AST generator for throwing errors from compiled code.
787
  Expression* NewThrowError(Handle<String> constructor,
788
                            Handle<String> type,
789
                            Vector< Handle<Object> > arguments);
790

    
791
  PreParser::PreParseResult LazyParseFunctionLiteral(
792
       SingletonLogger* logger);
793

    
794
  AstNodeFactory<AstConstructionVisitor>* factory() {
795
    return current_function_state_->factory();
796
  }
797

    
798
  Isolate* isolate_;
799
  ZoneList<Handle<String> > symbol_cache_;
800

    
801
  Handle<Script> script_;
802
  Scanner scanner_;
803
  PreParser* reusable_preparser_;
804
  Scope* top_scope_;
805
  Scope* original_scope_;  // for ES5 function declarations in sloppy eval
806
  FunctionState* current_function_state_;
807
  Target* target_stack_;  // for break, continue statements
808
  v8::Extension* extension_;
809
  ScriptDataImpl* pre_parse_data_;
810
  FuncNameInferrer* fni_;
811

    
812
  Mode mode_;
813
  // If true, the next (and immediately following) function literal is
814
  // preceded by a parenthesis.
815
  // Heuristically that means that the function will be called immediately,
816
  // so never lazily compile it.
817
  bool parenthesized_function_;
818

    
819
  Zone* zone_;
820
  CompilationInfo* info_;
821
  friend class BlockState;
822
  friend class FunctionState;
823
};
824

    
825

    
826
// Support for handling complex values (array and object literals) that
827
// can be fully handled at compile time.
828
class CompileTimeValue: public AllStatic {
829
 public:
830
  enum LiteralType {
831
    OBJECT_LITERAL_FAST_ELEMENTS,
832
    OBJECT_LITERAL_SLOW_ELEMENTS,
833
    ARRAY_LITERAL
834
  };
835

    
836
  static bool IsCompileTimeValue(Expression* expression);
837

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

    
841
  // Get the type of a compile time value returned by GetValue().
842
  static LiteralType GetLiteralType(Handle<FixedArray> value);
843

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

    
847
 private:
848
  static const int kLiteralTypeSlot = 0;
849
  static const int kElementsSlot = 1;
850

    
851
  DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue);
852
};
853

    
854
} }  // namespace v8::internal
855

    
856
#endif  // V8_PARSER_H_