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 / ast.h @ 40c0f755

History | View | Annotate | Download (49.7 KB)

1
// Copyright 2006-2008 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_AST_H_
29
#define V8_AST_H_
30

    
31
#include "execution.h"
32
#include "factory.h"
33
#include "runtime.h"
34
#include "token.h"
35
#include "variables.h"
36
#include "macro-assembler.h"
37
#include "jsregexp.h"
38
#include "jump-target.h"
39

    
40
namespace v8 { namespace internal {
41

    
42
// The abstract syntax tree is an intermediate, light-weight
43
// representation of the parsed JavaScript code suitable for
44
// compilation to native code.
45

    
46
// Nodes are allocated in a separate zone, which allows faster
47
// allocation and constant-time deallocation of the entire syntax
48
// tree.
49

    
50

    
51
// ----------------------------------------------------------------------------
52
// Nodes of the abstract syntax tree. Only concrete classes are
53
// enumerated here.
54

    
55
#define NODE_LIST(V)                            \
56
  V(Block)                                      \
57
  V(Declaration)                                \
58
  V(ExpressionStatement)                        \
59
  V(EmptyStatement)                             \
60
  V(IfStatement)                                \
61
  V(ContinueStatement)                          \
62
  V(BreakStatement)                             \
63
  V(ReturnStatement)                            \
64
  V(WithEnterStatement)                         \
65
  V(WithExitStatement)                          \
66
  V(SwitchStatement)                            \
67
  V(LoopStatement)                              \
68
  V(ForInStatement)                             \
69
  V(TryCatch)                                   \
70
  V(TryFinally)                                 \
71
  V(DebuggerStatement)                          \
72
  V(FunctionLiteral)                            \
73
  V(FunctionBoilerplateLiteral)                 \
74
  V(Conditional)                                \
75
  V(Slot)                                       \
76
  V(VariableProxy)                              \
77
  V(Literal)                                    \
78
  V(RegExpLiteral)                              \
79
  V(ObjectLiteral)                              \
80
  V(ArrayLiteral)                               \
81
  V(CatchExtensionObject)                       \
82
  V(Assignment)                                 \
83
  V(Throw)                                      \
84
  V(Property)                                   \
85
  V(Call)                                       \
86
  V(CallEval)                                   \
87
  V(CallNew)                                    \
88
  V(CallRuntime)                                \
89
  V(UnaryOperation)                             \
90
  V(CountOperation)                             \
91
  V(BinaryOperation)                            \
92
  V(CompareOperation)                           \
93
  V(ThisFunction)
94

    
95

    
96
// Forward declarations
97
class TargetCollector;
98
class MaterializedLiteral;
99

    
100
#define DEF_FORWARD_DECLARATION(type) class type;
101
NODE_LIST(DEF_FORWARD_DECLARATION)
102
#undef DEF_FORWARD_DECLARATION
103

    
104

    
105
// Typedef only introduced to avoid unreadable code.
106
// Please do appreciate the required space in "> >".
107
typedef ZoneList<Handle<String> > ZoneStringList;
108

    
109

    
110
class Node: public ZoneObject {
111
 public:
112
  Node(): statement_pos_(RelocInfo::kNoPosition) { }
113
  virtual ~Node() { }
114
  virtual void Accept(AstVisitor* v) = 0;
115

    
116
  // Type testing & conversion.
117
  virtual Statement* AsStatement() { return NULL; }
118
  virtual ExpressionStatement* AsExpressionStatement() { return NULL; }
119
  virtual EmptyStatement* AsEmptyStatement() { return NULL; }
120
  virtual Expression* AsExpression() { return NULL; }
121
  virtual Literal* AsLiteral() { return NULL; }
122
  virtual Slot* AsSlot() { return NULL; }
123
  virtual VariableProxy* AsVariableProxy() { return NULL; }
124
  virtual Property* AsProperty() { return NULL; }
125
  virtual Call* AsCall() { return NULL; }
126
  virtual TargetCollector* AsTargetCollector() { return NULL; }
127
  virtual BreakableStatement* AsBreakableStatement() { return NULL; }
128
  virtual IterationStatement* AsIterationStatement() { return NULL; }
129
  virtual UnaryOperation* AsUnaryOperation() { return NULL; }
130
  virtual BinaryOperation* AsBinaryOperation() { return NULL; }
131
  virtual Assignment* AsAssignment() { return NULL; }
132
  virtual FunctionLiteral* AsFunctionLiteral() { return NULL; }
133
  virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; }
134
  virtual ObjectLiteral* AsObjectLiteral() { return NULL; }
135
  virtual ArrayLiteral* AsArrayLiteral() { return NULL; }
136

    
137
  void set_statement_pos(int statement_pos) { statement_pos_ = statement_pos; }
138
  int statement_pos() const { return statement_pos_; }
139

    
140
 private:
141
  int statement_pos_;
142
};
143

    
144

    
145
class Statement: public Node {
146
 public:
147
  virtual Statement* AsStatement()  { return this; }
148
  virtual ReturnStatement* AsReturnStatement() { return NULL; }
149

    
150
  bool IsEmpty() { return AsEmptyStatement() != NULL; }
151
};
152

    
153

    
154
class Expression: public Node {
155
 public:
156
  virtual Expression* AsExpression()  { return this; }
157

    
158
  virtual bool IsValidLeftHandSide() { return false; }
159

    
160
  // Mark the expression as being compiled as an expression
161
  // statement. This is used to transform postfix increments to
162
  // (faster) prefix increments.
163
  virtual void MarkAsStatement() { /* do nothing */ }
164

    
165
  // Static type information for this expression.
166
  SmiAnalysis* type() { return &type_; }
167

    
168
 private:
169
  SmiAnalysis type_;
170
};
171

    
172

    
173
/**
174
 * A sentinel used during pre parsing that represents some expression
175
 * that is a valid left hand side without having to actually build
176
 * the expression.
177
 */
178
class ValidLeftHandSideSentinel: public Expression {
179
 public:
180
  virtual bool IsValidLeftHandSide() { return true; }
181
  virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
182
  static ValidLeftHandSideSentinel* instance() { return &instance_; }
183
 private:
184
  static ValidLeftHandSideSentinel instance_;
185
};
186

    
187

    
188
class BreakableStatement: public Statement {
189
 public:
190
  enum Type {
191
    TARGET_FOR_ANONYMOUS,
192
    TARGET_FOR_NAMED_ONLY
193
  };
194

    
195
  // The labels associated with this statement. May be NULL;
196
  // if it is != NULL, guaranteed to contain at least one entry.
197
  ZoneStringList* labels() const { return labels_; }
198

    
199
  // Type testing & conversion.
200
  virtual BreakableStatement* AsBreakableStatement() { return this; }
201

    
202
  // Code generation
203
  BreakTarget* break_target() { return &break_target_; }
204

    
205
  // Testers.
206
  bool is_target_for_anonymous() const { return type_ == TARGET_FOR_ANONYMOUS; }
207

    
208
 protected:
209
  BreakableStatement(ZoneStringList* labels, Type type)
210
      : labels_(labels), type_(type) {
211
    ASSERT(labels == NULL || labels->length() > 0);
212
  }
213

    
214
 private:
215
  ZoneStringList* labels_;
216
  Type type_;
217
  BreakTarget break_target_;
218
};
219

    
220

    
221
class Block: public BreakableStatement {
222
 public:
223
  Block(ZoneStringList* labels, int capacity, bool is_initializer_block)
224
      : BreakableStatement(labels, TARGET_FOR_NAMED_ONLY),
225
        statements_(capacity),
226
        is_initializer_block_(is_initializer_block) { }
227

    
228
  virtual void Accept(AstVisitor* v);
229

    
230
  void AddStatement(Statement* statement) { statements_.Add(statement); }
231

    
232
  ZoneList<Statement*>* statements() { return &statements_; }
233
  bool is_initializer_block() const  { return is_initializer_block_; }
234

    
235
 private:
236
  ZoneList<Statement*> statements_;
237
  bool is_initializer_block_;
238
};
239

    
240

    
241
class Declaration: public Node {
242
 public:
243
  Declaration(VariableProxy* proxy, Variable::Mode mode, FunctionLiteral* fun)
244
      : proxy_(proxy),
245
        mode_(mode),
246
        fun_(fun) {
247
    ASSERT(mode == Variable::VAR || mode == Variable::CONST);
248
    // At the moment there are no "const functions"'s in JavaScript...
249
    ASSERT(fun == NULL || mode == Variable::VAR);
250
  }
251

    
252
  virtual void Accept(AstVisitor* v);
253

    
254
  VariableProxy* proxy() const  { return proxy_; }
255
  Variable::Mode mode() const  { return mode_; }
256
  FunctionLiteral* fun() const  { return fun_; }  // may be NULL
257

    
258
 private:
259
  VariableProxy* proxy_;
260
  Variable::Mode mode_;
261
  FunctionLiteral* fun_;
262
};
263

    
264

    
265
class IterationStatement: public BreakableStatement {
266
 public:
267
  // Type testing & conversion.
268
  virtual IterationStatement* AsIterationStatement() { return this; }
269

    
270
  Statement* body() const { return body_; }
271

    
272
  // Code generation
273
  BreakTarget* continue_target()  { return &continue_target_; }
274

    
275
 protected:
276
  explicit IterationStatement(ZoneStringList* labels)
277
      : BreakableStatement(labels, TARGET_FOR_ANONYMOUS), body_(NULL) { }
278

    
279
  void Initialize(Statement* body) {
280
    body_ = body;
281
  }
282

    
283
 private:
284
  Statement* body_;
285
  BreakTarget continue_target_;
286
};
287

    
288

    
289
class LoopStatement: public IterationStatement {
290
 public:
291
  enum Type { DO_LOOP, FOR_LOOP, WHILE_LOOP };
292

    
293
  LoopStatement(ZoneStringList* labels, Type type)
294
      : IterationStatement(labels),
295
        type_(type),
296
        init_(NULL),
297
        cond_(NULL),
298
        next_(NULL),
299
        may_have_function_literal_(true) {
300
  }
301

    
302
  void Initialize(Statement* init,
303
                  Expression* cond,
304
                  Statement* next,
305
                  Statement* body) {
306
    ASSERT(init == NULL || type_ == FOR_LOOP);
307
    ASSERT(next == NULL || type_ == FOR_LOOP);
308
    IterationStatement::Initialize(body);
309
    init_ = init;
310
    cond_ = cond;
311
    next_ = next;
312
  }
313

    
314
  virtual void Accept(AstVisitor* v);
315

    
316
  Type type() const  { return type_; }
317
  Statement* init() const  { return init_; }
318
  Expression* cond() const  { return cond_; }
319
  Statement* next() const  { return next_; }
320
  bool may_have_function_literal() const {
321
    return may_have_function_literal_;
322
  }
323

    
324
#ifdef DEBUG
325
  const char* OperatorString() const;
326
#endif
327

    
328
 private:
329
  Type type_;
330
  Statement* init_;
331
  Expression* cond_;
332
  Statement* next_;
333
  // True if there is a function literal subexpression in the condition.
334
  bool may_have_function_literal_;
335

    
336
  friend class AstOptimizer;
337
};
338

    
339

    
340
class ForInStatement: public IterationStatement {
341
 public:
342
  explicit ForInStatement(ZoneStringList* labels)
343
      : IterationStatement(labels), each_(NULL), enumerable_(NULL) { }
344

    
345
  void Initialize(Expression* each, Expression* enumerable, Statement* body) {
346
    IterationStatement::Initialize(body);
347
    each_ = each;
348
    enumerable_ = enumerable;
349
  }
350

    
351
  virtual void Accept(AstVisitor* v);
352

    
353
  Expression* each() const { return each_; }
354
  Expression* enumerable() const { return enumerable_; }
355

    
356
 private:
357
  Expression* each_;
358
  Expression* enumerable_;
359
};
360

    
361

    
362
class ExpressionStatement: public Statement {
363
 public:
364
  explicit ExpressionStatement(Expression* expression)
365
      : expression_(expression) { }
366

    
367
  virtual void Accept(AstVisitor* v);
368

    
369
  // Type testing & conversion.
370
  virtual ExpressionStatement* AsExpressionStatement() { return this; }
371

    
372
  void set_expression(Expression* e) { expression_ = e; }
373
  Expression* expression() { return expression_; }
374

    
375
 private:
376
  Expression* expression_;
377
};
378

    
379

    
380
class ContinueStatement: public Statement {
381
 public:
382
  explicit ContinueStatement(IterationStatement* target)
383
      : target_(target) { }
384

    
385
  virtual void Accept(AstVisitor* v);
386

    
387
  IterationStatement* target() const  { return target_; }
388

    
389
 private:
390
  IterationStatement* target_;
391
};
392

    
393

    
394
class BreakStatement: public Statement {
395
 public:
396
  explicit BreakStatement(BreakableStatement* target)
397
      : target_(target) { }
398

    
399
  virtual void Accept(AstVisitor* v);
400

    
401
  BreakableStatement* target() const  { return target_; }
402

    
403
 private:
404
  BreakableStatement* target_;
405
};
406

    
407

    
408
class ReturnStatement: public Statement {
409
 public:
410
  explicit ReturnStatement(Expression* expression)
411
      : expression_(expression) { }
412

    
413
  virtual void Accept(AstVisitor* v);
414

    
415
  // Type testing & conversion.
416
  virtual ReturnStatement* AsReturnStatement() { return this; }
417

    
418
  Expression* expression() { return expression_; }
419

    
420
 private:
421
  Expression* expression_;
422
};
423

    
424

    
425
class WithEnterStatement: public Statement {
426
 public:
427
  explicit WithEnterStatement(Expression* expression, bool is_catch_block)
428
      : expression_(expression), is_catch_block_(is_catch_block) { }
429

    
430
  virtual void Accept(AstVisitor* v);
431

    
432
  Expression* expression() const  { return expression_; }
433

    
434
  bool is_catch_block() const { return is_catch_block_; }
435

    
436
 private:
437
  Expression* expression_;
438
  bool is_catch_block_;
439
};
440

    
441

    
442
class WithExitStatement: public Statement {
443
 public:
444
  WithExitStatement() { }
445

    
446
  virtual void Accept(AstVisitor* v);
447
};
448

    
449

    
450
class CaseClause: public ZoneObject {
451
 public:
452
  CaseClause(Expression* label, ZoneList<Statement*>* statements)
453
      : label_(label), statements_(statements) { }
454

    
455
  bool is_default() const  { return label_ == NULL; }
456
  Expression* label() const  {
457
    CHECK(!is_default());
458
    return label_;
459
  }
460
  JumpTarget* body_target() { return &body_target_; }
461
  ZoneList<Statement*>* statements() const  { return statements_; }
462

    
463
 private:
464
  Expression* label_;
465
  JumpTarget body_target_;
466
  ZoneList<Statement*>* statements_;
467
};
468

    
469

    
470
class SwitchStatement: public BreakableStatement {
471
 public:
472
  explicit SwitchStatement(ZoneStringList* labels)
473
      : BreakableStatement(labels, TARGET_FOR_ANONYMOUS),
474
        tag_(NULL), cases_(NULL) { }
475

    
476
  void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) {
477
    tag_ = tag;
478
    cases_ = cases;
479
  }
480

    
481
  virtual void Accept(AstVisitor* v);
482

    
483
  Expression* tag() const  { return tag_; }
484
  ZoneList<CaseClause*>* cases() const  { return cases_; }
485

    
486
 private:
487
  Expression* tag_;
488
  ZoneList<CaseClause*>* cases_;
489
};
490

    
491

    
492
// If-statements always have non-null references to their then- and
493
// else-parts. When parsing if-statements with no explicit else-part,
494
// the parser implicitly creates an empty statement. Use the
495
// HasThenStatement() and HasElseStatement() functions to check if a
496
// given if-statement has a then- or an else-part containing code.
497
class IfStatement: public Statement {
498
 public:
499
  IfStatement(Expression* condition,
500
              Statement* then_statement,
501
              Statement* else_statement)
502
      : condition_(condition),
503
        then_statement_(then_statement),
504
        else_statement_(else_statement) { }
505

    
506
  virtual void Accept(AstVisitor* v);
507

    
508
  bool HasThenStatement() const { return !then_statement()->IsEmpty(); }
509
  bool HasElseStatement() const { return !else_statement()->IsEmpty(); }
510

    
511
  Expression* condition() const { return condition_; }
512
  Statement* then_statement() const { return then_statement_; }
513
  Statement* else_statement() const { return else_statement_; }
514

    
515
 private:
516
  Expression* condition_;
517
  Statement* then_statement_;
518
  Statement* else_statement_;
519
};
520

    
521

    
522
// NOTE: TargetCollectors are represented as nodes to fit in the target
523
// stack in the compiler; this should probably be reworked.
524
class TargetCollector: public Node {
525
 public:
526
  explicit TargetCollector(ZoneList<BreakTarget*>* targets)
527
      : targets_(targets) {
528
  }
529

    
530
  // Adds a jump target to the collector. The collector stores a pointer not
531
  // a copy of the target to make binding work, so make sure not to pass in
532
  // references to something on the stack.
533
  void AddTarget(BreakTarget* target);
534

    
535
  // Virtual behaviour. TargetCollectors are never part of the AST.
536
  virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
537
  virtual TargetCollector* AsTargetCollector() { return this; }
538

    
539
  ZoneList<BreakTarget*>* targets() { return targets_; }
540

    
541
 private:
542
  ZoneList<BreakTarget*>* targets_;
543
};
544

    
545

    
546
class TryStatement: public Statement {
547
 public:
548
  explicit TryStatement(Block* try_block)
549
      : try_block_(try_block), escaping_targets_(NULL) { }
550

    
551
  void set_escaping_targets(ZoneList<BreakTarget*>* targets) {
552
    escaping_targets_ = targets;
553
  }
554

    
555
  Block* try_block() const { return try_block_; }
556
  ZoneList<BreakTarget*>* escaping_targets() const { return escaping_targets_; }
557

    
558
 private:
559
  Block* try_block_;
560
  ZoneList<BreakTarget*>* escaping_targets_;
561
};
562

    
563

    
564
class TryCatch: public TryStatement {
565
 public:
566
  TryCatch(Block* try_block, Expression* catch_var, Block* catch_block)
567
      : TryStatement(try_block),
568
        catch_var_(catch_var),
569
        catch_block_(catch_block) {
570
    ASSERT(catch_var->AsVariableProxy() != NULL);
571
  }
572

    
573
  virtual void Accept(AstVisitor* v);
574

    
575
  Expression* catch_var() const  { return catch_var_; }
576
  Block* catch_block() const  { return catch_block_; }
577

    
578
 private:
579
  Expression* catch_var_;
580
  Block* catch_block_;
581
};
582

    
583

    
584
class TryFinally: public TryStatement {
585
 public:
586
  TryFinally(Block* try_block, Block* finally_block)
587
      : TryStatement(try_block),
588
        finally_block_(finally_block) { }
589

    
590
  virtual void Accept(AstVisitor* v);
591

    
592
  Block* finally_block() const { return finally_block_; }
593

    
594
 private:
595
  Block* finally_block_;
596
};
597

    
598

    
599
class DebuggerStatement: public Statement {
600
 public:
601
  virtual void Accept(AstVisitor* v);
602
};
603

    
604

    
605
class EmptyStatement: public Statement {
606
 public:
607
  virtual void Accept(AstVisitor* v);
608

    
609
  // Type testing & conversion.
610
  virtual EmptyStatement* AsEmptyStatement() { return this; }
611
};
612

    
613

    
614
class Literal: public Expression {
615
 public:
616
  explicit Literal(Handle<Object> handle) : handle_(handle) { }
617

    
618
  virtual void Accept(AstVisitor* v);
619

    
620
  // Type testing & conversion.
621
  virtual Literal* AsLiteral() { return this; }
622

    
623
  // Check if this literal is identical to the other literal.
624
  bool IsIdenticalTo(const Literal* other) const {
625
    return handle_.is_identical_to(other->handle_);
626
  }
627

    
628
  // Identity testers.
629
  bool IsNull() const { return handle_.is_identical_to(Factory::null_value()); }
630
  bool IsTrue() const { return handle_.is_identical_to(Factory::true_value()); }
631
  bool IsFalse() const {
632
    return handle_.is_identical_to(Factory::false_value());
633
  }
634

    
635
  Handle<Object> handle() const { return handle_; }
636

    
637
 private:
638
  Handle<Object> handle_;
639
};
640

    
641

    
642
// Base class for literals that needs space in the corresponding JSFunction.
643
class MaterializedLiteral: public Expression {
644
 public:
645
  explicit MaterializedLiteral(int literal_index, bool is_simple, int depth)
646
      : literal_index_(literal_index), is_simple_(is_simple), depth_(depth) {}
647

    
648
  virtual MaterializedLiteral* AsMaterializedLiteral() { return this; }
649

    
650
  int literal_index() { return literal_index_; }
651

    
652
  // A materialized literal is simple if the values consist of only
653
  // constants and simple object and array literals.
654
  bool is_simple() const { return is_simple_; }
655

    
656
  int depth() const { return depth_; }
657

    
658
 private:
659
  int literal_index_;
660
  bool is_simple_;
661
  int depth_;
662
};
663

    
664

    
665
// An object literal has a boilerplate object that is used
666
// for minimizing the work when constructing it at runtime.
667
class ObjectLiteral: public MaterializedLiteral {
668
 public:
669
  // Property is used for passing information
670
  // about an object literal's properties from the parser
671
  // to the code generator.
672
  class Property: public ZoneObject {
673
   public:
674

    
675
    enum Kind {
676
      CONSTANT,              // Property with constant value (compile time).
677
      COMPUTED,              // Property with computed value (execution time).
678
      MATERIALIZED_LITERAL,  // Property value is a materialized literal.
679
      GETTER, SETTER,        // Property is an accessor function.
680
      PROTOTYPE              // Property is __proto__.
681
    };
682

    
683
    Property(Literal* key, Expression* value);
684
    Property(bool is_getter, FunctionLiteral* value);
685

    
686
    Literal* key() { return key_; }
687
    Expression* value() { return value_; }
688
    Kind kind() { return kind_; }
689

    
690
   private:
691
    Literal* key_;
692
    Expression* value_;
693
    Kind kind_;
694
  };
695

    
696
  ObjectLiteral(Handle<FixedArray> constant_properties,
697
                ZoneList<Property*>* properties,
698
                int literal_index,
699
                bool is_simple,
700
                int depth)
701
      : MaterializedLiteral(literal_index, is_simple, depth),
702
        constant_properties_(constant_properties),
703
        properties_(properties) {}
704

    
705
  virtual ObjectLiteral* AsObjectLiteral() { return this; }
706
  virtual void Accept(AstVisitor* v);
707

    
708
  Handle<FixedArray> constant_properties() const {
709
    return constant_properties_;
710
  }
711
  ZoneList<Property*>* properties() const { return properties_; }
712

    
713
 private:
714
  Handle<FixedArray> constant_properties_;
715
  ZoneList<Property*>* properties_;
716
};
717

    
718

    
719
// Node for capturing a regexp literal.
720
class RegExpLiteral: public MaterializedLiteral {
721
 public:
722
  RegExpLiteral(Handle<String> pattern,
723
                Handle<String> flags,
724
                int literal_index)
725
      : MaterializedLiteral(literal_index, false, 1),
726
        pattern_(pattern),
727
        flags_(flags) {}
728

    
729
  virtual void Accept(AstVisitor* v);
730

    
731
  Handle<String> pattern() const { return pattern_; }
732
  Handle<String> flags() const { return flags_; }
733

    
734
 private:
735
  Handle<String> pattern_;
736
  Handle<String> flags_;
737
};
738

    
739
// An array literal has a literals object that is used
740
// for minimizing the work when constructing it at runtime.
741
class ArrayLiteral: public MaterializedLiteral {
742
 public:
743
  ArrayLiteral(Handle<FixedArray> literals,
744
               ZoneList<Expression*>* values,
745
               int literal_index,
746
               bool is_simple,
747
               int depth)
748
      : MaterializedLiteral(literal_index, is_simple, depth),
749
        literals_(literals),
750
        values_(values) {}
751

    
752
  virtual void Accept(AstVisitor* v);
753
  virtual ArrayLiteral* AsArrayLiteral() { return this; }
754

    
755
  Handle<FixedArray> literals() const { return literals_; }
756
  ZoneList<Expression*>* values() const { return values_; }
757

    
758
 private:
759
  Handle<FixedArray> literals_;
760
  ZoneList<Expression*>* values_;
761
};
762

    
763

    
764
// Node for constructing a context extension object for a catch block.
765
// The catch context extension object has one property, the catch
766
// variable, which should be DontDelete.
767
class CatchExtensionObject: public Expression {
768
 public:
769
  CatchExtensionObject(Literal* key, VariableProxy* value)
770
      : key_(key), value_(value) {
771
  }
772

    
773
  virtual void Accept(AstVisitor* v);
774

    
775
  Literal* key() const { return key_; }
776
  VariableProxy* value() const { return value_; }
777

    
778
 private:
779
  Literal* key_;
780
  VariableProxy* value_;
781
};
782

    
783

    
784
class VariableProxy: public Expression {
785
 public:
786
  virtual void Accept(AstVisitor* v);
787

    
788
  // Type testing & conversion
789
  virtual Property* AsProperty() {
790
    return var_ == NULL ? NULL : var_->AsProperty();
791
  }
792
  virtual VariableProxy* AsVariableProxy()  { return this; }
793

    
794
  Variable* AsVariable() {
795
    return this == NULL || var_ == NULL ? NULL : var_->AsVariable();
796
  }
797
  virtual bool IsValidLeftHandSide() {
798
    return var_ == NULL ? true : var_->IsValidLeftHandSide();
799
  }
800
  bool IsVariable(Handle<String> n) {
801
    return !is_this() && name().is_identical_to(n);
802
  }
803

    
804
  // If this assertion fails it means that some code has tried to
805
  // treat the special "this" variable as an ordinary variable with
806
  // the name "this".
807
  Handle<String> name() const  { return name_; }
808
  Variable* var() const  { return var_; }
809
  UseCount* var_uses()  { return &var_uses_; }
810
  UseCount* obj_uses()  { return &obj_uses_; }
811
  bool is_this() const  { return is_this_; }
812
  bool inside_with() const  { return inside_with_; }
813

    
814
  // Bind this proxy to the variable var.
815
  void BindTo(Variable* var);
816

    
817
 protected:
818
  Handle<String> name_;
819
  Variable* var_;  // resolved variable, or NULL
820
  bool is_this_;
821
  bool inside_with_;
822

    
823
  // VariableProxy usage info.
824
  UseCount var_uses_;  // uses of the variable value
825
  UseCount obj_uses_;  // uses of the object the variable points to
826

    
827
  VariableProxy(Handle<String> name, bool is_this, bool inside_with);
828
  explicit VariableProxy(bool is_this);
829

    
830
  friend class Scope;
831
};
832

    
833

    
834
class VariableProxySentinel: public VariableProxy {
835
 public:
836
  virtual bool IsValidLeftHandSide() { return !is_this(); }
837
  static VariableProxySentinel* this_proxy() { return &this_proxy_; }
838
  static VariableProxySentinel* identifier_proxy() {
839
    return &identifier_proxy_;
840
  }
841

    
842
 private:
843
  explicit VariableProxySentinel(bool is_this) : VariableProxy(is_this) { }
844
  static VariableProxySentinel this_proxy_;
845
  static VariableProxySentinel identifier_proxy_;
846
};
847

    
848

    
849
class Slot: public Expression {
850
 public:
851
  enum Type {
852
    // A slot in the parameter section on the stack. index() is
853
    // the parameter index, counting left-to-right, starting at 0.
854
    PARAMETER,
855

    
856
    // A slot in the local section on the stack. index() is
857
    // the variable index in the stack frame, starting at 0.
858
    LOCAL,
859

    
860
    // An indexed slot in a heap context. index() is the
861
    // variable index in the context object on the heap,
862
    // starting at 0. var()->scope() is the corresponding
863
    // scope.
864
    CONTEXT,
865

    
866
    // A named slot in a heap context. var()->name() is the
867
    // variable name in the context object on the heap,
868
    // with lookup starting at the current context. index()
869
    // is invalid.
870
    LOOKUP,
871

    
872
    // A property in the global object. var()->name() is
873
    // the property name.
874
    GLOBAL
875
  };
876

    
877
  Slot(Variable* var, Type type, int index)
878
      : var_(var), type_(type), index_(index) {
879
    ASSERT(var != NULL);
880
  }
881

    
882
  virtual void Accept(AstVisitor* v);
883

    
884
  // Type testing & conversion
885
  virtual Slot* AsSlot()  { return this; }
886

    
887
  // Accessors
888
  Variable* var() const  { return var_; }
889
  Type type() const  { return type_; }
890
  int index() const  { return index_; }
891

    
892
 private:
893
  Variable* var_;
894
  Type type_;
895
  int index_;
896
};
897

    
898

    
899
class Property: public Expression {
900
 public:
901
  // Synthetic properties are property lookups introduced by the system,
902
  // to objects that aren't visible to the user. Function calls to synthetic
903
  // properties should use the global object as receiver, not the base object
904
  // of the resolved Reference.
905
  enum Type { NORMAL, SYNTHETIC };
906
  Property(Expression* obj, Expression* key, int pos, Type type = NORMAL)
907
      : obj_(obj), key_(key), pos_(pos), type_(type) { }
908

    
909
  virtual void Accept(AstVisitor* v);
910

    
911
  // Type testing & conversion
912
  virtual Property* AsProperty() { return this; }
913

    
914
  virtual bool IsValidLeftHandSide() { return true; }
915

    
916
  Expression* obj() const { return obj_; }
917
  Expression* key() const { return key_; }
918
  int position() const { return pos_; }
919
  bool is_synthetic() const { return type_ == SYNTHETIC; }
920

    
921
  // Returns a property singleton property access on 'this'.  Used
922
  // during preparsing.
923
  static Property* this_property() { return &this_property_; }
924

    
925
 private:
926
  Expression* obj_;
927
  Expression* key_;
928
  int pos_;
929
  Type type_;
930

    
931
  // Dummy property used during preparsing.
932
  static Property this_property_;
933
};
934

    
935

    
936
class Call: public Expression {
937
 public:
938
  Call(Expression* expression,
939
       ZoneList<Expression*>* arguments,
940
       int pos)
941
      : expression_(expression),
942
        arguments_(arguments),
943
        pos_(pos) { }
944

    
945
  virtual void Accept(AstVisitor* v);
946

    
947
  // Type testing and conversion.
948
  virtual Call* AsCall() { return this; }
949

    
950
  Expression* expression() const { return expression_; }
951
  ZoneList<Expression*>* arguments() const { return arguments_; }
952
  int position() { return pos_; }
953

    
954
  static Call* sentinel() { return &sentinel_; }
955

    
956
 private:
957
  Expression* expression_;
958
  ZoneList<Expression*>* arguments_;
959
  int pos_;
960

    
961
  static Call sentinel_;
962
};
963

    
964

    
965
class CallNew: public Call {
966
 public:
967
  CallNew(Expression* expression, ZoneList<Expression*>* arguments, int pos)
968
      : Call(expression, arguments, pos) { }
969

    
970
  virtual void Accept(AstVisitor* v);
971
};
972

    
973

    
974
// The CallEval class represents a call of the form 'eval(...)' where eval
975
// cannot be seen to be overwritten at compile time. It is potentially a
976
// direct (i.e. not aliased) eval call. The real nature of the call is
977
// determined at runtime.
978
class CallEval: public Call {
979
 public:
980
  CallEval(Expression* expression, ZoneList<Expression*>* arguments, int pos)
981
      : Call(expression, arguments, pos) { }
982

    
983
  virtual void Accept(AstVisitor* v);
984

    
985
  static CallEval* sentinel() { return &sentinel_; }
986

    
987
 private:
988
  static CallEval sentinel_;
989
};
990

    
991

    
992
// The CallRuntime class does not represent any official JavaScript
993
// language construct. Instead it is used to call a C or JS function
994
// with a set of arguments. This is used from the builtins that are
995
// implemented in JavaScript (see "v8natives.js").
996
class CallRuntime: public Expression {
997
 public:
998
  CallRuntime(Handle<String> name,
999
              Runtime::Function* function,
1000
              ZoneList<Expression*>* arguments)
1001
      : name_(name), function_(function), arguments_(arguments) { }
1002

    
1003
  virtual void Accept(AstVisitor* v);
1004

    
1005
  Handle<String> name() const { return name_; }
1006
  Runtime::Function* function() const { return function_; }
1007
  ZoneList<Expression*>* arguments() const { return arguments_; }
1008

    
1009
 private:
1010
  Handle<String> name_;
1011
  Runtime::Function* function_;
1012
  ZoneList<Expression*>* arguments_;
1013
};
1014

    
1015

    
1016
class UnaryOperation: public Expression {
1017
 public:
1018
  UnaryOperation(Token::Value op, Expression* expression)
1019
      : op_(op), expression_(expression) {
1020
    ASSERT(Token::IsUnaryOp(op));
1021
  }
1022

    
1023
  virtual void Accept(AstVisitor* v);
1024

    
1025
  // Type testing & conversion
1026
  virtual UnaryOperation* AsUnaryOperation() { return this; }
1027

    
1028
  Token::Value op() const { return op_; }
1029
  Expression* expression() const { return expression_; }
1030

    
1031
 private:
1032
  Token::Value op_;
1033
  Expression* expression_;
1034
};
1035

    
1036

    
1037
class BinaryOperation: public Expression {
1038
 public:
1039
  BinaryOperation(Token::Value op, Expression* left, Expression* right)
1040
      : op_(op), left_(left), right_(right) {
1041
    ASSERT(Token::IsBinaryOp(op));
1042
  }
1043

    
1044
  virtual void Accept(AstVisitor* v);
1045

    
1046
  // Type testing & conversion
1047
  virtual BinaryOperation* AsBinaryOperation() { return this; }
1048

    
1049
  // True iff the result can be safely overwritten (to avoid allocation).
1050
  // False for operations that can return one of their operands.
1051
  bool ResultOverwriteAllowed() {
1052
    switch (op_) {
1053
      case Token::COMMA:
1054
      case Token::OR:
1055
      case Token::AND:
1056
        return false;
1057
      case Token::BIT_OR:
1058
      case Token::BIT_XOR:
1059
      case Token::BIT_AND:
1060
      case Token::SHL:
1061
      case Token::SAR:
1062
      case Token::SHR:
1063
      case Token::ADD:
1064
      case Token::SUB:
1065
      case Token::MUL:
1066
      case Token::DIV:
1067
      case Token::MOD:
1068
        return true;
1069
      default:
1070
        UNREACHABLE();
1071
    }
1072
    return false;
1073
  }
1074

    
1075
  Token::Value op() const { return op_; }
1076
  Expression* left() const { return left_; }
1077
  Expression* right() const { return right_; }
1078

    
1079
 private:
1080
  Token::Value op_;
1081
  Expression* left_;
1082
  Expression* right_;
1083
};
1084

    
1085

    
1086
class CountOperation: public Expression {
1087
 public:
1088
  CountOperation(bool is_prefix, Token::Value op, Expression* expression)
1089
      : is_prefix_(is_prefix), op_(op), expression_(expression) {
1090
    ASSERT(Token::IsCountOp(op));
1091
  }
1092

    
1093
  virtual void Accept(AstVisitor* v);
1094

    
1095
  bool is_prefix() const { return is_prefix_; }
1096
  bool is_postfix() const { return !is_prefix_; }
1097
  Token::Value op() const { return op_; }
1098
  Expression* expression() const { return expression_; }
1099

    
1100
  virtual void MarkAsStatement() { is_prefix_ = true; }
1101

    
1102
 private:
1103
  bool is_prefix_;
1104
  Token::Value op_;
1105
  Expression* expression_;
1106
};
1107

    
1108

    
1109
class CompareOperation: public Expression {
1110
 public:
1111
  CompareOperation(Token::Value op, Expression* left, Expression* right)
1112
      : op_(op), left_(left), right_(right) {
1113
    ASSERT(Token::IsCompareOp(op));
1114
  }
1115

    
1116
  virtual void Accept(AstVisitor* v);
1117

    
1118
  Token::Value op() const { return op_; }
1119
  Expression* left() const { return left_; }
1120
  Expression* right() const { return right_; }
1121

    
1122
 private:
1123
  Token::Value op_;
1124
  Expression* left_;
1125
  Expression* right_;
1126
};
1127

    
1128

    
1129
class Conditional: public Expression {
1130
 public:
1131
  Conditional(Expression* condition,
1132
              Expression* then_expression,
1133
              Expression* else_expression)
1134
      : condition_(condition),
1135
        then_expression_(then_expression),
1136
        else_expression_(else_expression) { }
1137

    
1138
  virtual void Accept(AstVisitor* v);
1139

    
1140
  Expression* condition() const { return condition_; }
1141
  Expression* then_expression() const { return then_expression_; }
1142
  Expression* else_expression() const { return else_expression_; }
1143

    
1144
 private:
1145
  Expression* condition_;
1146
  Expression* then_expression_;
1147
  Expression* else_expression_;
1148
};
1149

    
1150

    
1151
class Assignment: public Expression {
1152
 public:
1153
  Assignment(Token::Value op, Expression* target, Expression* value, int pos)
1154
      : op_(op), target_(target), value_(value), pos_(pos),
1155
        block_start_(false), block_end_(false) {
1156
    ASSERT(Token::IsAssignmentOp(op));
1157
  }
1158

    
1159
  virtual void Accept(AstVisitor* v);
1160
  virtual Assignment* AsAssignment() { return this; }
1161

    
1162
  Token::Value binary_op() const;
1163

    
1164
  Token::Value op() const { return op_; }
1165
  Expression* target() const { return target_; }
1166
  Expression* value() const { return value_; }
1167
  int position() { return pos_; }
1168

    
1169
  // An initialization block is a series of statments of the form
1170
  // x.y.z.a = ...; x.y.z.b = ...; etc. The parser marks the beginning and
1171
  // ending of these blocks to allow for optimizations of initialization
1172
  // blocks.
1173
  bool starts_initialization_block() { return block_start_; }
1174
  bool ends_initialization_block() { return block_end_; }
1175
  void mark_block_start() { block_start_ = true; }
1176
  void mark_block_end() { block_end_ = true; }
1177

    
1178
 private:
1179
  Token::Value op_;
1180
  Expression* target_;
1181
  Expression* value_;
1182
  int pos_;
1183
  bool block_start_;
1184
  bool block_end_;
1185
};
1186

    
1187

    
1188
class Throw: public Expression {
1189
 public:
1190
  Throw(Expression* exception, int pos)
1191
      : exception_(exception), pos_(pos) {}
1192

    
1193
  virtual void Accept(AstVisitor* v);
1194
  Expression* exception() const { return exception_; }
1195
  int position() const { return pos_; }
1196

    
1197
 private:
1198
  Expression* exception_;
1199
  int pos_;
1200
};
1201

    
1202

    
1203
class FunctionLiteral: public Expression {
1204
 public:
1205
  FunctionLiteral(Handle<String> name,
1206
                  Scope* scope,
1207
                  ZoneList<Statement*>* body,
1208
                  int materialized_literal_count,
1209
                  bool contains_array_literal,
1210
                  int expected_property_count,
1211
                  int num_parameters,
1212
                  int start_position,
1213
                  int end_position,
1214
                  bool is_expression)
1215
      : name_(name),
1216
        scope_(scope),
1217
        body_(body),
1218
        materialized_literal_count_(materialized_literal_count),
1219
        contains_array_literal_(contains_array_literal),
1220
        expected_property_count_(expected_property_count),
1221
        num_parameters_(num_parameters),
1222
        start_position_(start_position),
1223
        end_position_(end_position),
1224
        is_expression_(is_expression),
1225
        loop_nesting_(0),
1226
        function_token_position_(RelocInfo::kNoPosition),
1227
        inferred_name_(Heap::empty_string()) {
1228
#ifdef DEBUG
1229
    already_compiled_ = false;
1230
#endif
1231
  }
1232

    
1233
  virtual void Accept(AstVisitor* v);
1234

    
1235
  // Type testing & conversion
1236
  virtual FunctionLiteral* AsFunctionLiteral()  { return this; }
1237

    
1238
  Handle<String> name() const  { return name_; }
1239
  Scope* scope() const  { return scope_; }
1240
  ZoneList<Statement*>* body() const  { return body_; }
1241
  void set_function_token_position(int pos) { function_token_position_ = pos; }
1242
  int function_token_position() const { return function_token_position_; }
1243
  int start_position() const { return start_position_; }
1244
  int end_position() const { return end_position_; }
1245
  bool is_expression() const { return is_expression_; }
1246

    
1247
  int materialized_literal_count() { return materialized_literal_count_; }
1248
  bool contains_array_literal() { return contains_array_literal_; }
1249
  int expected_property_count() { return expected_property_count_; }
1250
  int num_parameters() { return num_parameters_; }
1251

    
1252
  bool AllowsLazyCompilation();
1253

    
1254
  bool loop_nesting() const { return loop_nesting_; }
1255
  void set_loop_nesting(int nesting) { loop_nesting_ = nesting; }
1256

    
1257
  Handle<String> inferred_name() const  { return inferred_name_; }
1258
  void set_inferred_name(Handle<String> inferred_name) {
1259
    inferred_name_ = inferred_name;
1260
  }
1261

    
1262
#ifdef DEBUG
1263
  void mark_as_compiled() {
1264
    ASSERT(!already_compiled_);
1265
    already_compiled_ = true;
1266
  }
1267
#endif
1268

    
1269
 private:
1270
  Handle<String> name_;
1271
  Scope* scope_;
1272
  ZoneList<Statement*>* body_;
1273
  int materialized_literal_count_;
1274
  bool contains_array_literal_;
1275
  int expected_property_count_;
1276
  int num_parameters_;
1277
  int start_position_;
1278
  int end_position_;
1279
  bool is_expression_;
1280
  int loop_nesting_;
1281
  int function_token_position_;
1282
  Handle<String> inferred_name_;
1283
#ifdef DEBUG
1284
  bool already_compiled_;
1285
#endif
1286
};
1287

    
1288

    
1289
class FunctionBoilerplateLiteral: public Expression {
1290
 public:
1291
  explicit FunctionBoilerplateLiteral(Handle<JSFunction> boilerplate)
1292
      : boilerplate_(boilerplate) {
1293
    ASSERT(boilerplate->IsBoilerplate());
1294
  }
1295

    
1296
  Handle<JSFunction> boilerplate() const { return boilerplate_; }
1297

    
1298
  virtual void Accept(AstVisitor* v);
1299

    
1300
 private:
1301
  Handle<JSFunction> boilerplate_;
1302
};
1303

    
1304

    
1305
class ThisFunction: public Expression {
1306
 public:
1307
  virtual void Accept(AstVisitor* v);
1308
};
1309

    
1310

    
1311
// ----------------------------------------------------------------------------
1312
// Regular expressions
1313

    
1314

    
1315
class RegExpVisitor BASE_EMBEDDED {
1316
 public:
1317
  virtual ~RegExpVisitor() { }
1318
#define MAKE_CASE(Name)                                              \
1319
  virtual void* Visit##Name(RegExp##Name*, void* data) = 0;
1320
  FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
1321
#undef MAKE_CASE
1322
};
1323

    
1324

    
1325
class RegExpTree: public ZoneObject {
1326
 public:
1327
  static const int kInfinity = kMaxInt;
1328
  virtual ~RegExpTree() { }
1329
  virtual void* Accept(RegExpVisitor* visitor, void* data) = 0;
1330
  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1331
                             RegExpNode* on_success) = 0;
