~james-page/ubuntu/precise/nodejs/0.6.x-merge

« back to all changes in this revision

Viewing changes to deps/v8/src/ast.h

  • Committer: James Page
  • Date: 2012-03-30 12:09:16 UTC
  • mfrom: (7.1.23 sid)
  • Revision ID: james.page@canonical.com-20120330120916-40hfu9o00qr5t87b
* Merge from Debian unstable:
  - New upstream release (LP: #892034).
  - This package is x86/arm only. Update control to match
  - d/patches/2009_increase_test_timeout.patch: Increased default test
    timeout from 60 to 120 seconds to support reliable execution of all
    tests on armhf/armel architectures.
  - d/patches/2005_expected_failing_tests.patch: 
    - Allow racey tests to fail: test-cluster-kill-workers,
      test-child-process-fork2 
    - Allow test-fs-watch to fail as LP buildd's don't support
      inotify.
    - Revert all other Ubuntu changes as no longer required.
* Update Standards-Version to 3.9.3.
* Patch wscript to enable build on mipsel arch, libv8 being available.
  Upstream does not support that arch, failure expected.
* test-cluster-kill-workers is expected to fail on armhf,
  Bug#660802 will be closed when test pass.
* test-buffer is expected to fail on armel,
  Bug#660800 will be closed when test pass.
* Add epoch to dependency on libev >= 1:4.11. Closes: bug#658441.
* Remove tools/doc because node-doc-generator has no license for now.
* Add copyright for doc/sh* files (shjs).
* source.lintian-overrides : source-contains-waf-binary tools/node-waf
  it is simply not the case here.
* test-stream-pipe-multi expected to timeout sometimes on busy builds. 
* New upstream release.
* Remove upstream patches.
* test-dgram-pingpong expected to timeout, the test itself is buggy.
* test-buffer expected to fail on armel, allow building package to make
  it easier to find the cause of the failure.
  Closes: bug#639636.
* Expect tests dgram-multicast and broadcast to fail.
  debian/patches/2005_expected_failing_tests.patch
* Drop dpkg-source local-options: Defaults since dpkg-source 1.16.1.
* New upstream release.
* Depend on libev-dev 4.11, see bug#657080.
* Bump dependency on openssl to 1.0.0g.
* Remove useless uv_loop_refcount from libuv,
  refreshed 2009_fix_shared_ev.patch.
* Apply to upstream patches landed after 0.6.10 release,
  to fix debugger repl and http client.
* New upstream release. Closes:bug#650661
* Repackage to remove non-dfsg font files ./deps/npm/html/*/*.ttf
* Remove unneeded bundled dependencies: lighter tarball,
  debian/copyright is easier to maintain.
* Drop unneeded build-dependency on scons.
* Depend on zlib1g, libc-ares, libev.
  Patches done to support building with those shared libs.
* Fix DEB_UPSTREAM_URL in debian/rules, and debian/watch.
* nodejs.pc file for pkgconfig is no more available.
* Build-depend on procps package, a test is using /bin/ps.
* Refreshed debian/patches/2005_expected_failing_tests.patch,
  only for tests that need networking.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright 2010 the V8 project authors. All rights reserved.
 
1
// Copyright 2011 the V8 project authors. All rights reserved.
2
2
// Redistribution and use in source and binary forms, with or without
3
3
// modification, are permitted provided that the following conditions are
4
4
// met:
28
28
#ifndef V8_AST_H_
29
29
#define V8_AST_H_
30
30
 
 
31
#include "allocation.h"
31
32
#include "execution.h"
32
33
#include "factory.h"
33
34
#include "jsregexp.h"
34
 
#include "jump-target.h"
35
35
#include "runtime.h"
 
36
#include "small-pointer-list.h"
36
37
#include "token.h"
37
38
#include "variables.h"
38
39
 
60
61
  V(ContinueStatement)                          \
61
62
  V(BreakStatement)                             \
62
63
  V(ReturnStatement)                            \
63
 
  V(WithEnterStatement)                         \
64
 
  V(WithExitStatement)                          \
 
64
  V(WithStatement)                              \
65
65
  V(SwitchStatement)                            \
66
66
  V(DoWhileStatement)                           \
67
67
  V(WhileStatement)                             \
80
80
  V(RegExpLiteral)                              \
81
81
  V(ObjectLiteral)                              \
82
82
  V(ArrayLiteral)                               \
83
 
  V(CatchExtensionObject)                       \
84
83
  V(Assignment)                                 \
85
84
  V(Throw)                                      \
86
85
  V(Property)                                   \
88
87
  V(CallNew)                                    \
89
88
  V(CallRuntime)                                \
90
89
  V(UnaryOperation)                             \
91
 
  V(IncrementOperation)                         \
92
90
  V(CountOperation)                             \
93
91
  V(BinaryOperation)                            \
94
92
  V(CompareOperation)                           \
134
132
#undef DECLARE_TYPE_ENUM
135
133
 
136
134
  static const int kNoNumber = -1;
137
 
 
138
 
  AstNode() : id_(GetNextId()) { count_++; }
 
135
  static const int kFunctionEntryId = 2;  // Using 0 could disguise errors.
 
136
  // This AST id identifies the point after the declarations have been
 
137
  // visited. We need it to capture the environment effects of declarations
 
138
  // that emit code (function declarations).
 
139
  static const int kDeclarationsId = 3;
 
140
 
 
141
  // Override ZoneObject's new to count allocated AST nodes.
 
142
  void* operator new(size_t size, Zone* zone) {
 
143
    Isolate* isolate = zone->isolate();
 
144
    isolate->set_ast_node_count(isolate->ast_node_count() + 1);
 
145
    return zone->New(static_cast<int>(size));
 
146
  }
 
147
 
 
148
  AstNode() {}
139
149
 
140
150
  virtual ~AstNode() { }
141
151
 
154
164
  virtual BreakableStatement* AsBreakableStatement() { return NULL; }
155
165
  virtual IterationStatement* AsIterationStatement() { return NULL; }
156
166
  virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; }
157
 
  virtual Slot* AsSlot() { return NULL; }
158
167
 
159
168
  // True if the node is simple enough for us to inline calls containing it.
160
 
  virtual bool IsInlineable() const { return false; }
 
169
  virtual bool IsInlineable() const = 0;
161
170
 
162
 
  static int Count() { return count_; }
163
 
  static void ResetIds() { current_id_ = 0; }
164
 
  unsigned id() const { return id_; }
 
171
  static int Count() { return Isolate::Current()->ast_node_count(); }
 
172
  static void ResetIds() { Isolate::Current()->set_ast_node_id(0); }
165
173
 
166
174
 protected:
167
 
  static unsigned GetNextId() { return current_id_++; }
168
 
  static unsigned ReserveIdRange(int n) {
169
 
    unsigned tmp = current_id_;
170
 
    current_id_ += n;
 
175
  static unsigned GetNextId(Isolate* isolate) {
 
176
    return ReserveIdRange(isolate, 1);
 
177
  }
 
178
 
 
179
  static unsigned ReserveIdRange(Isolate* isolate, int n) {
 
180
    unsigned tmp = isolate->ast_node_id();
 
181
    isolate->set_ast_node_id(tmp + n);
171
182
    return tmp;
172
183
  }
173
184
 
174
185
 private:
175
 
  static unsigned current_id_;
176
 
  static unsigned count_;
177
 
  unsigned id_;
 
186
  // Hidden to prevent accidental usage. It would have to load the
 
187
  // current zone from the TLS.
 
188
  void* operator new(size_t size);
 
189
 
 
190
  friend class CaseClause;  // Generates AST IDs.
178
191
};
179
192
 
180
193
 
197
210
};
198
211
 
199
212
 
 
213
class SmallMapList {
 
214
 public:
 
215
  SmallMapList() {}
 
216
  explicit SmallMapList(int capacity) : list_(capacity) {}
 
217
 
 
218
  void Reserve(int capacity) { list_.Reserve(capacity); }
 
219
  void Clear() { list_.Clear(); }
 
220
 
 
221
  bool is_empty() const { return list_.is_empty(); }
 
222
  int length() const { return list_.length(); }
 
223
 
 
224
  void Add(Handle<Map> handle) {
 
225
    list_.Add(handle.location());
 
226
  }
 
227
 
 
228
  Handle<Map> at(int i) const {
 
229
    return Handle<Map>(list_.at(i));
 
230
  }
 
231
 
 
232
  Handle<Map> first() const { return at(0); }
 
233
  Handle<Map> last() const { return at(length() - 1); }
 
234
 
 
235
 private:
 
236
  // The list stores pointers to Map*, that is Map**, so it's GC safe.
 
237
  SmallPointerList<Map*> list_;
 
238
 
 
239
  DISALLOW_COPY_AND_ASSIGN(SmallMapList);
 
240
};
 
241
 
 
242
 
200
243
class Expression: public AstNode {
201
244
 public:
202
245
  enum Context {
211
254
    kTest
212
255
  };
213
256
 
214
 
  Expression() : bitfields_(0) {}
 
257
  explicit Expression(Isolate* isolate)
 
258
      : id_(GetNextId(isolate)),
 
259
        test_id_(GetNextId(isolate)) {}
 
260
 
 
261
  virtual int position() const {
 
262
    UNREACHABLE();
 
263
    return 0;
 
264
  }
215
265
 
216
266
  virtual Expression* AsExpression()  { return this; }
217
267
 
248
298
    UNREACHABLE();
249
299
    return false;
250
300
  }
251
 
  virtual ZoneMapList* GetReceiverTypes() {
 
301
  virtual SmallMapList* GetReceiverTypes() {
252
302
    UNREACHABLE();
253
303
    return NULL;
254
304
  }
255
 
  virtual Handle<Map> GetMonomorphicReceiverType() {
256
 
    UNREACHABLE();
257
 
    return Handle<Map>();
258
 
  }
259
 
 
260
 
  // Static type information for this expression.
261
 
  StaticType* type() { return &type_; }
262
 
 
263
 
  // True if the expression is a loop condition.
264
 
  bool is_loop_condition() const {
265
 
    return LoopConditionField::decode(bitfields_);
266
 
  }
267
 
  void set_is_loop_condition(bool flag) {
268
 
    bitfields_ = (bitfields_ & ~LoopConditionField::mask()) |
269
 
        LoopConditionField::encode(flag);
270
 
  }
271
 
 
272
 
  // The value of the expression is guaranteed to be a smi, because the
273
 
  // top operation is a bit operation with a mask, or a shift.
274
 
  bool GuaranteedSmiResult();
275
 
 
276
 
  // AST analysis results.
277
 
  void CopyAnalysisResultsFrom(Expression* other);
278
 
 
279
 
  // True if the expression rooted at this node can be compiled by the
280
 
  // side-effect free compiler.
281
 
  bool side_effect_free() { return SideEffectFreeField::decode(bitfields_); }
282
 
  void set_side_effect_free(bool is_side_effect_free) {
283
 
    bitfields_ &= ~SideEffectFreeField::mask();
284
 
    bitfields_ |= SideEffectFreeField::encode(is_side_effect_free);
285
 
  }
286
 
 
287
 
  // Will the use of this expression treat -0 the same as 0 in all cases?
288
 
  // If so, we can return 0 instead of -0 if we want to, to optimize code.
289
 
  bool no_negative_zero() { return NoNegativeZeroField::decode(bitfields_); }
290
 
  void set_no_negative_zero(bool no_negative_zero) {
291
 
    bitfields_ &= ~NoNegativeZeroField::mask();
292
 
    bitfields_ |= NoNegativeZeroField::encode(no_negative_zero);
293
 
  }
294
 
 
295
 
  // Will ToInt32 (ECMA 262-3 9.5) or ToUint32 (ECMA 262-3 9.6)
296
 
  // be applied to the value of this expression?
297
 
  // If so, we may be able to optimize the calculation of the value.
298
 
  bool to_int32() { return ToInt32Field::decode(bitfields_); }
299
 
  void set_to_int32(bool to_int32) {
300
 
    bitfields_ &= ~ToInt32Field::mask();
301
 
    bitfields_ |= ToInt32Field::encode(to_int32);
302
 
  }
303
 
 
304
 
  // How many bitwise logical or shift operators are used in this expression?
305
 
  int num_bit_ops() { return NumBitOpsField::decode(bitfields_); }
306
 
  void set_num_bit_ops(int num_bit_ops) {
307
 
    bitfields_ &= ~NumBitOpsField::mask();
308
 
    num_bit_ops = Min(num_bit_ops, kMaxNumBitOps);
309
 
    bitfields_ |= NumBitOpsField::encode(num_bit_ops);
310
 
  }
311
 
 
312
 
 private:
313
 
  static const int kMaxNumBitOps = (1 << 5) - 1;
314
 
 
315
 
  uint32_t bitfields_;
316
 
  StaticType type_;
317
 
 
318
 
  // Using template BitField<type, start, size>.
319
 
  class SideEffectFreeField : public BitField<bool, 0, 1> {};
320
 
  class NoNegativeZeroField : public BitField<bool, 1, 1> {};
321
 
  class ToInt32Field : public BitField<bool, 2, 1> {};
322
 
  class NumBitOpsField : public BitField<int, 3, 5> {};
323
 
  class LoopConditionField: public BitField<bool, 8, 1> {};
324
 
};
325
 
 
326
 
 
327
 
/**
328
 
 * A sentinel used during pre parsing that represents some expression
329
 
 * that is a valid left hand side without having to actually build
330
 
 * the expression.
331
 
 */
332
 
class ValidLeftHandSideSentinel: public Expression {
333
 
 public:
334
 
  virtual bool IsValidLeftHandSide() { return true; }
335
 
  virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
336
 
  static ValidLeftHandSideSentinel* instance() { return &instance_; }
337
 
 
338
 
 private:
339
 
  static ValidLeftHandSideSentinel instance_;
 
305
  Handle<Map> GetMonomorphicReceiverType() {
 
306
    ASSERT(IsMonomorphic());
 
307
    SmallMapList* types = GetReceiverTypes();
 
308
    ASSERT(types != NULL && types->length() == 1);
 
309
    return types->at(0);
 
310
  }
 
311
 
 
312
  unsigned id() const { return id_; }
 
313
  unsigned test_id() const { return test_id_; }
 
314
 
 
315
 private:
 
316
  unsigned id_;
 
317
  unsigned test_id_;
340
318
};
341
319
 
342
320
 
355
333
  virtual BreakableStatement* AsBreakableStatement() { return this; }
356
334
 
357
335
  // Code generation
358
 
  BreakTarget* break_target() { return &break_target_; }
 
336
  Label* break_target() { return &break_target_; }
359
337
 
360
338
  // Testers.
361
339
  bool is_target_for_anonymous() const { return type_ == TARGET_FOR_ANONYMOUS; }
365
343
  int ExitId() const { return exit_id_; }
366
344
 
367
345
 protected:
368
 
  inline BreakableStatement(ZoneStringList* labels, Type type);
 
346
  BreakableStatement(Isolate* isolate, ZoneStringList* labels, Type type);
369
347
 
370
348
 private:
371
349
  ZoneStringList* labels_;
372
350
  Type type_;
373
 
  BreakTarget break_target_;
 
351
  Label break_target_;
374
352
  int entry_id_;
375
353
  int exit_id_;
376
354
};
378
356
 
