OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/ast/ast.h" | 5 #include "src/ast/ast.h" |
6 | 6 |
7 #include <cmath> // For isfinite. | 7 #include <cmath> // For isfinite. |
8 | 8 |
9 #include "src/ast/prettyprinter.h" | 9 #include "src/ast/prettyprinter.h" |
10 #include "src/ast/scopes.h" | 10 #include "src/ast/scopes.h" |
(...skipping 25 matching lines...) Expand all Loading... |
36 | 36 |
37 #ifdef DEBUG | 37 #ifdef DEBUG |
38 | 38 |
39 void AstNode::Print(Isolate* isolate) { | 39 void AstNode::Print(Isolate* isolate) { |
40 AstPrinter::PrintOut(isolate, this); | 40 AstPrinter::PrintOut(isolate, this); |
41 } | 41 } |
42 | 42 |
43 | 43 |
44 #endif // DEBUG | 44 #endif // DEBUG |
45 | 45 |
| 46 #define RETURN_NODE(Node) \ |
| 47 case k##Node: \ |
| 48 return static_cast<Node*>(this); |
| 49 |
| 50 IterationStatement* AstNode::AsIterationStatement() { |
| 51 switch (node_type()) { |
| 52 ITERATION_NODE_LIST(RETURN_NODE); |
| 53 default: |
| 54 return nullptr; |
| 55 } |
| 56 } |
| 57 |
| 58 BreakableStatement* AstNode::AsBreakableStatement() { |
| 59 switch (node_type()) { |
| 60 BREAKABLE_NODE_LIST(RETURN_NODE); |
| 61 ITERATION_NODE_LIST(RETURN_NODE); |
| 62 default: |
| 63 return nullptr; |
| 64 } |
| 65 } |
| 66 |
| 67 MaterializedLiteral* AstNode::AsMaterializedLiteral() { |
| 68 switch (node_type()) { |
| 69 LITERAL_NODE_LIST(RETURN_NODE); |
| 70 default: |
| 71 return nullptr; |
| 72 } |
| 73 } |
| 74 |
| 75 #undef RETURN_NODE |
| 76 |
| 77 InitializationFlag Declaration::initialization() const { |
| 78 switch (node_type()) { |
| 79 #define GENERATE_CASE(Node) \ |
| 80 case k##Node: \ |
| 81 return static_cast<const Node*>(this)->initialization(); |
| 82 DECLARATION_NODE_LIST(GENERATE_CASE); |
| 83 #undef GENERATE_CASE |
| 84 default: |
| 85 UNREACHABLE(); |
| 86 return kNeedsInitialization; |
| 87 } |
| 88 } |
46 | 89 |
47 bool Expression::IsSmiLiteral() const { | 90 bool Expression::IsSmiLiteral() const { |
48 return IsLiteral() && AsLiteral()->value()->IsSmi(); | 91 return IsLiteral() && AsLiteral()->value()->IsSmi(); |
49 } | 92 } |
50 | 93 |
51 | 94 |
52 bool Expression::IsStringLiteral() const { | 95 bool Expression::IsStringLiteral() const { |
53 return IsLiteral() && AsLiteral()->value()->IsString(); | 96 return IsLiteral() && AsLiteral()->value()->IsString(); |
54 } | 97 } |
55 | 98 |
| 99 bool Expression::IsPropertyName() const { |
| 100 return IsLiteral() && AsLiteral()->IsPropertyName(); |
| 101 } |
56 | 102 |
57 bool Expression::IsNullLiteral() const { | 103 bool Expression::IsNullLiteral() const { |
58 if (!IsLiteral()) return false; | 104 if (!IsLiteral()) return false; |
59 Handle<Object> value = AsLiteral()->value(); | 105 Handle<Object> value = AsLiteral()->value(); |
60 return !value->IsSmi() && | 106 return !value->IsSmi() && |
61 value->IsNull(HeapObject::cast(*value)->GetIsolate()); | 107 value->IsNull(HeapObject::cast(*value)->GetIsolate()); |
62 } | 108 } |
63 | 109 |
64 bool Expression::IsUndefinedLiteral() const { | 110 bool Expression::IsUndefinedLiteral() const { |
65 if (IsLiteral()) { | 111 if (IsLiteral()) { |
66 Handle<Object> value = AsLiteral()->value(); | 112 Handle<Object> value = AsLiteral()->value(); |
67 if (!value->IsSmi() && | 113 if (!value->IsSmi() && |
68 value->IsUndefined(HeapObject::cast(*value)->GetIsolate())) { | 114 value->IsUndefined(HeapObject::cast(*value)->GetIsolate())) { |
69 return true; | 115 return true; |
70 } | 116 } |
71 } | 117 } |
72 | 118 |
73 const VariableProxy* var_proxy = AsVariableProxy(); | 119 const VariableProxy* var_proxy = AsVariableProxy(); |
74 if (var_proxy == NULL) return false; | 120 if (var_proxy == NULL) return false; |
75 Variable* var = var_proxy->var(); | 121 Variable* var = var_proxy->var(); |
76 // The global identifier "undefined" is immutable. Everything | 122 // The global identifier "undefined" is immutable. Everything |
77 // else could be reassigned. | 123 // else could be reassigned. |
78 return var != NULL && var->IsUnallocatedOrGlobalSlot() && | 124 return var != NULL && var->IsUnallocatedOrGlobalSlot() && |
79 var_proxy->raw_name()->IsOneByteEqualTo("undefined"); | 125 var_proxy->raw_name()->IsOneByteEqualTo("undefined"); |
80 } | 126 } |
81 | 127 |
| 128 bool Expression::ToBooleanIsTrue() const { |
| 129 return IsLiteral() && AsLiteral()->ToBooleanIsTrue(); |
| 130 } |
| 131 |
| 132 bool Expression::ToBooleanIsFalse() const { |
| 133 return IsLiteral() && AsLiteral()->ToBooleanIsFalse(); |
| 134 } |
| 135 |
| 136 bool Expression::IsValidReferenceExpression() const { |
| 137 return IsProperty() || |
| 138 (IsVariableProxy() && AsVariableProxy()->IsValidReferenceExpression()); |
| 139 } |
82 | 140 |
83 bool Expression::IsValidReferenceExpressionOrThis() const { | 141 bool Expression::IsValidReferenceExpressionOrThis() const { |
84 return IsValidReferenceExpression() || | 142 return IsValidReferenceExpression() || |
85 (IsVariableProxy() && AsVariableProxy()->is_this()); | 143 (IsVariableProxy() && AsVariableProxy()->is_this()); |
86 } | 144 } |
87 | 145 |
| 146 bool Expression::IsAnonymousFunctionDefinition() const { |
| 147 return (IsFunctionLiteral() && |
| 148 AsFunctionLiteral()->IsAnonymousFunctionDefinition()) || |
| 149 (IsClassLiteral() && |
| 150 AsClassLiteral()->IsAnonymousFunctionDefinition()); |
| 151 } |
| 152 |
| 153 void Expression::MarkTail() { |
| 154 if (IsConditional()) { |
| 155 AsConditional()->MarkTail(); |
| 156 } else if (IsCall()) { |
| 157 AsCall()->MarkTail(); |
| 158 } else if (IsBinaryOperation()) { |
| 159 AsBinaryOperation()->MarkTail(); |
| 160 } |
| 161 } |
| 162 |
| 163 bool Statement::IsJump() const { |
| 164 switch (node_type()) { |
| 165 #define JUMP_NODE_LIST(V) \ |
| 166 V(Block) \ |
| 167 V(ExpressionStatement) \ |
| 168 V(ContinueStatement) \ |
| 169 V(BreakStatement) \ |
| 170 V(ReturnStatement) \ |
| 171 V(IfStatement) |
| 172 #define GENERATE_CASE(Node) \ |
| 173 case k##Node: \ |
| 174 return static_cast<const Node*>(this)->IsJump(); |
| 175 JUMP_NODE_LIST(GENERATE_CASE) |
| 176 #undef GENERATE_CASE |
| 177 #undef JUMP_NODE_LIST |
| 178 default: |
| 179 return false; |
| 180 } |
| 181 } |
88 | 182 |
89 VariableProxy::VariableProxy(Zone* zone, Variable* var, int start_position, | 183 VariableProxy::VariableProxy(Zone* zone, Variable* var, int start_position, |
90 int end_position) | 184 int end_position) |
91 : Expression(zone, start_position), | 185 : Expression(zone, start_position), |
92 bit_field_(IsThisField::encode(var->is_this()) | | 186 bit_field_(IsThisField::encode(var->is_this()) | |
93 IsAssignedField::encode(false) | | 187 IsAssignedField::encode(false) | |
94 IsResolvedField::encode(false)), | 188 IsResolvedField::encode(false)), |
95 raw_name_(var->raw_name()), | 189 raw_name_(var->raw_name()), |
96 end_position_(end_position) { | 190 end_position_(end_position) { |
97 BindTo(var); | 191 BindTo(var); |
(...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
708 } | 802 } |
709 | 803 |
710 | 804 |
711 // ---------------------------------------------------------------------------- | 805 // ---------------------------------------------------------------------------- |
712 // Recording of type feedback | 806 // Recording of type feedback |
713 | 807 |
714 // TODO(rossberg): all RecordTypeFeedback functions should disappear | 808 // TODO(rossberg): all RecordTypeFeedback functions should disappear |
715 // once we use the common type field in the AST consistently. | 809 // once we use the common type field in the AST consistently. |
716 | 810 |
717 void Expression::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) { | 811 void Expression::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) { |
718 set_to_boolean_types(oracle->ToBooleanTypes(test_id())); | 812 if (IsUnaryOperation()) { |
| 813 AsUnaryOperation()->RecordToBooleanTypeFeedback(oracle); |
| 814 } else if (IsBinaryOperation()) { |
| 815 AsBinaryOperation()->RecordToBooleanTypeFeedback(oracle); |
| 816 } else { |
| 817 set_to_boolean_types(oracle->ToBooleanTypes(test_id())); |
| 818 } |
719 } | 819 } |
720 | 820 |
| 821 SmallMapList* Expression::GetReceiverTypes() { |
| 822 switch (node_type()) { |
| 823 #define NODE_LIST(V) \ |
| 824 PROPERTY_NODE_LIST(V) \ |
| 825 V(Call) |
| 826 #define GENERATE_CASE(Node) \ |
| 827 case k##Node: \ |
| 828 return static_cast<Node*>(this)->GetReceiverTypes(); |
| 829 NODE_LIST(GENERATE_CASE) |
| 830 #undef NODE_LIST |
| 831 #undef GENERATE_CASE |
| 832 default: |
| 833 UNREACHABLE(); |
| 834 return nullptr; |
| 835 } |
| 836 } |
| 837 |
| 838 KeyedAccessStoreMode Expression::GetStoreMode() const { |
| 839 switch (node_type()) { |
| 840 #define GENERATE_CASE(Node) \ |
| 841 case k##Node: \ |
| 842 return static_cast<const Node*>(this)->GetStoreMode(); |
| 843 PROPERTY_NODE_LIST(GENERATE_CASE) |
| 844 #undef GENERATE_CASE |
| 845 default: |
| 846 UNREACHABLE(); |
| 847 return STANDARD_STORE; |
| 848 } |
| 849 } |
| 850 |
| 851 IcCheckType Expression::GetKeyType() const { |
| 852 switch (node_type()) { |
| 853 #define GENERATE_CASE(Node) \ |
| 854 case k##Node: \ |
| 855 return static_cast<const Node*>(this)->GetKeyType(); |
| 856 PROPERTY_NODE_LIST(GENERATE_CASE) |
| 857 #undef GENERATE_CASE |
| 858 default: |
| 859 UNREACHABLE(); |
| 860 return PROPERTY; |
| 861 } |
| 862 } |
| 863 |
| 864 bool Expression::IsMonomorphic() const { |
| 865 switch (node_type()) { |
| 866 #define GENERATE_CASE(Node) \ |
| 867 case k##Node: \ |
| 868 return static_cast<const Node*>(this)->IsMonomorphic(); |
| 869 PROPERTY_NODE_LIST(GENERATE_CASE) |
| 870 CALL_NODE_LIST(GENERATE_CASE) |
| 871 #undef GENERATE_CASE |
| 872 default: |
| 873 UNREACHABLE(); |
| 874 return false; |
| 875 } |
| 876 } |
721 | 877 |
722 bool Call::IsUsingCallFeedbackICSlot(Isolate* isolate) const { | 878 bool Call::IsUsingCallFeedbackICSlot(Isolate* isolate) const { |
723 CallType call_type = GetCallType(isolate); | 879 CallType call_type = GetCallType(isolate); |
724 if (call_type == POSSIBLY_EVAL_CALL) { | 880 if (call_type == POSSIBLY_EVAL_CALL) { |
725 return false; | 881 return false; |
726 } | 882 } |
727 return true; | 883 return true; |
728 } | 884 } |
729 | 885 |
730 | 886 |
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1123 bool Literal::Match(void* literal1, void* literal2) { | 1279 bool Literal::Match(void* literal1, void* literal2) { |
1124 const AstValue* x = static_cast<Literal*>(literal1)->raw_value(); | 1280 const AstValue* x = static_cast<Literal*>(literal1)->raw_value(); |
1125 const AstValue* y = static_cast<Literal*>(literal2)->raw_value(); | 1281 const AstValue* y = static_cast<Literal*>(literal2)->raw_value(); |
1126 return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) || | 1282 return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) || |
1127 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber()); | 1283 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber()); |
1128 } | 1284 } |
1129 | 1285 |
1130 | 1286 |
1131 } // namespace internal | 1287 } // namespace internal |
1132 } // namespace v8 | 1288 } // namespace v8 |
OLD | NEW |