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

Unified Diff: runtime/vm/class_finalizer.cc

Issue 11613007: Include super type in interface list for cycle detection (issue 4318). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/parser.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/class_finalizer.cc
===================================================================
--- runtime/vm/class_finalizer.cc (revision 16235)
+++ runtime/vm/class_finalizer.cc (working copy)
@@ -138,9 +138,8 @@
if (FLAG_trace_class_finalization) {
OS::Print("Resolving super and interfaces: %s\n", cls.ToCString());
}
- ResolveSuperType(cls);
GrowableArray<intptr_t> visited_interfaces;
- ResolveInterfaces(cls, &visited_interfaces);
+ ResolveInterfaces(cls, &visited_interfaces); // Including super type.
}
// Finalize all classes.
for (intptr_t i = 0; i < class_array.Length(); i++) {
@@ -309,88 +308,6 @@
}
-// Resolve unresolved supertype (String -> Class).
-void ClassFinalizer::ResolveSuperType(const Class& cls) {
- if (cls.is_finalized()) {
- return;
- }
- Type& super_type = Type::Handle(cls.super_type());
- if (super_type.IsNull()) {
- return;
- }
- // Resolve failures lead to a longjmp.
- ResolveType(cls, super_type, kCanonicalizeWellFormed);
- const Class& super_class = Class::Handle(super_type.type_class());
- // If cls belongs to core lib or to core lib's implementation, restrictions
- // about allowed interfaces are lifted.
- if (cls.library() != Library::CoreLibrary()) {
- // Prevent extending core implementation classes.
- bool is_error = false;
- switch (super_class.id()) {
- case kNumberCid:
- case kIntegerCid:
- case kSmiCid:
- case kMintCid:
- case kBigintCid:
- case kDoubleCid:
- case kOneByteStringCid:
- case kTwoByteStringCid:
- case kExternalOneByteStringCid:
- case kExternalTwoByteStringCid:
- case kBoolCid:
- case kArrayCid:
- case kImmutableArrayCid:
- case kGrowableObjectArrayCid:
- case kInt8ArrayCid:
- case kExternalInt8ArrayCid:
- case kUint8ArrayCid:
- case kUint8ClampedArrayCid:
- case kExternalUint8ArrayCid:
- case kExternalUint8ClampedArrayCid:
- case kInt16ArrayCid:
- case kExternalInt16ArrayCid:
- case kUint16ArrayCid:
- case kExternalUint16ArrayCid:
- case kInt32ArrayCid:
- case kExternalInt32ArrayCid:
- case kUint32ArrayCid:
- case kExternalUint32ArrayCid:
- case kInt64ArrayCid:
- case kExternalInt64ArrayCid:
- case kUint64ArrayCid:
- case kExternalUint64ArrayCid:
- case kFloat32ArrayCid:
- case kExternalFloat32ArrayCid:
- case kFloat64ArrayCid:
- case kExternalFloat64ArrayCid:
- case kDartFunctionCid:
- case kWeakPropertyCid:
- is_error = true;
- break;
- default: {
- // Special case: classes for which we don't have a known class id.
- // TODO(regis): Why isn't comparing to kIntegerCid enough?
- if (Type::Handle(Type::Double()).type_class() == super_class.raw() ||
- Type::Handle(Type::IntType()).type_class() == super_class.raw() ||
- Type::Handle(
- Type::StringType()).type_class() == super_class.raw()) {
- is_error = true;
- }
- break;
- }
- }
- if (is_error) {
- const Script& script = Script::Handle(cls.script());
- ReportError(script, cls.token_pos(),
- "'%s' is not allowed to extend '%s'",
- String::Handle(cls.Name()).ToCString(),
- String::Handle(super_class.Name()).ToCString());
- }
- }
- return;
-}
-
-
void ClassFinalizer::ResolveRedirectingFactoryTarget(
const Class& cls,
const Function& factory,
@@ -1326,9 +1243,9 @@
}
-// Walks the graph of explicitly declared interfaces of classes and
-// interfaces recursively. Resolves unresolved interfaces.
-// Returns false if there is an interface reference that cannot be
+// Recursively walks the graph of explicitly declared super type and
+// interfaces, resolving unresolved super types and interfaces.
+// Reports an error if there is an interface reference that cannot be
// resolved, or if there is a cycle in the graph. We detect cycles by
// remembering interfaces we've visited in each path through the
// graph. If we visit an interface a second time on a given path,
@@ -1339,18 +1256,20 @@
const intptr_t cls_index = cls.id();
for (int i = 0; i < visited->length(); i++) {
if ((*visited)[i] == cls_index) {
- // We have already visited interface class 'cls'. We found a cycle.
- const String& interface_name = String::Handle(cls.Name());
+ // We have already visited class 'cls'. We found a cycle.
+ const String& class_name = String::Handle(cls.Name());
const Script& script = Script::Handle(cls.script());
ReportError(script, cls.token_pos(),
- "cyclic reference found for interface '%s'",
- interface_name.ToCString());
+ "cyclic reference found for class '%s'",
+ class_name.ToCString());
}
}
- // If the class/interface has no explicit interfaces, we are done.
+ // If the class/interface has no explicit super class/interfaces, we are done.
+ Type& super_type = Type::Handle(cls.super_type());
Array& super_interfaces = Array::Handle(cls.interfaces());
- if (super_interfaces.Length() == 0) {
+ if ((super_type.IsNull() || super_type.IsObjectType()) &&
+ (super_interfaces.Length() == 0)) {
return;
}
@@ -1358,10 +1277,84 @@
// about allowed interfaces are lifted.
const bool cls_belongs_to_core_lib = cls.library() == Library::CoreLibrary();
- // Resolve and check the interfaces of cls.
+ // Resolve and check the super type and interfaces of cls.
visited->Add(cls_index);
AbstractType& interface = AbstractType::Handle();
Class& interface_class = Class::Handle();
+
+ // Resolve super type. Failures lead to a longjmp.
+ ResolveType(cls, super_type, kCanonicalizeWellFormed);
+
+ // If cls belongs to core lib or to core lib's implementation, restrictions
+ interface_class = super_type.type_class();
+ // If cls belongs to core lib or to core lib's implementation, restrictions
+ // about allowed interfaces are lifted.
+ if (!cls_belongs_to_core_lib) {
+ // Prevent extending core implementation classes.
+ bool is_error = false;
+ switch (interface_class.id()) {
+ case kNumberCid:
+ case kIntegerCid: // Class Integer, not int.
+ case kSmiCid:
+ case kMintCid:
+ case kBigintCid:
+ case kDoubleCid: // Class Double, not double.
+ case kOneByteStringCid:
+ case kTwoByteStringCid:
+ case kExternalOneByteStringCid:
+ case kExternalTwoByteStringCid:
+ case kBoolCid:
+ case kArrayCid:
+ case kImmutableArrayCid:
+ case kGrowableObjectArrayCid:
+ case kInt8ArrayCid:
+ case kExternalInt8ArrayCid:
+ case kUint8ArrayCid:
+ case kUint8ClampedArrayCid:
+ case kExternalUint8ArrayCid:
+ case kExternalUint8ClampedArrayCid:
+ case kInt16ArrayCid:
+ case kExternalInt16ArrayCid:
+ case kUint16ArrayCid:
+ case kExternalUint16ArrayCid:
+ case kInt32ArrayCid:
+ case kExternalInt32ArrayCid:
+ case kUint32ArrayCid:
+ case kExternalUint32ArrayCid:
+ case kInt64ArrayCid:
+ case kExternalInt64ArrayCid:
+ case kUint64ArrayCid:
+ case kExternalUint64ArrayCid:
+ case kFloat32ArrayCid:
+ case kExternalFloat32ArrayCid:
+ case kFloat64ArrayCid:
+ case kExternalFloat64ArrayCid:
+ case kDartFunctionCid:
+ case kWeakPropertyCid:
+ is_error = true;
+ break;
+ default: {
+ // Special case: classes for which we don't have a known class id.
+ if (super_type.IsDoubleType() ||
+ super_type.IsIntType() ||
+ super_type.IsStringType()) {
+ is_error = true;
+ }
+ break;
+ }
+ }
+ if (is_error) {
+ const Script& script = Script::Handle(cls.script());
+ ReportError(script, cls.token_pos(),
+ "'%s' is not allowed to extend '%s'",
+ String::Handle(cls.Name()).ToCString(),
+ String::Handle(interface_class.Name()).ToCString());
+ }
+ }
+ // Now resolve the super interfaces of the super type.
+ ResolveInterfaces(interface_class, visited);
+
+ // Resolve interfaces. Failures lead to a longjmp.
for (intptr_t i = 0; i < super_interfaces.Length(); i++) {
interface ^= super_interfaces.At(i);
ResolveType(cls, interface, kCanonicalizeWellFormed);
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/parser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698