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

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

Issue 14820028: Delay Class parsing until the class is actually used. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 7 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
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 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 cls ^= class_array.At(i); 140 cls ^= class_array.At(i);
141 if (FLAG_trace_class_finalization) { 141 if (FLAG_trace_class_finalization) {
142 OS::Print("Resolving super and interfaces: %s\n", cls.ToCString()); 142 OS::Print("Resolving super and interfaces: %s\n", cls.ToCString());
143 } 143 }
144 GrowableArray<intptr_t> visited_interfaces; 144 GrowableArray<intptr_t> visited_interfaces;
145 ResolveSuperTypeAndInterfaces(cls, &visited_interfaces); 145 ResolveSuperTypeAndInterfaces(cls, &visited_interfaces);
146 } 146 }
147 // Finalize all classes. 147 // Finalize all classes.
148 for (intptr_t i = 0; i < class_array.Length(); i++) { 148 for (intptr_t i = 0; i < class_array.Length(); i++) {
149 cls ^= class_array.At(i); 149 cls ^= class_array.At(i);
150 FinalizeClass(cls); 150 FinalizeTypesInClass(cls);
151 } 151 }
152 if (FLAG_print_classes) { 152 if (FLAG_print_classes) {
153 for (intptr_t i = 0; i < class_array.Length(); i++) { 153 for (intptr_t i = 0; i < class_array.Length(); i++) {
154 cls ^= class_array.At(i); 154 cls ^= class_array.At(i);
155 PrintClassInformation(cls); 155 PrintClassInformation(cls);
156 } 156 }
157 } 157 }
158 // Clear pending classes array. 158 // Clear pending classes array.
159 class_array = GrowableObjectArray::New(); 159 class_array = GrowableObjectArray::New();
160 object_store->set_pending_classes(class_array); 160 object_store->set_pending_classes(class_array);
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 // Input: C<String, double> expressed as 497 // Input: C<String, double> expressed as
498 // cls = C, arguments = [null, null, String, double], 498 // cls = C, arguments = [null, null, String, double],
499 // i.e. cls_args = [String, double], offset = 2, length = 2. 499 // i.e. cls_args = [String, double], offset = 2, length = 2.
500 // Output: arguments = [int, double, String, double] 500 // Output: arguments = [int, double, String, double]
501 void ClassFinalizer::FinalizeTypeArguments( 501 void ClassFinalizer::FinalizeTypeArguments(
502 const Class& cls, 502 const Class& cls,
503 const AbstractTypeArguments& arguments, 503 const AbstractTypeArguments& arguments,
504 FinalizationKind finalization, 504 FinalizationKind finalization,
505 Error* bound_error) { 505 Error* bound_error) {
506 ASSERT(arguments.Length() >= cls.NumTypeArguments()); 506 ASSERT(arguments.Length() >= cls.NumTypeArguments());
507 if (!cls.is_finalized()) { 507 if (!cls.is_type_finalized()) {
508 FinalizeTypeParameters(cls); 508 FinalizeTypeParameters(cls);
509 ResolveUpperBounds(cls); 509 ResolveUpperBounds(cls);
510 } 510 }
511 AbstractType& super_type = AbstractType::Handle(cls.super_type()); 511 AbstractType& super_type = AbstractType::Handle(cls.super_type());
512 if (!super_type.IsNull()) { 512 if (!super_type.IsNull()) {
513 const Class& super_class = Class::Handle(super_type.type_class()); 513 const Class& super_class = Class::Handle(super_type.type_class());
514 AbstractTypeArguments& super_type_args = AbstractTypeArguments::Handle(); 514 AbstractTypeArguments& super_type_args = AbstractTypeArguments::Handle();
515 if (super_type.IsBeingFinalized()) { 515 if (super_type.IsBeingFinalized()) {
516 // This type references itself via its type arguments. This is legal, but 516 // This type references itself via its type arguments. This is legal, but
517 // we must avoid endless recursion. We therefore map the innermost 517 // we must avoid endless recursion. We therefore map the innermost
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 566
567 // Check the type argument vector 'arguments' against the corresponding bounds 567 // Check the type argument vector 'arguments' against the corresponding bounds
568 // of the type parameters of class 'cls' and, recursively, of its superclasses. 568 // of the type parameters of class 'cls' and, recursively, of its superclasses.
569 // Replace a type argument that cannot be checked at compile time by a 569 // Replace a type argument that cannot be checked at compile time by a
570 // BoundedType, thereby postponing the bound check to run time. 570 // BoundedType, thereby postponing the bound check to run time.
571 // Return a bound error if a type argument is not within bound at compile time. 571 // Return a bound error if a type argument is not within bound at compile time.
572 void ClassFinalizer::CheckTypeArgumentBounds( 572 void ClassFinalizer::CheckTypeArgumentBounds(
573 const Class& cls, 573 const Class& cls,
574 const AbstractTypeArguments& arguments, 574 const AbstractTypeArguments& arguments,
575 Error* bound_error) { 575 Error* bound_error) {
576 if (!cls.is_finalized()) { 576 if (!cls.is_type_finalized()) {
577 FinalizeUpperBounds(cls); 577 FinalizeUpperBounds(cls);
578 } 578 }
579 // Note that when finalizing a type, we need to verify the bounds in both 579 // Note that when finalizing a type, we need to verify the bounds in both
580 // production mode and checked mode, because the finalized type may be written 580 // production mode and checked mode, because the finalized type may be written
581 // to a snapshot. It would be wrong to ignore bounds when generating the 581 // to a snapshot. It would be wrong to ignore bounds when generating the
582 // snapshot in production mode and then use the unchecked type in checked mode 582 // snapshot in production mode and then use the unchecked type in checked mode
583 // after reading it from the snapshot. 583 // after reading it from the snapshot.
584 // However, we do not immediately report a bound error, which would be wrong 584 // However, we do not immediately report a bound error, which would be wrong
585 // in production mode, but simply postpone the bound checking to runtime. 585 // in production mode, but simply postpone the bound checking to runtime.
586 const intptr_t num_type_params = cls.NumTypeParameters(); 586 const intptr_t num_type_params = cls.NumTypeParameters();
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 } else { 676 } else {
677 return type.Canonicalize(); 677 return type.Canonicalize();
678 } 678 }
679 } 679 }
680 return type.raw(); 680 return type.raw();
681 } 681 }
682 ASSERT(type.IsResolved()); 682 ASSERT(type.IsResolved());
683 ASSERT(finalization >= kFinalize); 683 ASSERT(finalization >= kFinalize);
684 684
685 if (FLAG_trace_type_finalization) { 685 if (FLAG_trace_type_finalization) {
686 OS::Print("Finalize type '%s'\n", String::Handle(type.Name()).ToCString()); 686 OS::Print("Finalize type '%s' for class %s\n",
regis 2013/05/23 16:50:04 Wrap names in single quotes: '%s'
siva 2013/05/23 20:19:46 Done.
687 String::Handle(type.Name()).ToCString(),
688 cls.ToCString());
687 } 689 }
688 690
689 if (type.IsTypeParameter()) { 691 if (type.IsTypeParameter()) {
690 const TypeParameter& type_parameter = TypeParameter::Cast(type); 692 const TypeParameter& type_parameter = TypeParameter::Cast(type);
691 const Class& parameterized_class = 693 const Class& parameterized_class =
692 Class::Handle(type_parameter.parameterized_class()); 694 Class::Handle(type_parameter.parameterized_class());
693 ASSERT(!parameterized_class.IsNull()); 695 ASSERT(!parameterized_class.IsNull());
694 // The index must reflect the position of this type parameter in the type 696 // The index must reflect the position of this type parameter in the type
695 // arguments vector of its parameterized class. The offset to add is the 697 // arguments vector of its parameterized class. The offset to add is the
696 // number of type arguments in the super type, which is equal to the 698 // number of type arguments in the super type, which is equal to the
(...skipping 22 matching lines...) Expand all
719 721
720 // Mark type as being finalized in order to detect illegal self reference. 722 // Mark type as being finalized in order to detect illegal self reference.
721 parameterized_type.set_is_being_finalized(); 723 parameterized_type.set_is_being_finalized();
722 724
723 // The type class does not need to be finalized in order to finalize the type, 725 // The type class does not need to be finalized in order to finalize the type,
724 // however, it must at least be resolved (this was done as part of resolving 726 // however, it must at least be resolved (this was done as part of resolving
725 // the type itself, a precondition to calling FinalizeType). 727 // the type itself, a precondition to calling FinalizeType).
726 // Also, the interfaces of the type class must be resolved and the type 728 // Also, the interfaces of the type class must be resolved and the type
727 // parameters of the type class must be finalized. 729 // parameters of the type class must be finalized.
728 Class& type_class = Class::Handle(parameterized_type.type_class()); 730 Class& type_class = Class::Handle(parameterized_type.type_class());
729 if (!type_class.is_finalized()) { 731 if (!type_class.is_type_finalized()) {
730 FinalizeTypeParameters(type_class); 732 FinalizeTypeParameters(type_class);
731 ResolveUpperBounds(type_class); 733 ResolveUpperBounds(type_class);
732 } 734 }
733 735
734 // Finalize the current type arguments of the type, which are still the 736 // Finalize the current type arguments of the type, which are still the
735 // parsed type arguments. 737 // parsed type arguments.
736 AbstractTypeArguments& arguments = 738 AbstractTypeArguments& arguments =
737 AbstractTypeArguments::Handle(parameterized_type.arguments()); 739 AbstractTypeArguments::Handle(parameterized_type.arguments());
738 if (!arguments.IsNull()) { 740 if (!arguments.IsNull()) {
739 intptr_t num_arguments = arguments.Length(); 741 intptr_t num_arguments = arguments.Length();
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
852 } 854 }
853 855
854 // If the type class is a signature class, we are currently finalizing a 856 // If the type class is a signature class, we are currently finalizing a
855 // signature type, i.e. finalizing the result type and parameter types of the 857 // signature type, i.e. finalizing the result type and parameter types of the
856 // signature function of this signature type. 858 // signature function of this signature type.
857 // We do this after marking this type as finalized in order to allow a 859 // We do this after marking this type as finalized in order to allow a
858 // function type to refer to itself via its parameter types and result type. 860 // function type to refer to itself via its parameter types and result type.
859 if (type_class.IsSignatureClass()) { 861 if (type_class.IsSignatureClass()) {
860 // The class may be created while parsing a function body, after all 862 // The class may be created while parsing a function body, after all
861 // pending classes have already been finalized. 863 // pending classes have already been finalized.
862 FinalizeClass(type_class); 864 FinalizeTypesInClass(type_class);
863 } 865 }
864 866
865 // If a bound error occurred, return a BoundedType with a malformed bound. 867 // If a bound error occurred, return a BoundedType with a malformed bound.
866 // The malformed bound will be ignored in production mode. 868 // The malformed bound will be ignored in production mode.
867 if (!bound_error.IsNull()) { 869 if (!bound_error.IsNull()) {
868 FinalizationKind bound_finalization = kTryResolve; // No compile error. 870 FinalizationKind bound_finalization = kTryResolve; // No compile error.
869 if (FLAG_enable_type_checks || FLAG_error_on_malformed_type) { 871 if (FLAG_enable_type_checks || FLAG_error_on_malformed_type) {
870 bound_finalization = finalization; 872 bound_finalization = finalization;
871 } 873 }
872 const String& parameterized_type_name = String::Handle( 874 const String& parameterized_type_name = String::Handle(
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
1246 param_bound, 1248 param_bound,
1247 param.token_pos()); 1249 param.token_pos());
1248 cloned_type_params.SetTypeAt(cloned_index, cloned_param); 1250 cloned_type_params.SetTypeAt(cloned_index, cloned_param);
1249 cloned_index++; 1251 cloned_index++;
1250 } 1252 }
1251 } 1253 }
1252 mixapp_class.set_type_parameters(cloned_type_params); 1254 mixapp_class.set_type_parameters(cloned_type_params);
1253 } 1255 }
1254 1256
1255 1257
1256 void ClassFinalizer::ApplyMixin(const Class& cls) { 1258 void ClassFinalizer::ApplyMixinTypes(const Class& cls) {
1257 const Type& mixin_type = Type::Handle(cls.mixin()); 1259 const Type& mixin_type = Type::Handle(cls.mixin());
1258 ASSERT(!mixin_type.IsNull()); 1260 ASSERT(!mixin_type.IsNull());
1259 ASSERT(mixin_type.HasResolvedTypeClass()); 1261 ASSERT(mixin_type.HasResolvedTypeClass());
1260 const Class& mixin_cls = Class::Handle(mixin_type.type_class()); 1262 const Class& mixin_cls = Class::Handle(mixin_type.type_class());
1261 1263
1262 if (FLAG_trace_class_finalization) { 1264 if (FLAG_trace_class_finalization) {
1263 OS::Print("Applying mixin '%s' to '%s' at pos %"Pd"\n", 1265 OS::Print("Applying mixin type '%s' to '%s' at pos %"Pd"\n",
1264 String::Handle(mixin_cls.Name()).ToCString(), 1266 String::Handle(mixin_cls.Name()).ToCString(),
1265 cls.ToCString(), 1267 cls.ToCString(),
1266 cls.token_pos()); 1268 cls.token_pos());
1267 } 1269 }
1268 1270
1269 // Check that the super class of the mixin class is extending 1271 // Check that the super class of the mixin class is extending
1270 // class Object. 1272 // class Object.
1271 const AbstractType& mixin_super_type = 1273 const AbstractType& mixin_super_type =
1272 AbstractType::Handle(mixin_cls.super_type()); 1274 AbstractType::Handle(mixin_cls.super_type());
1273 if (!mixin_super_type.IsObjectType()) { 1275 if (!mixin_super_type.IsObjectType()) {
1274 const Script& script = Script::Handle(cls.script()); 1276 const Script& script = Script::Handle(cls.script());
1275 const String& class_name = String::Handle(mixin_cls.Name()); 1277 const String& class_name = String::Handle(mixin_cls.Name());
1276 ReportError(script, cls.token_pos(), 1278 ReportError(script, cls.token_pos(),
1277 "mixin class %s must extend class Object", 1279 "mixin class %s must extend class Object",
1278 class_name.ToCString()); 1280 class_name.ToCString());
1279 } 1281 }
1280 1282
1281 // Copy type parameters to mixin application class. 1283 // Copy type parameters to mixin application class.
1282 CloneTypeParameters(cls); 1284 CloneTypeParameters(cls);
1283 1285
1286 if (FLAG_trace_class_finalization) {
1287 OS::Print("done mixin type appl %s %s extending %s\n",
regis 2013/05/23 16:50:04 Wrap %s in single quotes.
siva 2013/05/23 20:19:46 Done.
1288 String::Handle(cls.Name()).ToCString(),
1289 TypeArguments::Handle(cls.type_parameters()).ToCString(),
1290 AbstractType::Handle(cls.super_type()).ToCString());
1291 }
1292 }
1293
1294
1295 void ClassFinalizer::ApplyMixin(const Class& cls) {
1296 Isolate* isolate = Isolate::Current();
1297 const Type& mixin_type = Type::Handle(isolate, cls.mixin());
1298 ASSERT(!mixin_type.IsNull());
1299 ASSERT(mixin_type.HasResolvedTypeClass());
1300 const Class& mixin_cls = Class::Handle(isolate, mixin_type.type_class());
1301 mixin_cls.EnsureIsFinalized(isolate);
1302
1303 if (FLAG_trace_class_finalization) {
1304 OS::Print("Applying mixin '%s' to '%s' at pos %"Pd"\n",
1305 String::Handle(mixin_cls.Name()).ToCString(),
1306 cls.ToCString(),
1307 cls.token_pos());
1308 }
1309
1284 const GrowableObjectArray& cloned_funcs = 1310 const GrowableObjectArray& cloned_funcs =
1285 GrowableObjectArray::Handle(GrowableObjectArray::New()); 1311 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New());
1286 Array& functions = Array::Handle(); 1312 Array& functions = Array::Handle(isolate);
1287 Function& func = Function::Handle(); 1313 Function& func = Function::Handle(isolate);
1288 // The parser creates the mixin application class and adds just 1314 // The parser creates the mixin application class and adds just
1289 // one function, the implicit constructor. 1315 // one function, the implicit constructor.
1290 functions = cls.functions(); 1316 functions = cls.functions();
1291 ASSERT(functions.Length() == 1); 1317 ASSERT(functions.Length() == 1);
1292 func ^= functions.At(0); 1318 func ^= functions.At(0);
1293 ASSERT(func.IsImplicitConstructor()); 1319 ASSERT(func.IsImplicitConstructor());
1294 cloned_funcs.Add(func); 1320 cloned_funcs.Add(func);
1295 // Now clone the functions from the mixin class. 1321 // Now clone the functions from the mixin class.
1296 functions = mixin_cls.functions(); 1322 functions = mixin_cls.functions();
1297 const intptr_t num_functions = functions.Length(); 1323 const intptr_t num_functions = functions.Length();
1298 for (int i = 0; i < num_functions; i++) { 1324 for (int i = 0; i < num_functions; i++) {
1299 func ^= functions.At(i); 1325 func ^= functions.At(i);
1300 if (func.IsConstructor()) { 1326 if (func.IsConstructor()) {
1301 // A mixin class must not have explicit constructors. 1327 // A mixin class must not have explicit constructors.
1302 if (!func.IsImplicitConstructor()) { 1328 if (!func.IsImplicitConstructor()) {
1303 const Script& script = Script::Handle(cls.script()); 1329 const Script& script = Script::Handle(isolate, cls.script());
1304 ReportError(script, cls.token_pos(), 1330 ReportError(script, cls.token_pos(),
1305 "mixin class %s must not have constructors\n", 1331 "mixin class %s must not have constructors\n",
1306 String::Handle(mixin_cls.Name()).ToCString()); 1332 String::Handle(isolate, mixin_cls.Name()).ToCString());
1307 } 1333 }
1308 continue; // Skip the implicit constructor. 1334 continue; // Skip the implicit constructor.
1309 } 1335 }
1310 if (!func.is_static()) { 1336 if (!func.is_static()) {
1311 func = func.Clone(cls); 1337 func = func.Clone(cls);
1312 cloned_funcs.Add(func); 1338 cloned_funcs.Add(func);
1313 } 1339 }
1314 } 1340 }
1315 functions = Array::MakeArray(cloned_funcs); 1341 functions = Array::MakeArray(cloned_funcs);
1316 cls.SetFunctions(functions); 1342 cls.SetFunctions(functions);
1317 1343
1318 // Now clone the fields from the mixin class. There should be no 1344 // Now clone the fields from the mixin class. There should be no
1319 // existing fields in the mixin application class. 1345 // existing fields in the mixin application class.
1320 ASSERT(Array::Handle(cls.fields()).Length() == 0); 1346 ASSERT(Array::Handle(cls.fields()).Length() == 0);
1321 Array& fields = Array::Handle(mixin_cls.fields()); 1347 Array& fields = Array::Handle(isolate, mixin_cls.fields());
1322 Field& field = Field::Handle(); 1348 Field& field = Field::Handle(isolate);
1323 const GrowableObjectArray& cloned_fields = 1349 const GrowableObjectArray& cloned_fields =
1324 GrowableObjectArray::Handle(GrowableObjectArray::New()); 1350 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New());
1325 const intptr_t num_fields = fields.Length(); 1351 const intptr_t num_fields = fields.Length();
1326 for (int i = 0; i < num_fields; i++) { 1352 for (int i = 0; i < num_fields; i++) {
1327 field ^= fields.At(i); 1353 field ^= fields.At(i);
1328 if (!field.is_static()) { 1354 if (!field.is_static()) {
1329 field = field.Clone(cls); 1355 field = field.Clone(cls);
1330 cloned_fields.Add(field); 1356 cloned_fields.Add(field);
1331 } 1357 }
1332 } 1358 }
1333 fields = Array::MakeArray(cloned_fields); 1359 fields = Array::MakeArray(cloned_fields);
1334 cls.SetFields(fields); 1360 cls.SetFields(fields);
1335 1361
1336 if (FLAG_trace_class_finalization) { 1362 if (FLAG_trace_class_finalization) {
1337 OS::Print("done mixin appl %s %s extending %s\n", 1363 OS::Print("done mixin appl %s %s extending %s\n",
1338 String::Handle(cls.Name()).ToCString(), 1364 String::Handle(cls.Name()).ToCString(),
1339 TypeArguments::Handle(cls.type_parameters()).ToCString(), 1365 TypeArguments::Handle(cls.type_parameters()).ToCString(),
1340 AbstractType::Handle(cls.super_type()).ToCString()); 1366 AbstractType::Handle(cls.super_type()).ToCString());
1341 } 1367 }
1342 } 1368 }
1343 1369
1344 1370
1345 void ClassFinalizer::FinalizeClass(const Class& cls) { 1371 void ClassFinalizer::FinalizeTypesInClass(const Class& cls) {
1346 HANDLESCOPE(Isolate::Current()); 1372 HANDLESCOPE(Isolate::Current());
1347 if (cls.is_finalized()) { 1373 if (cls.is_type_finalized()) {
1348 return; 1374 return;
1349 } 1375 }
1350 if (FLAG_trace_class_finalization) { 1376 if (FLAG_trace_class_finalization) {
1351 OS::Print("Finalize %s\n", cls.ToCString()); 1377 OS::Print("Finalize %s\n", cls.ToCString());
1352 } 1378 }
1353 if (!IsSuperCycleFree(cls)) { 1379 if (!IsSuperCycleFree(cls)) {
1354 const String& name = String::Handle(cls.Name()); 1380 const String& name = String::Handle(cls.Name());
1355 const Script& script = Script::Handle(cls.script()); 1381 const Script& script = Script::Handle(cls.script());
1356 ReportError(script, cls.token_pos(), 1382 ReportError(script, cls.token_pos(),
1357 "class '%s' has a cycle in its superclass relationship", 1383 "class '%s' has a cycle in its superclass relationship",
1358 name.ToCString()); 1384 name.ToCString());
1359 } 1385 }
1360 // Finalize super class. 1386 // Finalize super class.
1361 const Class& super_class = Class::Handle(cls.SuperClass()); 1387 const Class& super_class = Class::Handle(cls.SuperClass());
1362 if (!super_class.IsNull()) { 1388 if (!super_class.IsNull()) {
1363 FinalizeClass(super_class); 1389 FinalizeTypesInClass(super_class);
1364 } 1390 }
1365 if (cls.mixin() != Type::null()) { 1391 if (cls.mixin() != Type::null()) {
1366 // Copy instance methods and fields from the mixin class. 1392 // Copy the type parameters to the mixin application.
1367 // This has to happen before the check whether the methods of 1393 ApplyMixinTypes(cls);
1368 // the class conflict with inherited methods.
1369 ApplyMixin(cls);
1370 } 1394 }
1371 // Finalize type parameters before finalizing the super type. 1395 // Finalize type parameters before finalizing the super type.
1372 FinalizeTypeParameters(cls); 1396 FinalizeTypeParameters(cls);
1373 ResolveUpperBounds(cls); 1397 ResolveUpperBounds(cls);
1374 // Finalize super type. 1398 // Finalize super type.
1375 AbstractType& super_type = AbstractType::Handle(cls.super_type()); 1399 AbstractType& super_type = AbstractType::Handle(cls.super_type());
1376 if (!super_type.IsNull()) { 1400 if (!super_type.IsNull()) {
1377 // In case of a bound error in the super type in production mode, the 1401 // In case of a bound error in the super type in production mode, the
1378 // finalized super type will be a BoundedType with a malformed bound. 1402 // finalized super type will be a BoundedType with a malformed bound.
1379 // It should not be a problem if the class is written to a snapshot and 1403 // It should not be a problem if the class is written to a snapshot and
1380 // later executed in checked mode. Note that the finalized type argument 1404 // later executed in checked mode. Note that the finalized type argument
1381 // vector of any type of the base class will contain a BoundedType for the 1405 // vector of any type of the base class will contain a BoundedType for the
1382 // out of bound type argument. 1406 // out of bound type argument.
1383 super_type = FinalizeType(cls, super_type, kCanonicalizeWellFormed); 1407 super_type = FinalizeType(cls, super_type, kCanonicalizeWellFormed);
1384 cls.set_super_type(super_type); 1408 cls.set_super_type(super_type);
1385 } 1409 }
1386 if (cls.IsSignatureClass()) { 1410 if (cls.IsSignatureClass()) {
1387 // Check for illegal self references. 1411 // Check for illegal self references.
1388 GrowableArray<intptr_t> visited_aliases; 1412 GrowableArray<intptr_t> visited_aliases;
1389 if (!IsAliasCycleFree(cls, &visited_aliases)) { 1413 if (!IsAliasCycleFree(cls, &visited_aliases)) {
1390 const String& name = String::Handle(cls.Name()); 1414 const String& name = String::Handle(cls.Name());
1391 const Script& script = Script::Handle(cls.script()); 1415 const Script& script = Script::Handle(cls.script());
1392 ReportError(script, cls.token_pos(), 1416 ReportError(script, cls.token_pos(),
1393 "typedef '%s' illegally refers to itself", 1417 "typedef '%s' illegally refers to itself",
1394 name.ToCString()); 1418 name.ToCString());
1395 } 1419 }
1396 cls.Finalize(); 1420 cls.set_is_type_finalized();
1397 // Signature classes extend Object. No need to add this class to the direct 1421 // Signature classes extend Object. No need to add this class to the direct
1398 // subclasses of Object. 1422 // subclasses of Object.
1399 ASSERT(super_type.IsNull() || super_type.IsObjectType()); 1423 ASSERT(super_type.IsNull() || super_type.IsObjectType());
1400 1424
1401 // The type parameters of signature classes may have bounds. 1425 // The type parameters of signature classes may have bounds.
1402 FinalizeUpperBounds(cls); 1426 FinalizeUpperBounds(cls);
1403 1427
1404 // Resolve and finalize the result and parameter types of the signature 1428 // Resolve and finalize the result and parameter types of the signature
1405 // function of this signature class. 1429 // function of this signature class.
1406 const Function& sig_function = Function::Handle(cls.signature_function()); 1430 const Function& sig_function = Function::Handle(cls.signature_function());
1407 ResolveAndFinalizeSignature(cls, sig_function); 1431 ResolveAndFinalizeSignature(cls, sig_function);
1408 1432
1409 // Resolve and finalize the signature type of this signature class. 1433 // Resolve and finalize the signature type of this signature class.
1410 const Type& sig_type = Type::Handle(cls.SignatureType()); 1434 const Type& sig_type = Type::Handle(cls.SignatureType());
1411 FinalizeType(cls, sig_type, kCanonicalizeWellFormed); 1435 FinalizeType(cls, sig_type, kCanonicalizeWellFormed);
1412 return; 1436 return;
1413 } 1437 }
1414 // Finalize interface types (but not necessarily interface classes). 1438 // Finalize interface types (but not necessarily interface classes).
1415 Array& interface_types = Array::Handle(cls.interfaces()); 1439 Array& interface_types = Array::Handle(cls.interfaces());
1416 AbstractType& interface_type = AbstractType::Handle(); 1440 AbstractType& interface_type = AbstractType::Handle();
1417 for (intptr_t i = 0; i < interface_types.Length(); i++) { 1441 for (intptr_t i = 0; i < interface_types.Length(); i++) {
1418 interface_type ^= interface_types.At(i); 1442 interface_type ^= interface_types.At(i);
1419 interface_type = FinalizeType(cls, interface_type, kCanonicalizeWellFormed); 1443 interface_type = FinalizeType(cls, interface_type, kCanonicalizeWellFormed);
1420 interface_types.SetAt(i, interface_type); 1444 interface_types.SetAt(i, interface_type);
1421 1445
1422 // Check whether the interface is duplicated. We need to wait with 1446 // Check whether the interface is duplicated. We need to wait with
1423 // this check until the super type and interface types are finalized, 1447 // this check until the super type and interface types are finalized,
1424 // so that we can use Type::Equals() for the test. 1448 // so that we can use Type::Equals() for the test.
1425 ASSERT(interface_type.IsFinalized()); 1449 ASSERT(interface_type.IsFinalized());
1426 ASSERT(super_type.IsFinalized()); 1450 ASSERT(super_type.IsNull() || super_type.IsFinalized());
1427 if (interface_type.Equals(super_type)) { 1451 if (!super_type.IsNull() && interface_type.Equals(super_type)) {
1428 const Script& script = Script::Handle(cls.script()); 1452 const Script& script = Script::Handle(cls.script());
1429 ReportError(script, cls.token_pos(), 1453 ReportError(script, cls.token_pos(),
1430 "super type '%s' may not be listed in " 1454 "super type '%s' may not be listed in "
1431 "implements clause of class '%s'", 1455 "implements clause of class '%s'",
1432 String::Handle(super_type.Name()).ToCString(), 1456 String::Handle(super_type.Name()).ToCString(),
1433 String::Handle(cls.Name()).ToCString()); 1457 String::Handle(cls.Name()).ToCString());
1434 } 1458 }
1435 AbstractType& seen_interf = AbstractType::Handle(); 1459 AbstractType& seen_interf = AbstractType::Handle();
1436 for (intptr_t j = 0; j < i; j++) { 1460 for (intptr_t j = 0; j < i; j++) {
1437 seen_interf ^= interface_types.At(j); 1461 seen_interf ^= interface_types.At(j);
1438 if (interface_type.Equals(seen_interf)) { 1462 if (interface_type.Equals(seen_interf)) {
1439 const Script& script = Script::Handle(cls.script()); 1463 const Script& script = Script::Handle(cls.script());
1440 ReportError(script, cls.token_pos(), 1464 ReportError(script, cls.token_pos(),
1441 "interface '%s' appears twice in " 1465 "interface '%s' appears twice in "
1442 "implements clause of class '%s'", 1466 "implements clause of class '%s'",
1443 String::Handle(interface_type.Name()).ToCString(), 1467 String::Handle(interface_type.Name()).ToCString(),
1444 String::Handle(cls.Name()).ToCString()); 1468 String::Handle(cls.Name()).ToCString());
1445 } 1469 }
1446 } 1470 }
1447 } 1471 }
1448 // Mark as finalized before resolving type parameter upper bounds and member 1472 // Mark as type finalized before resolving type parameter upper bounds and
1449 // types in order to break cycles. 1473 // member types in order to break cycles.
regis 2013/05/23 16:50:04 The comment still mentions ' member types', but yo
siva 2013/05/23 20:19:46 Done.
1450 cls.Finalize(); 1474 cls.set_is_type_finalized();
1451 // Finalize bounds even if running in production mode, so that a snapshot 1475 // Finalize bounds even if running in production mode, so that a snapshot
1452 // contains them. 1476 // contains them.
1453 FinalizeUpperBounds(cls); 1477 FinalizeUpperBounds(cls);
1454 ResolveAndFinalizeMemberTypes(cls);
1455 // Run additional checks after all types are finalized.
1456 if (cls.is_const()) {
1457 CheckForLegalConstClass(cls);
1458 }
1459 // Add this class to the direct subclasses of the superclass, unless the 1478 // Add this class to the direct subclasses of the superclass, unless the
1460 // superclass is Object. 1479 // superclass is Object.
1461 if (!super_type.IsNull() && !super_type.IsObjectType()) { 1480 if (!super_type.IsNull() && !super_type.IsObjectType()) {
1462 ASSERT(!super_class.IsNull()); 1481 ASSERT(!super_class.IsNull());
1463 super_class.AddDirectSubclass(cls); 1482 super_class.AddDirectSubclass(cls);
1464 } 1483 }
1484 // Top level classes are parsed eagerly so just finalize it.
1485 if (cls.IsTopLevel()) {
1486 ClassFinalizer::FinalizeClass(cls);
1487 }
1488 }
1489
1490
1491 void ClassFinalizer::FinalizeClass(const Class& cls) {
1492 HANDLESCOPE(Isolate::Current());
1493 if (cls.is_finalized()) {
1494 return;
1495 }
1496 if (cls.mixin() != Type::null()) {
1497 // Copy instance methods and fields from the mixin class.
1498 // This has to happen before the check whether the methods of
1499 // the class conflict with inherited methods.
1500 ApplyMixin(cls);
1501 }
1502 // Mark as parsed and finalized.
1503 cls.Finalize();
1504 // Resolve and finalize all member types.
1505 ResolveAndFinalizeMemberTypes(cls);
1506 // Run additional checks after all types are finalized.
1507 if (cls.is_const()) {
1508 CheckForLegalConstClass(cls);
1509 }
1465 } 1510 }
1466 1511
1467 1512
1468 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) { 1513 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) {
1469 Class& test1 = Class::Handle(cls.raw()); 1514 Class& test1 = Class::Handle(cls.raw());
1470 Class& test2 = Class::Handle(cls.SuperClass()); 1515 Class& test2 = Class::Handle(cls.SuperClass());
1471 // A finalized class has been checked for cycles. 1516 // A finalized class has been checked for cycles.
1472 // Using the hare and tortoise algorithm for locating cycles. 1517 // Using the hare and tortoise algorithm for locating cycles.
1473 while (!test1.is_finalized() && 1518 while (!test1.is_type_finalized() &&
1474 !test2.IsNull() && !test2.is_finalized()) { 1519 !test2.IsNull() && !test2.is_type_finalized()) {
1475 if (test1.raw() == test2.raw()) { 1520 if (test1.raw() == test2.raw()) {
1476 // Found a cycle. 1521 // Found a cycle.
1477 return false; 1522 return false;
1478 } 1523 }
1479 test1 = test1.SuperClass(); 1524 test1 = test1.SuperClass();
1480 test2 = test2.SuperClass(); 1525 test2 = test2.SuperClass();
1481 if (!test2.IsNull()) { 1526 if (!test2.IsNull()) {
1482 test2 = test2.SuperClass(); 1527 test2 = test2.SuperClass();
1483 } 1528 }
1484 } 1529 }
1485 // No cycles. 1530 // No cycles.
1486 return true; 1531 return true;
1487 } 1532 }
1488 1533
1489 1534
1490 // Returns false if the function type alias illegally refers to itself. 1535 // Returns false if the function type alias illegally refers to itself.
1491 bool ClassFinalizer::IsAliasCycleFree(const Class& cls, 1536 bool ClassFinalizer::IsAliasCycleFree(const Class& cls,
1492 GrowableArray<intptr_t>* visited) { 1537 GrowableArray<intptr_t>* visited) {
1493 ASSERT(cls.IsSignatureClass()); 1538 ASSERT(cls.IsSignatureClass());
1494 ASSERT(!cls.is_finalized()); 1539 ASSERT(!cls.is_type_finalized());
1495 ASSERT(visited != NULL); 1540 ASSERT(visited != NULL);
1496 const intptr_t cls_index = cls.id(); 1541 const intptr_t cls_index = cls.id();
1497 for (int i = 0; i < visited->length(); i++) { 1542 for (int i = 0; i < visited->length(); i++) {
1498 if ((*visited)[i] == cls_index) { 1543 if ((*visited)[i] == cls_index) {
1499 // We have already visited alias 'cls'. We found a cycle. 1544 // We have already visited alias 'cls'. We found a cycle.
1500 return false; 1545 return false;
1501 } 1546 }
1502 } 1547 }
1503 1548
1504 // Visit the result type and parameter types of this signature type. 1549 // Visit the result type and parameter types of this signature type.
1505 visited->Add(cls.id()); 1550 visited->Add(cls.id());
1506 const Function& function = Function::Handle(cls.signature_function()); 1551 const Function& function = Function::Handle(cls.signature_function());
1507 // Check class of result type. 1552 // Check class of result type.
1508 AbstractType& type = AbstractType::Handle(function.result_type()); 1553 AbstractType& type = AbstractType::Handle(function.result_type());
1509 ResolveType(cls, type, kCanonicalize); 1554 ResolveType(cls, type, kCanonicalize);
1510 if (type.IsType() && !type.IsMalformed()) { 1555 if (type.IsType() && !type.IsMalformed()) {
1511 const Class& type_class = Class::Handle(type.type_class()); 1556 const Class& type_class = Class::Handle(type.type_class());
1512 if (!type_class.is_finalized() && 1557 if (!type_class.is_type_finalized() &&
1513 type_class.IsSignatureClass() && 1558 type_class.IsSignatureClass() &&
1514 !IsAliasCycleFree(type_class, visited)) { 1559 !IsAliasCycleFree(type_class, visited)) {
1515 return false; 1560 return false;
1516 } 1561 }
1517 } 1562 }
1518 // Check classes of formal parameter types. 1563 // Check classes of formal parameter types.
1519 const intptr_t num_parameters = function.NumParameters(); 1564 const intptr_t num_parameters = function.NumParameters();
1520 for (intptr_t i = 0; i < num_parameters; i++) { 1565 for (intptr_t i = 0; i < num_parameters; i++) {
1521 type = function.ParameterTypeAt(i); 1566 type = function.ParameterTypeAt(i);
1522 ResolveType(cls, type, kCanonicalize); 1567 ResolveType(cls, type, kCanonicalize);
1523 if (type.IsType() && !type.IsMalformed()) { 1568 if (type.IsType() && !type.IsMalformed()) {
1524 const Class& type_class = Class::Handle(type.type_class()); 1569 const Class& type_class = Class::Handle(type.type_class());
1525 if (!type_class.is_finalized() && 1570 if (!type_class.is_type_finalized() &&
1526 type_class.IsSignatureClass() && 1571 type_class.IsSignatureClass() &&
1527 !IsAliasCycleFree(type_class, visited)) { 1572 !IsAliasCycleFree(type_class, visited)) {
1528 return false; 1573 return false;
1529 } 1574 }
1530 } 1575 }
1531 } 1576 }
1532 visited->RemoveLast(); 1577 visited->RemoveLast();
1533 return true; 1578 return true;
1534 } 1579 }
1535 1580
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
1939 va_start(args, format); 1984 va_start(args, format);
1940 const Error& error = Error::Handle( 1985 const Error& error = Error::Handle(
1941 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); 1986 Parser::FormatError(Script::Handle(), -1, "Error", format, args));
1942 va_end(args); 1987 va_end(args);
1943 ReportError(error); 1988 ReportError(error);
1944 } 1989 }
1945 1990
1946 1991
1947 void ClassFinalizer::VerifyImplicitFieldOffsets() { 1992 void ClassFinalizer::VerifyImplicitFieldOffsets() {
1948 #ifdef DEBUG 1993 #ifdef DEBUG
1949 const ClassTable& class_table = *(Isolate::Current()->class_table()); 1994 Isolate* isolate = Isolate::Current();
1950 Class& cls = Class::Handle(); 1995 const ClassTable& class_table = *(isolate->class_table());
1951 Array& fields_array = Array::Handle(); 1996 Class& cls = Class::Handle(isolate);
1952 Field& field = Field::Handle(); 1997 Array& fields_array = Array::Handle(isolate);
1953 String& name = String::Handle(); 1998 Field& field = Field::Handle(isolate);
1954 String& expected_name = String::Handle(); 1999 String& name = String::Handle(isolate);
2000 String& expected_name = String::Handle(isolate);
2001 Error& error = Error::Handle(isolate);
1955 2002
1956 // First verify field offsets of all the TypedDataView classes. 2003 // First verify field offsets of all the TypedDataView classes.
1957 for (intptr_t cid = kTypedDataInt8ArrayViewCid; 2004 for (intptr_t cid = kTypedDataInt8ArrayViewCid;
1958 cid <= kTypedDataFloat32x4ArrayViewCid; 2005 cid <= kTypedDataFloat32x4ArrayViewCid;
1959 cid++) { 2006 cid++) {
1960 cls = class_table.At(cid); // Get the TypedDataView class. 2007 cls = class_table.At(cid); // Get the TypedDataView class.
2008 error = cls.EnsureIsFinalized(isolate);
2009 ASSERT(error.IsNull());
1961 cls = cls.SuperClass(); // Get it's super class '_TypedListView'. 2010 cls = cls.SuperClass(); // Get it's super class '_TypedListView'.
1962 fields_array ^= cls.fields(); 2011 fields_array ^= cls.fields();
1963 ASSERT(fields_array.Length() == TypedDataView::NumberOfFields()); 2012 ASSERT(fields_array.Length() == TypedDataView::NumberOfFields());
1964 field ^= fields_array.At(0); 2013 field ^= fields_array.At(0);
1965 ASSERT(field.Offset() == TypedDataView::data_offset()); 2014 ASSERT(field.Offset() == TypedDataView::data_offset());
1966 name ^= field.name(); 2015 name ^= field.name();
1967 expected_name ^= String::New("_typedData"); 2016 expected_name ^= String::New("_typedData");
1968 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); 2017 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name));
1969 field ^= fields_array.At(1); 2018 field ^= fields_array.At(1);
1970 ASSERT(field.Offset() == TypedDataView::offset_in_bytes_offset()); 2019 ASSERT(field.Offset() == TypedDataView::offset_in_bytes_offset());
1971 name ^= field.name(); 2020 name ^= field.name();
1972 ASSERT(name.Equals("offsetInBytes")); 2021 ASSERT(name.Equals("offsetInBytes"));
1973 field ^= fields_array.At(2); 2022 field ^= fields_array.At(2);
1974 ASSERT(field.Offset() == TypedDataView::length_offset()); 2023 ASSERT(field.Offset() == TypedDataView::length_offset());
1975 name ^= field.name(); 2024 name ^= field.name();
1976 ASSERT(name.Equals("length")); 2025 ASSERT(name.Equals("length"));
1977 } 2026 }
1978 2027
1979 // Now verify field offsets of '_ByteDataView' class. 2028 // Now verify field offsets of '_ByteDataView' class.
1980 cls = class_table.At(kByteDataViewCid); 2029 cls = class_table.At(kByteDataViewCid);
2030 error = cls.EnsureIsFinalized(isolate);
2031 ASSERT(error.IsNull());
1981 fields_array ^= cls.fields(); 2032 fields_array ^= cls.fields();
1982 ASSERT(fields_array.Length() == TypedDataView::NumberOfFields()); 2033 ASSERT(fields_array.Length() == TypedDataView::NumberOfFields());
1983 field ^= fields_array.At(0); 2034 field ^= fields_array.At(0);
1984 ASSERT(field.Offset() == TypedDataView::data_offset()); 2035 ASSERT(field.Offset() == TypedDataView::data_offset());
1985 name ^= field.name(); 2036 name ^= field.name();
1986 expected_name ^= String::New("_typedData"); 2037 expected_name ^= String::New("_typedData");
1987 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); 2038 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name));
1988 field ^= fields_array.At(1); 2039 field ^= fields_array.At(1);
1989 ASSERT(field.Offset() == TypedDataView::offset_in_bytes_offset()); 2040 ASSERT(field.Offset() == TypedDataView::offset_in_bytes_offset());
1990 name ^= field.name(); 2041 name ^= field.name();
1991 expected_name ^= String::New("_offset"); 2042 expected_name ^= String::New("_offset");
1992 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); 2043 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name));
1993 field ^= fields_array.At(2); 2044 field ^= fields_array.At(2);
1994 ASSERT(field.Offset() == TypedDataView::length_offset()); 2045 ASSERT(field.Offset() == TypedDataView::length_offset());
1995 name ^= field.name(); 2046 name ^= field.name();
1996 ASSERT(name.Equals("length")); 2047 ASSERT(name.Equals("length"));
1997 #endif 2048 #endif
1998 } 2049 }
1999 2050
2000 } // namespace dart 2051 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698