1332
  virtual bool IsTextElement() { return false; }
1333
  virtual bool IsAnchored() { return false; }
1334
  virtual int min_match() = 0;
1335
  virtual int max_match() = 0;
1336
  // Returns the interval of registers used for captures within this
1337
  // expression.
1338
  virtual Interval CaptureRegisters() { return Interval::Empty(); }
1339
  virtual void AppendToText(RegExpText* text);
1340
  SmartPointer<const char> ToString();
1341
#define MAKE_ASTYPE(Name)                                                  \
1342
  virtual RegExp##Name* As##Name();                                        \
1343
  virtual bool Is##Name();
1344
  FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE)
1345
#undef MAKE_ASTYPE
1346
};
1347

    
1348

    
1349
class RegExpDisjunction: public RegExpTree {
1350
 public:
1351
  explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives);
1352
  virtual void* Accept(RegExpVisitor* visitor, void* data);
1353
  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1354
                             RegExpNode* on_success);
1355
  virtual RegExpDisjunction* AsDisjunction();
1356
  virtual Interval CaptureRegisters();
1357
  virtual bool IsDisjunction();
1358
  virtual bool IsAnchored();
1359
  virtual int min_match() { return min_match_; }
1360
  virtual int max_match() { return max_match_; }
1361
  ZoneList<RegExpTree*>* alternatives() { return alternatives_; }
