| 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 |