379
357
class Block: public BreakableStatement {
380
358
 public:
381
 
  inline Block(ZoneStringList* labels, int capacity, bool is_initializer_block);
 
359
  inline Block(Isolate* isolate,
 
360
               ZoneStringList* labels,
 
361
               int capacity,
 
362
               bool is_initializer_block);
382
363
 
383
364
  DECLARE_NODE_TYPE(Block)
384
365
 
399
380
  ZoneList<Statement*>* statements() { return &statements_; }
400
381
  bool is_initializer_block() const { return is_initializer_block_; }
401
382
 
 
383
  Scope* block_scope() const { return block_scope_; }
 
384
  void set_block_scope(Scope* block_scope) { block_scope_ = block_scope; }
 
385
 
402
386
 private:
403
387
  ZoneList<Statement*> statements_;
404
388
  bool is_initializer_block_;
 
389
  Scope* block_scope_;
405
390
};
406
391
 
407
392
 
408
393
class Declaration: public AstNode {
409
394
 public:
410
 
  Declaration(VariableProxy* proxy, Variable::Mode mode, FunctionLiteral* fun)
 
395
  Declaration(VariableProxy* proxy,
 
396
              Variable::Mode mode,
 
397
              FunctionLiteral* fun,
 
398
              Scope* scope)
411
399
      : proxy_(proxy),
412
400
        mode_(mode),
413
 
        fun_(fun) {
414
 
    ASSERT(mode == Variable::VAR || mode == Variable::CONST);
 
401
        fun_(fun),
 
402
        scope_(scope) {
 
403
    ASSERT(mode == Variable::VAR ||
 
404
           mode == Variable::CONST ||
 
405
           mode == Variable::LET);
415
406
    // At the moment there are no "const functions"'s in JavaScript...
416
 
    ASSERT(fun == NULL || mode == Variable::VAR);
 
407
    ASSERT(fun == NULL || mode == Variable::VAR || mode == Variable::LET);
417
408
  }
418
409
 
419
410
  DECLARE_NODE_TYPE(Declaration)
421
412
  VariableProxy* proxy() const { return proxy_; }
422
413
  Variable::Mode mode() const { return mode_; }
423
414
  FunctionLiteral* fun() const { return fun_; }  // may be NULL
 
415
  virtual bool IsInlineable() const;
 
416
  Scope* scope() const { return scope_; }
424
417
 
425
418
 private:
426
419
  VariableProxy* proxy_;
427
420
  Variable::Mode mode_;
428
421
  FunctionLiteral* fun_;
 
422
 
 
423
  // Nested scope from which the declaration originated.
 
424
  Scope* scope_;
429
425
};
430
426
 
431
427
 
439
435
  // Bailout support.
440
436
  int OsrEntryId() const { return osr_entry_id_; }
441
437
  virtual int ContinueId() const = 0;
 
438
  virtual int StackCheckId() const = 0;
442
439
 
443
440
  // Code generation
444
 
