| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/bootstrap.h" | 5 #include "vm/bootstrap.h" |
| 6 | 6 |
| 7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 | 8 |
| 9 #include "vm/bootstrap_natives.h" | 9 #include "vm/bootstrap_natives.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 namespace dart { | 21 namespace dart { |
| 22 | 22 |
| 23 struct BootstrapLibProps { | 23 struct BootstrapLibProps { |
| 24 ObjectStore::BootstrapLibraryId index; | 24 ObjectStore::BootstrapLibraryId index; |
| 25 const char* uri; | 25 const char* uri; |
| 26 const char** source_paths; | 26 const char** source_paths; |
| 27 const char* patch_uri; | 27 const char* patch_uri; |
| 28 const char** patch_paths; | 28 const char** patch_paths; |
| 29 }; | 29 }; |
| 30 | 30 |
| 31 | |
| 32 enum { kPathsUriOffset = 0, kPathsSourceOffset = 1, kPathsEntryLength = 2 }; | 31 enum { kPathsUriOffset = 0, kPathsSourceOffset = 1, kPathsEntryLength = 2 }; |
| 33 | 32 |
| 34 | |
| 35 const char** Bootstrap::profiler_patch_paths_ = NULL; | 33 const char** Bootstrap::profiler_patch_paths_ = NULL; |
| 36 | 34 |
| 37 | |
| 38 #define MAKE_PROPERTIES(CamelName, name) \ | 35 #define MAKE_PROPERTIES(CamelName, name) \ |
| 39 {ObjectStore::k##CamelName, "dart:" #name, Bootstrap::name##_source_paths_, \ | 36 {ObjectStore::k##CamelName, "dart:" #name, Bootstrap::name##_source_paths_, \ |
| 40 "dart:" #name "-patch", Bootstrap::name##_patch_paths_}, | 37 "dart:" #name "-patch", Bootstrap::name##_patch_paths_}, |
| 41 | 38 |
| 42 static const BootstrapLibProps bootstrap_libraries[] = { | 39 static const BootstrapLibProps bootstrap_libraries[] = { |
| 43 FOR_EACH_BOOTSTRAP_LIBRARY(MAKE_PROPERTIES)}; | 40 FOR_EACH_BOOTSTRAP_LIBRARY(MAKE_PROPERTIES)}; |
| 44 | 41 |
| 45 #undef MAKE_PROPERTIES | 42 #undef MAKE_PROPERTIES |
| 46 | 43 |
| 47 | |
| 48 static const intptr_t kBootstrapLibraryCount = ARRAY_SIZE(bootstrap_libraries); | 44 static const intptr_t kBootstrapLibraryCount = ARRAY_SIZE(bootstrap_libraries); |
| 49 | 45 |
| 50 | |
| 51 static RawString* GetLibrarySourceByIndex(intptr_t index, | 46 static RawString* GetLibrarySourceByIndex(intptr_t index, |
| 52 const String& uri, | 47 const String& uri, |
| 53 bool patch) { | 48 bool patch) { |
| 54 ASSERT(index >= 0 && index < kBootstrapLibraryCount); | 49 ASSERT(index >= 0 && index < kBootstrapLibraryCount); |
| 55 | 50 |
| 56 // Try to read the source using the path specified for the uri. | 51 // Try to read the source using the path specified for the uri. |
| 57 const char** source_paths = patch ? bootstrap_libraries[index].patch_paths | 52 const char** source_paths = patch ? bootstrap_libraries[index].patch_paths |
| 58 : bootstrap_libraries[index].source_paths; | 53 : bootstrap_libraries[index].source_paths; |
| 59 if (source_paths == NULL) { | 54 if (source_paths == NULL) { |
| 60 return String::null(); // No path mapping information exists for library. | 55 return String::null(); // No path mapping information exists for library. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 77 file_length = strlen(source_data); | 72 file_length = strlen(source_data); |
| 78 utf8_array = reinterpret_cast<const uint8_t*>(source_data); | 73 utf8_array = reinterpret_cast<const uint8_t*>(source_data); |
| 79 } else { | 74 } else { |
| 80 return String::null(); | 75 return String::null(); |
| 81 } | 76 } |
| 82 ASSERT(utf8_array != NULL); | 77 ASSERT(utf8_array != NULL); |
| 83 ASSERT(file_length >= 0); | 78 ASSERT(file_length >= 0); |
| 84 return String::FromUTF8(utf8_array, file_length); | 79 return String::FromUTF8(utf8_array, file_length); |
| 85 } | 80 } |
| 86 | 81 |
| 87 | |
| 88 static RawString* GetLibrarySource(const Library& lib, | 82 static RawString* GetLibrarySource(const Library& lib, |
| 89 const String& uri, | 83 const String& uri, |
| 90 bool patch) { | 84 bool patch) { |
| 91 // First check if this is a valid bootstrap library and find its index in | 85 // First check if this is a valid bootstrap library and find its index in |
| 92 // the 'bootstrap_libraries' table above. | 86 // the 'bootstrap_libraries' table above. |
| 93 intptr_t index; | 87 intptr_t index; |
| 94 const String& lib_uri = String::Handle(lib.url()); | 88 const String& lib_uri = String::Handle(lib.url()); |
| 95 for (index = 0; index < kBootstrapLibraryCount; ++index) { | 89 for (index = 0; index < kBootstrapLibraryCount; ++index) { |
| 96 if (lib_uri.Equals(bootstrap_libraries[index].uri)) { | 90 if (lib_uri.Equals(bootstrap_libraries[index].uri)) { |
| 97 break; | 91 break; |
| 98 } | 92 } |
| 99 } | 93 } |
| 100 if (index == kBootstrapLibraryCount) { | 94 if (index == kBootstrapLibraryCount) { |
| 101 return String::null(); // The library is not a bootstrap library. | 95 return String::null(); // The library is not a bootstrap library. |
| 102 } | 96 } |
| 103 | 97 |
| 104 return GetLibrarySourceByIndex(index, uri, patch); | 98 return GetLibrarySourceByIndex(index, uri, patch); |
| 105 } | 99 } |
| 106 | 100 |
| 107 | |
| 108 static RawError* Compile(const Library& library, const Script& script) { | 101 static RawError* Compile(const Library& library, const Script& script) { |
| 109 bool update_lib_status = (script.kind() == RawScript::kScriptTag || | 102 bool update_lib_status = (script.kind() == RawScript::kScriptTag || |
| 110 script.kind() == RawScript::kLibraryTag); | 103 script.kind() == RawScript::kLibraryTag); |
| 111 if (update_lib_status) { | 104 if (update_lib_status) { |
| 112 library.SetLoadInProgress(); | 105 library.SetLoadInProgress(); |
| 113 } | 106 } |
| 114 const Error& error = Error::Handle(Compiler::Compile(library, script)); | 107 const Error& error = Error::Handle(Compiler::Compile(library, script)); |
| 115 if (update_lib_status) { | 108 if (update_lib_status) { |
| 116 if (error.IsNull()) { | 109 if (error.IsNull()) { |
| 117 library.SetLoaded(); | 110 library.SetLoaded(); |
| 118 } else { | 111 } else { |
| 119 // Compilation errors are not Dart instances, so just mark the library | 112 // Compilation errors are not Dart instances, so just mark the library |
| 120 // as having failed to load without providing an error instance. | 113 // as having failed to load without providing an error instance. |
| 121 library.SetLoadError(Object::null_instance()); | 114 library.SetLoadError(Object::null_instance()); |
| 122 } | 115 } |
| 123 } | 116 } |
| 124 return error.raw(); | 117 return error.raw(); |
| 125 } | 118 } |
| 126 | 119 |
| 127 | |
| 128 static Dart_Handle LoadPartSource(Thread* thread, | 120 static Dart_Handle LoadPartSource(Thread* thread, |
| 129 const Library& lib, | 121 const Library& lib, |
| 130 const String& uri) { | 122 const String& uri) { |
| 131 Zone* zone = thread->zone(); | 123 Zone* zone = thread->zone(); |
| 132 const String& part_source = | 124 const String& part_source = |
| 133 String::Handle(zone, GetLibrarySource(lib, uri, false)); | 125 String::Handle(zone, GetLibrarySource(lib, uri, false)); |
| 134 const String& lib_uri = String::Handle(zone, lib.url()); | 126 const String& lib_uri = String::Handle(zone, lib.url()); |
| 135 if (part_source.IsNull()) { | 127 if (part_source.IsNull()) { |
| 136 return Api::NewError("Unable to read part file '%s' of library '%s'", | 128 return Api::NewError("Unable to read part file '%s' of library '%s'", |
| 137 uri.ToCString(), lib_uri.ToCString()); | 129 uri.ToCString(), lib_uri.ToCString()); |
| 138 } | 130 } |
| 139 | 131 |
| 140 // Prepend the library URI to form a unique script URI for the part. | 132 // Prepend the library URI to form a unique script URI for the part. |
| 141 const Array& strings = Array::Handle(zone, Array::New(3)); | 133 const Array& strings = Array::Handle(zone, Array::New(3)); |
| 142 strings.SetAt(0, lib_uri); | 134 strings.SetAt(0, lib_uri); |
| 143 strings.SetAt(1, Symbols::Slash()); | 135 strings.SetAt(1, Symbols::Slash()); |
| 144 strings.SetAt(2, uri); | 136 strings.SetAt(2, uri); |
| 145 const String& part_uri = String::Handle(zone, String::ConcatAll(strings)); | 137 const String& part_uri = String::Handle(zone, String::ConcatAll(strings)); |
| 146 | 138 |
| 147 // Create a script object and compile the part. | 139 // Create a script object and compile the part. |
| 148 const Script& part_script = Script::Handle( | 140 const Script& part_script = Script::Handle( |
| 149 zone, Script::New(part_uri, part_source, RawScript::kSourceTag)); | 141 zone, Script::New(part_uri, part_source, RawScript::kSourceTag)); |
| 150 const Error& error = Error::Handle(zone, Compile(lib, part_script)); | 142 const Error& error = Error::Handle(zone, Compile(lib, part_script)); |
| 151 return Api::NewHandle(thread, error.raw()); | 143 return Api::NewHandle(thread, error.raw()); |
| 152 } | 144 } |
| 153 | 145 |
| 154 | |
| 155 static Dart_Handle BootstrapLibraryTagHandler(Dart_LibraryTag tag, | 146 static Dart_Handle BootstrapLibraryTagHandler(Dart_LibraryTag tag, |
| 156 Dart_Handle library, | 147 Dart_Handle library, |
| 157 Dart_Handle uri) { | 148 Dart_Handle uri) { |
| 158 Thread* thread = Thread::Current(); | 149 Thread* thread = Thread::Current(); |
| 159 Zone* zone = thread->zone(); | 150 Zone* zone = thread->zone(); |
| 160 // This handler calls into the VM directly and does not use the Dart | 151 // This handler calls into the VM directly and does not use the Dart |
| 161 // API so we transition back to VM. | 152 // API so we transition back to VM. |
| 162 TransitionNativeToVM transition(thread); | 153 TransitionNativeToVM transition(thread); |
| 163 if (!Dart_IsLibrary(library)) { | 154 if (!Dart_IsLibrary(library)) { |
| 164 return Api::NewError("not a library"); | 155 return Api::NewError("not a library"); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 180 // The bootstrap process explicitly loads all the libraries one by one. | 171 // The bootstrap process explicitly loads all the libraries one by one. |
| 181 return Api::NewError("Invalid import of '%s' in a bootstrap library", | 172 return Api::NewError("Invalid import of '%s' in a bootstrap library", |
| 182 uri_str.ToCString()); | 173 uri_str.ToCString()); |
| 183 } | 174 } |
| 184 ASSERT(tag == Dart_kSourceTag); | 175 ASSERT(tag == Dart_kSourceTag); |
| 185 const Library& lib = Api::UnwrapLibraryHandle(zone, library); | 176 const Library& lib = Api::UnwrapLibraryHandle(zone, library); |
| 186 ASSERT(!lib.IsNull()); | 177 ASSERT(!lib.IsNull()); |
| 187 return LoadPartSource(thread, lib, uri_str); | 178 return LoadPartSource(thread, lib, uri_str); |
| 188 } | 179 } |
| 189 | 180 |
| 190 | |
| 191 static RawError* LoadPatchFiles(Thread* thread, | 181 static RawError* LoadPatchFiles(Thread* thread, |
| 192 const Library& lib, | 182 const Library& lib, |
| 193 intptr_t index) { | 183 intptr_t index) { |
| 194 const char** patch_files = bootstrap_libraries[index].patch_paths; | 184 const char** patch_files = bootstrap_libraries[index].patch_paths; |
| 195 if (patch_files == NULL) return Error::null(); | 185 if (patch_files == NULL) return Error::null(); |
| 196 | 186 |
| 197 Zone* zone = thread->zone(); | 187 Zone* zone = thread->zone(); |
| 198 String& patch_uri = String::Handle( | 188 String& patch_uri = String::Handle( |
| 199 zone, Symbols::New(thread, bootstrap_libraries[index].patch_uri)); | 189 zone, Symbols::New(thread, bootstrap_libraries[index].patch_uri)); |
| 200 String& patch_file_uri = String::Handle(zone); | 190 String& patch_file_uri = String::Handle(zone); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 218 patch_file_uri = String::ConcatAll(strings); | 208 patch_file_uri = String::ConcatAll(strings); |
| 219 script = Script::New(patch_file_uri, source, RawScript::kPatchTag); | 209 script = Script::New(patch_file_uri, source, RawScript::kPatchTag); |
| 220 error = lib.Patch(script); | 210 error = lib.Patch(script); |
| 221 if (!error.IsNull()) { | 211 if (!error.IsNull()) { |
| 222 return error.raw(); | 212 return error.raw(); |
| 223 } | 213 } |
| 224 } | 214 } |
| 225 return Error::null(); | 215 return Error::null(); |
| 226 } | 216 } |
| 227 | 217 |
| 228 | |
| 229 static void Finish(Thread* thread, bool from_kernel) { | 218 static void Finish(Thread* thread, bool from_kernel) { |
| 230 Bootstrap::SetupNativeResolver(); | 219 Bootstrap::SetupNativeResolver(); |
| 231 if (!ClassFinalizer::ProcessPendingClasses(from_kernel)) { | 220 if (!ClassFinalizer::ProcessPendingClasses(from_kernel)) { |
| 232 FATAL("Error in class finalization during bootstrapping."); | 221 FATAL("Error in class finalization during bootstrapping."); |
| 233 } | 222 } |
| 234 | 223 |
| 235 // Eagerly compile the _Closure class as it is the class of all closure | 224 // Eagerly compile the _Closure class as it is the class of all closure |
| 236 // instances. This allows us to just finalize function types without going | 225 // instances. This allows us to just finalize function types without going |
| 237 // through the hoops of trying to compile their scope class. | 226 // through the hoops of trying to compile their scope class. |
| 238 ObjectStore* object_store = thread->isolate()->object_store(); | 227 ObjectStore* object_store = thread->isolate()->object_store(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 253 ASSERT(field.Offset() == Closure::function_offset()); | 242 ASSERT(field.Offset() == Closure::function_offset()); |
| 254 field ^= fields.At(3); | 243 field ^= fields.At(3); |
| 255 ASSERT(field.Offset() == Closure::context_offset()); | 244 ASSERT(field.Offset() == Closure::context_offset()); |
| 256 #endif // defined(DEBUG) | 245 #endif // defined(DEBUG) |
| 257 | 246 |
| 258 // Eagerly compile Bool class, bool constants are used from within compiler. | 247 // Eagerly compile Bool class, bool constants are used from within compiler. |
| 259 cls = object_store->bool_class(); | 248 cls = object_store->bool_class(); |
| 260 Compiler::CompileClass(cls); | 249 Compiler::CompileClass(cls); |
| 261 } | 250 } |
| 262 | 251 |
| 263 | |
| 264 static RawError* BootstrapFromSource(Thread* thread) { | 252 static RawError* BootstrapFromSource(Thread* thread) { |
| 265 Isolate* isolate = thread->isolate(); | 253 Isolate* isolate = thread->isolate(); |
| 266 Zone* zone = thread->zone(); | 254 Zone* zone = thread->zone(); |
| 267 String& uri = String::Handle(zone); | 255 String& uri = String::Handle(zone); |
| 268 String& source = String::Handle(zone); | 256 String& source = String::Handle(zone); |
| 269 Script& script = Script::Handle(zone); | 257 Script& script = Script::Handle(zone); |
| 270 Library& lib = Library::Handle(zone); | 258 Library& lib = Library::Handle(zone); |
| 271 Error& error = Error::Handle(zone); | 259 Error& error = Error::Handle(zone); |
| 272 | 260 |
| 273 // Set the library tag handler for the isolate to the bootstrap | 261 // Set the library tag handler for the isolate to the bootstrap |
| (...skipping 29 matching lines...) Expand all Loading... |
| 303 | 291 |
| 304 if (error.IsNull()) { | 292 if (error.IsNull()) { |
| 305 Finish(thread, /*from_kernel=*/false); | 293 Finish(thread, /*from_kernel=*/false); |
| 306 } | 294 } |
| 307 // Restore the library tag handler for the isolate. | 295 // Restore the library tag handler for the isolate. |
| 308 isolate->set_library_tag_handler(saved_tag_handler); | 296 isolate->set_library_tag_handler(saved_tag_handler); |
| 309 | 297 |
| 310 return error.raw(); | 298 return error.raw(); |
| 311 } | 299 } |
| 312 | 300 |
| 313 | |
| 314 #if !defined(DART_PRECOMPILED_RUNTIME) | 301 #if !defined(DART_PRECOMPILED_RUNTIME) |
| 315 static RawError* BootstrapFromKernel(Thread* thread, kernel::Program* program) { | 302 static RawError* BootstrapFromKernel(Thread* thread, kernel::Program* program) { |
| 316 Zone* zone = thread->zone(); | 303 Zone* zone = thread->zone(); |
| 317 kernel::KernelReader reader(program); | 304 kernel::KernelReader reader(program); |
| 318 | 305 |
| 319 Isolate* isolate = thread->isolate(); | 306 Isolate* isolate = thread->isolate(); |
| 320 // Mark the already-pending classes. This mark bit will be used to avoid | 307 // Mark the already-pending classes. This mark bit will be used to avoid |
| 321 // adding classes to the list more than once. | 308 // adding classes to the list more than once. |
| 322 GrowableObjectArray& pending_classes = GrowableObjectArray::Handle( | 309 GrowableObjectArray& pending_classes = GrowableObjectArray::Handle( |
| 323 zone, isolate->object_store()->pending_classes()); | 310 zone, isolate->object_store()->pending_classes()); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 | 345 |
| 359 return Error::null(); | 346 return Error::null(); |
| 360 } | 347 } |
| 361 #else | 348 #else |
| 362 static RawError* BootstrapFromKernel(Thread* thread, kernel::Program* program) { | 349 static RawError* BootstrapFromKernel(Thread* thread, kernel::Program* program) { |
| 363 UNREACHABLE(); | 350 UNREACHABLE(); |
| 364 return Error::null(); | 351 return Error::null(); |
| 365 } | 352 } |
| 366 #endif | 353 #endif |
| 367 | 354 |
| 368 | |
| 369 RawError* Bootstrap::DoBootstrapping(kernel::Program* kernel_program) { | 355 RawError* Bootstrap::DoBootstrapping(kernel::Program* kernel_program) { |
| 370 Thread* thread = Thread::Current(); | 356 Thread* thread = Thread::Current(); |
| 371 Isolate* isolate = thread->isolate(); | 357 Isolate* isolate = thread->isolate(); |
| 372 Zone* zone = thread->zone(); | 358 Zone* zone = thread->zone(); |
| 373 String& uri = String::Handle(zone); | 359 String& uri = String::Handle(zone); |
| 374 Library& lib = Library::Handle(zone); | 360 Library& lib = Library::Handle(zone); |
| 375 | 361 |
| 376 HANDLESCOPE(thread); | 362 HANDLESCOPE(thread); |
| 377 | 363 |
| 378 // Ensure there are library objects for all the bootstrap libraries. | 364 // Ensure there are library objects for all the bootstrap libraries. |
| 379 for (intptr_t i = 0; i < kBootstrapLibraryCount; ++i) { | 365 for (intptr_t i = 0; i < kBootstrapLibraryCount; ++i) { |
| 380 ObjectStore::BootstrapLibraryId id = bootstrap_libraries[i].index; | 366 ObjectStore::BootstrapLibraryId id = bootstrap_libraries[i].index; |
| 381 uri = Symbols::New(thread, bootstrap_libraries[i].uri); | 367 uri = Symbols::New(thread, bootstrap_libraries[i].uri); |
| 382 lib = isolate->object_store()->bootstrap_library(id); | 368 lib = isolate->object_store()->bootstrap_library(id); |
| 383 ASSERT(lib.raw() == Library::LookupLibrary(thread, uri)); | 369 ASSERT(lib.raw() == Library::LookupLibrary(thread, uri)); |
| 384 if (lib.IsNull()) { | 370 if (lib.IsNull()) { |
| 385 lib = Library::NewLibraryHelper(uri, false); | 371 lib = Library::NewLibraryHelper(uri, false); |
| 386 lib.SetLoadRequested(); | 372 lib.SetLoadRequested(); |
| 387 lib.Register(thread); | 373 lib.Register(thread); |
| 388 isolate->object_store()->set_bootstrap_library(id, lib); | 374 isolate->object_store()->set_bootstrap_library(id, lib); |
| 389 } | 375 } |
| 390 } | 376 } |
| 391 | 377 |
| 392 return (kernel_program == NULL) ? BootstrapFromSource(thread) | 378 return (kernel_program == NULL) ? BootstrapFromSource(thread) |
| 393 : BootstrapFromKernel(thread, kernel_program); | 379 : BootstrapFromKernel(thread, kernel_program); |
| 394 } | 380 } |
| 395 | 381 |
| 396 } // namespace dart | 382 } // namespace dart |
| OLD | NEW |