mirror of
https://github.com/dart-lang/sdk
synced 2024-09-19 14:51:30 +00:00
Revert r1380 that is breaking frog.
Review URL: http://codereview.chromium.org//8509031 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@1382 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
parent
1e203b2dc9
commit
a6282231eb
|
@ -148,7 +148,7 @@ static void RunIsolate(uword parameter) {
|
|||
if (setjmp(*jump.Set()) == 0) {
|
||||
Zone zone;
|
||||
HandleScope handle_scope;
|
||||
ASSERT(ClassFinalizer::AllClassesFinalized());
|
||||
ASSERT(ClassFinalizer::FinalizePendingClasses());
|
||||
// Lookup the target class by name, create an instance and call the run
|
||||
// method.
|
||||
const String& lib_name = String::Handle(String::NewSymbol(library_url));
|
||||
|
@ -223,7 +223,7 @@ static bool CheckArguments(const char* library_url, const char* class_name) {
|
|||
Zone zone;
|
||||
HandleScope handle_scope;
|
||||
String& name = String::Handle();
|
||||
if (!ClassFinalizer::FinalizeAllClasses()) {
|
||||
if (!ClassFinalizer::FinalizePendingClasses()) {
|
||||
return false;
|
||||
}
|
||||
// Lookup the target class by name, create an instance and call the run
|
||||
|
|
|
@ -18,27 +18,8 @@ DEFINE_FLAG(bool, verify_implements, false,
|
|||
"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 @@ void ClassFinalizer::AddClassesToFinalize(
|
|||
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 @@ bool ClassFinalizer::FinalizeAllClasses() {
|
|||
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 @@ bool ClassFinalizer::FinalizeAllClasses() {
|
|||
}
|
||||
}
|
||||
// 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 @@ bool ClassFinalizer::FinalizeAllClasses() {
|
|||
}
|
||||
}
|
||||
// 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 @@ void ClassFinalizer::VerifyBootstrapClasses() {
|
|||
}
|
||||
|
||||
// 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 @@ void ClassFinalizer::VerifyBootstrapClasses() {
|
|||
}
|
||||
|
||||
|
||||
// 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 @@ void ClassFinalizer::ResolveSuperClass(const Class& cls) {
|
|||
}
|
||||
// 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 @@ RawType* ClassFinalizer::ResolveType(const Class& cls, const Type& type) {
|
|||
}
|
||||
|
||||
// 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 @@ RawType* ClassFinalizer::FinalizeType(const Type& type) {
|
|||
}
|
||||
|
||||
// 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 @@ RawType* ClassFinalizer::FinalizeType(const Type& type) {
|
|||
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 @@ RawType* ClassFinalizer::FinalizeAndCanonicalizeType(const Type& type,
|
|||
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 @@ RawType* ClassFinalizer::FinalizeAndCanonicalizeType(const Type& type,
|
|||
}
|
||||
|
||||
|
||||
// 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 @@ static RawClass* FindSuperOwnerOfFunction(const Class& cls,
|
|||
}
|
||||
|
||||
|
||||
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 @@ void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) {
|
|||
}
|
||||
}
|
||||
}
|
||||
// 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 @@ void ClassFinalizer::FinalizeClass(const Class& cls) {
|
|||
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 @@ void ClassFinalizer::ResolveInterfaces(const Class& cls,
|
|||
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);
|
||||
|
|
|
@ -12,13 +12,11 @@ namespace dart {
|
|||
|
||||
class Class;
|
||||
class Function;
|
||||
class RawClass;
|
||||
class RawType;
|
||||
class Script;
|
||||
class String;
|
||||
class Type;
|
||||
class TypeArguments;
|
||||
class UnresolvedClass;
|
||||
|
||||
// Traverses all pending, unfinalized classes, validates and marks them as
|
||||
// finalized.
|
||||
|
@ -38,26 +36,17 @@ class ClassFinalizer : public AllStatic {
|
|||
// Set the error message on failure (to String::null() if no error).
|
||||
static RawType* FinalizeAndCanonicalizeType(const Type& type, String* errmsg);
|
||||
|
||||
// Notify finalizer to expect classes to be finalized.
|
||||
static void ExpectClassesToFinalize();
|
||||
// Pending classes are classes that need to be finalized.
|
||||
static void AddPendingClasses(const GrowableArray<const Class*>& classes);
|
||||
|
||||
// Return true after a call to ExpectClassesToFinalize() and before a call to
|
||||
// FinalizeAllClasses().
|
||||
static bool IsExpectingClassesToFinalize();
|
||||
|
||||
// Add given classes to the list of pending classes to be finalized.
|
||||
// ExpectClassesToFinalize() must be called prior to AddClassesToFinalize().
|
||||
static void AddClassesToFinalize(const GrowableArray<const Class*>& classes);
|
||||
|
||||
// Return false if we still have classes pending to be finalized or expecting
|
||||
// more classes to be finalized.
|
||||
static bool AllClassesFinalized() { return !IsExpectingClassesToFinalize(); }
|
||||
// Return false if we still have classes pending to be finalized.
|
||||
static bool AllClassesFinalized();
|
||||
|
||||
// Return whether class finalization failed.
|
||||
// The function returns true if the finalization was successful.
|
||||
// If finalization fails, an error message is set in the sticky error field
|
||||
// in the object store.
|
||||
static bool FinalizeAllClasses();
|
||||
static bool FinalizePendingClasses();
|
||||
|
||||
// Verify that the pending classes have been properly prefinalized. This is
|
||||
// needed during bootstrapping where the classes have been preloaded.
|
||||
|
@ -67,8 +56,6 @@ class ClassFinalizer : public AllStatic {
|
|||
static void FinalizeClass(const Class& cls);
|
||||
static bool IsSuperCycleFree(const Class& cls);
|
||||
static void CheckForLegalConstClass(const Class& cls);
|
||||
static RawClass* ResolveClass(const Class& cls,
|
||||
const UnresolvedClass& unresolved_class);
|
||||
static void ResolveSuperClass(const Class& cls);
|
||||
static void ResolveDefaultClass(const Class& cls);
|
||||
static void ResolveInterfaces(const Class& cls,
|
||||
|
@ -77,7 +64,6 @@ class ClassFinalizer : public AllStatic {
|
|||
const TypeArguments& arguments);
|
||||
static RawType* ResolveType(const Class& cls, const Type& type);
|
||||
static RawType* FinalizeType(const Type& type);
|
||||
static void ResolveAndFinalizeUpperBounds(const Class& cls);
|
||||
static void ResolveAndFinalizeSignature(const Class& cls,
|
||||
const Function& function);
|
||||
static void ResolveAndFinalizeMemberTypes(const Class& cls);
|
||||
|
|
|
@ -22,29 +22,27 @@ static RawClass* CreateTestClass(const char* name) {
|
|||
|
||||
|
||||
TEST_CASE(ClassFinalizer) {
|
||||
ClassFinalizer::ExpectClassesToFinalize();
|
||||
GrowableArray<const Class*> classes_1;
|
||||
classes_1.Add(&Class::ZoneHandle(CreateTestClass("BMW")));
|
||||
classes_1.Add(&Class::ZoneHandle(CreateTestClass("Porsche")));
|
||||
ClassFinalizer::AddClassesToFinalize(classes_1);
|
||||
ClassFinalizer::AddPendingClasses(classes_1);
|
||||
GrowableArray<const Class*> classes_2;
|
||||
classes_2.Add(&Class::ZoneHandle(CreateTestClass("Ferrari")));
|
||||
classes_2.Add(&Class::ZoneHandle(CreateTestClass("Fiat")));
|
||||
classes_2.Add(&Class::ZoneHandle(CreateTestClass("Alfa")));
|
||||
ClassFinalizer::AddClassesToFinalize(classes_2);
|
||||
EXPECT(ClassFinalizer::FinalizeAllClasses());
|
||||
ClassFinalizer::AddPendingClasses(classes_2);
|
||||
EXPECT(ClassFinalizer::FinalizePendingClasses());
|
||||
for (int i = 0; i < classes_1.length(); i++) {
|
||||
EXPECT(classes_1[i]->is_finalized());
|
||||
}
|
||||
for (int i = 0; i < classes_2.length(); i++) {
|
||||
EXPECT(classes_2[i]->is_finalized());
|
||||
}
|
||||
EXPECT(ClassFinalizer::FinalizeAllClasses());
|
||||
EXPECT(ClassFinalizer::FinalizePendingClasses());
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE(ClassFinalize_Cycles) {
|
||||
ClassFinalizer::ExpectClassesToFinalize();
|
||||
GrowableArray<const Class*> classes;
|
||||
classes.Add(&Class::ZoneHandle(CreateTestClass("Jungfrau")));
|
||||
classes.Add(&Class::ZoneHandle(CreateTestClass("Eiger")));
|
||||
|
@ -53,8 +51,8 @@ TEST_CASE(ClassFinalize_Cycles) {
|
|||
Type::Handle(Type::NewNonParameterizedType(*classes[1])));
|
||||
classes[1]->set_super_type(
|
||||
Type::Handle(Type::NewNonParameterizedType(*classes[0])));
|
||||
ClassFinalizer::AddClassesToFinalize(classes);
|
||||
EXPECT(!ClassFinalizer::FinalizeAllClasses());
|
||||
ClassFinalizer::AddPendingClasses(classes);
|
||||
EXPECT(!ClassFinalizer::FinalizePendingClasses());
|
||||
}
|
||||
|
||||
|
||||
|
@ -65,7 +63,6 @@ static RawLibrary* NewLib(const char* url_chars) {
|
|||
|
||||
|
||||
TEST_CASE(ClassFinalize_Resolve) {
|
||||
ClassFinalizer::ExpectClassesToFinalize();
|
||||
GrowableArray<const Class*> classes;
|
||||
Class& rhb = Class::ZoneHandle(CreateTestClass("RhB"));
|
||||
Class& sbb = Class::ZoneHandle(CreateTestClass("SBB"));
|
||||
|
@ -80,8 +77,8 @@ TEST_CASE(ClassFinalize_Resolve) {
|
|||
TypeArguments& type_arguments = TypeArguments::Handle();
|
||||
rhb.set_super_type(Type::Handle(Type::NewParameterizedType(
|
||||
Object::Handle(unresolved.raw()), type_arguments)));
|
||||
ClassFinalizer::AddClassesToFinalize(classes);
|
||||
EXPECT(ClassFinalizer::FinalizeAllClasses());
|
||||
ClassFinalizer::AddPendingClasses(classes);
|
||||
EXPECT(ClassFinalizer::FinalizePendingClasses());
|
||||
}
|
||||
|
||||
} // namespace dart
|
||||
|
|
|
@ -1389,10 +1389,11 @@ void CodeGenerator::GenerateInstanceOf(intptr_t node_id,
|
|||
const Bool& bool_true = Bool::ZoneHandle(Bool::True());
|
||||
const Bool& bool_false = Bool::ZoneHandle(Bool::False());
|
||||
|
||||
// All instances are of a subtype of the Object type.
|
||||
// All instances are of type Object.
|
||||
const Type& object_type =
|
||||
Type::Handle(Isolate::Current()->object_store()->object_type());
|
||||
if (type.IsInstantiated() && object_type.IsSubtypeOf(type)) {
|
||||
// All objects are an instance of the Object class.
|
||||
__ PushObject(negate_result ? bool_false : bool_true);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -331,7 +331,7 @@ CODEGEN_TEST_GENERATE(InstanceCallCodegen, test) {
|
|||
Script& script = Script::Handle(Script::New(url, source, RawScript::kSource));
|
||||
Library& lib = MakeTestLibrary("TestLib");
|
||||
EXPECT(CompilerTest::TestCompileScript(lib, script));
|
||||
EXPECT(ClassFinalizer::FinalizeAllClasses());
|
||||
EXPECT(ClassFinalizer::FinalizePendingClasses());
|
||||
Class& cls = Class::ZoneHandle(LookupClass(lib, "A"));
|
||||
EXPECT(!cls.IsNull());
|
||||
|
||||
|
@ -467,7 +467,7 @@ CODEGEN_TEST_GENERATE(AllocateNewObjectCodegen, test) {
|
|||
Script& script = Script::Handle(Script::New(url, source, RawScript::kSource));
|
||||
Library& lib = MakeTestLibrary("TestLib");
|
||||
EXPECT(CompilerTest::TestCompileScript(lib, script));
|
||||
EXPECT(ClassFinalizer::FinalizeAllClasses());
|
||||
EXPECT(ClassFinalizer::FinalizePendingClasses());
|
||||
Class& cls = Class::ZoneHandle(LookupClass(lib, "A"));
|
||||
EXPECT(!cls.IsNull());
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ TEST_CASE(CodeIndexTable) {
|
|||
EXPECT(CompilerTest::TestCompileScript(lib, script));
|
||||
clsA = lib.LookupClass(String::Handle(String::NewSymbol("A")));
|
||||
EXPECT(!clsA.IsNull());
|
||||
ClassFinalizer::FinalizeAllClasses();
|
||||
ClassFinalizer::FinalizePendingClasses();
|
||||
for (int i = 0; i < kNumFunctions; i++) {
|
||||
OS::SNPrint(buffer, 256, "foo%d", i);
|
||||
function_name = String::New(buffer);
|
||||
|
@ -103,7 +103,7 @@ TEST_CASE(CodeIndexTable) {
|
|||
EXPECT(CompilerTest::TestCompileScript(lib, script));
|
||||
clsB = lib.LookupClass(String::Handle(String::NewSymbol("B")));
|
||||
EXPECT(!clsB.IsNull());
|
||||
ClassFinalizer::FinalizeAllClasses();
|
||||
ClassFinalizer::FinalizePendingClasses();
|
||||
for (int i = 0; i < kNumFunctions; i++) {
|
||||
OS::SNPrint(buffer, 256, "moo%d", i);
|
||||
function_name = String::New(buffer);
|
||||
|
|
|
@ -313,7 +313,7 @@ static void CompileAll(Dart_Handle* result) {
|
|||
// Return error if isolate is in an inconsistent state.
|
||||
// Return NULL when no error condition exists.
|
||||
static const char* CheckIsolateState() {
|
||||
if (!ClassFinalizer::FinalizeAllClasses()) {
|
||||
if (!ClassFinalizer::FinalizePendingClasses()) {
|
||||
// Make a copy of the error message as the original message string
|
||||
// may get deallocated when we return back from the Dart API call.
|
||||
const String& err =
|
||||
|
|
|
@ -239,7 +239,6 @@ void Object::InitOnce() {
|
|||
|
||||
// Allocate and initialize the null class.
|
||||
cls = Class::New<Instance>();
|
||||
cls.set_is_finalized();
|
||||
null_class_ = cls.raw();
|
||||
|
||||
// Complete initialization of null_ instance, i.e. initialize its class_
|
||||
|
@ -265,7 +264,6 @@ void Object::InitOnce() {
|
|||
// see GetSingletonClassIndex) and its array fields cannot be set to the empty
|
||||
// array, but remain null.
|
||||
cls = Class::New<Instance>();
|
||||
cls.set_is_finalized();
|
||||
cls.set_is_interface();
|
||||
dynamic_class_ = cls.raw();
|
||||
|
||||
|
@ -274,7 +272,6 @@ void Object::InitOnce() {
|
|||
unresolved_class_class_ = cls.raw();
|
||||
|
||||
cls = Class::New<Instance>();
|
||||
cls.set_is_finalized();
|
||||
void_class_ = cls.raw();
|
||||
|
||||
cls = Class::New<ParameterizedType>();
|
||||
|
@ -338,33 +335,13 @@ void Object::InitOnce() {
|
|||
}
|
||||
|
||||
|
||||
RawClass* Object::CreateAndRegisterCoreInterface(const char* cname,
|
||||
const Script& script,
|
||||
const Library& core_lib) {
|
||||
const String& name = String::Handle(String::NewSymbol(cname));
|
||||
const Class& cls = Class::Handle(Class::NewInterface(name, script));
|
||||
core_lib.AddClass(cls);
|
||||
return cls.raw();
|
||||
}
|
||||
|
||||
|
||||
void Object::RegisterCoreImplClass(const Class& cls,
|
||||
const char* cname,
|
||||
const Script& impl_script,
|
||||
const Library& core_impl_lib) {
|
||||
const String& name = String::Handle(String::NewSymbol(cname));
|
||||
cls.set_name(name);
|
||||
cls.set_script(impl_script);
|
||||
core_impl_lib.AddClass(cls);
|
||||
}
|
||||
|
||||
|
||||
void Object::Init(Isolate* isolate) {
|
||||
TIMERSCOPE(time_bootstrap);
|
||||
ObjectStore* object_store = isolate->object_store();
|
||||
|
||||
Class& cls = Class::Handle();
|
||||
Type& type = Type::Handle();
|
||||
String& name = String::Handle();
|
||||
Array& array = Array::Handle();
|
||||
|
||||
// All RawArray fields will be initialized to an empty array, therefore
|
||||
|
@ -386,6 +363,52 @@ void Object::Init(Isolate* isolate) {
|
|||
// has been created.
|
||||
cls.InitEmptyFields();
|
||||
|
||||
cls = Class::New<ImmutableArray>();
|
||||
object_store->set_immutable_array_class(cls);
|
||||
cls.set_type_arguments_instance_field_offset(Array::type_arguments_offset());
|
||||
|
||||
// Allocate and initialize the object class and type.
|
||||
cls = Class::New<Instance>();
|
||||
object_store->set_object_class(cls);
|
||||
type = Type::NewNonParameterizedType(cls);
|
||||
object_store->set_object_type(type);
|
||||
|
||||
cls = Class::New<Smi>();
|
||||
object_store->set_smi_class(cls);
|
||||
|
||||
cls = Class::New<Mint>();
|
||||
object_store->set_mint_class(cls);
|
||||
|
||||
cls = Class::New<Bigint>();
|
||||
object_store->set_bigint_class(cls);
|
||||
|
||||
cls = Class::New<Double>();
|
||||
object_store->set_double_class(cls);
|
||||
|
||||
cls = Class::New<OneByteString>();
|
||||
object_store->set_one_byte_string_class(cls);
|
||||
|
||||
cls = Class::New<TwoByteString>();
|
||||
object_store->set_two_byte_string_class(cls);
|
||||
|
||||
cls = Class::New<FourByteString>();
|
||||
object_store->set_four_byte_string_class(cls);
|
||||
|
||||
cls = Class::New<Bool>();
|
||||
object_store->set_bool_class(cls);
|
||||
|
||||
cls = Class::New<UnhandledException>();
|
||||
object_store->set_unhandled_exception_class(cls);
|
||||
|
||||
cls = Class::New<Stacktrace>();
|
||||
object_store->set_stacktrace_class(cls);
|
||||
// Set the super type so that the 'toString' method is implemented.
|
||||
type = object_store->object_type();
|
||||
cls.set_super_type(type);
|
||||
|
||||
cls = Class::New<JSRegExp>();
|
||||
object_store->set_jsregexp_class(cls);
|
||||
|
||||
// Setup the symbol table used within the String class.
|
||||
const int kInitialSymbolTableSize = 16;
|
||||
array = Array::New(kInitialSymbolTableSize + 1);
|
||||
|
@ -393,145 +416,156 @@ void Object::Init(Isolate* isolate) {
|
|||
array.SetAt(kInitialSymbolTableSize, Smi::Handle(Smi::New(0)));
|
||||
object_store->set_symbol_table(array);
|
||||
|
||||
// Pre-allocate the OneByteString class needed by the symbol table.
|
||||
cls = Class::New<OneByteString>();
|
||||
object_store->set_one_byte_string_class(cls);
|
||||
|
||||
// Basic infrastructure has been setup, initialize the class dictionary.
|
||||
Library::InitCoreLibrary(isolate);
|
||||
Library& core_lib = Library::Handle(Library::CoreLibrary());
|
||||
Library& core_lib = Library::Handle(isolate->object_store()->core_library());
|
||||
ASSERT(!core_lib.IsNull());
|
||||
Library& core_impl_lib = Library::Handle(Library::CoreImplLibrary());
|
||||
ASSERT(!core_impl_lib.IsNull());
|
||||
|
||||
object_store->set_pending_classes(Array::Handle());
|
||||
// Allocate pre-initialized values.
|
||||
Bool& bool_value = Bool::Handle();
|
||||
bool_value = Bool::New(true);
|
||||
object_store->set_true_value(bool_value);
|
||||
bool_value = Bool::New(false);
|
||||
object_store->set_false_value(bool_value);
|
||||
|
||||
object_store->set_pending_classes(Array::Handle(Array::Empty()));
|
||||
|
||||
Context& context = Context::Handle(Context::New(0));
|
||||
object_store->set_empty_context(context);
|
||||
|
||||
// Now that the symbol table is initialized and that the core dictionary as
|
||||
// well as the core implementation dictionary have been setup, preallocate
|
||||
// remaining classes and register them by name in the dictionaries.
|
||||
// Now that the String class is initialized and the dictionary has been setup,
|
||||
// add the names to preallocated classes and register them in the dictionary.
|
||||
const Script& impl_script = Script::Handle(Bootstrap::LoadImplScript());
|
||||
GrowableArray<const Class*> pending_classes;
|
||||
|
||||
cls = Class::New<Smi>();
|
||||
object_store->set_smi_class(cls);
|
||||
RegisterCoreImplClass(cls, "Smi", impl_script, core_impl_lib);
|
||||
pending_classes.Add(&Class::ZoneHandle(cls.raw()));
|
||||
name = String::NewSymbol("Smi");
|
||||
cls = object_store->smi_class();
|
||||
cls.set_name(name);
|
||||
cls.set_script(impl_script);
|
||||
core_impl_lib.AddClass(cls);
|
||||
|
||||
cls = Class::New<Mint>();
|
||||
object_store->set_mint_class(cls);
|
||||
RegisterCoreImplClass(cls, "Mint", impl_script, core_impl_lib);
|
||||
pending_classes.Add(&Class::ZoneHandle(cls.raw()));
|
||||
name = String::NewSymbol("OneByteString");
|
||||
cls = object_store->one_byte_string_class();
|
||||
cls.set_name(name);
|
||||
cls.set_script(impl_script);
|
||||
core_impl_lib.AddClass(cls);
|
||||
|
||||
cls = Class::New<Bigint>();
|
||||
object_store->set_bigint_class(cls);
|
||||
RegisterCoreImplClass(cls, "Bigint", impl_script, core_impl_lib);
|
||||
pending_classes.Add(&Class::ZoneHandle(cls.raw()));
|
||||
name = String::NewSymbol("TwoByteString");
|
||||
cls = object_store->two_byte_string_class();
|
||||
cls.set_name(name);
|
||||
cls.set_script(impl_script);
|
||||
core_impl_lib.AddClass(cls);
|
||||
|
||||
cls = Class::New<Double>();
|
||||
object_store->set_double_class(cls);
|
||||
RegisterCoreImplClass(cls, "Double", impl_script, core_impl_lib);
|
||||
pending_classes.Add(&Class::ZoneHandle(cls.raw()));
|
||||
name = String::NewSymbol("FourByteString");
|
||||
cls = object_store->four_byte_string_class();
|
||||
cls.set_name(name);
|
||||
cls.set_script(impl_script);
|
||||
core_impl_lib.AddClass(cls);
|
||||
|
||||
cls = Class::New<Bool>();
|
||||
object_store->set_bool_class(cls);
|
||||
RegisterCoreImplClass(cls, "Bool", impl_script, core_impl_lib);
|
||||
pending_classes.Add(&Class::ZoneHandle(cls.raw()));
|
||||
name = String::NewSymbol("Mint");
|
||||
cls = object_store->mint_class();
|
||||
cls.set_name(name);
|
||||
cls.set_script(impl_script);
|
||||
core_impl_lib.AddClass(cls);
|
||||
|
||||
cls = object_store->array_class(); // Was allocated above.
|
||||
RegisterCoreImplClass(cls, "ObjectArray", impl_script, core_impl_lib);
|
||||
pending_classes.Add(&Class::ZoneHandle(cls.raw()));
|
||||
name = String::NewSymbol("Bigint");
|
||||
cls = object_store->bigint_class();
|
||||
cls.set_name(name);
|
||||
cls.set_script(impl_script);
|
||||
core_impl_lib.AddClass(cls);
|
||||
|
||||
cls = Class::New<ImmutableArray>();
|
||||
object_store->set_immutable_array_class(cls);
|
||||
cls.set_type_arguments_instance_field_offset(Array::type_arguments_offset());
|
||||
name = String::NewSymbol("Double");
|
||||
cls = object_store->double_class();
|
||||
cls.set_name(name);
|
||||
cls.set_script(impl_script);
|
||||
core_impl_lib.AddClass(cls);
|
||||
|
||||
name = String::NewSymbol("Bool");
|
||||
cls = object_store->bool_class();
|
||||
cls.set_name(name);
|
||||
cls.set_script(impl_script);
|
||||
core_impl_lib.AddClass(cls);
|
||||
|
||||
name = String::NewSymbol("ObjectArray");
|
||||
cls = object_store->array_class();
|
||||
cls.set_name(name);
|
||||
cls.set_script(impl_script);
|
||||
core_impl_lib.AddClass(cls);
|
||||
|
||||
name = String::NewSymbol("ImmutableArray");
|
||||
cls = object_store->immutable_array_class();
|
||||
ASSERT(object_store->immutable_array_class() != object_store->array_class());
|
||||
RegisterCoreImplClass(cls, "ImmutableArray", impl_script, core_impl_lib);
|
||||
pending_classes.Add(&Class::ZoneHandle(cls.raw()));
|
||||
cls.set_name(name);
|
||||
cls.set_script(impl_script);
|
||||
core_impl_lib.AddClass(cls);
|
||||
|
||||
cls = object_store->one_byte_string_class(); // Was allocated above.
|
||||
RegisterCoreImplClass(cls, "OneByteString", impl_script, core_impl_lib);
|
||||
pending_classes.Add(&Class::ZoneHandle(cls.raw()));
|
||||
name = String::NewSymbol("UnhandledException");
|
||||
cls = object_store->unhandled_exception_class();
|
||||
cls.set_name(name);
|
||||
cls.set_script(impl_script);
|
||||
core_impl_lib.AddClass(cls);
|
||||
|
||||
cls = Class::New<TwoByteString>();
|
||||
object_store->set_two_byte_string_class(cls);
|
||||
RegisterCoreImplClass(cls, "TwoByteString", impl_script, core_impl_lib);
|
||||
pending_classes.Add(&Class::ZoneHandle(cls.raw()));
|
||||
name = String::NewSymbol("Stacktrace");
|
||||
cls = object_store->stacktrace_class();
|
||||
cls.set_name(name);
|
||||
cls.set_script(impl_script);
|
||||
core_impl_lib.AddClass(cls);
|
||||
|
||||
cls = Class::New<FourByteString>();
|
||||
object_store->set_four_byte_string_class(cls);
|
||||
RegisterCoreImplClass(cls, "FourByteString", impl_script, core_impl_lib);
|
||||
pending_classes.Add(&Class::ZoneHandle(cls.raw()));
|
||||
|
||||
cls = Class::New<UnhandledException>();
|
||||
object_store->set_unhandled_exception_class(cls);
|
||||
RegisterCoreImplClass(cls, "UnhandledException", impl_script, core_impl_lib);
|
||||
pending_classes.Add(&Class::ZoneHandle(cls.raw()));
|
||||
|
||||
cls = Class::New<Stacktrace>();
|
||||
object_store->set_stacktrace_class(cls);
|
||||
RegisterCoreImplClass(cls, "Stacktrace", impl_script, core_impl_lib);
|
||||
pending_classes.Add(&Class::ZoneHandle(cls.raw()));
|
||||
// Super type set below, after Object is allocated.
|
||||
|
||||
cls = Class::New<JSRegExp>();
|
||||
object_store->set_jsregexp_class(cls);
|
||||
RegisterCoreImplClass(cls, "JSSyntaxRegExp", impl_script, core_impl_lib);
|
||||
pending_classes.Add(&Class::ZoneHandle(cls.raw()));
|
||||
name = String::NewSymbol("JSSyntaxRegExp");
|
||||
cls = object_store->jsregexp_class();
|
||||
cls.set_name(name);
|
||||
cls.set_script(impl_script);
|
||||
core_impl_lib.AddClass(cls);
|
||||
|
||||
// Initialize the base interfaces used by the core VM classes.
|
||||
const Script& script = Script::Handle(Bootstrap::LoadScript());
|
||||
|
||||
// Allocate and initialize the Object class and type.
|
||||
// Object class is the only pre-allocated non-interface in the core library.
|
||||
cls = Class::New<Instance>();
|
||||
object_store->set_object_class(cls);
|
||||
cls.set_name(String::Handle(String::NewSymbol("Object")));
|
||||
name = String::NewSymbol("Object");
|
||||
cls = object_store->object_class();
|
||||
cls.set_name(name);
|
||||
cls.set_script(script);
|
||||
core_lib.AddClass(cls);
|
||||
pending_classes.Add(&Class::ZoneHandle(cls.raw()));
|
||||
type = Type::NewNonParameterizedType(cls);
|
||||
object_store->set_object_type(type);
|
||||
|
||||
// Set the super type of class Stacktrace to Object type so that the
|
||||
// 'toString' method is implemented.
|
||||
cls = object_store->stacktrace_class();
|
||||
cls.set_super_type(type);
|
||||
|
||||
cls = CreateAndRegisterCoreInterface("Function", script, core_lib);
|
||||
pending_classes.Add(&Class::ZoneHandle(cls.raw()));
|
||||
name = String::NewSymbol("Function");
|
||||
cls = Class::NewInterface(name, script);
|
||||
core_lib.AddClass(cls);
|
||||
type = Type::NewNonParameterizedType(cls);
|
||||
object_store->set_function_interface(type);
|
||||
|
||||
cls = CreateAndRegisterCoreInterface("num", script, core_lib);
|
||||
pending_classes.Add(&Class::ZoneHandle(cls.raw()));
|
||||
name = String::NewSymbol("num");
|
||||
cls = Class::NewInterface(name, script);
|
||||
core_lib.AddClass(cls);
|
||||
type = Type::NewNonParameterizedType(cls);
|
||||
object_store->set_number_interface(type);
|
||||
|
||||
cls = CreateAndRegisterCoreInterface("int", script, core_lib);
|
||||
pending_classes.Add(&Class::ZoneHandle(cls.raw()));
|
||||
name = String::NewSymbol("int");
|
||||
cls = Class::NewInterface(name, script);
|
||||
core_lib.AddClass(cls);
|
||||
type = Type::NewNonParameterizedType(cls);
|
||||
object_store->set_int_interface(type);
|
||||
|
||||
cls = CreateAndRegisterCoreInterface("double", script, core_lib);
|
||||
pending_classes.Add(&Class::ZoneHandle(cls.raw()));
|
||||
name = String::NewSymbol("double");
|
||||
cls = Class::NewInterface(name, script);
|
||||
core_lib.AddClass(cls);
|
||||
type = Type::NewNonParameterizedType(cls);
|
||||
object_store->set_double_interface(type);
|
||||
|
||||
cls = CreateAndRegisterCoreInterface("String", script, core_lib);
|
||||
pending_classes.Add(&Class::ZoneHandle(cls.raw()));
|
||||
name = String::NewSymbol("String");
|
||||
cls = Class::NewInterface(name, script);
|
||||
core_lib.AddClass(cls);
|
||||
type = Type::NewNonParameterizedType(cls);
|
||||
object_store->set_string_interface(type);
|
||||
|
||||
cls = CreateAndRegisterCoreInterface("bool", script, core_lib);
|
||||
pending_classes.Add(&Class::ZoneHandle(cls.raw()));
|
||||
name = String::NewSymbol("bool");
|
||||
cls = Class::NewInterface(name, script);
|
||||
core_lib.AddClass(cls);
|
||||
type = Type::NewNonParameterizedType(cls);
|
||||
object_store->set_bool_interface(type);
|
||||
|
||||
cls = CreateAndRegisterCoreInterface("List", script, core_lib);
|
||||
pending_classes.Add(&Class::ZoneHandle(cls.raw()));
|
||||
name = String::NewSymbol("List");
|
||||
cls = Class::NewInterface(name, script);
|
||||
core_lib.AddClass(cls);
|
||||
type = Type::NewNonParameterizedType(cls);
|
||||
object_store->set_list_interface(type);
|
||||
|
||||
|
@ -556,21 +590,10 @@ void Object::Init(Isolate* isolate) {
|
|||
object_store->set_dynamic_type(type);
|
||||
core_lib.AddClass(cls);
|
||||
|
||||
// Add the preallocated classes to the list of classes to be finalized.
|
||||
ClassFinalizer::ExpectClassesToFinalize();
|
||||
ClassFinalizer::AddClassesToFinalize(pending_classes);
|
||||
|
||||
// Allocate pre-initialized values.
|
||||
Bool& bool_value = Bool::Handle();
|
||||
bool_value = Bool::New(true);
|
||||
object_store->set_true_value(bool_value);
|
||||
bool_value = Bool::New(false);
|
||||
object_store->set_false_value(bool_value);
|
||||
|
||||
// Finish the initialization by compiling the bootstrap scripts containing the
|
||||
// base interfaces and the implementation of the internal classes.
|
||||
Bootstrap::Compile(core_lib, script);
|
||||
Bootstrap::Compile(core_impl_lib, impl_script);
|
||||
// Finish the initialization by compiling the bootstrap script containing the
|
||||
// implementation of the internal classes.
|
||||
Bootstrap::Compile(Library::Handle(Library::CoreLibrary()), script);
|
||||
Bootstrap::Compile(Library::Handle(Library::CoreImplLibrary()), impl_script);
|
||||
|
||||
Bootstrap::SetupNativeResolver();
|
||||
|
||||
|
@ -1035,25 +1058,17 @@ RawClass* Class::NewSignatureClass(const String& name,
|
|||
result.set_type_parameter_extends(type_parameter_extends);
|
||||
result.SetFields(Array::Handle(Array::Empty()));
|
||||
result.SetFunctions(Array::Handle(Array::Empty()));
|
||||
// Implements interface "Function".
|
||||
// Implements interface Function.
|
||||
const Type& function_interface = Type::Handle(Type::FunctionInterface());
|
||||
const Array& interfaces = Array::Handle(Array::New(1, Heap::kOld));
|
||||
interfaces.SetAt(0, function_interface);
|
||||
result.set_interfaces(interfaces);
|
||||
// Unless the signature function already has a signature class, create a
|
||||
// canonical signature class by having the signature function point back to
|
||||
// canonical signature class by having the signature function pointing back to
|
||||
// the signature class.
|
||||
if (signature_function.signature_class() == Object::null()) {
|
||||
signature_function.set_signature_class(result);
|
||||
}
|
||||
// If the class finalizer is expecting more pending classes to finalize, it
|
||||
// will add the signature class to the pending list in order to postpone
|
||||
// finalization of the signature type.
|
||||
const Type& signature_type = Type::Handle(result.SignatureType());
|
||||
ASSERT(!signature_type.IsFinalized());
|
||||
String& errmsg = String::Handle();
|
||||
ClassFinalizer::FinalizeAndCanonicalizeType(signature_type, &errmsg);
|
||||
ASSERT(errmsg.IsNull());
|
||||
return result.raw();
|
||||
}
|
||||
|
||||
|
@ -1321,8 +1336,6 @@ bool Class::TestType(TypeTestKind test,
|
|||
const TypeArguments& type_arguments,
|
||||
const Class& other,
|
||||
const TypeArguments& other_type_arguments) const {
|
||||
ASSERT(is_finalized());
|
||||
ASSERT(other.is_finalized());
|
||||
if (test == kIsAssignableTo) {
|
||||
// The spec states that "a type T is assignable to a type S if T is a
|
||||
// subtype of S or S is a subtype of T". This is from the perspective of a
|
||||
|
@ -1797,12 +1810,6 @@ bool Type::IsListInterface() const {
|
|||
}
|
||||
|
||||
|
||||
bool Type::IsSignatureType() const {
|
||||
return HasResolvedTypeClass() &&
|
||||
Class::Handle(type_class()).IsSignatureClass();
|
||||
}
|
||||
|
||||
|
||||
bool Type::IsMoreSpecificThan(const Type& other) const {
|
||||
ASSERT(IsFinalized());
|
||||
ASSERT(other.IsFinalized());
|
||||
|
@ -2007,7 +2014,6 @@ RawType* ParameterizedType::InstantiateFrom(
|
|||
offset);
|
||||
}
|
||||
const Class& cls = Class::Handle(type_class());
|
||||
ASSERT(cls.is_finalized());
|
||||
ParameterizedType& instantiated_type = ParameterizedType::Handle(
|
||||
ParameterizedType::New(cls, type_arguments));
|
||||
ASSERT(type_arguments.IsNull() ||
|
||||
|
|
|
@ -245,14 +245,6 @@ CLASS_LIST_NO_OBJECT(DEFINE_CLASS_TESTER);
|
|||
static RawClass* GetSingletonClass(int index);
|
||||
static const char* GetSingletonClassName(int index);
|
||||
|
||||
static RawClass* CreateAndRegisterCoreInterface(const char* cname,
|
||||
const Script& script,
|
||||
const Library& core_lib);
|
||||
static void RegisterCoreImplClass(const Class& cls,
|
||||
const char* cname,
|
||||
const Script& impl_script,
|
||||
const Library& core_impl_lib);
|
||||
|
||||
static void Init(Isolate* isolate);
|
||||
static void InitFromSnapshot(Isolate* isolate);
|
||||
static void InitOnce();
|
||||
|
@ -749,9 +741,6 @@ class Type : public Object {
|
|||
// Check if this type represents the 'List' interface.
|
||||
bool IsListInterface() const;
|
||||
|
||||
// Check if this type represents a signature type.
|
||||
bool IsSignatureType() const;
|
||||
|
||||
// Check if this type is an interface type.
|
||||
bool IsInterfaceType() const {
|
||||
if (!HasResolvedTypeClass()) {
|
||||
|
|
|
@ -204,6 +204,7 @@ class ObjectStore {
|
|||
|
||||
RawArray* pending_classes() const { return pending_classes_; }
|
||||
void set_pending_classes(const Array& value) {
|
||||
ASSERT(!value.IsNull());
|
||||
pending_classes_ = value.raw();
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include "vm/assert.h"
|
||||
#include "vm/assembler.h"
|
||||
#include "vm/bigint_operations.h"
|
||||
#include "vm/class_finalizer.h"
|
||||
#include "vm/isolate.h"
|
||||
#include "vm/object.h"
|
||||
#include "vm/object_store.h"
|
||||
|
@ -1745,8 +1744,6 @@ TEST_CASE(Closure) {
|
|||
Function& function = Function::Handle();
|
||||
const String& function_name = String::Handle(String::NewSymbol("foo"));
|
||||
function = Function::NewClosureFunction(function_name, parent, 0);
|
||||
// Postpone signature class finalization.
|
||||
ClassFinalizer::ExpectClassesToFinalize();
|
||||
const Class& signature_class = Class::Handle(
|
||||
Class::NewSignatureClass(function_name, function, script));
|
||||
const Closure& closure = Closure::Handle(Closure::New(function, context));
|
||||
|
|
|
@ -174,8 +174,6 @@ Parser::Parser(const Script& script, const Library& library)
|
|||
current_class_(Class::Handle()),
|
||||
library_(library),
|
||||
try_blocks_list_(NULL) {
|
||||
ASSERT(!tokens_.IsNull());
|
||||
ASSERT(!library.IsNull());
|
||||
SetPosition(0);
|
||||
}
|
||||
|
||||
|
@ -194,8 +192,6 @@ Parser::Parser(const Script& script,
|
|||
current_class_(Class::Handle(current_function_.owner())),
|
||||
library_(Library::Handle(current_class_.library())),
|
||||
try_blocks_list_(NULL) {
|
||||
ASSERT(!tokens_.IsNull());
|
||||
ASSERT(!function.IsNull());
|
||||
SetPosition(token_index);
|
||||
}
|
||||
|
||||
|
@ -2616,8 +2612,7 @@ void Parser::ParseFunctionTypeAlias(GrowableArray<const Class*>* classes) {
|
|||
// Allocate an interface to hold the type parameters and their 'extends'
|
||||
// constraints. Make it the owner of the function type descriptor.
|
||||
const Class& alias_owner = Class::Handle(
|
||||
Class::New(String::Handle(String::NewSymbol(":alias_owner")),
|
||||
Script::Handle()));
|
||||
Class::New(String::Handle(String::NewSymbol("")), Script::Handle()));
|
||||
alias_owner.set_is_interface();
|
||||
set_current_class(alias_owner);
|
||||
ParseTypeParameters(alias_owner);
|
||||
|
@ -3212,14 +3207,9 @@ void Parser::ParseTopLevel() {
|
|||
is_top_level_ = true;
|
||||
TopLevel top_level;
|
||||
Class& toplevel_class = Class::ZoneHandle(
|
||||
Class::New(String::ZoneHandle(String::NewSymbol("::")), script_));
|
||||
Class::New(String::ZoneHandle(String::NewSymbol("")), script_));
|
||||
toplevel_class.set_library(library_);
|
||||
|
||||
// We notify the class finalizer to expect classes to finalize.
|
||||
// This allows signature classes generated at runtime to be properly
|
||||
// finalized, without finalizing them prematurely at compile time.
|
||||
ClassFinalizer::ExpectClassesToFinalize();
|
||||
|
||||
if (is_library_source()) {
|
||||
ParseLibraryDefinition();
|
||||
}
|
||||
|
@ -3255,7 +3245,7 @@ void Parser::ParseTopLevel() {
|
|||
library_.AddAnonymousClass(toplevel_class);
|
||||
classes.Add(&toplevel_class);
|
||||
}
|
||||
ClassFinalizer::AddClassesToFinalize(classes);
|
||||
ClassFinalizer::AddPendingClasses(classes);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3689,8 +3679,8 @@ AstNode* Parser::ParseFunctionStatement(bool is_literal) {
|
|||
if (!errmsg.IsNull()) {
|
||||
ErrorMsg(errmsg.ToCString());
|
||||
}
|
||||
// The call to ClassFinalizer::FinalizeAndCanonicalizeType may have
|
||||
// extended the vector of type arguments.
|
||||
// The call to ClassFinalizer::FinalizeTypeWhileParsing may have extended
|
||||
// the vector of type arguments.
|
||||
ASSERT(signature_type_arguments.IsNull() ||
|
||||
(signature_type_arguments.Length() ==
|
||||
signature_class.NumTypeArguments()));
|
||||
|
|
|
@ -120,7 +120,7 @@ TEST_CASE(ParseClassDefinition) {
|
|||
script.Tokenize(String::Handle(String::New("")));
|
||||
|
||||
Parser::ParseCompilationUnit(lib, script);
|
||||
EXPECT(ClassFinalizer::FinalizeAllClasses());
|
||||
EXPECT(ClassFinalizer::FinalizePendingClasses());
|
||||
CheckField(lib, "A", "f1", false, false);
|
||||
CheckField(lib, "A", "f2", false, true);
|
||||
CheckField(lib, "A", "f3", false, true);
|
||||
|
@ -164,7 +164,7 @@ TEST_CASE(Parser_TopLevel) {
|
|||
script.Tokenize(String::Handle(String::New("")));
|
||||
|
||||
Parser::ParseCompilationUnit(lib, script);
|
||||
EXPECT(ClassFinalizer::FinalizeAllClasses());
|
||||
EXPECT(ClassFinalizer::FinalizePendingClasses());
|
||||
|
||||
DumpFunction(lib, "A", "foo");
|
||||
DumpFunction(lib, "A", "bar");
|
||||
|
|
|
@ -45,7 +45,7 @@ static void SetupFunction(const char* test_library_name,
|
|||
Library& lib = Library::Handle(Library::New(lib_name));
|
||||
lib.Register();
|
||||
EXPECT(CompilerTest::TestCompileScript(lib, script));
|
||||
EXPECT(ClassFinalizer::FinalizeAllClasses());
|
||||
EXPECT(ClassFinalizer::FinalizePendingClasses());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -400,7 +400,7 @@ UNIT_TEST_CASE(FullSnapshot1) {
|
|||
|
||||
// Create a test library and Load up a test script in it.
|
||||
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
|
||||
ClassFinalizer::FinalizeAllClasses();
|
||||
ClassFinalizer::FinalizePendingClasses();
|
||||
timer1.Stop();
|
||||
OS::PrintErr("Without Snapshot: %dus\n", timer1.TotalElapsedTime());
|
||||
|
||||
|
|
Loading…
Reference in a new issue