| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "vm/ast_printer.h" | 8 #include "vm/ast_printer.h" |
| 9 #include "vm/code_descriptors.h" | 9 #include "vm/code_descriptors.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 993 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1004 | 1004 |
| 1005 | 1005 |
| 1006 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) { | 1006 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) { |
| 1007 ASSERT(Token::IsTypeTestOperator(node->kind())); | 1007 ASSERT(Token::IsTypeTestOperator(node->kind())); |
| 1008 EffectGraphVisitor for_left_value(owner(), temp_index()); | 1008 EffectGraphVisitor for_left_value(owner(), temp_index()); |
| 1009 node->left()->Visit(&for_left_value); | 1009 node->left()->Visit(&for_left_value); |
| 1010 Append(for_left_value); | 1010 Append(for_left_value); |
| 1011 } | 1011 } |
| 1012 | 1012 |
| 1013 | 1013 |
| 1014 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { | |
| 1015 ASSERT(Token::IsTypeCastOperator(node->kind())); | |
| 1016 const AbstractType& type = node->right()->AsTypeNode()->type(); | |
| 1017 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. | |
| 1018 ValueGraphVisitor for_value(owner(), temp_index()); | |
| 1019 node->left()->Visit(&for_value); | |
| 1020 const String& dst_name = String::ZoneHandle( | |
| 1021 Symbols::New(Exceptions::kCastErrorDstName)); | |
| 1022 if (!CanSkipTypeCheck(node->token_pos(), for_value.value(), type, dst_name)) { | |
| 1023 Append(for_value); | |
| 1024 Do(BuildAssertAssignable( | |
| 1025 node->token_pos(), for_value.value(), type, dst_name)); | |
| 1026 } | |
| 1027 } | |
| 1028 | |
| 1029 | |
| 1030 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) { | 1014 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) { |
| 1031 ASSERT(Token::IsTypeTestOperator(node->kind())); | 1015 ASSERT(Token::IsTypeTestOperator(node->kind())); |
| 1032 const AbstractType& type = node->right()->AsTypeNode()->type(); | 1016 const AbstractType& type = node->right()->AsTypeNode()->type(); |
| 1033 ASSERT(type.IsFinalized() && !type.IsMalformed()); | 1017 ASSERT(type.IsFinalized() && !type.IsMalformed()); |
| 1034 const bool negate_result = (node->kind() == Token::kISNOT); | 1018 const bool negate_result = (node->kind() == Token::kISNOT); |
| 1035 // All objects are instances of type T if Object type is a subtype of type T. | 1019 // All objects are instances of type T if Object type is a subtype of type T. |
| 1036 const Type& object_type = Type::Handle(Type::ObjectType()); | 1020 const Type& object_type = Type::Handle(Type::ObjectType()); |
| 1037 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) { | 1021 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) { |
| 1038 // Must evaluate left side. | 1022 // Must evaluate left side. |
| 1039 EffectGraphVisitor for_left_value(owner(), temp_index()); | 1023 EffectGraphVisitor for_left_value(owner(), temp_index()); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1100 const Bool& negate = (node->kind() == Token::kISNOT) ? Bool::True() : | 1084 const Bool& negate = (node->kind() == Token::kISNOT) ? Bool::True() : |
| 1101 Bool::False(); | 1085 Bool::False(); |
| 1102 Value* negate_arg = Bind(new ConstantInstr(negate)); | 1086 Value* negate_arg = Bind(new ConstantInstr(negate)); |
| 1103 arguments->Add(PushArgument(negate_arg)); | 1087 arguments->Add(PushArgument(negate_arg)); |
| 1104 const intptr_t kNumArgsChecked = 1; | 1088 const intptr_t kNumArgsChecked = 1; |
| 1105 InstanceCallInstr* call = new InstanceCallInstr( | 1089 InstanceCallInstr* call = new InstanceCallInstr( |
| 1106 node->token_pos(), | 1090 node->token_pos(), |
| 1107 PrivateCoreLibName(Symbols::_instanceOf()), | 1091 PrivateCoreLibName(Symbols::_instanceOf()), |
| 1108 node->kind(), | 1092 node->kind(), |
| 1109 arguments, | 1093 arguments, |
| 1110 Array::ZoneHandle(), | 1094 Array::ZoneHandle(), // No argument names. |
| 1111 kNumArgsChecked); | 1095 kNumArgsChecked); |
| 1112 ReturnDefinition(call); | 1096 ReturnDefinition(call); |
| 1113 } | 1097 } |
| 1114 | 1098 |
| 1115 | 1099 |
| 1116 void ValueGraphVisitor::BuildTypeCast(ComparisonNode* node) { | 1100 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { |
| 1117 ASSERT(Token::IsTypeCastOperator(node->kind())); | 1101 ASSERT(Token::IsTypeCastOperator(node->kind())); |
| 1118 const AbstractType& type = node->right()->AsTypeNode()->type(); | 1102 const AbstractType& type = node->right()->AsTypeNode()->type(); |
| 1119 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. | 1103 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. |
| 1120 ValueGraphVisitor for_value(owner(), temp_index()); | 1104 ValueGraphVisitor for_value(owner(), temp_index()); |
| 1105 node->left()->Visit(&for_value); |
| 1106 const String& dst_name = String::ZoneHandle( |
| 1107 Symbols::New(Exceptions::kCastErrorDstName)); |
| 1108 if (!CanSkipTypeCheck(node->token_pos(), for_value.value(), type, dst_name)) { |
| 1109 Append(for_value); |
| 1110 Do(BuildAssertAssignable( |
| 1111 node->token_pos(), for_value.value(), type, dst_name)); |
| 1112 } |
| 1113 } |
| 1114 |
| 1115 |
| 1116 void ValueGraphVisitor::BuildTypeCast(ComparisonNode* node) { |
| 1117 ASSERT(Token::IsTypeCastOperator(node->kind())); |
| 1118 ASSERT(!node->right()->AsTypeNode()->type().IsNull()); |
| 1119 const AbstractType& type = node->right()->AsTypeNode()->type(); |
| 1120 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. |
| 1121 ValueGraphVisitor for_value(owner(), temp_index()); |
| 1121 node->left()->Visit(&for_value); | 1122 node->left()->Visit(&for_value); |
| 1122 Append(for_value); | 1123 Append(for_value); |
| 1123 const String& dst_name = String::ZoneHandle( | 1124 const String& dst_name = String::ZoneHandle( |
| 1124 Symbols::New(Exceptions::kCastErrorDstName)); | 1125 Symbols::New(Exceptions::kCastErrorDstName)); |
| 1125 ReturnValue(BuildAssignableValue(node->token_pos(), | 1126 if (type.IsMalformed()) { |
| 1126 for_value.value(), | 1127 ReturnValue(BuildAssignableValue(node->token_pos(), |
| 1127 type, | 1128 for_value.value(), |
| 1128 dst_name)); | 1129 type, |
| 1130 dst_name)); |
| 1131 } else { |
| 1132 if (CanSkipTypeCheck(node->token_pos(), |
| 1133 for_value.value(), |
| 1134 type, |
| 1135 dst_name)) { |
| 1136 ReturnValue(for_value.value()); |
| 1137 return; |
| 1138 } |
| 1139 PushArgumentInstr* push_left = PushArgument(for_value.value()); |
| 1140 PushArgumentInstr* push_instantiator = NULL; |
| 1141 PushArgumentInstr* push_type_args = NULL; |
| 1142 if (type.IsInstantiated()) { |
| 1143 push_instantiator = PushArgument(BuildNullValue()); |
| 1144 push_type_args = PushArgument(BuildNullValue()); |
| 1145 } else { |
| 1146 BuildTypecheckPushArguments(node->token_pos(), |
| 1147 &push_instantiator, |
| 1148 &push_type_args); |
| 1149 } |
| 1150 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1151 new ZoneGrowableArray<PushArgumentInstr*>(4); |
| 1152 arguments->Add(push_left); |
| 1153 arguments->Add(push_instantiator); |
| 1154 arguments->Add(push_type_args); |
| 1155 Value* type_arg = Bind(new ConstantInstr(type)); |
| 1156 arguments->Add(PushArgument(type_arg)); |
| 1157 const intptr_t kNumArgsChecked = 1; |
| 1158 InstanceCallInstr* call = new InstanceCallInstr( |
| 1159 node->token_pos(), |
| 1160 PrivateCoreLibName(Symbols::_as()), |
| 1161 node->kind(), |
| 1162 arguments, |
| 1163 Array::ZoneHandle(), // No argument names. |
| 1164 kNumArgsChecked); |
| 1165 ReturnDefinition(call); |
| 1166 } |
| 1129 } | 1167 } |
| 1130 | 1168 |
| 1131 | 1169 |
| 1132 // <Expression> :: Comparison { kind: Token::Kind | 1170 // <Expression> :: Comparison { kind: Token::Kind |
| 1133 // left: <Expression> | 1171 // left: <Expression> |
| 1134 // right: <Expression> } | 1172 // right: <Expression> } |
| 1135 // TODO(srdjan): Implement new equality. | 1173 // TODO(srdjan): Implement new equality. |
| 1136 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { | 1174 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { |
| 1137 if (Token::IsTypeTestOperator(node->kind())) { | 1175 if (Token::IsTypeTestOperator(node->kind())) { |
| 1138 BuildTypeTest(node); | 1176 BuildTypeTest(node); |
| (...skipping 2167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3306 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 3344 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 3307 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 3345 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 3308 OS::SNPrint(chars, len, kFormat, function_name, reason); | 3346 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 3309 const Error& error = Error::Handle( | 3347 const Error& error = Error::Handle( |
| 3310 LanguageError::New(String::Handle(String::New(chars)))); | 3348 LanguageError::New(String::Handle(String::New(chars)))); |
| 3311 Isolate::Current()->long_jump_base()->Jump(1, error); | 3349 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 3312 } | 3350 } |
| 3313 | 3351 |
| 3314 | 3352 |
| 3315 } // namespace dart | 3353 } // namespace dart |
| OLD | NEW |