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

Unified Diff: runtime/vm/class_finalizer.cc

Issue 8509031: Revert r1380 that is breaking frog. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 9 years, 1 month 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/class_finalizer_test.cc » ('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 1381)
+++ runtime/vm/class_finalizer.cc (working copy)
@@ -18,27 +18,8 @@
"Verify that all classes implement their interface.");
DECLARE_FLAG(bool, enable_type_checks);
-void ClassFinalizer::ExpectClassesToFinalize() {
- if (!IsExpectingClassesToFinalize()) {
- ObjectStore* object_store = Isolate::Current()->object_store();
- object_store->set_pending_classes(Array::Handle(Array::Empty()));
- ASSERT(IsExpectingClassesToFinalize());
- }
-}
-
-
-bool ClassFinalizer::IsExpectingClassesToFinalize() {
- ObjectStore* object_store = Isolate::Current()->object_store();
- const Array& classes = Array::Handle(object_store->pending_classes());
- return !classes.IsNull();
-}
-
-
-void ClassFinalizer::AddClassesToFinalize(
+void ClassFinalizer::AddPendingClasses(
const GrowableArray<const Class*>& classes) {
- // ExpectClassesToFinalize() must be called prior to calling
- // AddClassesToFinalize().
- ASSERT(IsExpectingClassesToFinalize());
if (!classes.is_empty()) {
ObjectStore* object_store = Isolate::Current()->object_store();
const Array& old_array = Array::Handle(object_store->pending_classes());
@@ -50,15 +31,21 @@
new_array.SetAt(i + old_length, *classes[i]);
}
object_store->set_pending_classes(new_array);
- ASSERT(IsExpectingClassesToFinalize());
}
}
+bool ClassFinalizer::AllClassesFinalized() {
+ ObjectStore* object_store = Isolate::Current()->object_store();
+ const Array& classes = Array::Handle(object_store->pending_classes());
+ return classes.Length() == 0;
+}
+
+
// Class finalization occurs:
// a) when bootstrap process completes (VerifyBootstrapClasses).
// b) after the user classes are loaded (dart_api).
-bool ClassFinalizer::FinalizeAllClasses() {
+bool ClassFinalizer::FinalizePendingClasses() {
bool retval = true;
Isolate* isolate = Isolate::Current();
ASSERT(isolate != NULL);
@@ -72,11 +59,10 @@
isolate->set_long_jump_base(&jump);
if (setjmp(*jump.Set()) == 0) {
const Array& class_array = Array::Handle(object_store->pending_classes());
- const intptr_t num_pending_classes =
- class_array.IsNull() ? 0 : class_array.Length();
+ ASSERT(!class_array.IsNull());
Class& cls = Class::Handle();
// First resolve all superclasses.
- for (intptr_t i = 0; i < num_pending_classes; i++) {
+ for (intptr_t i = 0; i < class_array.Length(); i++) {
cls ^= class_array.At(i);
if (FLAG_trace_class_finalization) {
OS::Print("Resolving super and default: %s\n", cls.ToCString());
@@ -87,18 +73,18 @@
}
}
// Finalize all classes.
- for (intptr_t i = 0; i < num_pending_classes; i++) {
+ for (intptr_t i = 0; i < class_array.Length(); i++) {
cls ^= class_array.At(i);
FinalizeClass(cls);
}
if (FLAG_print_classes) {
- for (intptr_t i = 0; i < num_pending_classes; i++) {
+ for (intptr_t i = 0; i < class_array.Length(); i++) {
cls ^= class_array.At(i);
PrintClassInformation(cls);
}
}
if (FLAG_verify_implements) {
- for (intptr_t i = 0; i < num_pending_classes; i++) {
+ for (intptr_t i = 0; i < class_array.Length(); i++) {
cls ^= class_array.At(i);
if (!cls.is_interface()) {
VerifyClassImplements(cls);
@@ -106,8 +92,7 @@
}
}
// Clear pending classes array.
- object_store->set_pending_classes(Array::Handle());
- ASSERT(!IsExpectingClassesToFinalize());
+ object_store->set_pending_classes(Array::Handle(Array::Empty()));
// Check to ensure there are no duplicate definitions in the library
// hierarchy.
@@ -244,7 +229,7 @@
}
// Finalize classes that aren't pre-finalized by Object::Init().
- if (!FinalizeAllClasses()) {
+ if (!FinalizePendingClasses()) {
// TODO(srdjan): Exit like a real VM instead.
const String& err = String::Handle(object_store->sticky_error());
OS::PrintErr("Could not verify bootstrap classes : %s\n", err.ToCString());
@@ -257,39 +242,6 @@
}
-// Resolve unresolved_class in the library of cls.
-RawClass* ClassFinalizer::ResolveClass(
- const Class& cls, const UnresolvedClass& unresolved_class) {
- Library& lib = Library::Handle();
- if (unresolved_class.qualifier() == String::null()) {
- lib = cls.library();
- } else {
- const String& qualifier = String::Handle(unresolved_class.qualifier());
- LibraryPrefix& lib_prefix = LibraryPrefix::Handle();
- lib_prefix = cls.LookupLibraryPrefix(qualifier);
- if (lib_prefix.IsNull()) {
- const Script& script = Script::Handle(cls.script());
- ReportError(script, unresolved_class.token_index(),
- "cannot resolve library prefix '%s' from '%s'.\n",
- String::Handle(unresolved_class.Name()).ToCString(),
- String::Handle(cls.Name()).ToCString());
- }
- lib = lib_prefix.library();
- }
- ASSERT(!lib.IsNull());
- const String& class_name = String::Handle(unresolved_class.ident());
- const Class& resolved_class = Class::Handle(lib.LookupClass(class_name));
- if (resolved_class.IsNull()) {
- const Script& script = Script::Handle(cls.script());
- ReportError(script, unresolved_class.token_index(),
- "cannot resolve class name '%s' from '%s'.\n",
- String::Handle(unresolved_class.Name()).ToCString(),
- String::Handle(cls.Name()).ToCString());
- }
- return resolved_class.raw();
-}
-
-
// Resolve unresolved superclasses (String -> Class).
void ClassFinalizer::ResolveSuperClass(const Class& cls) {
if (cls.is_finalized()) {
@@ -301,13 +253,6 @@
}
// Resolve failures lead to a longjmp.
super_type = ResolveType(cls, super_type);
- if (super_type.IsTypeParameter()) {
- String& class_name = String::Handle(cls.Name());
- String& type_parameter_name = String::Handle(super_type.Name());
- ReportError("'%s' cannot extend or implement type parameter '%s'.\n",
- class_name.ToCString(),
- type_parameter_name.ToCString());
- }
cls.set_super_type(super_type);
const Class& super_class = Class::Handle(super_type.type_class());
if (cls.is_interface() != super_class.is_interface()) {
@@ -409,9 +354,31 @@
}
// Lookup the type class.
- const Class& type_class =
- Class::Handle(ResolveClass(cls, unresolved_class));
-
+ Class& type_class = Class::Handle();
+ Library& lib = Library::Handle();
+ if (unresolved_class.qualifier() == String::null()) {
+ lib = cls.library();
+ } else {
+ const String& qualifier = String::Handle(unresolved_class.qualifier());
+ LibraryPrefix& lib_prefix = LibraryPrefix::Handle();
+ lib_prefix = cls.LookupLibraryPrefix(qualifier);
+ if (lib_prefix.IsNull()) {
+ const Script& script = Script::Handle(cls.script());
+ ReportError(script, unresolved_class.token_index(),
+ "cannot resolve name '%s'\n",
+ String::Handle(unresolved_class.Name()).ToCString());
+ }
+ lib = lib_prefix.library();
+ }
+ ASSERT(!lib.IsNull());
+ type_class = lib.LookupClass(type_class_name);
+ if (type_class.IsNull()) {
+ const Script& script = Script::Handle(cls.script());
+ ReportError(script, unresolved_class.token_index(),
+ "cannot resolve class name '%s' from '%s'\n",
+ String::Handle(unresolved_class.Name()).ToCString(),
+ String::Handle(cls.Name()).ToCString());
+ }
// Replace unresolved class with resolved type class.
ASSERT(type.IsParameterizedType());
ParameterizedType& parameterized_type = ParameterizedType::Handle();
@@ -539,18 +506,10 @@
}
// The type class does not need to be finalized in order to finalize the type,
- // however, it must at least be resolved (this was done as part of resolving
- // the type itself, a precondition to calling FinalizeType) and the upper
- // bounds of its type parameters must be finalized (done here).
+ // however, it must at least be resolved. This was done as part of resolving
+ // the type itself.
Class& type_class = Class::Handle(parameterized_type.type_class());
- // If the type class is a signature class, finalize it, thereby finalizing the
- // result and parameter types of its signature function.
- // Do this before marking this type as finalized in order to detect cycles.
- if (type_class.IsSignatureClass()) {
- FinalizeClass(type_class);
- }
-
// The finalized type argument vector needs num_type_arguments types.
const intptr_t num_type_arguments = type_class.NumTypeArguments();
// The type class has num_type_parameters type parameters.
@@ -586,11 +545,14 @@
FinalizeTypeArguments(type_class, full_arguments);
parameterized_type.set_arguments(full_arguments);
}
- // Mark the type as finalized before finalizing the upper bounds, because
- // cycles via upper bounds are legal at compile time.
- parameterized_type.set_is_finalized();
- ResolveAndFinalizeUpperBounds(type_class);
+ // If the type is a function type, finalize the result and parameter types.
+ if (type_class.IsSignatureClass()) {
+ ResolveAndFinalizeSignature(
+ type_class, Function::Handle(type_class.signature_function()));
+ }
+
+ parameterized_type.set_is_finalized();
return parameterized_type.Canonicalize();
}
@@ -603,15 +565,7 @@
LongJump jump;
isolate->set_long_jump_base(&jump);
if (setjmp(*jump.Set()) == 0) {
- Type& canonical_type = Type::Handle();
- if (type.IsSignatureType() && !AllClassesFinalized()) {
- // Postpone the finalization of this signature type and class.
- GrowableArray<const Class*> classes;
- classes.Add(&Class::ZoneHandle(type.type_class()));
- ClassFinalizer::AddClassesToFinalize(classes);
- } else {
- canonical_type = FinalizeType(type);
- }
+ const Type& canonical_type = Type::Handle(FinalizeType(type));
isolate->set_long_jump_base(base);
*errmsg = String::null();
return canonical_type.raw();
@@ -626,6 +580,11 @@
}
+// Top level function signatures are canonicalized, added to the library class
+// dictionary, and finalized with other library classes and interfaces.
+// Function signatures used as type of a local variable or of a local function
+// are canonicalized and finalized upon creation, since all the types they
+// reference are already resolved.
void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls,
const Function& function) {
// Resolve result type.
@@ -685,23 +644,6 @@
}
-void ClassFinalizer::ResolveAndFinalizeUpperBounds(const Class& cls) {
- const intptr_t num_type_params = cls.NumTypeParameters();
- Type& type_extends = Type::Handle();
- const TypeArguments& extends_array =
- TypeArguments::Handle(cls.type_parameter_extends());
- ASSERT((extends_array.IsNull() && (num_type_params == 0)) ||
- (extends_array.Length() == num_type_params));
- for (intptr_t i = 0; i < num_type_params; i++) {
- type_extends = extends_array.TypeAt(i);
- type_extends = ResolveType(cls, type_extends);
- extends_array.SetTypeAt(i, type_extends);
- type_extends = FinalizeType(type_extends);
- extends_array.SetTypeAt(i, type_extends);
- }
-}
-
-
void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) {
// Note that getters and setters are explicitly listed as such in the list of
// functions of a class, so we do not need to consider fields as implicitly
@@ -835,6 +777,13 @@
}
}
}
+ // Resolve the signature type if this class is a signature class.
+ if (cls.IsSignatureClass()) {
+ Type& signature_type = Type::Handle(cls.SignatureType());
+ signature_type = FinalizeType(signature_type);
+ // Signature types are canonicalized by default.
+ ASSERT(signature_type.raw() == cls.SignatureType());
+ }
}
@@ -884,25 +833,9 @@
interface_type = FinalizeType(interface_type);
interface_types.SetAt(i, interface_type);
}
- // Mark as finalized before resolving type parameter upper bounds and member
- // types in order to break cycles.
+ // Mark as finalized before resolving member types in order to break cycles.
cls.Finalize();
- ResolveAndFinalizeUpperBounds(cls);
ResolveAndFinalizeMemberTypes(cls);
-
- if (cls.IsSignatureClass()) {
- // Finalize the signature type of this signature class.
- Type& signature_type = Type::Handle(cls.SignatureType());
- signature_type = FinalizeType(signature_type);
- // Signature types are canonicalized by default.
- ASSERT(signature_type.raw() == cls.SignatureType());
-
- // Resolve and finalize the result and parameter types of the signature
- // function of this signature class.
- ResolveAndFinalizeSignature(cls,
- Function::Handle(cls.signature_function()));
- }
-
// Run additional checks after all types are finalized.
if (cls.is_const()) {
CheckForLegalConstClass(cls);
@@ -1031,6 +964,8 @@
String::Handle(cls.Name()).ToCString(),
String::Handle(interface_class.Name()).ToCString());
}
+ // TODO(regis): We also need to prevent extending classes Smi, Mint,
+ // BigInt, Double, OneByteString, TwoByteString, FourByteString.
}
// Now resolve the super interfaces.
ResolveInterfaces(interface_class, visited);
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/class_finalizer_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698