  BreakTarget* continue_target()  { return &continue_target_; }
 
441
  Label* continue_target()  { return &continue_target_; }
445
442
 
446
443
 protected:
447
 
  explicit inline IterationStatement(ZoneStringList* labels);
 
444
  inline IterationStatement(Isolate* isolate, ZoneStringList* labels);
448
445
 
449
446
  void Initialize(Statement* body) {
450
447
    body_ = body;
452
449
 
453
450
 private:
454
451
  Statement* body_;
455
 
  BreakTarget continue_target_;
 
452
  Label continue_target_;
456
453
  int osr_entry_id_;
457
454
};
458
455
 
459
456
 
460
457
class DoWhileStatement: public IterationStatement {
461
458
 public:
462
 
  explicit inline DoWhileStatement(ZoneStringList* labels);
 
459
  inline DoWhileStatement(Isolate* isolate, ZoneStringList* labels);
463
460
 
464
461
  DECLARE_NODE_TYPE(DoWhileStatement)
465
462
 
477
474
 
478
475
  // Bailout support.
479
476
  virtual int ContinueId() const { return continue_id_; }
 
477
  virtual int StackCheckId() const { return back_edge_id_; }
480
478
  int BackEdgeId() const { return back_edge_id_; }
481
479
 
 
480
  virtual bool IsInlineable() const;
 
481
 
482
482
 private:
483
483
  Expression* cond_;
484
484
  int condition_position_;
489
489
 
490
490
class WhileStatement: public IterationStatement {
491
491
 public:
492
 
  explicit inline WhileStatement(ZoneStringList* labels);
 
492
  inline WhileStatement(Isolate* isolate, ZoneStringList* labels);
493
493
 
494
494
  DECLARE_NODE_TYPE(WhileStatement)
495
495
 
505
505
  void set_may_have_function_literal(bool value) {
506
506
    may_have_function_literal_ = value;
507
507
  }
 
508
  virtual bool IsInlineable() const;
508
509
 
509
510
  // Bailout support.
510
511
  virtual int ContinueId() const { return EntryId(); }
 
512
  virtual int StackCheckId() const { return body_id_; }
511
513
  int BodyId() const { return body_id_; }
512
514
 
513
515
 private:
520
522
 
521
523
class ForStatement: public IterationStatement {
522
524
 public:
523
 
  explicit inline ForStatement(ZoneStringList* labels);
 
525
  inline ForStatement(Isolate* isolate, ZoneStringList* labels);
524
526
 
525
527
  DECLARE_NODE_TYPE(ForStatement)
526
528
 
547
549
 
548
550
  // Bailout support.
549
551
  virtual int ContinueId() const { return continue_id_; }
 
552
  virtual int StackCheckId() const { return body_id_; }
550
553
  int BodyId() const { return body_id_; }
551
554
 
552
555
  bool is_fast_smi_loop() { return loop_variable_ != NULL; }
553
556
  Variable* loop_variable() { return loop_variable_; }
554
557
  void set_loop_variable(Variable* var) { loop_variable_ = var; }
 
558
  virtual bool IsInlineable() const;
555
559
 
556
560
 private:
557
561
  Statement* init_;
567
571
 
568
572
class ForInStatement: public IterationStatement {
569
573
 public:
570
 
  explicit inline ForInStatement(ZoneStringList* labels);
 
574
  inline ForInStatement(Isolate* isolate, ZoneStringList* labels);
571
575
 
572
576
  DECLARE_NODE_TYPE(ForInStatement)
573
577
 
579
583
 
580
584
  Expression* each() const { return each_; }
581
585
  Expression* enumerable() const { return enumerable_; }
 
586
  virtual bool IsInlineable() const;
582
587
 
583
588
  // Bailout support.
584
589
  int AssignmentId() const { return assignment_id_; }
585
590
  virtual int ContinueId() const { return EntryId(); }
 
591
  virtual int StackCheckId() const { return EntryId(); }
586
592
 
587
593
 private:
588
594
  Expression* each_;
619
625
  DECLARE_NODE_TYPE(ContinueStatement)
620
626
 
621
627
  IterationStatement* target() const { return target_; }
 
628
  virtual bool IsInlineable() const;
622
629
 
623
630
 private:
624
631
  IterationStatement* target_;
633
640
  DECLARE_NODE_TYPE(BreakStatement)
634
641
 
635
642
  BreakableStatement* target() const { return target_; }
 
643
  virtual bool IsInlineable() const;
636
644
 
637
645
 private:
638
646
  BreakableStatement* target_;
654
662
};
655
663
 
656
664
 
657
 
class WithEnterStatement: public Statement {
 
665
class WithStatement: public Statement {
658
666
 public:
659
 
  explicit WithEnterStatement(Expression* expression, bool is_catch_block)
660
 
      : expression_(expression), is_catch_block_(is_catch_block) { }
 
667
  WithStatement(Expression* expression, Statement* statement)
 
668
      : expression_(expression), statement_(statement) { }
661
669
 
662
 
  DECLARE_NODE_TYPE(WithEnterStatement)
 
670
  DECLARE_NODE_TYPE(WithStatement)
663
671
 
664
672
  Expression* expression() const { return expression_; }
 
673
  Statement* statement() const { return statement_; }
665
674
 
666
 
  bool is_catch_block() const { return is_catch_block_; }
 
675
  virtual bool IsInlineable() const;
667
676
 
668
677
 private:
669
678
  Expression* expression_;
670
 
  bool is_catch_block_;
671
 
};
672
 
 
673
 
 
674
 
class WithExitStatement: public Statement {
675
 
 public:
676
 
  WithExitStatement() { }
677
 
 
678
 
  DECLARE_NODE_TYPE(WithExitStatement)
 
679
  Statement* statement_;
679
680
};
680
681
 
681
682
 
682
683
class CaseClause: public ZoneObject {
683
684
 public:
684
 
  CaseClause(Expression* label, ZoneList<Statement*>* statements, int pos);
 
685
  CaseClause(Isolate* isolate,
 
686
             Expression* label,
 
687
             ZoneList<Statement*>* statements,
 
688
             int pos);
685
689
 
686
690
  bool is_default() const { return label_ == NULL; }
687
691
  Expression* label() const {
688
692
    CHECK(!is_default());
689
693
    return label_;
690
694
  }
691
 
  JumpTarget* body_target() { return &body_target_; }
 
695
  Label* body_target() { return &body_target_; }
692
696
  ZoneList<Statement*>* statements() const { return statements_; }
693
697
 
694
 
  int position() { return position_; }
 
698
  int position() const { return position_; }
695
699
  void set_position(int pos) { position_ = pos; }
696
700
 
 
701
  int EntryId() { return entry_id_; }
 
702
  int CompareId() { return compare_id_; }
 
703
 
697
704
  // Type feedback information.
698
705
  void RecordTypeFeedback(TypeFeedbackOracle* oracle);
699
706
  bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
701
708
 
702
709
 private:
703
710
  Expression* label_;
704
 
  JumpTarget body_target_;
 
711
  Label body_target_;
705
712
  ZoneList<Statement*>* statements_;
706
713
  int position_;
707
714
  enum CompareTypeFeedback { NONE, SMI_ONLY, OBJECT_ONLY };
708
715
  CompareTypeFeedback compare_type_;
 
716
  int compare_id_;
 
717
  int entry_id_;
709
718
};
710
719
 
711
720
 
712
721
class SwitchStatement: public BreakableStatement {
713
722
 public:
714
 
  explicit inline SwitchStatement(ZoneStringList* labels);
 
723
  inline SwitchStatement(Isolate* isolate, ZoneStringList* labels);
715
724
 
716
725
  DECLARE_NODE_TYPE(SwitchStatement)
717
726
 
722
731
 
723
732
  Expression* tag() const { return tag_; }
724
733
  ZoneList<CaseClause*>* cases() const { return cases_; }
 
734
  virtual bool IsInlineable() const;
725
735
 
726
736
 private:
727
737
  Expression* tag_;
736
746
// given if-statement has a then- or an else-part containing code.
737
747
class IfStatement: public Statement {
738
748
 public:
739
 
