Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(580)

Side by Side Diff: runtime/vm/flow_graph_builder.cc

Issue 23190035: Distinguish between malformed and malbounded types (fix issues 12552 and 12554). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/code_generator.cc ('k') | runtime/vm/flow_graph_compiler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/bit_vector.h" 9 #include "vm/bit_vector.h"
10 #include "vm/code_descriptors.h" 10 #include "vm/code_descriptors.h"
(...skipping 835 matching lines...) Expand 10 before | Expand all | Expand 10 after
846 // Type nodes are used when a type is referenced as a literal. Type nodes 846 // Type nodes are used when a type is referenced as a literal. Type nodes
847 // can also be used for the right-hand side of instanceof comparisons, 847 // can also be used for the right-hand side of instanceof comparisons,
848 // but they are handled specially in that context, not here. 848 // but they are handled specially in that context, not here.
849 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) { 849 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) {
850 return; 850 return;
851 } 851 }
852 852
853 853
854 void ValueGraphVisitor::VisitTypeNode(TypeNode* node) { 854 void ValueGraphVisitor::VisitTypeNode(TypeNode* node) {
855 const AbstractType& type = node->type(); 855 const AbstractType& type = node->type();
856 ASSERT(type.IsFinalized() && !type.IsMalformed()); 856 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded());
857 if (type.IsInstantiated()) { 857 if (type.IsInstantiated()) {
858 ReturnDefinition(new ConstantInstr(type)); 858 ReturnDefinition(new ConstantInstr(type));
859 } else { 859 } else {
860 const Class& instantiator_class = Class::ZoneHandle( 860 const Class& instantiator_class = Class::ZoneHandle(
861 owner()->parsed_function()->function().Owner()); 861 owner()->parsed_function()->function().Owner());
862 Value* instantiator_value = BuildInstantiatorTypeArguments( 862 Value* instantiator_value = BuildInstantiatorTypeArguments(
863 node->token_pos(), instantiator_class, NULL); 863 node->token_pos(), instantiator_class, NULL);
864 ReturnDefinition(new InstantiateTypeInstr( 864 ReturnDefinition(new InstantiateTypeInstr(
865 node->token_pos(), type, instantiator_class, instantiator_value)); 865 node->token_pos(), type, instantiator_class, instantiator_value));
866 } 866 }
867 } 867 }
868 868
869 869
870 // Returns true if the type check can be skipped, for example, if the 870 // Returns true if the type check can be skipped, for example, if the
871 // destination type is dynamic or if the compile type of the value is a subtype 871 // destination type is dynamic or if the compile type of the value is a subtype
872 // of the destination type. 872 // of the destination type.
873 bool EffectGraphVisitor::CanSkipTypeCheck(intptr_t token_pos, 873 bool EffectGraphVisitor::CanSkipTypeCheck(intptr_t token_pos,
874 Value* value, 874 Value* value,
875 const AbstractType& dst_type, 875 const AbstractType& dst_type,
876 const String& dst_name) { 876 const String& dst_name) {
877 ASSERT(!dst_type.IsNull()); 877 ASSERT(!dst_type.IsNull());
878 ASSERT(dst_type.IsFinalized()); 878 ASSERT(dst_type.IsFinalized());
879 879
880 // If the destination type is malformed, a dynamic type error must be thrown 880 // If the destination type is malformed or malbounded, a dynamic type error
881 // at run time. 881 // must be thrown at run time.
882 if (dst_type.IsMalformed()) { 882 if (dst_type.IsMalformed() || dst_type.IsMalbounded()) {
883 return false; 883 return false;
884 } 884 }
885 885
886 // Any type is more specific than the dynamic type and than the Object type. 886 // Any type is more specific than the dynamic type and than the Object type.
887 if (dst_type.IsDynamicType() || dst_type.IsObjectType()) { 887 if (dst_type.IsDynamicType() || dst_type.IsObjectType()) {
888 return true; 888 return true;
889 } 889 }
890 890
891 // Do not perform type check elimination if this optimization is turned off. 891 // Do not perform type check elimination if this optimization is turned off.
892 if (!FLAG_eliminate_type_checks) { 892 if (!FLAG_eliminate_type_checks) {
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
1197 ASSERT(Token::IsTypeTestOperator(node->kind())); 1197 ASSERT(Token::IsTypeTestOperator(node->kind()));
1198 EffectGraphVisitor for_left_value(owner(), temp_index()); 1198 EffectGraphVisitor for_left_value(owner(), temp_index());
1199 node->left()->Visit(&for_left_value); 1199 node->left()->Visit(&for_left_value);
1200 Append(for_left_value); 1200 Append(for_left_value);
1201 } 1201 }
1202 1202
1203 1203
1204 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) { 1204 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) {
1205 ASSERT(Token::IsTypeTestOperator(node->kind())); 1205 ASSERT(Token::IsTypeTestOperator(node->kind()));
1206 const AbstractType& type = node->right()->AsTypeNode()->type(); 1206 const AbstractType& type = node->right()->AsTypeNode()->type();
1207 ASSERT(type.IsFinalized() && !type.IsMalformed()); 1207 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded());
1208 const bool negate_result = (node->kind() == Token::kISNOT); 1208 const bool negate_result = (node->kind() == Token::kISNOT);
1209 // All objects are instances of type T if Object type is a subtype of type T. 1209 // All objects are instances of type T if Object type is a subtype of type T.
1210 const Type& object_type = Type::Handle(Type::ObjectType()); 1210 const Type& object_type = Type::Handle(Type::ObjectType());
1211 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) { 1211 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) {
1212 // Must evaluate left side. 1212 // Must evaluate left side.
1213 EffectGraphVisitor for_left_value(owner(), temp_index()); 1213 EffectGraphVisitor for_left_value(owner(), temp_index());
1214 node->left()->Visit(&for_left_value); 1214 node->left()->Visit(&for_left_value);
1215 Append(for_left_value); 1215 Append(for_left_value);
1216 ReturnDefinition(new ConstantInstr(negate_result ? 1216 ReturnDefinition(new ConstantInstr(negate_result ?
1217 Bool::False() : Bool::True())); 1217 Bool::False() : Bool::True()));
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1300 void ValueGraphVisitor::BuildTypeCast(ComparisonNode* node) { 1300 void ValueGraphVisitor::BuildTypeCast(ComparisonNode* node) {
1301 ASSERT(Token::IsTypeCastOperator(node->kind())); 1301 ASSERT(Token::IsTypeCastOperator(node->kind()));
1302 ASSERT(!node->right()->AsTypeNode()->type().IsNull()); 1302 ASSERT(!node->right()->AsTypeNode()->type().IsNull());
1303 const AbstractType& type = node->right()->AsTypeNode()->type(); 1303 const AbstractType& type = node->right()->AsTypeNode()->type();
1304 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. 1304 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed.
1305 ValueGraphVisitor for_value(owner(), temp_index()); 1305 ValueGraphVisitor for_value(owner(), temp_index());
1306 node->left()->Visit(&for_value); 1306 node->left()->Visit(&for_value);
1307 Append(for_value); 1307 Append(for_value);
1308 const String& dst_name = String::ZoneHandle( 1308 const String& dst_name = String::ZoneHandle(
1309 Symbols::New(Exceptions::kCastErrorDstName)); 1309 Symbols::New(Exceptions::kCastErrorDstName));
1310 if (type.IsMalformed()) { 1310 if (type.IsMalformed() || type.IsMalbounded()) {
1311 ReturnValue(BuildAssignableValue(node->token_pos(), 1311 ReturnValue(BuildAssignableValue(node->token_pos(),
1312 for_value.value(), 1312 for_value.value(),
1313 type, 1313 type,
1314 dst_name)); 1314 dst_name));
1315 } else { 1315 } else {
1316 if (CanSkipTypeCheck(node->token_pos(), 1316 if (CanSkipTypeCheck(node->token_pos(),
1317 for_value.value(), 1317 for_value.value(),
1318 type, 1318 type,
1319 dst_name)) { 1319 dst_name)) {
1320 ReturnValue(for_value.value()); 1320 ReturnValue(for_value.value());
(...skipping 1140 matching lines...) Expand 10 before | Expand all | Expand 10 after
2461 const Class& instantiator_class, 2461 const Class& instantiator_class,
2462 Value* instantiator) { 2462 Value* instantiator) {
2463 if (instantiator_class.NumTypeParameters() == 0) { 2463 if (instantiator_class.NumTypeParameters() == 0) {
2464 // The type arguments are compile time constants. 2464 // The type arguments are compile time constants.
2465 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); 2465 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle();
2466 // Type is temporary. Only its type arguments are preserved. 2466 // Type is temporary. Only its type arguments are preserved.
2467 Type& type = Type::Handle( 2467 Type& type = Type::Handle(
2468 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); 2468 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew));
2469 type ^= ClassFinalizer::FinalizeType( 2469 type ^= ClassFinalizer::FinalizeType(
2470 instantiator_class, type, ClassFinalizer::kFinalize); 2470 instantiator_class, type, ClassFinalizer::kFinalize);
2471 ASSERT(!type.IsMalformed()); 2471 ASSERT(!type.IsMalformed() && !type.IsMalbounded());
2472 type_arguments = type.arguments(); 2472 type_arguments = type.arguments();
2473 type_arguments = type_arguments.Canonicalize(); 2473 type_arguments = type_arguments.Canonicalize();
2474 return Bind(new ConstantInstr(type_arguments)); 2474 return Bind(new ConstantInstr(type_arguments));
2475 } 2475 }
2476 Function& outer_function = 2476 Function& outer_function =
2477 Function::Handle(owner()->parsed_function()->function().raw()); 2477 Function::Handle(owner()->parsed_function()->function().raw());
2478 while (outer_function.IsLocalFunction()) { 2478 while (outer_function.IsLocalFunction()) {
2479 outer_function = outer_function.parent_function(); 2479 outer_function = outer_function.parent_function();
2480 } 2480 }
2481 if (outer_function.IsFactory()) { 2481 if (outer_function.IsFactory()) {
(...skipping 1262 matching lines...) Expand 10 before | Expand all | Expand 10 after
3744 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; 3744 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
3745 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 3745 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
3746 OS::SNPrint(chars, len, kFormat, function_name, reason); 3746 OS::SNPrint(chars, len, kFormat, function_name, reason);
3747 const Error& error = Error::Handle( 3747 const Error& error = Error::Handle(
3748 LanguageError::New(String::Handle(String::New(chars)))); 3748 LanguageError::New(String::Handle(String::New(chars))));
3749 Isolate::Current()->long_jump_base()->Jump(1, error); 3749 Isolate::Current()->long_jump_base()->Jump(1, error);
3750 } 3750 }
3751 3751
3752 3752
3753 } // namespace dart 3753 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/code_generator.cc ('k') | runtime/vm/flow_graph_compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698