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 |