  IfStatement(Expression* condition,
 
749
  IfStatement(Isolate* isolate,
 
750
              Expression* condition,
740
751
              Statement* then_statement,
741
752
              Statement* else_statement)
742
753
      : condition_(condition),
743
754
        then_statement_(then_statement),
744
755
        else_statement_(else_statement),
745
 
        then_id_(GetNextId()),
746
 
        else_id_(GetNextId()) {
 
756
        if_id_(GetNextId(isolate)),
 
757
        then_id_(GetNextId(isolate)),
 
758
        else_id_(GetNextId(isolate)) {
747
759
  }
748
760
 
749
761
  DECLARE_NODE_TYPE(IfStatement)
757
769
  Statement* then_statement() const { return then_statement_; }
758
770
  Statement* else_statement() const { return else_statement_; }
759
771
 
 
772
  int IfId() const { return if_id_; }
760
773
  int ThenId() const { return then_id_; }
761
774
  int ElseId() const { return else_id_; }
762
775
 
764
777
  Expression* condition_;
765
778
  Statement* then_statement_;
766
779
  Statement* else_statement_;
 
780
  int if_id_;
767
781
  int then_id_;
768
782
  int else_id_;
769
783
};
773
787
// stack in the compiler; this should probably be reworked.
774
788
class TargetCollector: public AstNode {
775
789
 public:
776
 
  explicit TargetCollector(ZoneList<BreakTarget*>* targets)
777
 
      : targets_(targets) {
778
 
  }
 
790
  TargetCollector(): targets_(0) { }
779
791
 
780
792
  // Adds a jump target to the collector. The collector stores a pointer not
781
793
  // a copy of the target to make binding work, so make sure not to pass in
782
794
  // references to something on the stack.
783
 
  void AddTarget(BreakTarget* target);
 
795
  void AddTarget(Label* target);
784
796
 
785
797
  // Virtual behaviour. TargetCollectors are never part of the AST.
786
798
  virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
787
799
  virtual TargetCollector* AsTargetCollector() { return this; }
788
800
 
789
 
  ZoneList<BreakTarget*>* targets() { return targets_; }
 
801
  ZoneList<Label*>* targets() { return &targets_; }
 
802
  virtual bool IsInlineable() const;
790
803
 
791
804
 private:
792
 
  ZoneList<BreakTarget*>* targets_;
 
805
  ZoneList<Label*> targets_;
793
806
};
794
807
 
795
808
 
798
811
  explicit TryStatement(Block* try_block)
799
812
      : try_block_(try_block), escaping_targets_(NULL) { }
800
813
 
801
 
  void set_escaping_targets(ZoneList<BreakTarget*>* targets) {
 
814
  void set_escaping_targets(ZoneList<Label*>* targets) {
802
815
    escaping_targets_ = targets;
803
816
  }
804
817
 
805
818
  Block* try_block() const { return try_block_; }
806
 
  ZoneList<BreakTarget*>* escaping_targets() const { return escaping_targets_; }
 
819
  ZoneList<Label*>* escaping_targets() const { return escaping_targets_; }
 
820
  virtual bool IsInlineable() const;
807
821
 
808
822
 private:
809
823
  Block* try_block_;
810
 
  ZoneList<BreakTarget*>* escaping_targets_;
 
824
  ZoneList<Label*>* escaping_targets_;
811
825
};
812
826
 
813
827
 
814
828
class TryCatchStatement: public TryStatement {
815
829
 public:
816
830
  TryCatchStatement(Block* try_block,
817
 
                    VariableProxy* catch_var,
 
831
                    Scope* scope,
 
832
                    Variable* variable,
818
833
                    Block* catch_block)
819
834
      : TryStatement(try_block),
820
 
        catch_var_(catch_var),
 
835
        scope_(scope),
 
836
        variable_(variable),
821
837
        catch_block_(catch_block) {
822
838
  }
823
839
 
824
840
  DECLARE_NODE_TYPE(TryCatchStatement)
825
841
 
826
 
  VariableProxy* catch_var() const { return catch_var_; }
 
842
  Scope* scope() { return scope_; }
 
843
  Variable* variable() { return variable_; }
827
844
  Block* catch_block() const { return catch_block_; }
 
845
  virtual bool IsInlineable() const;
828
846
 
829
847
 private:
830
 
  VariableProxy* catch_var_;
 
848
  Scope* scope_;
 
849
  Variable* variable_;
831
850
  Block* catch_block_;
832
851
};
833
852
 
841
860
  DECLARE_NODE_TYPE(TryFinallyStatement)
842
861
 
843
862
  Block* finally_block() const { return finally_block_; }
 
863
  virtual bool IsInlineable() const;
844
864
 
845
865
 private:
846
866
  Block* finally_block_;
850
870
class DebuggerStatement: public Statement {
851
871
 public:
852
872
  DECLARE_NODE_TYPE(DebuggerStatement)
 
873
  virtual bool IsInlineable() const;
853
874
};
854
875
 
855
876
 
857
878
 public:
858
879
  DECLARE_NODE_TYPE(EmptyStatement)
859
880
 
860
 
  virtual bool IsInlineable() const { return true; }
 
881
  virtual bool IsInlineable() const;
861
882
};
862
883
 
863
884
 
864
885
class Literal: public Expression {
865
886
 public:
866
 
  explicit Literal(Handle<Object> handle) : handle_(handle) { }
 
887
  Literal(Isolate* isolate, Handle<Object> handle)
 
888
      : Expression(isolate), handle_(handle) { }
867
889
 
868
890
  DECLARE_NODE_TYPE(Literal)
869
891
 
870
892
  virtual bool IsTrivial() { return true; }
871
 
  virtual bool IsInlineable() const { return true; }
872
893
  virtual bool IsSmiLiteral() { return handle_->IsSmi(); }
873
894
 
874
895
  // Check if this literal is identical to the other literal.
893
914
  virtual bool ToBooleanIsFalse() { return handle_->ToBoolean()->IsFalse(); }
894
915
 
895
916
  // Identity testers.
896
 
  bool IsNull() const { return handle_.is_identical_to(Factory::null_value()); }
897
 
  bool IsTrue() const { return handle_.is_identical_to(Factory::true_value()); }
 
917
  bool IsNull() const {
 
918
    ASSERT(!handle_.is_null());
 
919
    return handle_->IsNull();
 
920
  }
 
921
  bool IsTrue() const {
 
922
    ASSERT(!handle_.is_null());
 
923
    return handle_->IsTrue();
 
924
  }
898
925
  bool IsFalse() const {
899
 
    return handle_.is_identical_to(Factory::false_value());
 
926
    ASSERT(!handle_.is_null());
 
927
    return handle_->IsFalse();
900
928
  }
901
929
 
902
930
  Handle<Object> handle() const { return handle_; }
 
931
  virtual bool IsInlineable() const;
903
932
 
904
933
 private:
905
934
  Handle<Object> handle_;
909
938
// Base class for literals that needs space in the corresponding JSFunction.
910
939
class MaterializedLiteral: public Expression {
911
940
 public:
912
 
  explicit MaterializedLiteral(int literal_index, bool is_simple, int depth)
913
 
      : literal_index_(literal_index), is_simple_(is_simple), depth_(depth) {}
 
941
  MaterializedLiteral(Isolate* isolate,
 
942
                      int literal_index,
 
943
                      bool is_simple,
 
944
                      int depth)
 
945
      : Expression(isolate),
 
946
        literal_index_(literal_index),
 
947
        is_simple_(is_simple),
 
948
        depth_(depth) {}
914
949
 
915
950
  virtual MaterializedLiteral* AsMaterializedLiteral() { return this; }
916
951
 
921
956
  bool is_simple() const { return is_simple_; }
922
957
 
923
958
  int depth() const { return depth_; }
 
959
  virtual bool IsInlineable() const;
924
960
 
925
961
 private:
926
962
  int literal_index_;
965
1001
    bool emit_store_;
966
1002
  };
967
1003
 
968
 
  ObjectLiteral(Handle<FixedArray> constant_properties,
 
1004
  ObjectLiteral(Isolate* isolate,
 
1005
                Handle<FixedArray> constant_properties,
969
1006
                ZoneList<Property*>* properties,
970
1007
                int literal_index,
971
1008
                bool is_simple,
972
1009
                bool fast_elements,
973
 
                int depth)
974
 
      : MaterializedLiteral(literal_index, is_simple, depth),
 
1010
                int depth,
 
1011
                bool has_function)
 
1012
      : MaterializedLiteral(isolate, literal_index, is_simple, depth),
975
1013
        constant_properties_(constant_properties),
976
1014
        properties_(properties),
977
 
        fast_elements_(fast_elements) {}
 
1015
        fast_elements_(fast_elements),
 
1016
        has_function_(has_function) {}
978
1017
 
979
1018
  DECLARE_NODE_TYPE(ObjectLiteral)
980
1019
 
985
1024
 
986
1025
  bool fast_elements() const { return fast_elements_; }
987
1026
 
 
1027
  bool has_function() { return has_function_; }
988
1028
 
989
1029
  // Mark all computed expressions that are bound to a key that
990
1030
  // is shadowed by a later occurrence of the same key. For the
991
1031
  // marked expressions, no store code is emitted.
992
1032
  void CalculateEmitStore();
993
1033
 
 
1034
  enum Flags {
 
1035
    kNoFlags = 0,
 
1036
    kFastElements = 1,
 
1037
    kHasFunction = 1 << 1
 
1038
  };
 
1039
 
994
1040
 private:
995
1041
  Handle<FixedArray> constant_properties_;
996
1042
  ZoneList<Property*>* properties_;
997
1043
  bool fast_elements_;
 
1044
  bool has_function_;
998
1045
};
999
1046
 
1000
1047
 
1001
1048
// Node for capturing a regexp literal.
1002
1049
class RegExpLiteral: public MaterializedLiteral {
1003
1050
 public:
1004
 