1362
 private:
1363
  ZoneList<RegExpTree*>* alternatives_;
1364
  int min_match_;
1365
  int max_match_;
1366
};
1367

    
1368

    
1369
class RegExpAlternative: public RegExpTree {
1370
 public:
1371
  explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes);
1372
  virtual void* Accept(RegExpVisitor* visitor, void* data);
1373
  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1374
                             RegExpNode* on_success);
1375
  virtual RegExpAlternative* AsAlternative();
1376
  virtual Interval CaptureRegisters();
1377
  virtual bool IsAlternative();
1378
  virtual bool IsAnchored();
1379
  virtual int min_match() { return min_match_; }
1380
  virtual int max_match() { return max_match_; }
1381
  ZoneList<RegExpTree*>* nodes() { return nodes_; }
1382
 private:
1383
  ZoneList<RegExpTree*>* nodes_;
1384
  int min_match_;
1385
  int max_match_;
1386
};
1387

    
1388

    
1389
class RegExpAssertion: public RegExpTree {
1390
 public:
1391
  enum Type {
1392
    START_OF_LINE,
1393
    START_OF_INPUT,
1394
    END_OF_LINE,
1395
    END_OF_INPUT,
1396
    BOUNDARY,
1397
    NON_BOUNDARY
1398
  };
1399
  explicit RegExpAssertion(Type type) : type_(type) { }
1400
  virtual void* Accept(RegExpVisitor* visitor, void* data);
1401
  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1402
                             RegExpNode* on_success);
