Chromium Code Reviews| 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 |