Chromium Code Reviews| 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/compiler.h" | 10 #include "vm/compiler.h" |
| 11 #include "vm/dart_api_impl.h" | 11 #include "vm/dart_api_impl.h" |
| 12 #include "vm/object.h" | 12 #include "vm/object.h" |
| 13 #include "vm/object_store.h" | 13 #include "vm/object_store.h" |
| 14 #include "vm/symbols.h" | 14 #include "vm/symbols.h" |
| 15 | 15 |
| 16 namespace dart { | 16 namespace dart { |
| 17 | 17 |
| 18 DEFINE_FLAG(bool, print_bootstrap, false, "Print the bootstrap source."); | 18 DEFINE_FLAG(bool, print_bootstrap, false, "Print the bootstrap source."); |
| 19 | 19 |
| 20 #define INIT_LIBRARY(index, name, source, patch) \ | 20 #define INIT_LIBRARY(index, name, source, patch) \ |
| 21 { index, \ | 21 { index, \ |
| 22 "dart:"#name, source, \ | 22 "dart:"#name, source, \ |
| 23 "dart:"#name"-patch", patch } \ | 23 "dart:"#name"-patch", patch } \ |
| 24 | 24 |
| 25 typedef struct { | 25 typedef struct { |
| 26 intptr_t index_; | 26 intptr_t index_; |
| 27 const char* uri_; | 27 const char* uri_; |
| 28 const char* source_; | 28 const char** source_paths_; |
| 29 const char* patch_uri_; | 29 const char* patch_uri_; |
| 30 const char* patch_source_; | 30 const char* patch_source_; |
| 31 } bootstrap_lib_props; | 31 } bootstrap_lib_props; |
| 32 | 32 |
| 33 | 33 |
| 34 static bootstrap_lib_props bootstrap_libraries[] = { | 34 static bootstrap_lib_props bootstrap_libraries[] = { |
| 35 INIT_LIBRARY(ObjectStore::kCore, | 35 INIT_LIBRARY(ObjectStore::kCore, |
| 36 core, | 36 core, |
| 37 Bootstrap::corelib_source_, | 37 Bootstrap::corelib_source_paths_, |
| 38 Bootstrap::corelib_patch_), | 38 Bootstrap::corelib_patch_), |
| 39 INIT_LIBRARY(ObjectStore::kAsync, | 39 INIT_LIBRARY(ObjectStore::kAsync, |
| 40 async, | 40 async, |
| 41 Bootstrap::async_source_, | 41 Bootstrap::async_source_paths_, |
| 42 Bootstrap::async_patch_), | 42 Bootstrap::async_patch_), |
| 43 INIT_LIBRARY(ObjectStore::kCollection, | 43 INIT_LIBRARY(ObjectStore::kCollection, |
| 44 collection, | 44 collection, |
| 45 Bootstrap::collection_source_, | 45 Bootstrap::collection_source_paths_, |
| 46 Bootstrap::collection_patch_), | 46 Bootstrap::collection_patch_), |
| 47 INIT_LIBRARY(ObjectStore::kCollectionDev, | 47 INIT_LIBRARY(ObjectStore::kCollectionDev, |
| 48 _collection-dev, | 48 _collection-dev, |
| 49 Bootstrap::collection_dev_source_, | 49 Bootstrap::collection_dev_source_paths_, |
| 50 Bootstrap::collection_dev_patch_), | 50 Bootstrap::collection_dev_patch_), |
| 51 INIT_LIBRARY(ObjectStore::kCrypto, | 51 INIT_LIBRARY(ObjectStore::kCrypto, |
| 52 crypto, | 52 crypto, |
| 53 Bootstrap::crypto_source_, | 53 Bootstrap::crypto_source_paths_, |
| 54 NULL), | 54 NULL), |
| 55 INIT_LIBRARY(ObjectStore::kIsolate, | 55 INIT_LIBRARY(ObjectStore::kIsolate, |
| 56 isolate, | 56 isolate, |
| 57 Bootstrap::isolate_source_, | 57 Bootstrap::isolate_source_paths_, |
| 58 Bootstrap::isolate_patch_), | 58 Bootstrap::isolate_patch_), |
| 59 INIT_LIBRARY(ObjectStore::kJson, | 59 INIT_LIBRARY(ObjectStore::kJson, |
| 60 json, | 60 json, |
| 61 Bootstrap::json_source_, | 61 Bootstrap::json_source_paths_, |
| 62 Bootstrap::json_patch_), | 62 Bootstrap::json_patch_), |
| 63 INIT_LIBRARY(ObjectStore::kMath, | 63 INIT_LIBRARY(ObjectStore::kMath, |
| 64 math, | 64 math, |
| 65 Bootstrap::math_source_, | 65 Bootstrap::math_source_paths_, |
| 66 Bootstrap::math_patch_), | 66 Bootstrap::math_patch_), |
| 67 INIT_LIBRARY(ObjectStore::kMirrors, | 67 INIT_LIBRARY(ObjectStore::kMirrors, |
| 68 mirrors, | 68 mirrors, |
| 69 Bootstrap::mirrors_source_, | 69 Bootstrap::mirrors_source_paths_, |
| 70 Bootstrap::mirrors_patch_), | 70 Bootstrap::mirrors_patch_), |
| 71 INIT_LIBRARY(ObjectStore::kTypedData, | 71 INIT_LIBRARY(ObjectStore::kTypedData, |
| 72 typed_data, | 72 typed_data, |
| 73 Bootstrap::typed_data_source_, | 73 Bootstrap::typed_data_source_paths_, |
| 74 Bootstrap::typed_data_patch_), | 74 Bootstrap::typed_data_patch_), |
| 75 INIT_LIBRARY(ObjectStore::kUtf, | 75 INIT_LIBRARY(ObjectStore::kUtf, |
| 76 utf, | 76 utf, |
| 77 Bootstrap::utf_source_, | 77 Bootstrap::utf_source_paths_, |
| 78 NULL), | 78 NULL), |
| 79 INIT_LIBRARY(ObjectStore::kUri, | 79 INIT_LIBRARY(ObjectStore::kUri, |
| 80 uri, | 80 uri, |
| 81 Bootstrap::uri_source_, | 81 Bootstrap::uri_source_paths_, |
| 82 NULL), | 82 NULL), |
| 83 | 83 |
| 84 { ObjectStore::kNone, NULL, NULL, NULL, NULL } | 84 { ObjectStore::kNone, NULL, NULL, NULL, NULL } |
| 85 }; | 85 }; |
| 86 | 86 |
| 87 | 87 |
| 88 static RawString* GetLibrarySource(intptr_t index, bool patch) { | 88 static RawString* GetLibrarySource(const Library& lib, |
| 89 // TODO(asiva): Replace with actual read of the source file. | 89 const String& uri, |
| 90 const char* source = patch ? bootstrap_libraries[index].patch_source_ : | 90 bool patch) { |
| 91 bootstrap_libraries[index].source_; | 91 // First check if this is a valid boot strap library and find it's index |
| 92 ASSERT(source != NULL); | 92 // in the 'bootstrap_libraries' table above. |
| 93 return String::New(source, Heap::kOld); | 93 intptr_t index = 0; |
| 94 const String& lib_uri = String::Handle(lib.url()); | |
| 95 while (bootstrap_libraries[index].index_ != ObjectStore::kNone) { | |
| 96 if (lib_uri.Equals(bootstrap_libraries[index].uri_)) { | |
| 97 break; | |
| 98 } | |
| 99 index += 1; | |
| 100 } | |
| 101 if (bootstrap_libraries[index].index_ == ObjectStore::kNone) { | |
| 102 return String::null(); // Library is not a boot strap library. | |
| 103 } | |
| 104 | |
| 105 if (patch) { | |
| 106 // TODO(asiva): Replace with actual read of the source file. | |
| 107 const char* source = bootstrap_libraries[index].patch_source_; | |
| 108 ASSERT(source != NULL); | |
| 109 return String::New(source, Heap::kOld); | |
| 110 } | |
| 111 | |
| 112 // Try to read the source using the path specified for the uri. | |
| 113 const char** source_paths = bootstrap_libraries[index].source_paths_; | |
| 114 if (source_paths == NULL) { | |
| 115 return String::null(); // No path mapping information exists for library. | |
| 116 } | |
| 117 intptr_t i = 0; | |
| 118 const char* source_path = NULL; | |
| 119 while (source_paths[i] != NULL) { | |
| 120 if (uri.Equals(source_paths[i])) { | |
| 121 source_path = source_paths[i + 1]; | |
| 122 break; | |
| 123 } | |
| 124 i += 2; | |
| 125 } | |
| 126 if (source_path == NULL) { | |
| 127 return String::null(); // Uri does not exist in path mapping information. | |
| 128 } | |
| 129 | |
| 130 Dart_FileOpenCallback file_open = Isolate::file_open_callback(); | |
| 131 Dart_FileReadCallback file_read = Isolate::file_read_callback(); | |
| 132 Dart_FileCloseCallback file_close = Isolate::file_close_callback(); | |
| 133 if (file_open == NULL || file_read == NULL || file_close == NULL) { | |
| 134 return String::null(); // File operations are not supported. | |
| 135 } | |
| 136 | |
| 137 void* stream = (*file_open)(source_path, false); | |
| 138 if (stream == NULL) { | |
| 139 return String::null(); | |
| 140 } | |
| 141 | |
| 142 const uint8_t* utf8_array = NULL; | |
| 143 intptr_t file_length = -1; | |
| 144 (*file_read)(&utf8_array, &file_length, stream); | |
| 145 if (file_length == -1) { | |
| 146 return String::null(); | |
| 147 } | |
| 148 ASSERT(utf8_array != NULL); | |
| 149 | |
| 150 (*file_close)(stream); | |
| 151 | |
| 152 return String::FromUTF8(utf8_array, file_length); | |
| 153 } | |
| 154 | |
| 155 | |
| 156 static RawError* Compile(const Library& library, const Script& script) { | |
| 157 if (FLAG_print_bootstrap) { | |
| 158 OS::Print("Bootstrap source '%s':\n%s\n", | |
| 159 String::Handle(script.url()).ToCString(), | |
| 160 String::Handle(script.Source()).ToCString()); | |
| 161 } | |
| 162 bool update_lib_status = (script.kind() == RawScript::kScriptTag || | |
| 163 script.kind() == RawScript::kLibraryTag); | |
| 164 if (update_lib_status) { | |
| 165 library.SetLoadInProgress(); | |
| 166 } | |
| 167 const Error& error = Error::Handle(Compiler::Compile(library, script)); | |
| 168 if (update_lib_status) { | |
| 169 if (error.IsNull()) { | |
| 170 library.SetLoaded(); | |
| 171 } else { | |
| 172 library.SetLoadError(); | |
| 173 } | |
| 174 } | |
| 175 return error.raw(); | |
| 94 } | 176 } |
| 95 | 177 |
| 96 | 178 |
| 97 static Dart_Handle LoadPartSource(Isolate* isolate, | 179 static Dart_Handle LoadPartSource(Isolate* isolate, |
| 98 const Library& lib, | 180 const Library& lib, |
| 99 const String& uri) { | 181 const String& uri) { |
| 100 // TODO(asiva): For now we return an error here, once we start | 182 const String& part_source = String::Handle( |
| 101 // loading libraries from the real source this would have to call the | 183 isolate, GetLibrarySource(lib, uri, false)); |
| 102 // file read callback here and invoke Compiler::Compile on it. | 184 const String& lib_uri = String::Handle(isolate, lib.url()); |
| 103 return Dart_NewApiError("Unable to load source '%s' ", uri.ToCString()); | 185 if (part_source.IsNull()) { |
| 186 return Dart_NewApiError("Unable to read part file '%s' of library '%s'", | |
| 187 uri.ToCString(), lib_uri.ToCString()); | |
| 188 } | |
| 189 | |
| 190 // Prepend the library URI to form a unique script URI for the part. | |
| 191 const Array& strings = Array::Handle(isolate, Array::New(3)); | |
| 192 strings.SetAt(0, lib_uri); | |
| 193 strings.SetAt(1, String::Handle(isolate, String::New("/"))); | |
|
Ivan Posva
2013/05/03 05:21:35
Symbols::Slash()
siva
2013/05/03 17:03:08
Done.
| |
| 194 strings.SetAt(2, uri); | |
| 195 const String& part_uri = String::Handle(isolate, String::ConcatAll(strings)); | |
| 196 | |
| 197 OS::Print("%s\n", part_uri.ToCString()); | |
| 198 | |
| 199 // Create a script object and compile the part. | |
| 200 const Script& part_script = Script::Handle( | |
| 201 isolate, Script::New(part_uri, part_source, RawScript::kSourceTag)); | |
| 202 const Error& error = Error::Handle(isolate, Compile(lib, part_script)); | |
| 203 return Api::NewHandle(isolate, error.raw()); | |
| 104 } | 204 } |
| 105 | 205 |
| 106 | 206 |
| 107 static Dart_Handle BootstrapLibraryTagHandler(Dart_LibraryTag tag, | 207 static Dart_Handle BootstrapLibraryTagHandler(Dart_LibraryTag tag, |
| 108 Dart_Handle library, | 208 Dart_Handle library, |
| 109 Dart_Handle uri) { | 209 Dart_Handle uri) { |
| 110 Isolate* isolate = Isolate::Current(); | 210 Isolate* isolate = Isolate::Current(); |
| 111 if (!Dart_IsLibrary(library)) { | 211 if (!Dart_IsLibrary(library)) { |
| 112 return Dart_NewApiError("not a library"); | 212 return Dart_NewApiError("not a library"); |
| 113 } | 213 } |
| 114 if (!Dart_IsString(uri)) { | 214 if (!Dart_IsString(uri)) { |
| 115 return Dart_NewApiError("uri is not a string"); | 215 return Dart_NewApiError("uri is not a string"); |
| 116 } | 216 } |
| 217 if (tag == kCanonicalizeUrl) { | |
| 218 // In the boot strap loader we do not try and do any canonicalization. | |
| 219 return uri; | |
| 220 } | |
| 117 const String& uri_str = Api::UnwrapStringHandle(isolate, uri); | 221 const String& uri_str = Api::UnwrapStringHandle(isolate, uri); |
| 118 ASSERT(!uri_str.IsNull()); | 222 ASSERT(!uri_str.IsNull()); |
| 119 bool is_dart_scheme_uri = uri_str.StartsWith(Symbols::DartScheme()); | |
| 120 if (!is_dart_scheme_uri) { | |
| 121 // The bootstrap tag handler can only handle dart scheme uris. | |
| 122 return Dart_NewApiError("Do not know how to load '%s' ", | |
| 123 uri_str.ToCString()); | |
| 124 } | |
| 125 if (tag == kCanonicalizeUrl) { | |
| 126 // Dart Scheme URIs do not need any canonicalization. | |
| 127 return uri; | |
| 128 } | |
| 129 if (tag == kImportTag) { | 223 if (tag == kImportTag) { |
| 130 // We expect the core bootstrap libraries to only import other | 224 // We expect the core bootstrap libraries to only import other |
| 131 // core bootstrap libraries. | 225 // core bootstrap libraries. |
| 132 // We have precreated all the bootstrap library objects hence | 226 // We have precreated all the bootstrap library objects hence |
| 133 // we do not expect to be called back with the tag set to kImportTag. | 227 // we do not expect to be called back with the tag set to kImportTag. |
| 134 // The bootstrap process explicitly loads all the libraries one by one. | 228 // The bootstrap process explicitly loads all the libraries one by one. |
| 135 return Dart_NewApiError("Invalid import of '%s' in a bootstrap library", | 229 return Dart_NewApiError("Invalid import of '%s' in a bootstrap library", |
| 136 uri_str.ToCString()); | 230 uri_str.ToCString()); |
| 137 } | 231 } |
| 138 ASSERT(tag == kSourceTag); | 232 ASSERT(tag == kSourceTag); |
| 139 const Library& lib = Api::UnwrapLibraryHandle(isolate, library); | 233 const Library& lib = Api::UnwrapLibraryHandle(isolate, library); |
| 140 ASSERT(!lib.IsNull()); | 234 ASSERT(!lib.IsNull()); |
| 141 return LoadPartSource(isolate, lib, uri_str); | 235 return LoadPartSource(isolate, lib, uri_str); |
| 142 } | 236 } |
| 143 | 237 |
| 144 | 238 |
| 145 static RawError* Compile(const Library& library, const Script& script) { | |
| 146 if (FLAG_print_bootstrap) { | |
| 147 OS::Print("Bootstrap source '%s':\n%s\n", | |
| 148 String::Handle(script.url()).ToCString(), | |
| 149 String::Handle(script.Source()).ToCString()); | |
| 150 } | |
| 151 library.SetLoadInProgress(); | |
| 152 const Error& error = Error::Handle(Compiler::Compile(library, script)); | |
| 153 if (error.IsNull()) { | |
| 154 library.SetLoaded(); | |
| 155 } else { | |
| 156 library.SetLoadError(); | |
| 157 } | |
| 158 return error.raw(); | |
| 159 } | |
| 160 | |
| 161 | |
| 162 RawError* Bootstrap::LoadandCompileScripts() { | 239 RawError* Bootstrap::LoadandCompileScripts() { |
| 163 Isolate* isolate = Isolate::Current(); | 240 Isolate* isolate = Isolate::Current(); |
| 164 String& uri = String::Handle(); | 241 String& uri = String::Handle(); |
| 165 String& patch_uri = String::Handle(); | 242 String& patch_uri = String::Handle(); |
| 166 String& source = String::Handle(); | 243 String& source = String::Handle(); |
| 167 Script& script = Script::Handle(); | 244 Script& script = Script::Handle(); |
| 168 Library& lib = Library::Handle(); | 245 Library& lib = Library::Handle(); |
| 169 Error& error = Error::Handle(); | 246 Error& error = Error::Handle(); |
| 170 Dart_LibraryTagHandler saved_tag_handler = isolate->library_tag_handler(); | 247 Dart_LibraryTagHandler saved_tag_handler = isolate->library_tag_handler(); |
| 171 | 248 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 190 bootstrap_libraries[i].index_, lib); | 267 bootstrap_libraries[i].index_, lib); |
| 191 i = i + 1; | 268 i = i + 1; |
| 192 } | 269 } |
| 193 | 270 |
| 194 // Load and compile bootstrap libraries. | 271 // Load and compile bootstrap libraries. |
| 195 i = 0; | 272 i = 0; |
| 196 while (bootstrap_libraries[i].index_ != ObjectStore::kNone) { | 273 while (bootstrap_libraries[i].index_ != ObjectStore::kNone) { |
| 197 uri = Symbols::New(bootstrap_libraries[i].uri_); | 274 uri = Symbols::New(bootstrap_libraries[i].uri_); |
| 198 lib = Library::LookupLibrary(uri); | 275 lib = Library::LookupLibrary(uri); |
| 199 ASSERT(!lib.IsNull()); | 276 ASSERT(!lib.IsNull()); |
| 200 source = GetLibrarySource(i, false); | 277 source = GetLibrarySource(lib, uri, false); |
| 278 if (source.IsNull()) { | |
| 279 error ^= Api::UnwrapErrorHandle( | |
| 280 isolate, Api::NewError("Unable to find dart source for %s", | |
| 281 uri.ToCString())).raw(); | |
| 282 break; | |
| 283 } | |
| 201 script = Script::New(uri, source, RawScript::kLibraryTag); | 284 script = Script::New(uri, source, RawScript::kLibraryTag); |
| 202 error = Compile(lib, script); | 285 error = Compile(lib, script); |
| 203 if (!error.IsNull()) { | 286 if (!error.IsNull()) { |
| 204 break; | 287 break; |
| 205 } | 288 } |
| 206 // If a patch exists, load and patch the script. | 289 // If a patch exists, load and patch the script. |
| 207 if (bootstrap_libraries[i].patch_source_ != NULL) { | 290 if (bootstrap_libraries[i].patch_source_ != NULL) { |
| 208 patch_uri = String::New(bootstrap_libraries[i].patch_uri_, | 291 patch_uri = String::New(bootstrap_libraries[i].patch_uri_, |
| 209 Heap::kOld); | 292 Heap::kOld); |
| 210 source = GetLibrarySource(i, true); | 293 source = GetLibrarySource(lib, uri, true); |
| 294 if (source.IsNull()) { | |
| 295 error ^= Api::UnwrapErrorHandle( | |
| 296 isolate, Api::NewError("Unable to find dart patch source for %s", | |
| 297 uri.ToCString())).raw(); | |
| 298 break; | |
| 299 } | |
| 211 script = Script::New(patch_uri, source, RawScript::kPatchTag); | 300 script = Script::New(patch_uri, source, RawScript::kPatchTag); |
| 212 error = lib.Patch(script); | 301 error = lib.Patch(script); |
| 213 if (!error.IsNull()) { | 302 if (!error.IsNull()) { |
| 214 break; | 303 break; |
| 215 } | 304 } |
| 216 } | 305 } |
| 217 i = i + 1; | 306 i = i + 1; |
| 218 } | 307 } |
| 219 if (error.IsNull()) { | 308 if (error.IsNull()) { |
| 220 SetupNativeResolver(); | 309 SetupNativeResolver(); |
| 221 } | 310 } |
| 222 | 311 |
| 223 // Exit the Dart scope. | 312 // Exit the Dart scope. |
| 224 Dart_ExitScope(); | 313 Dart_ExitScope(); |
| 225 | 314 |
| 226 // Restore the library tag handler for the isolate. | 315 // Restore the library tag handler for the isolate. |
| 227 isolate->set_library_tag_handler(saved_tag_handler); | 316 isolate->set_library_tag_handler(saved_tag_handler); |
| 228 | 317 |
| 229 return error.raw(); | 318 return error.raw(); |
| 230 } | 319 } |
| 231 | 320 |
| 232 } // namespace dart | 321 } // namespace dart |
| OLD | NEW |