1403
  virtual RegExpAssertion* AsAssertion();
1404
  virtual bool IsAssertion();
1405
  virtual bool IsAnchored();
1406
  virtual int min_match() { return 0; }
1407
  virtual int max_match() { return 0; }
1408
  Type type() { return type_; }
1409
 private:
1410
  Type type_;
1411
};
1412

    
1413

    
1414
class CharacterSet BASE_EMBEDDED {
1415
 public:
1416
  explicit CharacterSet(uc16 standard_set_type)
1417
      : ranges_(NULL),
1418
        standard_set_type_(standard_set_type) {}
1419
  explicit CharacterSet(ZoneList<CharacterRange>* ranges)
1420
      : ranges_(ranges),
1421
        standard_set_type_(0) {}
1422
  ZoneList<CharacterRange>* ranges();
1423
  uc16 standard_set_type() { return standard_set_type_; }
1424
  void set_standard_set_type(uc16 special_set_type) {
1425
    standard_set_type_ = special_set_type;
1426
  }
1427
  bool is_standard() { return standard_set_type_ != 0; }
1428
 private:
1429
  ZoneList<CharacterRange>* ranges_;
1430
  // If non-zero, the value represents a standard set (e.g., all whitespace
1431
  // characters) without having to expand the ranges.
1432
  uc16 standard_set_type_;
1433
};
1434

    
1435

    
1436
class RegExpCharacterClass: public RegExpTree {
1437
 public:
1438
  RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated)
