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

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

Issue 12183014: Resubmit reverted r17962, but, for now, only report error about unfinalized (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 10 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/lib/growable_array.dart ('k') | runtime/vm/object.h » ('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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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/class_finalizer.h" 5 #include "vm/class_finalizer.h"
6 6
7 #include "vm/flags.h" 7 #include "vm/flags.h"
8 #include "vm/heap.h" 8 #include "vm/heap.h"
9 #include "vm/isolate.h" 9 #include "vm/isolate.h"
10 #include "vm/longjump.h" 10 #include "vm/longjump.h"
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 static void CollectFinalizedSuperClasses( 91 static void CollectFinalizedSuperClasses(
92 const GrowableObjectArray& pending_classes, 92 const GrowableObjectArray& pending_classes,
93 GrowableArray<intptr_t>* finalized_super_classes) { 93 GrowableArray<intptr_t>* finalized_super_classes) {
94 Class& cls = Class::Handle(); 94 Class& cls = Class::Handle();
95 Type& super_type = Type::Handle(); 95 Type& super_type = Type::Handle();
96 for (intptr_t i = 0; i < pending_classes.Length(); i++) { 96 for (intptr_t i = 0; i < pending_classes.Length(); i++) {
97 cls ^= pending_classes.At(i); 97 cls ^= pending_classes.At(i);
98 ASSERT(!cls.is_finalized()); 98 ASSERT(!cls.is_finalized());
99 super_type ^= cls.super_type(); 99 super_type ^= cls.super_type();
100 if (!super_type.IsNull()) { 100 if (!super_type.IsNull()) {
101 if (super_type.HasResolvedTypeClass() && 101 if (!super_type.IsMalformed() &&
102 super_type.HasResolvedTypeClass() &&
102 Class::Handle(super_type.type_class()).is_finalized()) { 103 Class::Handle(super_type.type_class()).is_finalized()) {
103 AddSuperType(super_type, finalized_super_classes); 104 AddSuperType(super_type, finalized_super_classes);
104 } 105 }
105 } 106 }
106 } 107 }
107 } 108 }
108 109
109 110
110 // Class finalization occurs: 111 // Class finalization occurs:
111 // a) when bootstrap process completes (VerifyBootstrapClasses). 112 // a) when bootstrap process completes (VerifyBootstrapClasses).
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 470
470 // Lookup the type class. 471 // Lookup the type class.
471 const UnresolvedClass& unresolved_class = 472 const UnresolvedClass& unresolved_class =
472 UnresolvedClass::Handle(type.unresolved_class()); 473 UnresolvedClass::Handle(type.unresolved_class());
473 const Class& type_class = 474 const Class& type_class =
474 Class::Handle(ResolveClass(cls, unresolved_class)); 475 Class::Handle(ResolveClass(cls, unresolved_class));
475 476
476 // Replace unresolved class with resolved type class. 477 // Replace unresolved class with resolved type class.
477 const Type& parameterized_type = Type::Cast(type); 478 const Type& parameterized_type = Type::Cast(type);
478 if (!type_class.IsNull()) { 479 if (!type_class.IsNull()) {
479 parameterized_type.set_type_class(Object::Handle(type_class.raw())); 480 parameterized_type.set_type_class(type_class);
480 } else { 481 } else {
481 // The type class could not be resolved. The type is malformed. 482 // The type class could not be resolved. The type is malformed.
482 FinalizeMalformedType(Error::Handle(), // No previous error. 483 FinalizeMalformedType(Error::Handle(), // No previous error.
483 cls, parameterized_type, finalization, 484 cls, parameterized_type, finalization,
484 "cannot resolve class name '%s' from '%s'", 485 "cannot resolve class name '%s' from '%s'",
485 String::Handle(unresolved_class.Name()).ToCString(), 486 String::Handle(unresolved_class.Name()).ToCString(),
486 String::Handle(cls.Name()).ToCString()); 487 String::Handle(cls.Name()).ToCString());
487 return; 488 return;
488 } 489 }
489 } 490 }
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
728 AbstractType& type_arg = AbstractType::Handle(Type::DynamicType()); 729 AbstractType& type_arg = AbstractType::Handle(Type::DynamicType());
729 for (intptr_t i = 0; i < num_type_parameters; i++) { 730 for (intptr_t i = 0; i < num_type_parameters; i++) {
730 // If no type parameters were provided, a raw type is desired, so we 731 // If no type parameters were provided, a raw type is desired, so we
731 // create a vector of DynamicType. 732 // create a vector of DynamicType.
732 if (!arguments.IsNull()) { 733 if (!arguments.IsNull()) {
733 type_arg = arguments.TypeAt(i); 734 type_arg = arguments.TypeAt(i);
734 } 735 }
735 ASSERT(type_arg.IsFinalized()); // Index of type parameter is adjusted. 736 ASSERT(type_arg.IsFinalized()); // Index of type parameter is adjusted.
736 full_arguments.SetTypeAt(offset + i, type_arg); 737 full_arguments.SetTypeAt(offset + i, type_arg);
737 } 738 }
739 // If the type class is a signature class, the full argument vector
740 // must include the argument vector of the super type.
741 // If the signature class is a function type alias, it is also the owner
742 // of its signature function and no super type is involved.
743 // If the signature class is canonical (not an alias), the owner of its
744 // signature function may either be an alias or the enclosing class of a
745 // local function, in which case the super type of the enclosing class is
746 // also considered when filling up the argument vector.
738 if (type_class.IsSignatureClass()) { 747 if (type_class.IsSignatureClass()) {
739 const Function& signature_fun = 748 const Function& signature_fun =
740 Function::Handle(type_class.signature_function()); 749 Function::Handle(type_class.signature_function());
741 ASSERT(!signature_fun.is_static()); 750 ASSERT(!signature_fun.is_static());
742 const Class& sig_fun_owner = Class::Handle(signature_fun.Owner()); 751 const Class& sig_fun_owner = Class::Handle(signature_fun.Owner());
743 FinalizeTypeArguments(sig_fun_owner, full_arguments, finalization); 752 FinalizeTypeArguments(sig_fun_owner, full_arguments, finalization);
744 } else { 753 } else {
745 FinalizeTypeArguments(type_class, full_arguments, finalization); 754 FinalizeTypeArguments(type_class, full_arguments, finalization);
746 } 755 }
747 if (full_arguments.IsRaw(num_type_arguments)) { 756 if (full_arguments.IsRaw(num_type_arguments)) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 return parameterized_type.raw(); 804 return parameterized_type.raw();
796 } 805 }
797 } 806 }
798 807
799 // If the type class is a signature class, we are currently finalizing a 808 // If the type class is a signature class, we are currently finalizing a
800 // signature type, i.e. finalizing the result type and parameter types of the 809 // signature type, i.e. finalizing the result type and parameter types of the
801 // signature function of this signature type. 810 // signature function of this signature type.
802 // We do this after marking this type as finalized in order to allow a 811 // We do this after marking this type as finalized in order to allow a
803 // function type to refer to itself via its parameter types and result type. 812 // function type to refer to itself via its parameter types and result type.
804 if (type_class.IsSignatureClass()) { 813 if (type_class.IsSignatureClass()) {
805 // Signature classes are finalized upon creation, except function type 814 // The class may be created while parsing a function body, after all
806 // aliases. 815 // pending classes have already been finalized.
807 if (type_class.IsCanonicalSignatureClass()) { 816 FinalizeClass(type_class);
808 ASSERT(type_class.is_finalized());
809 // Resolve and finalize the result and parameter types of the signature
810 // function of this signature class.
811 ASSERT(type_class.SignatureType() == type.raw());
812 ResolveAndFinalizeSignature(
813 type_class, Function::Handle(type_class.signature_function()));
814 } else {
815 // This type is a function type alias. Its class may need to be finalized
816 // and checked for illegal self reference.
817 FinalizeClass(type_class);
818 // Finalizing the signature function here (as in the canonical case above)
819 // would not mark the canonical signature type as finalized.
820 const Type& signature_type = Type::Handle(type_class.SignatureType());
821 FinalizeType(cls, signature_type, finalization);
822 }
823 } 817 }
824 818
825 if (finalization >= kCanonicalize) { 819 if (finalization >= kCanonicalize) {
826 return parameterized_type.Canonicalize(); 820 return parameterized_type.Canonicalize();
827 } else { 821 } else {
828 return parameterized_type.raw(); 822 return parameterized_type.raw();
829 } 823 }
830 } 824 }
831 825
832 826
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
1008 } 1002 }
1009 } 1003 }
1010 // Collect interfaces, super interfaces, and super classes of this class. 1004 // Collect interfaces, super interfaces, and super classes of this class.
1011 const GrowableObjectArray& interfaces = 1005 const GrowableObjectArray& interfaces =
1012 GrowableObjectArray::Handle(GrowableObjectArray::New()); 1006 GrowableObjectArray::Handle(GrowableObjectArray::New());
1013 CollectInterfaces(cls, interfaces); 1007 CollectInterfaces(cls, interfaces);
1014 // Include superclasses in list of interfaces and super interfaces. 1008 // Include superclasses in list of interfaces and super interfaces.
1015 super_class = cls.SuperClass(); 1009 super_class = cls.SuperClass();
1016 while (!super_class.IsNull()) { 1010 while (!super_class.IsNull()) {
1017 interfaces.Add(super_class); 1011 interfaces.Add(super_class);
1012 CollectInterfaces(super_class, interfaces);
1018 super_class = super_class.SuperClass(); 1013 super_class = super_class.SuperClass();
1019 } 1014 }
1020 // Resolve function signatures and check for conflicts in super classes and 1015 // Resolve function signatures and check for conflicts in super classes and
1021 // interfaces. 1016 // interfaces.
1022 array = cls.functions(); 1017 array = cls.functions();
1023 Function& function = Function::Handle(); 1018 Function& function = Function::Handle();
1024 Function& overridden_function = Function::Handle(); 1019 Function& overridden_function = Function::Handle();
1025 intptr_t num_functions = array.Length(); 1020 intptr_t num_functions = array.Length();
1026 String& function_name = String::Handle(); 1021 String& function_name = String::Handle();
1027 for (intptr_t i = 0; i < num_functions; i++) { 1022 for (intptr_t i = 0; i < num_functions; i++) {
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1123 FinalizeClass(super_class); 1118 FinalizeClass(super_class);
1124 } 1119 }
1125 // Finalize type parameters before finalizing the super type. 1120 // Finalize type parameters before finalizing the super type.
1126 FinalizeTypeParameters(cls); 1121 FinalizeTypeParameters(cls);
1127 // Finalize super type. 1122 // Finalize super type.
1128 Type& super_type = Type::Handle(cls.super_type()); 1123 Type& super_type = Type::Handle(cls.super_type());
1129 if (!super_type.IsNull()) { 1124 if (!super_type.IsNull()) {
1130 super_type ^= FinalizeType(cls, super_type, kCanonicalizeWellFormed); 1125 super_type ^= FinalizeType(cls, super_type, kCanonicalizeWellFormed);
1131 cls.set_super_type(super_type); 1126 cls.set_super_type(super_type);
1132 } 1127 }
1133 // Signature classes are finalized upon creation, except function type
1134 // aliases.
1135 if (cls.IsSignatureClass()) { 1128 if (cls.IsSignatureClass()) {
1136 ASSERT(!cls.IsCanonicalSignatureClass());
1137 // Check for illegal self references. 1129 // Check for illegal self references.
1138 GrowableArray<intptr_t> visited_aliases; 1130 GrowableArray<intptr_t> visited_aliases;
1139 if (!IsAliasCycleFree(cls, &visited_aliases)) { 1131 if (!IsAliasCycleFree(cls, &visited_aliases)) {
1140 const String& name = String::Handle(cls.Name()); 1132 const String& name = String::Handle(cls.Name());
1141 const Script& script = Script::Handle(cls.script()); 1133 const Script& script = Script::Handle(cls.script());
1142 ReportError(script, cls.token_pos(), 1134 ReportError(script, cls.token_pos(),
1143 "typedef '%s' illegally refers to itself", 1135 "typedef '%s' illegally refers to itself",
1144 name.ToCString()); 1136 name.ToCString());
1145 } 1137 }
1146 cls.Finalize(); 1138 cls.Finalize();
1147 // Signature classes extend Object. No need to add this class to the direct 1139 // Signature classes extend Object. No need to add this class to the direct
1148 // subclasses of Object. 1140 // subclasses of Object.
1149 ASSERT(super_type.IsNull() || super_type.IsObjectType()); 1141 ASSERT(super_type.IsNull() || super_type.IsObjectType());
1142
1143 // Resolve and finalize the result and parameter types of the signature
1144 // function of this signature class.
1145 const Function& sig_function = Function::Handle(cls.signature_function());
1146 ResolveAndFinalizeSignature(cls, sig_function);
1147
1148 // Resolve and finalize the signature type of this signature class.
1149 const Type& sig_type = Type::Handle(cls.SignatureType());
1150 FinalizeType(cls, sig_type, kCanonicalizeWellFormed);
1150 return; 1151 return;
1151 } 1152 }
1152 // Finalize interface types (but not necessarily interface classes). 1153 // Finalize interface types (but not necessarily interface classes).
1153 Array& interface_types = Array::Handle(cls.interfaces()); 1154 Array& interface_types = Array::Handle(cls.interfaces());
1154 AbstractType& interface_type = AbstractType::Handle(); 1155 AbstractType& interface_type = AbstractType::Handle();
1155 for (intptr_t i = 0; i < interface_types.Length(); i++) { 1156 for (intptr_t i = 0; i < interface_types.Length(); i++) {
1156 interface_type ^= interface_types.At(i); 1157 interface_type ^= interface_types.At(i);
1157 interface_type = FinalizeType(cls, interface_type, kCanonicalizeWellFormed); 1158 interface_type = FinalizeType(cls, interface_type, kCanonicalizeWellFormed);
1158 interface_types.SetAt(i, interface_type); 1159 interface_types.SetAt(i, interface_type);
1159 } 1160 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1194 } 1195 }
1195 // No cycles. 1196 // No cycles.
1196 return true; 1197 return true;
1197 } 1198 }
1198 1199
1199 1200
1200 // Returns false if the function type alias illegally refers to itself. 1201 // Returns false if the function type alias illegally refers to itself.
1201 bool ClassFinalizer::IsAliasCycleFree(const Class& cls, 1202 bool ClassFinalizer::IsAliasCycleFree(const Class& cls,
1202 GrowableArray<intptr_t>* visited) { 1203 GrowableArray<intptr_t>* visited) {
1203 ASSERT(cls.IsSignatureClass()); 1204 ASSERT(cls.IsSignatureClass());
1204 ASSERT(!cls.IsCanonicalSignatureClass());
1205 ASSERT(!cls.is_finalized()); 1205 ASSERT(!cls.is_finalized());
1206 ASSERT(visited != NULL); 1206 ASSERT(visited != NULL);
1207 const intptr_t cls_index = cls.id(); 1207 const intptr_t cls_index = cls.id();
1208 for (int i = 0; i < visited->length(); i++) { 1208 for (int i = 0; i < visited->length(); i++) {
1209 if ((*visited)[i] == cls_index) { 1209 if ((*visited)[i] == cls_index) {
1210 // We have already visited alias 'cls'. We found a cycle. 1210 // We have already visited alias 'cls'. We found a cycle.
1211 return false; 1211 return false;
1212 } 1212 }
1213 } 1213 }
1214 1214
1215 // Visit the result type and parameter types of this signature type. 1215 // Visit the result type and parameter types of this signature type.
1216 visited->Add(cls.id()); 1216 visited->Add(cls.id());
1217 const Function& function = Function::Handle(cls.signature_function()); 1217 const Function& function = Function::Handle(cls.signature_function());
1218 // Check class of result type. 1218 // Check class of result type.
1219 AbstractType& type = AbstractType::Handle(function.result_type()); 1219 AbstractType& type = AbstractType::Handle(function.result_type());
1220 ResolveType(cls, type, kCanonicalize); 1220 ResolveType(cls, type, kCanonicalize);
1221 if (type.IsType() && !type.IsMalformed()) { 1221 if (type.IsType() && !type.IsMalformed()) {
1222 const Class& type_class = Class::Handle(type.type_class()); 1222 const Class& type_class = Class::Handle(type.type_class());
1223 if (!type_class.is_finalized() && 1223 if (!type_class.is_finalized() &&
1224 type_class.IsSignatureClass() && 1224 type_class.IsSignatureClass() &&
1225 !type_class.IsCanonicalSignatureClass()) { 1225 !IsAliasCycleFree(type_class, visited)) {
1226 if (!IsAliasCycleFree(type_class, visited)) { 1226 return false;
1227 return false;
1228 }
1229 } 1227 }
1230 } 1228 }
1231 // Check classes of formal parameter types. 1229 // Check classes of formal parameter types.
1232 const intptr_t num_parameters = function.NumParameters(); 1230 const intptr_t num_parameters = function.NumParameters();
1233 for (intptr_t i = 0; i < num_parameters; i++) { 1231 for (intptr_t i = 0; i < num_parameters; i++) {
1234 type = function.ParameterTypeAt(i); 1232 type = function.ParameterTypeAt(i);
1235 ResolveType(cls, type, kCanonicalize); 1233 ResolveType(cls, type, kCanonicalize);
1236 if (type.IsType() && !type.IsMalformed()) { 1234 if (type.IsType() && !type.IsMalformed()) {
1237 const Class& type_class = Class::Handle(type.type_class()); 1235 const Class& type_class = Class::Handle(type.type_class());
1238 if (!type_class.is_finalized() && 1236 if (!type_class.is_finalized() &&
1239 type_class.IsSignatureClass() && 1237 type_class.IsSignatureClass() &&
1240 !type_class.IsCanonicalSignatureClass()) { 1238 !IsAliasCycleFree(type_class, visited)) {
1241 if (!IsAliasCycleFree(type_class, visited)) { 1239 return false;
1242 return false;
1243 }
1244 } 1240 }
1245 } 1241 }
1246 } 1242 }
1247 visited->RemoveLast(); 1243 visited->RemoveLast();
1248 return true; 1244 return true;
1249 } 1245 }
1250 1246
1251 1247
1252 // Recursively walks the graph of explicitly declared super type and 1248 // Recursively walks the graph of explicitly declared super type and
1253 // interfaces, resolving unresolved super types and interfaces. 1249 // interfaces, resolving unresolved super types and interfaces.
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
1504 if ((finalization == kCanonicalizeWellFormed) || 1500 if ((finalization == kCanonicalizeWellFormed) ||
1505 FLAG_error_on_malformed_type) { 1501 FLAG_error_on_malformed_type) {
1506 ReportError(error); 1502 ReportError(error);
1507 } 1503 }
1508 } 1504 }
1509 if (FLAG_enable_type_checks || !type.HasResolvedTypeClass()) { 1505 if (FLAG_enable_type_checks || !type.HasResolvedTypeClass()) {
1510 // In check mode, always mark the type as malformed. 1506 // In check mode, always mark the type as malformed.
1511 // In production mode, mark the type as malformed only if its type class is 1507 // In production mode, mark the type as malformed only if its type class is
1512 // not resolved. 1508 // not resolved.
1513 type.set_malformed_error(error); 1509 type.set_malformed_error(error);
1510 if (!type.HasResolvedTypeClass()) {
1511 // We do not want an unresolved class to end up in a snapshot.
1512 type.set_type_class(Object::Handle(Object::null_class()));
1513 }
1514 } else { 1514 } else {
1515 // In production mode, do not mark the type with a resolved type class as 1515 // In production mode, do not mark the type with a resolved type class as
1516 // malformed, but make it raw. 1516 // malformed, but make it raw.
1517 ASSERT(type.HasResolvedTypeClass());
1518 type.set_arguments(AbstractTypeArguments::Handle()); 1517 type.set_arguments(AbstractTypeArguments::Handle());
1519 } 1518 }
1519 ASSERT(type.HasResolvedTypeClass());
1520 if (!type.IsFinalized()) { 1520 if (!type.IsFinalized()) {
1521 type.set_is_finalized_instantiated(); 1521 type.set_is_finalized_instantiated();
1522 // Do not canonicalize malformed types, since they may not be resolved. 1522 // Do not canonicalize malformed types, since they may not be resolved.
1523 } else { 1523 } else {
1524 // The only case where the malformed type was already finalized is when its 1524 // The only case where the malformed type was already finalized is when its
1525 // type arguments are not within bounds. In that case, we have a prev_error. 1525 // type arguments are not within bounds. In that case, we have a prev_error.
1526 ASSERT(!prev_error.IsNull()); 1526 ASSERT(!prev_error.IsNull());
1527 } 1527 }
1528 } 1528 }
1529 1529
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1582 void ClassFinalizer::ReportError(const char* format, ...) { 1582 void ClassFinalizer::ReportError(const char* format, ...) {
1583 va_list args; 1583 va_list args;
1584 va_start(args, format); 1584 va_start(args, format);
1585 const Error& error = Error::Handle( 1585 const Error& error = Error::Handle(
1586 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); 1586 Parser::FormatError(Script::Handle(), -1, "Error", format, args));
1587 va_end(args); 1587 va_end(args);
1588 ReportError(error); 1588 ReportError(error);
1589 } 1589 }
1590 1590
1591 } // namespace dart 1591 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/lib/growable_array.dart ('k') | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698