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 29 matching lines...) Expand all Loading... | |
40 AstPrinter::PrintOut(isolate, this); | 40 AstPrinter::PrintOut(isolate, this); |
41 } | 41 } |
42 | 42 |
43 | 43 |
44 void AstNode::PrettyPrint(Isolate* isolate) { | 44 void AstNode::PrettyPrint(Isolate* isolate) { |
45 PrettyPrinter::PrintOut(isolate, this); | 45 PrettyPrinter::PrintOut(isolate, this); |
46 } | 46 } |
47 | 47 |
48 #endif // DEBUG | 48 #endif // DEBUG |
49 | 49 |
50 #define RETURN_NODE(Node) \ | |
51 case k##Node: \ | |
52 return static_cast<Node*>(this); | |
53 | |
54 IterationStatement* AstNode::AsIterationStatement() { | |
55 switch (node_type()) { | |
56 ITERATION_NODE_LIST(RETURN_NODE); | |
57 default: | |
58 return nullptr; | |
59 } | |
60 } | |
61 | |
62 BreakableStatement* AstNode::AsBreakableStatement() { | |
63 switch (node_type()) { | |
64 BREAKABLE_NODE_LIST(RETURN_NODE); | |
65 ITERATION_NODE_LIST(RETURN_NODE); | |
66 default: | |
67 return nullptr; | |
68 } | |
69 } | |
70 | |
71 MaterializedLiteral* AstNode::AsMaterializedLiteral() { | |
72 switch (node_type()) { | |
73 LITERAL_NODE_LIST(RETURN_NODE); | |
74 default: | |
75 return nullptr; | |
76 } | |
77 } | |
78 | |
79 #undef RETURN_NODE | |
80 | |
81 InitializationFlag Declaration::initialization() const { | |
82 switch (node_type()) { | |
83 #define GENERATE_CASE(Node) \ | |
84 case k##Node: \ | |
Igor Sheludko
2016/07/14 14:02:33
How about adding something like
STATIC_ASSERT(&
Toon Verwaest
2016/07/14 14:19:39
I'd add STATIC_ASSERT(k##Node != kExpression), how
Igor Sheludko
2016/07/14 14:49:30
No, the idea is to ensure that when you call a foo
| |
85 return static_cast<const Node*>(this)->initialization(); | |
86 DECLARATION_NODE_LIST(GENERATE_CASE); | |
87 #undef GENERATE_CASE | |
88 default: | |
89 UNREACHABLE(); | |
90 return kNeedsInitialization; | |
91 } | |
92 } | |
50 | 93 |
51 bool Expression::IsSmiLiteral() const { | 94 bool Expression::IsSmiLiteral() const { |
52 return IsLiteral() && AsLiteral()->value()->IsSmi(); | 95 return IsLiteral() && AsLiteral()->value()->IsSmi(); |
53 } | 96 } |
54 | 97 |
55 | 98 |
56 bool Expression::IsStringLiteral() const { | 99 bool Expression::IsStringLiteral() const { |
57 return IsLiteral() && AsLiteral()->value()->IsString(); | 100 return IsLiteral() && AsLiteral()->value()->IsString(); |
58 } | 101 } |
59 | 102 |
103 bool Expression::IsPropertyName() const { | |
104 return IsLiteral() && AsLiteral()->IsPropertyName(); | |
105 } | |
60 | 106 |
61 bool Expression::IsNullLiteral() const { | 107 bool Expression::IsNullLiteral() const { |
62 if (!IsLiteral()) return false; | 108 if (!IsLiteral()) return false; |
63 Handle<Object> value = AsLiteral()->value(); | 109 Handle<Object> value = AsLiteral()->value(); |
64 return !value->IsSmi() && | 110 return !value->IsSmi() && |
65 value->IsNull(HeapObject::cast(*value)->GetIsolate()); | 111 value->IsNull(HeapObject::cast(*value)->GetIsolate()); |
66 } | 112 } |
67 | 113 |
68 bool Expression::IsUndefinedLiteral() const { | 114 bool Expression::IsUndefinedLiteral() const { |
69 if (IsLiteral()) { | 115 if (IsLiteral()) { |
70 Handle<Object> value = AsLiteral()->value(); | 116 Handle<Object> value = AsLiteral()->value(); |
71 if (!value->IsSmi() && | 117 if (!value->IsSmi() && |
72 value->IsUndefined(HeapObject::cast(*value)->GetIsolate())) { | 118 value->IsUndefined(HeapObject::cast(*value)->GetIsolate())) { |
73 return true; | 119 return true; |
74 } | 120 } |
75 } | 121 } |
76 | 122 |
77 const VariableProxy* var_proxy = AsVariableProxy(); | 123 const VariableProxy* var_proxy = AsVariableProxy(); |
78 if (var_proxy == NULL) return false; | 124 if (var_proxy == NULL) return false; |
79 Variable* var = var_proxy->var(); | 125 Variable* var = var_proxy->var(); |
80 // The global identifier "undefined" is immutable. Everything | 126 // The global identifier "undefined" is immutable. Everything |
81 // else could be reassigned. | 127 // else could be reassigned. |
82 return var != NULL && var->IsUnallocatedOrGlobalSlot() && | 128 return var != NULL && var->IsUnallocatedOrGlobalSlot() && |
83 var_proxy->raw_name()->IsOneByteEqualTo("undefined"); | 129 var_proxy->raw_name()->IsOneByteEqualTo("undefined"); |
84 } | 130 } |
85 | 131 |
132 bool Expression::ToBooleanIsTrue() const { | |
133 return IsLiteral() && AsLiteral()->ToBooleanIsTrue(); | |
134 } | |
135 | |
136 bool Expression::ToBooleanIsFalse() const { | |
137 return IsLiteral() && AsLiteral()->ToBooleanIsFalse(); | |
138 } | |
139 | |
140 bool Expression::IsValidReferenceExpression() const { | |
141 return IsProperty() || | |
142 (IsVariableProxy() && AsVariableProxy()->IsValidReferenceExpression()); | |
143 } | |
86 | 144 |
87 bool Expression::IsValidReferenceExpressionOrThis() const { | 145 bool Expression::IsValidReferenceExpressionOrThis() const { |
88 return IsValidReferenceExpression() || | 146 return IsValidReferenceExpression() || |
89 (IsVariableProxy() && AsVariableProxy()->is_this()); | 147 (IsVariableProxy() && AsVariableProxy()->is_this()); |
90 } | 148 } |
91 | 149 |
150 bool Expression::IsAnonymousFunctionDefinition() const { | |
151 return (IsFunctionLiteral() && | |
152 AsFunctionLiteral()->IsAnonymousFunctionDefinition()) || | |
153 (IsClassLiteral() && | |
154 AsClassLiteral()->IsAnonymousFunctionDefinition()); | |
155 } | |
156 | |
157 void Expression::MarkTail() { | |
158 if (IsConditional()) { | |
159 AsConditional()->MarkTail(); | |
160 } else if (IsCall()) { | |
161 AsCall()->MarkTail(); | |
162 } else if (IsBinaryOperation()) { | |
163 AsBinaryOperation()->MarkTail(); | |
164 } | |
165 } | |
166 | |
167 bool Statement::IsJump() const { | |
168 return (IsBlock() && AsBlock()->IsJump()) || | |
169 (IsExpressionStatement() && AsExpressionStatement()->IsJump()) || | |
170 IsContinueStatement() || IsBreakStatement() || IsReturnStatement() || | |
Igor Sheludko
2016/07/14 14:02:33
How about following same pattern for all JumpState
Toon Verwaest
2016/07/14 14:19:39
Done.
| |
171 (IsIfStatement() && AsIfStatement()->IsJump()); | |
172 } | |
92 | 173 |
93 VariableProxy::VariableProxy(Zone* zone, Variable* var, int start_position, | 174 VariableProxy::VariableProxy(Zone* zone, Variable* var, int start_position, |
94 int end_position) | 175 int end_position) |
95 : Expression(zone, start_position), | 176 : Expression(zone, start_position), |
96 bit_field_(IsThisField::encode(var->is_this()) | | 177 bit_field_(IsThisField::encode(var->is_this()) | |
97 IsAssignedField::encode(false) | | 178 IsAssignedField::encode(false) | |
98 IsResolvedField::encode(false)), | 179 IsResolvedField::encode(false)), |
99 raw_name_(var->raw_name()), | 180 raw_name_(var->raw_name()), |
100 end_position_(end_position) { | 181 end_position_(end_position) { |
101 BindTo(var); | 182 BindTo(var); |
(...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
712 } | 793 } |
713 | 794 |
714 | 795 |
715 // ---------------------------------------------------------------------------- | 796 // ---------------------------------------------------------------------------- |
716 // Recording of type feedback | 797 // Recording of type feedback |
717 | 798 |
718 // TODO(rossberg): all RecordTypeFeedback functions should disappear | 799 // TODO(rossberg): all RecordTypeFeedback functions should disappear |
719 // once we use the common type field in the AST consistently. | 800 // once we use the common type field in the AST consistently. |
720 | 801 |
721 void Expression::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) { | 802 void Expression::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) { |
722 set_to_boolean_types(oracle->ToBooleanTypes(test_id())); | 803 if (IsUnaryOperation()) { |
804 AsUnaryOperation()->RecordToBooleanTypeFeedback(oracle); | |
805 } else if (IsBinaryOperation()) { | |
806 AsBinaryOperation()->RecordToBooleanTypeFeedback(oracle); | |
807 } else { | |
808 set_to_boolean_types(oracle->ToBooleanTypes(test_id())); | |
809 } | |
723 } | 810 } |
724 | 811 |
812 SmallMapList* Expression::GetReceiverTypes() { | |
813 switch (node_type()) { | |
814 #define NODE_LIST(V) \ | |
815 PROPERTY_NODE_LIST(V) \ | |
816 V(Call) | |
817 #define GENERATE_CASE(Node) \ | |
818 case k##Node: \ | |
819 return static_cast<Node*>(this)->GetReceiverTypes(); | |
820 NODE_LIST(GENERATE_CASE) | |
821 #undef NODE_LIST | |
822 #undef GENERATE_CASE | |
823 default: | |
824 UNREACHABLE(); | |
825 return nullptr; | |
826 } | |
827 } | |
828 | |
829 KeyedAccessStoreMode Expression::GetStoreMode() const { | |
830 switch (node_type()) { | |
831 #define GENERATE_CASE(Node) \ | |
832 case k##Node: \ | |
833 return static_cast<const Node*>(this)->GetStoreMode(); | |
834 PROPERTY_NODE_LIST(GENERATE_CASE) | |
835 #undef GENERATE_CASE | |
836 default: | |
837 UNREACHABLE(); | |
838 return STANDARD_STORE; | |
839 } | |
840 } | |
841 | |
842 IcCheckType Expression::GetKeyType() const { | |
843 switch (node_type()) { | |
844 #define GENERATE_CASE(Node) \ | |
845 case k##Node: \ | |
846 return static_cast<const Node*>(this)->GetKeyType(); | |
847 PROPERTY_NODE_LIST(GENERATE_CASE) | |
848 #undef GENERATE_CASE | |
849 default: | |
850 UNREACHABLE(); | |
851 return PROPERTY; | |
852 } | |
853 } | |
854 | |
855 bool Expression::IsMonomorphic() const { | |
856 switch (node_type()) { | |
857 #define GENERATE_CASE(Node) \ | |
858 case k##Node: \ | |
859 return static_cast<const Node*>(this)->IsMonomorphic(); | |
860 PROPERTY_NODE_LIST(GENERATE_CASE) | |
861 CALL_NODE_LIST(GENERATE_CASE) | |
Igor Sheludko
2016/07/14 14:02:33
GENERATE_CASE(ObjectLiteralProperty) ?
Toon Verwaest
2016/07/14 14:19:39
ObjectLiteralProperty is not an AstNode. It derive
Igor Sheludko
2016/07/14 14:49:30
Ah, indeed.
| |
862 #undef GENERATE_CASE | |
863 default: | |
864 UNREACHABLE(); | |
865 return false; | |
866 } | |
867 } | |
725 | 868 |
726 bool Call::IsUsingCallFeedbackICSlot(Isolate* isolate) const { | 869 bool Call::IsUsingCallFeedbackICSlot(Isolate* isolate) const { |
727 CallType call_type = GetCallType(isolate); | 870 CallType call_type = GetCallType(isolate); |
728 if (call_type == POSSIBLY_EVAL_CALL) { | 871 if (call_type == POSSIBLY_EVAL_CALL) { |
729 return false; | 872 return false; |
730 } | 873 } |
731 return true; | 874 return true; |
732 } | 875 } |
733 | 876 |
734 | 877 |
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1127 bool Literal::Match(void* literal1, void* literal2) { | 1270 bool Literal::Match(void* literal1, void* literal2) { |
1128 const AstValue* x = static_cast<Literal*>(literal1)->raw_value(); | 1271 const AstValue* x = static_cast<Literal*>(literal1)->raw_value(); |
1129 const AstValue* y = static_cast<Literal*>(literal2)->raw_value(); | 1272 const AstValue* y = static_cast<Literal*>(literal2)->raw_value(); |
1130 return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) || | 1273 return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) || |
1131 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber()); | 1274 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber()); |
1132 } | 1275 } |
1133 | 1276 |
1134 | 1277 |
1135 } // namespace internal | 1278 } // namespace internal |
1136 } // namespace v8 | 1279 } // namespace v8 |
OLD | NEW |