1439
      : set_(ranges),
1440
        is_negated_(is_negated) { }
1441
  explicit RegExpCharacterClass(uc16 type)
1442
      : set_(type),
1443
        is_negated_(false) { }
1444
  virtual void* Accept(RegExpVisitor* visitor, void* data);
1445
  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1446
                             RegExpNode* on_success);
1447
  virtual RegExpCharacterClass* AsCharacterClass();
1448
  virtual bool IsCharacterClass();
1449
  virtual bool IsTextElement() { return true; }
1450
  virtual int min_match() { return 1; }
1451
  virtual int max_match() { return 1; }
1452
  virtual void AppendToText(RegExpText* text);
1453
  CharacterSet character_set() { return set_; }
1454
  // TODO(lrn): Remove need for complex version if is_standard that
1455
  // recognizes a mangled standard set and just do { return set_.is_special(); }
1456
  bool is_standard();
1457
  // Returns a value representing the standard character set if is_standard()
1458
  // returns true.
1459
  // Currently used values are:
1460
  // s : unicode whitespace
1461
  // S : unicode non-whitespace
1462
  // w : ASCII word character (digit, letter, underscore)
1463
  // W : non-ASCII word character
1464
  // d : ASCII digit
1465
  // D : non-ASCII digit
1466
  // . : non-unicode non-newline
