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

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

Issue 2609393005: Always finalize the super class of a class before cloning the super class (Closed)
Patch Set: Created 3 years, 11 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
« no previous file with comments | « no previous file | no next file » | 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/code_generator.h" 7 #include "vm/code_generator.h"
8 #include "vm/flags.h" 8 #include "vm/flags.h"
9 #include "vm/heap.h" 9 #include "vm/heap.h"
10 #include "vm/isolate.h" 10 #include "vm/isolate.h"
(...skipping 1480 matching lines...) Expand 10 before | Expand all | Expand 10 after
1491 /* is_native = */ false, cls, field.token_pos())); 1491 /* is_native = */ false, cls, field.token_pos()));
1492 getter.set_result_type(type); 1492 getter.set_result_type(type);
1493 getter.set_is_debuggable(false); 1493 getter.set_is_debuggable(false);
1494 getter.set_kernel_function(field.kernel_field()); 1494 getter.set_kernel_function(field.kernel_field());
1495 cls.AddFunction(getter); 1495 cls.AddFunction(getter);
1496 field.SetStaticValue(Object::sentinel(), true); 1496 field.SetStaticValue(Object::sentinel(), true);
1497 } 1497 }
1498 } 1498 }
1499 } 1499 }
1500 } 1500 }
1501 // Collect interfaces, super interfaces, and super classes of this class. 1501 // If we check for bad overrides, collect interfaces, super interfaces, and
1502 // super classes of this class.
1502 GrowableArray<const Class*> interfaces(zone, 4); 1503 GrowableArray<const Class*> interfaces(zone, 4);
1503 CollectInterfaces(cls, &interfaces); 1504 if (Isolate::Current()->error_on_bad_override()) {
1504 // Include superclasses in list of interfaces and super interfaces. 1505 CollectInterfaces(cls, &interfaces);
1505 super_class = cls.SuperClass(); 1506 // Include superclasses in list of interfaces and super interfaces.
1506 while (!super_class.IsNull()) { 1507 super_class = cls.SuperClass();
1507 interfaces.Add(&Class::ZoneHandle(zone, super_class.raw())); 1508 while (!super_class.IsNull()) {
1508 CollectInterfaces(super_class, &interfaces); 1509 interfaces.Add(&Class::ZoneHandle(zone, super_class.raw()));
1509 super_class = super_class.SuperClass(); 1510 CollectInterfaces(super_class, &interfaces);
1511 super_class = super_class.SuperClass();
1512 }
1510 } 1513 }
1511 // Resolve function signatures and check for conflicts in super classes and 1514 // Resolve function signatures and check for conflicts in super classes and
1512 // interfaces. 1515 // interfaces.
1513 array = cls.functions(); 1516 array = cls.functions();
1514 Function& function = Function::Handle(zone); 1517 Function& function = Function::Handle(zone);
1515 Function& overridden_function = Function::Handle(zone); 1518 Function& overridden_function = Function::Handle(zone);
1516 const intptr_t num_functions = array.Length(); 1519 const intptr_t num_functions = array.Length();
1517 Error& error = Error::Handle(zone); 1520 Error& error = Error::Handle(zone);
1518 for (intptr_t i = 0; i < num_functions; i++) { 1521 for (intptr_t i = 0; i < num_functions; i++) {
1519 function ^= array.At(i); 1522 function ^= array.At(i);
1520 FinalizeSignature(cls, function); 1523 FinalizeSignature(cls, function);
1521 name = function.name(); 1524 name = function.name();
1522 // Report signature conflicts only. 1525 // Report signature conflicts only.
1523 if (Isolate::Current()->error_on_bad_override() && !function.is_static() && 1526 if (Isolate::Current()->error_on_bad_override() && !function.is_static() &&
1524 !function.IsGenerativeConstructor()) { 1527 !function.IsGenerativeConstructor()) {
1525 // A constructor cannot override anything. 1528 // A constructor cannot override anything.
1526 for (intptr_t i = 0; i < interfaces.length(); i++) { 1529 for (intptr_t i = 0; i < interfaces.length(); i++) {
1527 const Class* super_class = interfaces.At(i); 1530 const Class* interface = interfaces.At(i);
1528 // Finalize superclass since overrides check relies on all members 1531 // All interfaces should have been finalized since override checks
1529 // of the superclass to be finalized. 1532 // rely on all interface members to be finalized.
1530 FinalizeClass(*super_class); 1533 ASSERT(interface->is_finalized());
1531 overridden_function = super_class->LookupDynamicFunction(name); 1534 overridden_function = interface->LookupDynamicFunction(name);
1532 if (!overridden_function.IsNull() && 1535 if (!overridden_function.IsNull() &&
1533 !function.HasCompatibleParametersWith(overridden_function, 1536 !function.HasCompatibleParametersWith(overridden_function,
1534 &error)) { 1537 &error)) {
1535 const String& class_name = String::Handle(zone, cls.Name()); 1538 const String& class_name = String::Handle(zone, cls.Name());
1536 const String& super_cls_name = 1539 const String& interface_name =
1537 String::Handle(zone, super_class->Name()); 1540 String::Handle(zone, interface->Name());
1538 ReportErrors(error, cls, function.token_pos(), 1541 ReportErrors(error, cls, function.token_pos(),
1539 "class '%s' overrides method '%s' of super " 1542 "class '%s' overrides method '%s' of super class or "
1540 "class '%s' with incompatible parameters", 1543 "interface '%s' with incompatible parameters",
1541 class_name.ToCString(), name.ToCString(), 1544 class_name.ToCString(), name.ToCString(),
1542 super_cls_name.ToCString()); 1545 interface_name.ToCString());
1543 } 1546 }
1544 } 1547 }
1545 } 1548 }
1546 if (function.IsSetterFunction() || function.IsImplicitSetterFunction()) { 1549 if (function.IsSetterFunction() || function.IsImplicitSetterFunction()) {
1547 if (function.is_static()) { 1550 if (function.is_static()) {
1548 super_class = FindSuperOwnerOfFunction(cls, name); 1551 super_class = FindSuperOwnerOfFunction(cls, name);
1549 if (!super_class.IsNull()) { 1552 if (!super_class.IsNull()) {
1550 const String& class_name = String::Handle(zone, cls.Name()); 1553 const String& class_name = String::Handle(zone, cls.Name());
1551 const String& super_cls_name = 1554 const String& super_cls_name =
1552 String::Handle(zone, super_class.Name()); 1555 String::Handle(zone, super_class.Name());
(...skipping 919 matching lines...) Expand 10 before | Expand all | Expand 10 after
2472 THR_Print("Finalize %s\n", cls.ToCString()); 2475 THR_Print("Finalize %s\n", cls.ToCString());
2473 } 2476 }
2474 if (cls.is_patch()) { 2477 if (cls.is_patch()) {
2475 // The fields and functions of a patch class are copied to the 2478 // The fields and functions of a patch class are copied to the
2476 // patched class after parsing. There is nothing to finalize. 2479 // patched class after parsing. There is nothing to finalize.
2477 ASSERT(Array::Handle(cls.functions()).Length() == 0); 2480 ASSERT(Array::Handle(cls.functions()).Length() == 0);
2478 ASSERT(Array::Handle(cls.fields()).Length() == 0); 2481 ASSERT(Array::Handle(cls.fields()).Length() == 0);
2479 cls.set_is_finalized(); 2482 cls.set_is_finalized();
2480 return; 2483 return;
2481 } 2484 }
2485 // Ensure super class is finalized.
2486 const Class& super = Class::Handle(cls.SuperClass());
2487 if (!super.IsNull()) {
2488 FinalizeClass(super);
2489 }
2490 // Ensure interfaces are finalized in case we check for bad overrides.
2491 if (Isolate::Current()->error_on_bad_override()) {
2492 GrowableArray<const Class*> interfaces(4);
2493 CollectInterfaces(cls, &interfaces);
2494 for (intptr_t i = 0; i < interfaces.length(); i++) {
2495 FinalizeClass(*interfaces.At(i));
2496 }
2497 }
2482 if (cls.IsMixinApplication()) { 2498 if (cls.IsMixinApplication()) {
2483 // Copy instance methods and fields from the mixin class. 2499 // Copy instance methods and fields from the mixin class.
2484 // This has to happen before the check whether the methods of 2500 // This has to happen before the check whether the methods of
2485 // the class conflict with inherited methods. 2501 // the class conflict with inherited methods.
2486 ApplyMixinMembers(cls); 2502 ApplyMixinMembers(cls);
2487 } 2503 }
2488 // Ensure super class is finalized.
2489 const Class& super = Class::Handle(cls.SuperClass());
2490 if (!super.IsNull()) {
2491 FinalizeClass(super);
2492 }
2493 // Mark as parsed and finalized. 2504 // Mark as parsed and finalized.
2494 cls.Finalize(); 2505 cls.Finalize();
2495 // Mixin app alias classes may still lack their forwarding constructor. 2506 // Mixin app alias classes may still lack their forwarding constructor.
2496 if (cls.is_mixin_app_alias() && 2507 if (cls.is_mixin_app_alias() &&
2497 (cls.functions() == Object::empty_array().raw())) { 2508 (cls.functions() == Object::empty_array().raw())) {
2498 const GrowableObjectArray& cloned_funcs = 2509 const GrowableObjectArray& cloned_funcs =
2499 GrowableObjectArray::Handle(GrowableObjectArray::New()); 2510 GrowableObjectArray::Handle(GrowableObjectArray::New());
2500 2511
2501 const Class& mixin_app_class = Class::Handle(cls.SuperClass()); 2512 const Class& mixin_app_class = Class::Handle(cls.SuperClass());
2502 const Type& mixin_type = Type::Handle(mixin_app_class.mixin()); 2513 const Type& mixin_type = Type::Handle(mixin_app_class.mixin());
(...skipping 876 matching lines...) Expand 10 before | Expand all | Expand 10 after
3379 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); 3390 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields());
3380 field ^= fields_array.At(0); 3391 field ^= fields_array.At(0);
3381 ASSERT(field.Offset() == ByteBuffer::data_offset()); 3392 ASSERT(field.Offset() == ByteBuffer::data_offset());
3382 name ^= field.name(); 3393 name ^= field.name();
3383 expected_name ^= String::New("_data"); 3394 expected_name ^= String::New("_data");
3384 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); 3395 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name));
3385 #endif 3396 #endif
3386 } 3397 }
3387 3398
3388 } // namespace dart 3399 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698