Chromium Code Reviews| Index: runtime/vm/object.cc |
| =================================================================== |
| --- runtime/vm/object.cc (revision 1336) |
| +++ runtime/vm/object.cc (working copy) |
| @@ -239,6 +239,7 @@ |
| // 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_ |
| @@ -264,6 +265,7 @@ |
| // 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(); |
| @@ -272,6 +274,7 @@ |
| unresolved_class_class_ = cls.raw(); |
| cls = Class::New<Instance>(); |
| + cls.set_is_finalized(); |
| void_class_ = cls.raw(); |
| cls = Class::New<ParameterizedType>(); |
| @@ -335,13 +338,40 @@ |
| } |
| +RawClass* Object::CreateAndRegisterCoreInterface( |
| + const char* cname, |
| + const Script& script, |
| + GrowableArray<const Class*>* classes) { |
|
srdjan
2011/11/09 21:22:43
I think it would be clearer if classes->Add() woul
regis
2011/11/09 23:31:01
Done.
|
| + const String& name = String::Handle(String::NewSymbol(cname)); |
| + Class& cls = Class::ZoneHandle(Class::NewInterface(name, script)); |
| + Library& core_lib = Library::Handle(Library::CoreLibrary()); |
| + core_lib.AddClass(cls); |
| + classes->Add(&cls); |
| + return cls.raw(); |
| +} |
| + |
| + |
| +void Object::RegisterCoreImplClass( |
| + const Class& cls, |
| + const char* cname, |
| + const Script& impl_script, |
| + GrowableArray<const Class*>* classes) { |
|
srdjan
2011/11/09 21:22:43
Ditto
regis
2011/11/09 23:31:01
Done.
|
| + const String& name = String::Handle(String::NewSymbol(cname)); |
| + cls.set_name(name); |
| + cls.set_script(impl_script); |
| + Library& core_impl_lib = Library::Handle(Library::CoreImplLibrary()); |
| + core_impl_lib.AddClass(cls); |
| + const Class& pending_class = Class::ZoneHandle(cls.raw()); |
| + classes->Add(&pending_class); |
| +} |
| + |
| + |
| 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 |
| @@ -363,52 +393,6 @@ |
| // 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); |
| @@ -416,156 +400,126 @@ |
| 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(isolate->object_store()->core_library()); |
| + Library& core_lib = Library::Handle(Library::CoreLibrary()); |
| ASSERT(!core_lib.IsNull()); |
| Library& core_impl_lib = Library::Handle(Library::CoreImplLibrary()); |
| ASSERT(!core_impl_lib.IsNull()); |
| - // 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()); |
| - 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 String class is initialized and the dictionary has been setup, |
| - // add the names to preallocated classes and register them in the dictionary. |
| + // 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. |
| const Script& impl_script = Script::Handle(Bootstrap::LoadImplScript()); |
| + GrowableArray<const Class*> pending_classes; |
| - 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<Smi>(); |
| + object_store->set_smi_class(cls); |
| + RegisterCoreImplClass(cls, "Smi", impl_script, &pending_classes); |
| - 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<Mint>(); |
| + object_store->set_mint_class(cls); |
| + RegisterCoreImplClass(cls, "Mint", impl_script, &pending_classes); |
| - 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<Bigint>(); |
| + object_store->set_bigint_class(cls); |
| + RegisterCoreImplClass(cls, "Bigint", impl_script, &pending_classes); |
| - 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<Double>(); |
| + object_store->set_double_class(cls); |
| + RegisterCoreImplClass(cls, "Double", impl_script, &pending_classes); |
| - name = String::NewSymbol("Mint"); |
| - cls = object_store->mint_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, &pending_classes); |
| - name = String::NewSymbol("Bigint"); |
| - cls = object_store->bigint_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, &pending_classes); |
| - name = String::NewSymbol("Double"); |
| - cls = object_store->double_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()); |
| + ASSERT(object_store->immutable_array_class() != object_store->array_class()); |
| + RegisterCoreImplClass(cls, "ImmutableArray", impl_script, &pending_classes); |
| - name = String::NewSymbol("Bool"); |
| - cls = object_store->bool_class(); |
| - 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, &pending_classes); |
| - name = String::NewSymbol("ObjectArray"); |
| - cls = object_store->array_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, &pending_classes); |
| - name = String::NewSymbol("ImmutableArray"); |
| - cls = object_store->immutable_array_class(); |
| - ASSERT(object_store->immutable_array_class() != object_store->array_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, &pending_classes); |
| - 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<UnhandledException>(); |
| + object_store->set_unhandled_exception_class(cls); |
| + RegisterCoreImplClass( |
| + cls, "UnhandledException", impl_script, &pending_classes); |
| - 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<Stacktrace>(); |
| + object_store->set_stacktrace_class(cls); |
| + RegisterCoreImplClass(cls, "Stacktrace", impl_script, &pending_classes); |
| + // Super type set below, after Object is allocated. |
| - name = String::NewSymbol("JSSyntaxRegExp"); |
| - cls = object_store->jsregexp_class(); |
| - cls.set_name(name); |
| - cls.set_script(impl_script); |
| - core_impl_lib.AddClass(cls); |
| + cls = Class::New<JSRegExp>(); |
| + object_store->set_jsregexp_class(cls); |
| + RegisterCoreImplClass(cls, "JSSyntaxRegExp", impl_script, &pending_classes); |
| // Initialize the base interfaces used by the core VM classes. |
| const Script& script = Script::Handle(Bootstrap::LoadScript()); |
| - name = String::NewSymbol("Object"); |
| - cls = object_store->object_class(); |
| - cls.set_name(name); |
| + // 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"))); |
| 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); |
| - name = String::NewSymbol("Function"); |
| - cls = Class::NewInterface(name, script); |
| - core_lib.AddClass(cls); |
| + // 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, &pending_classes); |
| type = Type::NewNonParameterizedType(cls); |
| object_store->set_function_interface(type); |
| - name = String::NewSymbol("num"); |
| - cls = Class::NewInterface(name, script); |
| - core_lib.AddClass(cls); |
| + cls = CreateAndRegisterCoreInterface("num", script, &pending_classes); |
| type = Type::NewNonParameterizedType(cls); |
| object_store->set_number_interface(type); |
| - name = String::NewSymbol("int"); |
| - cls = Class::NewInterface(name, script); |
| - core_lib.AddClass(cls); |
| + cls = CreateAndRegisterCoreInterface("int", script, &pending_classes); |
| type = Type::NewNonParameterizedType(cls); |
| object_store->set_int_interface(type); |
| - name = String::NewSymbol("double"); |
| - cls = Class::NewInterface(name, script); |
| - core_lib.AddClass(cls); |
| + cls = CreateAndRegisterCoreInterface("double", script, &pending_classes); |
| type = Type::NewNonParameterizedType(cls); |
| object_store->set_double_interface(type); |
| - name = String::NewSymbol("String"); |
| - cls = Class::NewInterface(name, script); |
| - core_lib.AddClass(cls); |
| + cls = CreateAndRegisterCoreInterface("String", script, &pending_classes); |
| type = Type::NewNonParameterizedType(cls); |
| object_store->set_string_interface(type); |
| - name = String::NewSymbol("bool"); |
| - cls = Class::NewInterface(name, script); |
| - core_lib.AddClass(cls); |
| + cls = CreateAndRegisterCoreInterface("bool", script, &pending_classes); |
| type = Type::NewNonParameterizedType(cls); |
| object_store->set_bool_interface(type); |
| - name = String::NewSymbol("List"); |
| - cls = Class::NewInterface(name, script); |
| - core_lib.AddClass(cls); |
| + cls = CreateAndRegisterCoreInterface("List", script, &pending_classes); |
| type = Type::NewNonParameterizedType(cls); |
| object_store->set_list_interface(type); |
| @@ -590,11 +544,22 @@ |
| object_store->set_dynamic_type(type); |
| core_lib.AddClass(cls); |
| - // 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); |
| + // Add the preallocated classes to the list of classes to be finalized. |
| + ClassFinalizer::ExpectPendingClasses(); |
| + ClassFinalizer::AddPendingClasses(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); |
| + |
| Bootstrap::SetupNativeResolver(); |
| // Remove the Object superclass cycle by setting the super type to null (not |
| @@ -1058,17 +1023,25 @@ |
| 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 pointing back to |
| + // canonical signature class by having the signature function point 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(); |
| } |
| @@ -1336,6 +1309,8 @@ |
| 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 |
| @@ -1804,6 +1779,12 @@ |
| } |
| +bool Type::IsSignatureType() const { |
| + return HasResolvedTypeClass() && |
| + Class::Handle(type_class()).IsSignatureClass(); |
| +} |
| + |
| + |
| bool Type::IsMoreSpecificThan(const Type& other) const { |
| ASSERT(IsFinalized()); |
| ASSERT(other.IsFinalized()); |
| @@ -2003,6 +1984,7 @@ |
| 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() || |