1467
  // * : All characters
1468
  uc16 standard_type() { return set_.standard_set_type(); }
1469
  ZoneList<CharacterRange>* ranges() { return set_.ranges(); }
1470
  bool is_negated() { return is_negated_; }
1471
 private:
1472
  CharacterSet set_;
1473
  bool is_negated_;
1474
};
1475

    
1476

    
1477
class RegExpAtom: public RegExpTree {
1478
 public:
1479
  explicit RegExpAtom(Vector<const uc16> data) : data_(data) { }
1480
  virtual void* Accept(RegExpVisitor* visitor, void* data);
1481
  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1482
                             RegExpNode* on_success);
1483
  virtual RegExpAtom* AsAtom();
1484
  virtual bool IsAtom();
1485
  virtual bool IsTextElement() { return true; }
1486
  virtual int min_match() { return data_.length(); }
1487
  virtual int max_match() { return data_.length(); }
1488
  virtual void AppendToText(RegExpText* text);
1489
  Vector<const uc16> data() { return data_; }
1490
  int length() { return data_.length(); }
1491
 private:
1492
  Vector<const uc16> data_;
1493
};
1494

    
1495

    
1496
class RegExpText: public RegExpTree {
1497
 public:
1498
  RegExpText() : elements_(2), length_(0) {}
1499
  virtual void* Accept(RegExpVisitor* visitor, void* data);
1500
  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1501
                             RegExpNode* on_success);
