OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 13 matching lines...) Expand all Loading... |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #ifndef V8_AST_H_ | 28 #ifndef V8_AST_H_ |
29 #define V8_AST_H_ | 29 #define V8_AST_H_ |
30 | 30 |
31 #include "execution.h" | 31 #include "execution.h" |
32 #include "factory.h" | 32 #include "factory.h" |
33 #include "jsregexp.h" | 33 #include "jsregexp.h" |
34 #include "jump-target.h" | |
35 #include "runtime.h" | 34 #include "runtime.h" |
36 #include "token.h" | 35 #include "token.h" |
37 #include "variables.h" | 36 #include "variables.h" |
38 | 37 |
39 namespace v8 { | 38 namespace v8 { |
40 namespace internal { | 39 namespace internal { |
41 | 40 |
42 // The abstract syntax tree is an intermediate, light-weight | 41 // The abstract syntax tree is an intermediate, light-weight |
43 // representation of the parsed JavaScript code suitable for | 42 // representation of the parsed JavaScript code suitable for |
44 // compilation to native code. | 43 // compilation to native code. |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 // code generation. | 212 // code generation. |
214 kUninitialized, | 213 kUninitialized, |
215 // Evaluated for its side effects. | 214 // Evaluated for its side effects. |
216 kEffect, | 215 kEffect, |
217 // Evaluated for its value (and side effects). | 216 // Evaluated for its value (and side effects). |
218 kValue, | 217 kValue, |
219 // Evaluated for control flow (and side effects). | 218 // Evaluated for control flow (and side effects). |
220 kTest | 219 kTest |
221 }; | 220 }; |
222 | 221 |
223 Expression() : bitfields_(0) {} | 222 Expression() {} |
224 | 223 |
225 virtual Expression* AsExpression() { return this; } | 224 virtual Expression* AsExpression() { return this; } |
226 | 225 |
227 virtual bool IsTrivial() { return false; } | 226 virtual bool IsTrivial() { return false; } |
228 virtual bool IsValidLeftHandSide() { return false; } | 227 virtual bool IsValidLeftHandSide() { return false; } |
229 | 228 |
230 // Helpers for ToBoolean conversion. | 229 // Helpers for ToBoolean conversion. |
231 virtual bool ToBooleanIsTrue() { return false; } | 230 virtual bool ToBooleanIsTrue() { return false; } |
232 virtual bool ToBooleanIsFalse() { return false; } | 231 virtual bool ToBooleanIsFalse() { return false; } |
233 | 232 |
(...skipping 25 matching lines...) Expand all Loading... |
259 } | 258 } |
260 virtual ZoneMapList* GetReceiverTypes() { | 259 virtual ZoneMapList* GetReceiverTypes() { |
261 UNREACHABLE(); | 260 UNREACHABLE(); |
262 return NULL; | 261 return NULL; |
263 } | 262 } |
264 virtual Handle<Map> GetMonomorphicReceiverType() { | 263 virtual Handle<Map> GetMonomorphicReceiverType() { |
265 UNREACHABLE(); | 264 UNREACHABLE(); |
266 return Handle<Map>(); | 265 return Handle<Map>(); |
267 } | 266 } |
268 | 267 |
269 // Static type information for this expression. | |
270 StaticType* type() { return &type_; } | |
271 | |
272 // True if the expression is a loop condition. | |
273 bool is_loop_condition() const { | |
274 return LoopConditionField::decode(bitfields_); | |
275 } | |
276 void set_is_loop_condition(bool flag) { | |
277 bitfields_ = (bitfields_ & ~LoopConditionField::mask()) | | |
278 LoopConditionField::encode(flag); | |
279 } | |
280 | |
281 // The value of the expression is guaranteed to be a smi, because the | 268 // The value of the expression is guaranteed to be a smi, because the |
282 // top operation is a bit operation with a mask, or a shift. | 269 // top operation is a bit operation with a mask, or a shift. |
283 bool GuaranteedSmiResult(); | 270 bool GuaranteedSmiResult(); |
284 | |
285 // AST analysis results. | |
286 void CopyAnalysisResultsFrom(Expression* other); | |
287 | |
288 // True if the expression rooted at this node can be compiled by the | |
289 // side-effect free compiler. | |
290 bool side_effect_free() { return SideEffectFreeField::decode(bitfields_); } | |
291 void set_side_effect_free(bool is_side_effect_free) { | |
292 bitfields_ &= ~SideEffectFreeField::mask(); | |
293 bitfields_ |= SideEffectFreeField::encode(is_side_effect_free); | |
294 } | |
295 | |
296 // Will the use of this expression treat -0 the same as 0 in all cases? | |
297 // If so, we can return 0 instead of -0 if we want to, to optimize code. | |
298 bool no_negative_zero() { return NoNegativeZeroField::decode(bitfields_); } | |
299 void set_no_negative_zero(bool no_negative_zero) { | |
300 bitfields_ &= ~NoNegativeZeroField::mask(); | |
301 bitfields_ |= NoNegativeZeroField::encode(no_negative_zero); | |
302 } | |
303 | |
304 // Will ToInt32 (ECMA 262-3 9.5) or ToUint32 (ECMA 262-3 9.6) | |
305 // be applied to the value of this expression? | |
306 // If so, we may be able to optimize the calculation of the value. | |
307 bool to_int32() { return ToInt32Field::decode(bitfields_); } | |
308 void set_to_int32(bool to_int32) { | |
309 bitfields_ &= ~ToInt32Field::mask(); | |
310 bitfields_ |= ToInt32Field::encode(to_int32); | |
311 } | |
312 | |
313 // How many bitwise logical or shift operators are used in this expression? | |
314 int num_bit_ops() { return NumBitOpsField::decode(bitfields_); } | |
315 void set_num_bit_ops(int num_bit_ops) { | |
316 bitfields_ &= ~NumBitOpsField::mask(); | |
317 num_bit_ops = Min(num_bit_ops, kMaxNumBitOps); | |
318 bitfields_ |= NumBitOpsField::encode(num_bit_ops); | |
319 } | |
320 | |
321 private: | |
322 static const int kMaxNumBitOps = (1 << 5) - 1; | |
323 | |
324 uint32_t bitfields_; | |
325 StaticType type_; | |
326 | |
327 // Using template BitField<type, start, size>. | |
328 class SideEffectFreeField : public BitField<bool, 0, 1> {}; | |
329 class NoNegativeZeroField : public BitField<bool, 1, 1> {}; | |
330 class ToInt32Field : public BitField<bool, 2, 1> {}; | |
331 class NumBitOpsField : public BitField<int, 3, 5> {}; | |
332 class LoopConditionField: public BitField<bool, 8, 1> {}; | |
333 }; | 271 }; |
334 | 272 |
335 | 273 |
336 /** | 274 /** |
337 * A sentinel used during pre parsing that represents some expression | 275 * A sentinel used during pre parsing that represents some expression |
338 * that is a valid left hand side without having to actually build | 276 * that is a valid left hand side without having to actually build |
339 * the expression. | 277 * the expression. |
340 */ | 278 */ |
341 class ValidLeftHandSideSentinel: public Expression { | 279 class ValidLeftHandSideSentinel: public Expression { |
342 public: | 280 public: |
(...skipping 10 matching lines...) Expand all Loading... |
353 }; | 291 }; |
354 | 292 |
355 // The labels associated with this statement. May be NULL; | 293 // The labels associated with this statement. May be NULL; |
356 // if it is != NULL, guaranteed to contain at least one entry. | 294 // if it is != NULL, guaranteed to contain at least one entry. |
357 ZoneStringList* labels() const { return labels_; } | 295 ZoneStringList* labels() const { return labels_; } |
358 | 296 |
359 // Type testing & conversion. | 297 // Type testing & conversion. |
360 virtual BreakableStatement* AsBreakableStatement() { return this; } | 298 virtual BreakableStatement* AsBreakableStatement() { return this; } |
361 | 299 |
362 // Code generation | 300 // Code generation |
363 BreakTarget* break_target() { return &break_target_; } | 301 Label* break_target() { return &break_target_; } |
364 | 302 |
365 // Testers. | 303 // Testers. |
366 bool is_target_for_anonymous() const { return type_ == TARGET_FOR_ANONYMOUS; } | 304 bool is_target_for_anonymous() const { return type_ == TARGET_FOR_ANONYMOUS; } |
367 | 305 |
368 // Bailout support. | 306 // Bailout support. |
369 int EntryId() const { return entry_id_; } | 307 int EntryId() const { return entry_id_; } |
370 int ExitId() const { return exit_id_; } | 308 int ExitId() const { return exit_id_; } |
371 | 309 |
372 protected: | 310 protected: |
373 inline BreakableStatement(ZoneStringList* labels, Type type); | 311 inline BreakableStatement(ZoneStringList* labels, Type type); |
374 | 312 |
375 private: | 313 private: |
376 ZoneStringList* labels_; | 314 ZoneStringList* labels_; |
377 Type type_; | 315 Type type_; |
378 BreakTarget break_target_; | 316 Label break_target_; |
379 int entry_id_; | 317 int entry_id_; |
380 int exit_id_; | 318 int exit_id_; |
381 }; | 319 }; |
382 | 320 |
383 | 321 |
384 class Block: public BreakableStatement { | 322 class Block: public BreakableStatement { |
385 public: | 323 public: |
386 inline Block(ZoneStringList* labels, int capacity, bool is_initializer_block); | 324 inline Block(ZoneStringList* labels, int capacity, bool is_initializer_block); |
387 | 325 |
388 DECLARE_NODE_TYPE(Block) | 326 DECLARE_NODE_TYPE(Block) |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 // Type testing & conversion. | 377 // Type testing & conversion. |
440 virtual IterationStatement* AsIterationStatement() { return this; } | 378 virtual IterationStatement* AsIterationStatement() { return this; } |
441 | 379 |
442 Statement* body() const { return body_; } | 380 Statement* body() const { return body_; } |
443 | 381 |
444 // Bailout support. | 382 // Bailout support. |
445 int OsrEntryId() const { return osr_entry_id_; } | 383 int OsrEntryId() const { return osr_entry_id_; } |
446 virtual int ContinueId() const = 0; | 384 virtual int ContinueId() const = 0; |
447 | 385 |
448 // Code generation | 386 // Code generation |
449 BreakTarget* continue_target() { return &continue_target_; } | 387 Label* continue_target() { return &continue_target_; } |
450 | 388 |
451 protected: | 389 protected: |
452 explicit inline IterationStatement(ZoneStringList* labels); | 390 explicit inline IterationStatement(ZoneStringList* labels); |
453 | 391 |
454 void Initialize(Statement* body) { | 392 void Initialize(Statement* body) { |
455 body_ = body; | 393 body_ = body; |
456 } | 394 } |
457 | 395 |
458 private: | 396 private: |
459 Statement* body_; | 397 Statement* body_; |
460 BreakTarget continue_target_; | 398 Label continue_target_; |
461 int osr_entry_id_; | 399 int osr_entry_id_; |
462 }; | 400 }; |
463 | 401 |
464 | 402 |
465 class DoWhileStatement: public IterationStatement { | 403 class DoWhileStatement: public IterationStatement { |
466 public: | 404 public: |
467 explicit inline DoWhileStatement(ZoneStringList* labels); | 405 explicit inline DoWhileStatement(ZoneStringList* labels); |
468 | 406 |
469 DECLARE_NODE_TYPE(DoWhileStatement) | 407 DECLARE_NODE_TYPE(DoWhileStatement) |
470 | 408 |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
686 | 624 |
687 class CaseClause: public ZoneObject { | 625 class CaseClause: public ZoneObject { |
688 public: | 626 public: |
689 CaseClause(Expression* label, ZoneList<Statement*>* statements, int pos); | 627 CaseClause(Expression* label, ZoneList<Statement*>* statements, int pos); |
690 | 628 |
691 bool is_default() const { return label_ == NULL; } | 629 bool is_default() const { return label_ == NULL; } |
692 Expression* label() const { | 630 Expression* label() const { |
693 CHECK(!is_default()); | 631 CHECK(!is_default()); |
694 return label_; | 632 return label_; |
695 } | 633 } |
696 JumpTarget* body_target() { return &body_target_; } | 634 Label* body_target() { return &body_target_; } |
697 ZoneList<Statement*>* statements() const { return statements_; } | 635 ZoneList<Statement*>* statements() const { return statements_; } |
698 | 636 |
699 int position() { return position_; } | 637 int position() { return position_; } |
700 void set_position(int pos) { position_ = pos; } | 638 void set_position(int pos) { position_ = pos; } |
701 | 639 |
702 int EntryId() { return entry_id_; } | 640 int EntryId() { return entry_id_; } |
703 | 641 |
704 // Type feedback information. | 642 // Type feedback information. |
705 void RecordTypeFeedback(TypeFeedbackOracle* oracle); | 643 void RecordTypeFeedback(TypeFeedbackOracle* oracle); |
706 bool IsSmiCompare() { return compare_type_ == SMI_ONLY; } | 644 bool IsSmiCompare() { return compare_type_ == SMI_ONLY; } |
707 bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; } | 645 bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; } |
708 | 646 |
709 private: | 647 private: |
710 Expression* label_; | 648 Expression* label_; |
711 JumpTarget body_target_; | 649 Label body_target_; |
712 ZoneList<Statement*>* statements_; | 650 ZoneList<Statement*>* statements_; |
713 int position_; | 651 int position_; |
714 enum CompareTypeFeedback { NONE, SMI_ONLY, OBJECT_ONLY }; | 652 enum CompareTypeFeedback { NONE, SMI_ONLY, OBJECT_ONLY }; |
715 CompareTypeFeedback compare_type_; | 653 CompareTypeFeedback compare_type_; |
716 int entry_id_; | 654 int entry_id_; |
717 }; | 655 }; |
718 | 656 |
719 | 657 |
720 class SwitchStatement: public BreakableStatement { | 658 class SwitchStatement: public BreakableStatement { |
721 public: | 659 public: |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
774 Statement* else_statement_; | 712 Statement* else_statement_; |
775 int then_id_; | 713 int then_id_; |
776 int else_id_; | 714 int else_id_; |
777 }; | 715 }; |
778 | 716 |
779 | 717 |
780 // NOTE: TargetCollectors are represented as nodes to fit in the target | 718 // NOTE: TargetCollectors are represented as nodes to fit in the target |
781 // stack in the compiler; this should probably be reworked. | 719 // stack in the compiler; this should probably be reworked. |
782 class TargetCollector: public AstNode { | 720 class TargetCollector: public AstNode { |
783 public: | 721 public: |
784 explicit TargetCollector(ZoneList<BreakTarget*>* targets) | 722 explicit TargetCollector(ZoneList<Label*>* targets) |
785 : targets_(targets) { | 723 : targets_(targets) { |
786 } | 724 } |
787 | 725 |
788 // Adds a jump target to the collector. The collector stores a pointer not | 726 // Adds a jump target to the collector. The collector stores a pointer not |
789 // a copy of the target to make binding work, so make sure not to pass in | 727 // a copy of the target to make binding work, so make sure not to pass in |
790 // references to something on the stack. | 728 // references to something on the stack. |
791 void AddTarget(BreakTarget* target); | 729 void AddTarget(Label* target); |
792 | 730 |
793 // Virtual behaviour. TargetCollectors are never part of the AST. | 731 // Virtual behaviour. TargetCollectors are never part of the AST. |
794 virtual void Accept(AstVisitor* v) { UNREACHABLE(); } | 732 virtual void Accept(AstVisitor* v) { UNREACHABLE(); } |
795 virtual TargetCollector* AsTargetCollector() { return this; } | 733 virtual TargetCollector* AsTargetCollector() { return this; } |
796 | 734 |
797 ZoneList<BreakTarget*>* targets() { return targets_; } | 735 ZoneList<Label*>* targets() { return targets_; } |
798 | 736 |
799 private: | 737 private: |
800 ZoneList<BreakTarget*>* targets_; | 738 ZoneList<Label*>* targets_; |
801 }; | 739 }; |
802 | 740 |
803 | 741 |
804 class TryStatement: public Statement { | 742 class TryStatement: public Statement { |
805 public: | 743 public: |
806 explicit TryStatement(Block* try_block) | 744 explicit TryStatement(Block* try_block) |
807 : try_block_(try_block), escaping_targets_(NULL) { } | 745 : try_block_(try_block), escaping_targets_(NULL) { } |
808 | 746 |
809 void set_escaping_targets(ZoneList<BreakTarget*>* targets) { | 747 void set_escaping_targets(ZoneList<Label*>* targets) { |
810 escaping_targets_ = targets; | 748 escaping_targets_ = targets; |
811 } | 749 } |
812 | 750 |
813 Block* try_block() const { return try_block_; } | 751 Block* try_block() const { return try_block_; } |
814 ZoneList<BreakTarget*>* escaping_targets() const { return escaping_targets_; } | 752 ZoneList<Label*>* escaping_targets() const { return escaping_targets_; } |
815 | 753 |
816 private: | 754 private: |
817 Block* try_block_; | 755 Block* try_block_; |
818 ZoneList<BreakTarget*>* escaping_targets_; | 756 ZoneList<Label*>* escaping_targets_; |
819 }; | 757 }; |
820 | 758 |
821 | 759 |
822 class TryCatchStatement: public TryStatement { | 760 class TryCatchStatement: public TryStatement { |
823 public: | 761 public: |
824 TryCatchStatement(Block* try_block, | 762 TryCatchStatement(Block* try_block, |
825 VariableProxy* catch_var, | 763 VariableProxy* catch_var, |
826 Block* catch_block) | 764 Block* catch_block) |
827 : TryStatement(try_block), | 765 : TryStatement(try_block), |
828 catch_var_(catch_var), | 766 catch_var_(catch_var), |
(...skipping 1396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2225 | 2163 |
2226 private: | 2164 private: |
2227 Isolate* isolate_; | 2165 Isolate* isolate_; |
2228 bool stack_overflow_; | 2166 bool stack_overflow_; |
2229 }; | 2167 }; |
2230 | 2168 |
2231 | 2169 |
2232 } } // namespace v8::internal | 2170 } } // namespace v8::internal |
2233 | 2171 |
2234 #endif // V8_AST_H_ | 2172 #endif // V8_AST_H_ |
OLD | NEW |