  RegExpLiteral(Handle<String> pattern,
 
1051
  RegExpLiteral(Isolate* isolate,
 
1052
                Handle<String> pattern,
1005
1053
                Handle<String> flags,
1006
1054
                int literal_index)
1007
 
      : MaterializedLiteral(literal_index, false, 1),
 
1055
      : MaterializedLiteral(isolate, literal_index, false, 1),
1008
1056
        pattern_(pattern),
1009
1057
        flags_(flags) {}
1010
1058
 
1022
1070
// for minimizing the work when constructing it at runtime.
1023
1071
class ArrayLiteral: public MaterializedLiteral {
1024
1072
 public:
1025
 
  ArrayLiteral(Handle<FixedArray> constant_elements,
 
1073
  ArrayLiteral(Isolate* isolate,
 
1074
               Handle<FixedArray> constant_elements,
1026
1075
               ZoneList<Expression*>* values,
1027
1076
               int literal_index,
1028
1077
               bool is_simple,
1029
1078
               int depth)
1030
 
      : MaterializedLiteral(literal_index, is_simple, depth),
 
1079
      : MaterializedLiteral(isolate, literal_index, is_simple, depth),
1031
1080
        constant_elements_(constant_elements),
1032
1081
        values_(values),
1033
 
        first_element_id_(ReserveIdRange(values->length())) {}
 
1082
        first_element_id_(ReserveIdRange(isolate, values->length())) {}
1034
1083
 
1035
1084
  DECLARE_NODE_TYPE(ArrayLiteral)
1036
1085
 
1047
1096
};
1048
1097
 
1049
1098
 
1050
 
// Node for constructing a context extension object for a catch block.
1051
 
// The catch context extension object has one property, the catch
1052
 
// variable, which should be DontDelete.
1053
 
class CatchExtensionObject: public Expression {
1054
 
 public:
1055
 
  CatchExtensionObject(Literal* key, VariableProxy* value)
1056
 
      : key_(key), value_(value) {
1057
 
  }
1058
 
 
1059
 
  DECLARE_NODE_TYPE(CatchExtensionObject)
1060
 
 
1061
 
  Literal* key() const { return key_; }
1062
 
  VariableProxy* value() const { return value_; }
1063
 
 
1064
 
 private:
1065
 
  Literal* key_;
1066
 
  VariableProxy* value_;
1067
 
};
1068
 
 
1069
 
 
1070
1099
class VariableProxy: public Expression {
1071
1100
 public:
1072
 
  explicit VariableProxy(Variable* var);
 
1101
  VariableProxy(Isolate* isolate, Variable* var);
1073
1102
 
1074
1103
  DECLARE_NODE_TYPE(VariableProxy)
1075
1104
 
1076
 
  // Type testing & conversion
1077
 
  virtual Property* AsProperty() {
1078
 
    return var_ == NULL ? NULL : var_->AsProperty();
1079
 
  }
1080
 
 
1081
 
  Variable* AsVariable() {
1082
 
    if (this == NULL || var_ == NULL) return NULL;
1083
 
    Expression* rewrite = var_->rewrite();
1084
 
    if (rewrite == NULL || rewrite->AsSlot() != NULL) return var_;
1085
 
    return NULL;
1086
 
  }
1087
 
 
1088
1105
  virtual bool IsValidLeftHandSide() {
1089
1106
    return var_ == NULL ? true : var_->IsValidLeftHandSide();
1090
1107
  }
1101
1118
    return !is_this() && name().is_identical_to(n);
1102
1119
  }
1103
1120
 
1104
 
  bool IsArguments() {
1105
 
    Variable* variable = AsVariable();
1106
 
    return (variable == NULL) ? false : variable->is_arguments();
1107
 
  }
 
1121
  bool IsArguments() { return var_ != NULL && var_->is_arguments(); }
1108
1122
 
1109
1123
  Handle<String> name() const { return name_; }
1110
1124
  Variable* var() const { return var_; }
1111
1125
  bool is_this() const { return is_this_; }
1112
1126
  bool inside_with() const { return inside_with_; }
 
1127
  int position() const { return position_; }
1113
1128
 
1114
1129
  void MarkAsTrivial() { is_trivial_ = true; }
1115
1130
 
1122
1137
  bool is_this_;
1123
1138
  bool inside_with_;
1124
1139
  bool is_trivial_;
 
1140
  int position_;
1125
1141
 
1126
 
  VariableProxy(Handle<String> name, bool is_this, bool inside_with);
1127
 
  explicit VariableProxy(bool is_this);
 
1142
  VariableProxy(Isolate* isolate,
 
1143
                Handle<String> name,
 
1144
                bool is_this,
 
1145
                bool inside_with,
 
1146
                int position = RelocInfo::kNoPosition);
1128
1147
 
1129
1148
  friend class Scope;
1130
1149
};
1131
1150
 
1132
1151
 
1133
 
class VariableProxySentinel: public VariableProxy {
1134
 
 public:
1135
 
  virtual bool IsValidLeftHandSide() { return !is_this(); }
1136
 
  static VariableProxySentinel* this_proxy() { return &this_proxy_; }
1137
 
  static VariableProxySentinel* identifier_proxy() {
1138
 
    return &identifier_proxy_;
1139
 
  }
1140
 
 
1141
 
 private:
1142
 
  explicit VariableProxySentinel(bool is_this) : VariableProxy(is_this) { }
1143
 
  static VariableProxySentinel this_proxy_;
1144
 
  static VariableProxySentinel identifier_proxy_;
1145
 
};
1146
 
 
1147
 
 
1148
 
class Slot: public Expression {
1149
 
 public:
1150
 
  enum Type {
1151
 
    // A slot in the parameter section on the stack. index() is
1152
 
    // the parameter index, counting left-to-right, starting at 0.
1153
 
    PARAMETER,
1154
 
 
1155
 
    // A slot in the local section on the stack. index() is
1156
 
    // the variable index in the stack frame, starting at 0.
1157
 
    LOCAL,
1158
 
 
1159
 
    // An indexed slot in a heap context. index() is the
1160
 
    // variable index in the context object on the heap,
1161
 
    // starting at 0. var()->scope() is the corresponding
1162
 
    // scope.
1163
 
    CONTEXT,
1164
 
 
1165
 
    // A named slot in a heap context. var()->name() is the
1166
 
    // variable name in the context object on the heap,
1167
 
    // with lookup starting at the current context. index()
1168
 
    // is invalid.
1169
 
    LOOKUP
1170
 
  };
1171
 
 
1172
 
  Slot(Variable* var, Type type, int index)
1173
 
      : var_(var), type_(type), index_(index) {
1174
 
    ASSERT(var != NULL);
1175
 
  }
1176
 
 
1177
 
  virtual void Accept(AstVisitor* v);
1178
 
 
1179
 
  virtual Slot* AsSlot() { return this; }
1180
 
 
1181
 
  bool IsStackAllocated() { return type_ == PARAMETER || type_ == LOCAL; }
1182
 
 
1183
 
  // Accessors
1184
 
  Variable* var() const { return var_; }
1185
 
  Type type() const { return type_; }
1186
 
  int index() const { return index_; }
1187
 
  bool is_arguments() const { return var_->is_arguments(); }
1188
 
 
1189
 
 private:
1190
 
  Variable* var_;
1191
 
  Type type_;
1192
 
  int index_;
1193
 
};
1194
 
 
1195
 
 
1196
1152
class Property: public Expression {
1197
1153
 public:
1198
 
  // Synthetic properties are property lookups introduced by the system,
1199
 
  // to objects that aren't visible to the user. Function calls to synthetic
1200
 
  // properties should use the global object as receiver, not the base object
1201
 
  // of the resolved Reference.
1202
 
  enum Type { NORMAL, SYNTHETIC };
1203
 
  Property(Expression* obj, Expression* key, int pos, Type type = NORMAL)
1204
 
      : obj_(obj),
 
1154
  Property(Isolate* isolate,
 
1155
           Expression* obj,
 
1156
           Expression* key,
 
1157
           int pos)
 
1158
      : Expression(isolate),
 
1159
        obj_(obj),
1205
1160
        key_(key),
1206
1161
        pos_(pos),
1207
 
        type_(type),
1208
 
        receiver_types_(NULL),
1209
1162
        is_monomorphic_(false),
1210
1163
        is_array_length_(false),
1211
1164
        is_string_length_(false),
1212
 
        is_function_prototype_(false),
1213
 
        is_arguments_access_(false) { }
 
1165
        is_string_access_(false),
 
1166
        is_function_prototype_(false) { }
1214
1167
 
1215
1168
  DECLARE_NODE_TYPE(Property)
1216
1169
 
1219
1172
 
1220
1173
  Expression* obj() const { return obj_; }
1221
1174
  Expression* key() const { return key_; }
1222
 
  int position() const { return pos_; }
1223
 
  bool is_synthetic() const { return type_ == SYNTHETIC; }
 
1175
  virtual int position() const { return pos_; }
1224
1176
 
1225
1177
  bool IsStringLength() const { return is_string_length_; }
 
1178
  bool IsStringAccess() const { return is_string_access_; }
1226
1179
  bool IsFunctionPrototype() const { return is_function_prototype_; }
1227
1180
 
1228
 
  // Marks that this is actually an argument rewritten to a keyed property
1229
 
  // accessing the argument through the arguments shadow object.
1230
 
  void set_is_arguments_access(bool is_arguments_access) {
1231
 
    is_arguments_access_ = is_arguments_access;
1232
 
  }
1233
 
  bool is_arguments_access() const { return is_arguments_access_; }
1234
 
 
1235
1181
  // Type feedback information.
1236
1182
  void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1237
1183
  virtual bool IsMonomorphic() { return is_monomorphic_; }
1238
 
  virtual ZoneMapList* GetReceiverTypes() { return receiver_types_; }
 
1184
  virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
1239
1185
  virtual bool IsArrayLength() { return is_array_length_; }
1240
 
  virtual Handle<Map> GetMonomorphicReceiverType() {
1241
 
    return monomorphic_receiver_type_;
1242
 
  }
1243
 
 
1244
 
  // Returns a property singleton property access on 'this'.  Used
1245
 
  // during preparsing.
1246
 
  static Property* this_property() { return &this_property_; }
1247
1186
 
1248
1187
 private:
1249
1188
  Expression* obj_;
1250
1189
  Expression* key_;
1251
1190
  int pos_;
1252
 
  Type type_;
1253
1191
 
1254
 
  ZoneMapList* receiver_types_;
 
1192
  SmallMapList receiver_types_;
1255
1193
  bool is_monomorphic_ : 1;
1256
1194
  bool is_array_length_ : 1;
1257
1195
  bool is_string_length_ : 1;
 
1196
  bool is_string_access_ : 1;
1258
1197
  bool is_function_prototype_ : 1;
1259
 
  bool is_arguments_access_ : 1;
1260
 
  Handle<Map> monomorphic_receiver_type_;
1261
 
 
1262
 
  // Dummy property used during preparsing.
1263
 
  static Property this_property_;
1264
1198
};
1265
1199
 
1266
1200
 
1267
1201
class Call: public Expression {
1268
1202
 public:
1269
 
  Call(Expression* expression, ZoneList<Expression*>* arguments, int pos)
1270
 
      : expression_(expression),
 
1203
  Call(Isolate* isolate,
 
1204
       Expression* expression,
 
1205
       ZoneList<Expression*>* arguments,
 
1206
       int pos)
 
1207
      : Expression(isolate),
 
1208
        expression_(expression),
1271
1209
        arguments_(arguments),
1272
1210
        pos_(pos),
1273
1211
        is_monomorphic_(false),
1274
1212
        check_type_(RECEIVER_MAP_CHECK),
1275
 
        receiver_types_(NULL),
1276
 
        return_id_(GetNextId()) {
 
1213
        return_id_(GetNextId(isolate)) {
1277
1214
  }
1278
1215
 
1279
1216
  DECLARE_NODE_TYPE(Call)
1282
1219
 
1283
1220
  Expression* expression() const { return expression_; }
1284
1221
  ZoneList<Expression*>* arguments() const { return arguments_; }
1285
 
  int position() { return pos_; }
 
1222
  virtual int position() const { return pos_; }
1286
1223
 
1287
 
  void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1288
 
  virtual ZoneMapList* GetReceiverTypes() { return receiver_types_; }
 
1224
  void RecordTypeFeedback(TypeFeedbackOracle* oracle,
 
1225
                          CallKind call_kind);
 
1226
  virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
1289
1227
  virtual bool IsMonomorphic() { return is_monomorphic_; }
1290
1228
  CheckType check_type() const { return check_type_; }
1291
1229
  Handle<JSFunction> target() { return target_; }
1293
1231
  Handle<JSGlobalPropertyCell> cell() { return cell_; }
1294
1232
 
1295
1233
  bool ComputeTarget(Handle<Map> type, Handle<String> name);
1296
 
  bool ComputeGlobalTarget(Handle<GlobalObject> global, Handle<String> name);
 
1234
  bool ComputeGlobalTarget(Handle<GlobalObject> global, LookupResult* lookup);
1297
1235
 
1298
1236
  // Bailout support.
1299
1237
  int ReturnId() const { return return_id_; }
1300
1238
 
1301
 
  static Call* sentinel() { return &sentinel_; }
1302
 
 
1303
1239
#ifdef DEBUG
1304
1240
  // Used to assert that the FullCodeGenerator records the return site.
1305
1241
  bool return_is_recorded_;
1312
1248
 
1313
1249
  bool is_monomorphic_;
1314
1250
  CheckType check_type_;
1315
 
  ZoneMapList* receiver_types_;
 
1251
  SmallMapList receiver_types_;
1316
1252
  Handle<JSFunction> target_;
1317
1253
  Handle<JSObject> holder_;
1318
1254
  Handle<JSGlobalPropertyCell> cell_;
1319
1255
 
1320
1256
  int return_id_;
1321
 
 
1322
 
  static Call sentinel_;
1323
1257
};
1324
1258
 
1325
1259
 
1326
1260
class CallNew: public Expression {
1327
1261
 public:
1328
 
  CallNew(Expression* expression, ZoneList<Expression*>* arguments, int pos)
1329
 
      : expression_(expression), arguments_(arguments), pos_(pos) { }
 
1262
  CallNew(Isolate* isolate,
 
1263
          Expression* expression,
 
1264
          ZoneList<Expression*>* arguments,
 
1265
          int pos)
 
1266
      : Expression(isolate),
 
1267
        expression_(expression),
 
1268
        arguments_(arguments),
 
1269
        pos_(pos) { }
1330
1270
 
1331
1271
  DECLARE_NODE_TYPE(CallNew)
1332
1272
 
1334
1274
 
1335
1275
  Expression* expression() const { return expression_; }
1336
1276
  ZoneList<Expression*>* arguments() const { return arguments_; }
1337
 
  int position() { return pos_; }
 
1277
  virtual int position() const { return pos_; }
1338
1278
 
1339
1279
 private:
1340
1280
  Expression* expression_;
1349
1289
// implemented in JavaScript (see "v8natives.js").
1350
1290
class CallRuntime: public Expression {
1351
1291
 public:
1352
 
  CallRuntime(Handle<String> name,
1353
 
              Runtime::Function* function,
 
1292
  CallRuntime(Isolate* isolate,
 
1293
              Handle<String> name,
 
1294
              const Runtime::Function* function,
1354
1295
              ZoneList<Expression*>* arguments)
1355
 
      : name_(name), function_(function), arguments_(arguments) { }
 
1296
      : Expression(isolate),
 
1297
        name_(name),
 
1298
        function_(function),
 
1299
        arguments_(arguments) { }
1356
1300
 
1357
1301
  DECLARE_NODE_TYPE(CallRuntime)
1358
1302
 
1359
1303
  virtual bool IsInlineable() const;
1360
1304
 
1361
1305
  Handle<String> name() const { return name_; }
1362
 
  Runtime::Function* function() const { return function_; }
 
1306
  const Runtime::Function* function() const { return function_; }
1363
1307
  ZoneList<Expression*>* arguments() const { return arguments_; }
1364
1308
  bool is_jsruntime() const { return function_ == NULL; }
1365
1309
 
1366
1310
 private:
1367
1311
  Handle<String> name_;
1368
 
  Runtime::Function* function_;
 
1312
  const Runtime::Function* function_;
1369
1313
  ZoneList<Expression*>* arguments_;
1370
1314
};
1371
1315
 
1372
1316
 
1373
1317
class UnaryOperation: public Expression {
1374
1318
 public:
1375
 
  UnaryOperation(Token::Value op, Expression* expression)
1376
 
      : op_(op), expression_(expression) {
 
1319
  UnaryOperation(Isolate* isolate,
 
1320
                 Token::Value op,
 
1321
                 Expression* expression,
 
1322
                 int pos)
 
1323
      : Expression(isolate), op_(op), expression_(expression), pos_(pos) {
1377
1324
    ASSERT(Token::IsUnaryOp(op));
1378
1325
  }
1379
1326
 
1385
1332
 
1386
1333
  Token::Value op() const { return op_; }
1387
1334
  Expression* expression() const { return expression_; }
 
1335
  virtual int position() const { return pos_; }
1388
1336
 
1389
1337
 private:
1390
1338
  Token::Value op_;
1391
1339
  Expression* expression_;
 
1340
  int pos_;
1392
1341
};
1393
1342
 
1394
1343
 
1395
1344
class BinaryOperation: public Expression {
1396
1345
 public:
1397
 
  BinaryOperation(Token::Value op,
 
1346
  BinaryOperation(Isolate* isolate,
 
1347
                  Token::Value op,
1398
1348
                  Expression* left,
1399
1349
                  Expression* right,
1400
1350
                  int pos)
1401
 
      : op_(op), left_(left), right_(right), pos_(pos) {
 
1351
      : Expression(isolate), op_(op), left_(left), right_(right), pos_(pos) {
1402
1352
    ASSERT(Token::IsBinaryOp(op));
1403
1353
    right_id_ = (op == Token::AND || op == Token::OR)
1404
 
        ? static_cast<int>(GetNextId())
 
1354
        ? static_cast<int>(GetNextId(isolate))
1405
1355
        : AstNode::kNoNumber;
1406
1356
  }
1407
1357
 
1408
 
  // Create the binary operation corresponding to a compound assignment.
1409
 
  explicit BinaryOperation(Assignment* assignment);
1410
 
 
1411
1358
  DECLARE_NODE_TYPE(BinaryOperation)
1412
1359
 
1413
1360
  virtual bool IsInlineable() const;
1417
1364
  Token::Value op() const { return op_; }
1418
1365
  Expression* left() const { return left_; }
1419
1366
  Expression* right() const { return right_; }
1420
 
  int position() const { return pos_; }
 
1367
  virtual int position() const { return pos_; }
1421
1368
 
1422
1369
  // Bailout support.
1423
1370
  int RightId() const { return right_id_; }
1433
1380
};
1434
1381
 
1435
1382
 
1436
 
class IncrementOperation: public Expression {
1437
 
 public:
1438
 
  IncrementOperation(Token::Value op, Expression* expr)
1439
 
      : op_(op), expression_(expr) {
1440
 
    ASSERT(Token::IsCountOp(op));
1441
 
  }
1442
 
 
1443
 
  DECLARE_NODE_TYPE(IncrementOperation)
1444
 
 
1445
 
  Token::Value op() const { return op_; }
1446
 
  bool is_increment() { return op_ == Token::INC; }
1447
 
  Expression* expression() const { return expression_; }
1448
 
 
1449
 
 private:
1450
 
  Token::Value op_;
1451
 
  Expression* expression_;
1452
 
  int pos_;
1453
 
};
1454
 
 
1455
 
 
1456
1383
class CountOperation: public Expression {
1457
1384
 public:
1458
 
  CountOperation(bool is_prefix, IncrementOperation* increment, int pos)
1459
 
      : is_prefix_(is_prefix), increment_(increment), pos_(pos),
1460
 
        assignment_id_(GetNextId()) {
1461
 
  }
 
1385
  CountOperation(Isolate* isolate,
 
1386
                 Token::Value op,
 
1387
                 bool is_prefix,
 
1388
                 Expression* expr,
 
1389
                 int pos)
 
1390
      : Expression(isolate),
 
1391
        op_(op),
 
1392
        is_prefix_(is_prefix),
 
1393
        expression_(expr),
 
1394
        pos_(pos),
 
1395
        assignment_id_(GetNextId(isolate)),
 
1396
        count_id_(GetNextId(isolate)) {}
1462
1397
 
1463
1398
  DECLARE_NODE_TYPE(CountOperation)
1464
1399
 
1465
1400
  bool is_prefix() const { return is_prefix_; }
1466
1401
  bool is_postfix() const { return !is_prefix_; }
1467
1402
 
1468
 
  Token::Value op() const { return increment_->op(); }
 
1403
  Token::Value op() const { return op_; }
1469
1404
  Token::Value binary_op() {
1470
1405
    return (op() == Token::INC) ? Token::ADD : Token::SUB;
1471
1406
  }
1472
1407
 
1473
 
  Expression* expression() const { return increment_->expression(); }
1474
 
  IncrementOperation* increment() const { return increment_; }
1475
 
  int position() const { return pos_; }
 
1408
  Expression* expression() const { return expression_; }
 
1409
  virtual int position() const { return pos_; }
1476
1410
 
1477
1411
  virtual void MarkAsStatement() { is_prefix_ = true; }
1478
1412
 
1479
1413
  virtual bool IsInlineable() const;
1480
1414
 
 
1415
  void RecordTypeFeedback(TypeFeedbackOracle* oracle);
 
1416
  virtual bool IsMonomorphic() { return is_monomorphic_; }
 
1417
  virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
 
1418
 
1481
1419
  // Bailout support.
1482
1420
  int AssignmentId() const { return assignment_id_; }
 
1421
  int CountId() const { return count_id_; }
1483
1422
 
1484
1423
 private:
 
1424
  Token::Value op_;
1485
1425
  bool is_prefix_;
1486
 
  IncrementOperation* increment_;
 
1426
  bool is_monomorphic_;
 
1427
  Expression* expression_;
1487
1428
  int pos_;
1488
1429
  int assignment_id_;
 
1430
  int count_id_;
 
1431
  SmallMapList receiver_types_;
1489
1432
};
1490
1433
 
1491
1434
 
1492
1435
class CompareOperation: public Expression {
1493
1436
 public:
1494
 
  CompareOperation(Token::Value op,
 
1437
  CompareOperation(Isolate* isolate,
 
1438
                   Token::Value op,
1495
1439
                   Expression* left,
1496
1440
                   Expression* right,
1497
1441
                   int pos)
1498
 
      : op_(op), left_(left), right_(right), pos_(pos), compare_type_(NONE) {
 
1442
      : Expression(isolate),
 
1443
        op_(op),
 
1444
        left_(left),
 
1445
        right_(right),
 
1446
        pos_(pos),
 
1447
        compare_type_(NONE) {
1499
1448
    ASSERT(Token::IsCompareOp(op));
1500
1449
  }
1501
1450
 
1504
1453
  Token::Value op() const { return op_; }
1505
1454
  Expression* left() const { return left_; }
1506
1455
  Expression* right() const { return right_; }
1507
 
  int position() const { return pos_; }
 
1456
  virtual int position() const { return pos_; }
1508
1457
 
1509
1458
  virtual bool IsInlineable() const;
1510
1459
 
1513
1462
  bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
1514
1463
  bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; }
1515
1464
 
 
1465
  // Match special cases.
 
1466
  bool IsLiteralCompareTypeof(Expression** expr, Handle<String>* check);
 
1467
  bool IsLiteralCompareUndefined(Expression** expr);
 
1468
 
1516
1469
 private:
1517
1470
  Token::Value op_;
1518
1471
  Expression* left_;
1526
1479
 
1527
1480
class CompareToNull: public Expression {
1528
1481
 public:
1529
 
  CompareToNull(bool is_strict, Expression* expression)
1530
 
      : is_strict_(is_strict), expression_(expression) { }
 
1482
  CompareToNull(Isolate* isolate, bool is_strict, Expression* expression)
 
1483
      : Expression(isolate), is_strict_(is_strict), expression_(expression) { }
1531
1484
 
1532
1485
  DECLARE_NODE_TYPE(CompareToNull)
1533
1486
 
1545
1498
 
1546
1499
class Conditional: public Expression {
1547
1500
 public:
1548
 
  Conditional(Expression* condition,
 
1501
  Conditional(Isolate* isolate,
 
1502
              Expression* condition,
1549
1503
              Expression* then_expression,
1550
1504
              Expression* else_expression,
1551
1505
              int then_expression_position,
1552
1506
              int else_expression_position)
1553
 
      : condition_(condition),
 
1507
      : Expression(isolate),
 
1508
        condition_(condition),
1554
1509
        then_expression_(then_expression),
1555
1510
        else_expression_(else_expression),
1556
1511
        then_expression_position_(then_expression_position),
1557
1512
        else_expression_position_(else_expression_position),
1558
 
        then_id_(GetNextId()),
1559
 
        else_id_(GetNextId()) {
 
1513
        then_id_(GetNextId(isolate)),
 
1514
        else_id_(GetNextId(isolate)) {
1560
1515
  }
1561
1516
 
1562
1517
  DECLARE_NODE_TYPE(Conditional)
1586
1541
 
1587
1542
class Assignment: public Expression {
1588
1543
 public:
1589
 
  Assignment(Token::Value op, Expression* target, Expression* value, int pos);
 
1544
  Assignment(Isolate* isolate,
 
1545
             Token::Value op,
 
1546
             Expression* target,
 
1547
             Expression* value,
 
1548
             int pos);
1590
1549
 
1591
1550
  DECLARE_NODE_TYPE(Assignment)
1592
1551
 
1599
1558
  Token::Value op() const { return op_; }
1600
1559
  Expression* target() const { return target_; }
1601
1560
  Expression* value() const { return value_; }
1602
 
  int position() { return pos_; }
 
1561
  virtual int position() const { return pos_; }
1603
1562
  BinaryOperation* binary_operation() const { return binary_operation_; }
1604
1563
 
1605
1564
  // This check relies on the definition order of token in token.h.
1617
1576
  // Type feedback information.
1618
1577
  void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1619
1578
  virtual bool IsMonomorphic() { return is_monomorphic_; }
1620
 
  virtual ZoneMapList* GetReceiverTypes() { return receiver_types_; }
1621
 
  virtual Handle<Map> GetMonomorphicReceiverType() {
1622
 
    return monomorphic_receiver_type_;
1623
 
  }
 
1579
  virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
1624
1580
 
1625
1581
  // Bailout support.
1626
1582
  int CompoundLoadId() const { return compound_load_id_; }
1639
1595
  bool block_end_;
1640
1596
 
1641
1597
  bool is_monomorphic_;
1642
 
  ZoneMapList* receiver_types_;
1643
 
  Handle<Map> monomorphic_receiver_type_;
 
1598
  SmallMapList receiver_types_;
1644
1599
};
1645
1600
 
1646
1601
 
1647
1602
class Throw: public Expression {
1648
1603
 public:
1649
 
  Throw(Expression* exception, int pos)
1650
 
      : exception_(exception), pos_(pos) {}
 
1604
  Throw(Isolate* isolate, Expression* exception, int pos)
 
1605
      : Expression(isolate), exception_(exception), pos_(pos) {}
1651
1606
 
1652
1607
  DECLARE_NODE_TYPE(Throw)
1653
1608
 
1654
1609
  Expression* exception() const { return exception_; }
1655
 
  int position() const { return pos_; }
 
1610
  virtual int position() const { return pos_; }
 
1611
  virtual bool IsInlineable() const;
1656
1612
 
1657
1613
 private:
1658
1614
  Expression* exception_;
1662
1618
 
1663
1619
class FunctionLiteral: public Expression {
1664
1620
 public:
1665
 
  FunctionLiteral(Handle<String> name,
 
1621
  enum Type {
 
1622
    ANONYMOUS_EXPRESSION,
 
1623
    NAMED_EXPRESSION,
 
1624
    DECLARATION
 
1625
  };
 
1626
 
 
1627
  FunctionLiteral(Isolate* isolate,
 
1628
                  Handle<String> name,
1666
1629
                  Scope* scope,
1667
1630
                  ZoneList<Statement*>* body,
1668
1631
                  int materialized_literal_count,
1672
1635
                  int num_parameters,
1673
1636
                  int start_position,
1674
1637
                  int end_position,
1675
 
                  bool is_expression,
1676
 
                  bool contains_loops,
1677
 
                  bool strict_mode)
1678
 
      : name_(name),
 
1638
                  Type type,
 
1639
                  bool has_duplicate_parameters)
 
1640
      : Expression(isolate),
 
1641
        name_(name),
1679
1642
        scope_(scope),
1680
1643
        body_(body),
1681
1644
        materialized_literal_count_(materialized_literal_count),
1686
1649
        num_parameters_(num_parameters),
1687
1650
        start_position_(start_position),
1688
1651
        end_position_(end_position),
1689
 
        is_expression_(is_expression),
1690
 
        contains_loops_(contains_loops),
1691
 
        strict_mode_(strict_mode),
1692
1652
        function_token_position_(RelocInfo::kNoPosition),
1693
 
        inferred_name_(Heap::empty_string()),
1694
 
        try_full_codegen_(false),
1695
 
        pretenure_(false) { }
 
1653
        inferred_name_(HEAP->empty_string()),
 
1654
        is_expression_(type != DECLARATION),
 
1655
        is_anonymous_(type == ANONYMOUS_EXPRESSION),
 
1656
        pretenure_(false),
 
1657
        has_duplicate_parameters_(has_duplicate_parameters) {
 
1658
  }
1696
1659
 
1697
1660
  DECLARE_NODE_TYPE(FunctionLiteral)
1698
1661
 
1704
1667
  int start_position() const { return start_position_; }
1705
1668
  int end_position() const { return end_position_; }
1706
1669
  bool is_expression() const { return is_expression_; }
1707
 
  bool contains_loops() const { return contains_loops_; }
1708
 
  bool strict_mode() const { return strict_mode_; }
 
1670
  bool is_anonymous() const { return is_anonymous_; }
 
1671
  bool strict_mode() const;
1709
1672
 
1710
1673
  int materialized_literal_count() { return materialized_literal_count_; }
1711
1674
  int expected_property_count() { return expected_property_count_; }
1729
1692
    inferred_name_ = inferred_name;
1730
1693
  }
1731
1694
 
1732
 
  bool try_full_codegen() { return try_full_codegen_; }
1733
 
  void set_try_full_codegen(bool flag) { try_full_codegen_ = flag; }
1734
 
 
1735
1695
  bool pretenure() { return pretenure_; }
1736
1696
  void set_pretenure(bool value) { pretenure_ = value; }
 
1697
  virtual bool IsInlineable() const;
 
1698
 
 
1699
  bool has_duplicate_parameters() { return has_duplicate_parameters_; }
1737
1700
 
1738
1701
 private:
1739
1702
  Handle<String> name_;
1746
1709
  int num_parameters_;
1747
1710
  int start_position_;
1748
1711
  int end_position_;
1749
 
  bool is_expression_;
1750
 
  bool contains_loops_;
1751
 
  bool strict_mode_;
1752
1712
  int function_token_position_;
1753
1713
  Handle<String> inferred_name_;
1754
 
  bool try_full_codegen_;
 
1714
  bool is_expression_;
 
1715
  bool is_anonymous_;
1755
1716
  bool pretenure_;
 
1717
  bool has_duplicate_parameters_;
1756
1718
};
1757
1719
 
1758
1720
 
1759
1721
class SharedFunctionInfoLiteral: public Expression {
1760
1722
 public:
1761
 
  explicit SharedFunctionInfoLiteral(
 
1723
  SharedFunctionInfoLiteral(
 
1724
      Isolate* isolate,
1762
1725
      Handle<SharedFunctionInfo> shared_function_info)
1763
 
      : shared_function_info_(shared_function_info) { }
 
1726
      : Expression(isolate), shared_function_info_(shared_function_info) { }
1764
1727
 
1765
1728
  DECLARE_NODE_TYPE(SharedFunctionInfoLiteral)
1766
1729
 
1767
1730
  Handle<SharedFunctionInfo> shared_function_info() const {
1768
1731
    return shared_function_info_;
1769
1732
  }
 
1733
  virtual bool IsInlineable() const;
1770
1734
 
1771
1735
 private:
1772
1736
  Handle<SharedFunctionInfo> shared_function_info_;
1775
1739
 
1776
1740
class ThisFunction: public Expression {
1777
1741
 public:
 
1742
  explicit ThisFunction(Isolate* isolate) : Expression(isolate) {}
1778
1743
  DECLARE_NODE_TYPE(ThisFunction)
 
1744
  virtual bool IsInlineable() const;
1779
1745
};
1780
1746
 
1781
1747
 
1809
1775
  // expression.
1810
1776
  virtual Interval CaptureRegisters() { return Interval::Empty(); }
1811
1777
  virtual void AppendToText(RegExpText* text);
1812
 
  SmartPointer<const char> ToString();
 
1778
  SmartArrayPointer<const char> ToString();
1813
1779
#define MAKE_ASTYPE(Name)                                                  \
1814
1780
  virtual RegExp##Name* As##Name();                                        \
1815
1781
  virtual bool Is##Name();
1944
1910
  uc16 standard_type() { return set_.standard_set_type(); }
1945
1911
  ZoneList<CharacterRange>* ranges() { return set_.ranges(); }
1946
1912
  bool is_negated() { return is_negated_; }
 
1913
 
1947
1914
 private:
1948
1915
  CharacterSet set_;
1949
1916
  bool is_negated_;
2028
1995
  bool is_non_greedy() { return type_ == NON_GREEDY; }
2029
1996
  bool is_greedy() { return type_ == GREEDY; }
2030
1997
  RegExpTree* body() { return body_; }
 
1998
 
2031
1999
 private:
2032
2000
  RegExpTree* body_;
2033
2001
  int min_;
2060
2028
  int index() { return index_; }
2061
2029
  static int StartRegister(int index) { return index * 2; }
2062
2030
  static int EndRegister(int index) { return index * 2 + 1; }
 
2031
 
2063
2032
 private:
2064
2033
  RegExpTree* body_;
2065
2034
  int index_;
2090
2059
  bool is_positive() { return is_positive_; }
2091
2060
  int capture_count() { return capture_count_; }
2092
2061
  int capture_from() { return capture_from_; }
 
2062
 
2093
2063
 private:
2094
2064
  RegExpTree* body_;
2095
2065
  bool is_positive_;
2138
2108
 
2139
2109
class AstVisitor BASE_EMBEDDED {
2140
2110
 public:
2141
 
  AstVisitor() : stack_overflow_(false) { }
 
2111
  AstVisitor() : isolate_(Isolate::Current()), stack_overflow_(false) { }
2142
2112
  virtual ~AstVisitor() { }
2143
2113
 
2144
2114
  // Stack overflow check and dynamic dispatch.
2159
2129
  void SetStackOverflow() { stack_overflow_ = true; }
2160
2130
  void ClearStackOverflow() { stack_overflow_ = false; }
2161
2131
 
2162
 
  // Nodes not appearing in the AST, including slots.
2163
 
  virtual void VisitSlot(Slot* node) { UNREACHABLE(); }
2164
 
 
2165
2132
  // Individual AST nodes.
2166
2133
#define DEF_VISIT(type)                         \
2167
2134
  virtual void Visit##type(type* node) = 0;
2168
2135
  AST_NODE_LIST(DEF_VISIT)
2169
2136
#undef DEF_VISIT
2170
2137
 
 
2138
 protected:
 
2139
  Isolate* isolate() { return isolate_; }
 
2140
 
2171
2141
 private:
 
2142
  Isolate* isolate_;
2172
2143
  bool stack_overflow_;
2173
2144
};
2174
2145
 
 
2146
 
2175
2147
} }  // namespace v8::internal
2176
2148
 
2177
2149
#endif  // V8_AST_H_