1502
  virtual RegExpText* AsText();
1503
  virtual bool IsText();
1504
  virtual bool IsTextElement() { return true; }
1505
  virtual int min_match() { return length_; }
1506
  virtual int max_match() { return length_; }
1507
  virtual void AppendToText(RegExpText* text);
1508
  void AddElement(TextElement elm)  {
1509
    elements_.Add(elm);
1510
    length_ += elm.length();
1511
  };
1512
  ZoneList<TextElement>* elements() { return &elements_; }
1513
 private:
1514
  ZoneList<TextElement> elements_;
1515
  int length_;
1516
};
1517

    
1518

    
1519
class RegExpQuantifier: public RegExpTree {
1520
 public:
1521
  RegExpQuantifier(int min, int max, bool is_greedy, RegExpTree* body)
1522
      : min_(min),
1523
        max_(max),
1524
        is_greedy_(is_greedy),
1525
        body_(body),
1526
        min_match_(min * body->min_match()) {
1527
    if (max > 0 && body->max_match() > kInfinity / max) {
1528
      max_match_ = kInfinity;
1529
    } else {
1530
      max_match_ = max * body->max_match();
1531
    }
1532
  }
1533
  virtual void* Accept(RegExpVisitor* visitor, void* data);
1534
  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1535
                             RegExpNode* on_success);
1536
  static RegExpNode* ToNode(int min,
1537
                            int max,
1538
                            bool is_greedy,
1539
                            RegExpTree* body,
1540
                            RegExpCompiler* compiler,
1541
                            RegExpNode* on_success,
1542
                            bool not_at_start = false);
1543
  virtual RegExpQuantifier* AsQuantifier();
1544
  virtual Interval CaptureRegisters();
1545
  virtual bool IsQuantifier();
1546
  virtual int min_match() { return min_match_; }
1547
  virtual int max_match() { return max_match_; }
1548
  int min() { return min_; }
1549
  int max() { return max_; }
1550
  bool is_greedy() { return is_greedy_; }
1551
  RegExpTree* body() { return body_; }
1552
 private:
1553
  int min_;
1554
  int max_;
1555
  bool is_greedy_;
1556
  RegExpTree* body_;
1557
  int min_match_;
1558
  int max_match_;
1559
};
1560

    
1561

    
1562
enum CaptureAvailability {
1563
  CAPTURE_AVAILABLE,
1564
  CAPTURE_UNREACHABLE,
1565
  CAPTURE_PERMANENTLY_UNREACHABLE
1566
};
1567

    
1568
class RegExpCapture: public RegExpTree {
1569
 public:
1570
  explicit RegExpCapture(RegExpTree* body, int index)
1571
      : body_(body), index_(index), available_(CAPTURE_AVAILABLE) { }
1572
  virtual void* Accept(RegExpVisitor* visitor, void* data);
1573
  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1574
                             RegExpNode* on_success);
1575
  static RegExpNode* ToNode(RegExpTree* body,
1576
                            int index,
1577
                            RegExpCompiler* compiler,
1578
                            RegExpNode* on_success);
1579
  virtual RegExpCapture* AsCapture();
1580
  virtual bool IsAnchored();
1581
  virtual Interval CaptureRegisters();
1582
  virtual bool IsCapture();
1583
  virtual int min_match() { return body_->min_match(); }
1584
  virtual int max_match() { return body_->max_match(); }
1585
  RegExpTree* body() { return body_; }
1586
  int index() { return index_; }
1587
  inline CaptureAvailability available() { return available_; }
1588
  inline void set_available(CaptureAvailability availability) {
1589
    available_ = availability;
1590
  }
1591
  static int StartRegister(int index) { return index * 2; }
1592
  static int EndRegister(int index) { return index * 2 + 1; }
1593
 private:
1594
  RegExpTree* body_;
1595
  int index_;
1596
  CaptureAvailability available_;
1597
};
1598

    
1599

    
1600
class RegExpLookahead: public RegExpTree {
1601
 public:
1602
  RegExpLookahead(RegExpTree* body,
1603
                  bool is_positive,
1604
                  int capture_count,
1605
                  int capture_from)
1606
      : body_(body),
1607
        is_positive_(is_positive),
1608
        capture_count_(capture_count),
1609
        capture_from_(capture_from) { }
1610

    
1611
  virtual void* Accept(RegExpVisitor* visitor, void* data);
1612
  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1613
                             RegExpNode* on_success);
1614
  virtual RegExpLookahead* AsLookahead();
1615
  virtual Interval CaptureRegisters();
1616
  virtual bool IsLookahead();
1617
  virtual bool IsAnchored();
1618
  virtual int min_match() { return 0; }
1619
  virtual int max_match() { return 0; }
1620
  RegExpTree* body() { return body_; }
1621
  bool is_positive() { return is_positive_; }
1622
  int capture_count() { return capture_count_; }
1623
  int capture_from() { return capture_from_; }
1624
 private:
1625
  RegExpTree* body_;
1626
  bool is_positive_;
1627
  int capture_count_;
1628
  int capture_from_;
1629
};
1630

    
1631

    
1632
class RegExpBackReference: public RegExpTree {
1633
 public:
1634
  explicit RegExpBackReference(RegExpCapture* capture)
1635
      : capture_(capture) { }
1636
  virtual void* Accept(RegExpVisitor* visitor, void* data);
1637
  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1638
                             RegExpNode* on_success);
1639
  virtual RegExpBackReference* AsBackReference();
1640
  virtual bool IsBackReference();
1641
  virtual int min_match() { return 0; }
1642
  virtual int max_match() { return capture_->max_match(); }
1643
  int index() { return capture_->index(); }
1644
  RegExpCapture* capture() { return capture_; }
1645
 private:
1646
  RegExpCapture* capture_;
1647
};
1648

    
1649

    
1650
class RegExpEmpty: public RegExpTree {
1651
 public:
1652
  RegExpEmpty() { }
1653
  virtual void* Accept(RegExpVisitor* visitor, void* data);
1654
  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1655
                             RegExpNode* on_success);
1656
  virtual RegExpEmpty* AsEmpty();
1657
  virtual bool IsEmpty();
1658
  virtual int min_match() { return 0; }
1659
  virtual int max_match() { return 0; }
1660
  static RegExpEmpty* GetInstance() { return &kInstance; }
1661
 private:
1662
  static RegExpEmpty kInstance;
1663
};
1664

    
1665

    
1666
// ----------------------------------------------------------------------------
1667
// Basic visitor
1668
// - leaf node visitors are abstract.
1669

    
1670
class AstVisitor BASE_EMBEDDED {
1671
 public:
1672
  AstVisitor() : stack_overflow_(false) { }
1673
  virtual ~AstVisitor() { }
1674

    
1675
  // Dispatch
1676
  void Visit(Node* node) { node->Accept(this); }
1677

    
1678
  // Iteration
1679
  virtual void VisitStatements(ZoneList<Statement*>* statements);
1680
  virtual void VisitExpressions(ZoneList<Expression*>* expressions);
1681

    
1682
  // Stack overflow tracking support.
1683
  bool HasStackOverflow() const { return stack_overflow_; }
1684
  bool CheckStackOverflow() {
1685
    if (stack_overflow_) return true;
1686
    StackLimitCheck check;
1687
    if (!check.HasOverflowed()) return false;
1688
    return (stack_overflow_ = true);
1689
  }
1690

    
1691
  // If a stack-overflow exception is encountered when visiting a
1692
  // node, calling SetStackOverflow will make sure that the visitor
1693
  // bails out without visiting more nodes.
1694
  void SetStackOverflow() { stack_overflow_ = true; }
1695

    
1696

    
1697
  // Individual nodes
1698
#define DEF_VISIT(type)                         \
1699
  virtual void Visit##type(type* node) = 0;
1700
  NODE_LIST(DEF_VISIT)
1701
#undef DEF_VISIT
1702

    
1703
 private:
1704
  bool stack_overflow_;
1705
};
1706

    
1707

    
1708
} }  // namespace v8::internal
1709

    
1710
#endif  // V8_AST_H_