| 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, Symbols::Slash()); | 
|  | 194   strings.SetAt(2, uri); | 
|  | 195   const String& part_uri = String::Handle(isolate, String::ConcatAll(strings)); | 
|  | 196 | 
|  | 197   // Create a script object and compile the part. | 
|  | 198   const Script& part_script = Script::Handle( | 
|  | 199       isolate, Script::New(part_uri, part_source, RawScript::kSourceTag)); | 
|  | 200   const Error& error = Error::Handle(isolate, Compile(lib, part_script)); | 
|  | 201   return Api::NewHandle(isolate, error.raw()); | 
| 104 } | 202 } | 
| 105 | 203 | 
| 106 | 204 | 
| 107 static Dart_Handle BootstrapLibraryTagHandler(Dart_LibraryTag tag, | 205 static Dart_Handle BootstrapLibraryTagHandler(Dart_LibraryTag tag, | 
| 108                                               Dart_Handle library, | 206                                               Dart_Handle library, | 
| 109                                               Dart_Handle uri) { | 207                                               Dart_Handle uri) { | 
| 110   Isolate* isolate = Isolate::Current(); | 208   Isolate* isolate = Isolate::Current(); | 
| 111   if (!Dart_IsLibrary(library)) { | 209   if (!Dart_IsLibrary(library)) { | 
| 112     return Dart_NewApiError("not a library"); | 210     return Dart_NewApiError("not a library"); | 
| 113   } | 211   } | 
| 114   if (!Dart_IsString(uri)) { | 212   if (!Dart_IsString(uri)) { | 
| 115     return Dart_NewApiError("uri is not a string"); | 213     return Dart_NewApiError("uri is not a string"); | 
| 116   } | 214   } | 
|  | 215   if (tag == kCanonicalizeUrl) { | 
|  | 216     // In the boot strap loader we do not try and do any canonicalization. | 
|  | 217     return uri; | 
|  | 218   } | 
| 117   const String& uri_str = Api::UnwrapStringHandle(isolate, uri); | 219   const String& uri_str = Api::UnwrapStringHandle(isolate, uri); | 
| 118   ASSERT(!uri_str.IsNull()); | 220   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) { | 221   if (tag == kImportTag) { | 
| 130     // We expect the core bootstrap libraries to only import other | 222     // We expect the core bootstrap libraries to only import other | 
| 131     // core bootstrap libraries. | 223     // core bootstrap libraries. | 
| 132     // We have precreated all the bootstrap library objects hence | 224     // We have precreated all the bootstrap library objects hence | 
| 133     // we do not expect to be called back with the tag set to kImportTag. | 225     // 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. | 226     // The bootstrap process explicitly loads all the libraries one by one. | 
| 135     return Dart_NewApiError("Invalid import of '%s' in a bootstrap library", | 227     return Dart_NewApiError("Invalid import of '%s' in a bootstrap library", | 
| 136                             uri_str.ToCString()); | 228                             uri_str.ToCString()); | 
| 137   } | 229   } | 
| 138   ASSERT(tag == kSourceTag); | 230   ASSERT(tag == kSourceTag); | 
| 139   const Library& lib = Api::UnwrapLibraryHandle(isolate, library); | 231   const Library& lib = Api::UnwrapLibraryHandle(isolate, library); | 
| 140   ASSERT(!lib.IsNull()); | 232   ASSERT(!lib.IsNull()); | 
| 141   return LoadPartSource(isolate, lib, uri_str); | 233   return LoadPartSource(isolate, lib, uri_str); | 
| 142 } | 234 } | 
| 143 | 235 | 
| 144 | 236 | 
| 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() { | 237 RawError* Bootstrap::LoadandCompileScripts() { | 
| 163   Isolate* isolate = Isolate::Current(); | 238   Isolate* isolate = Isolate::Current(); | 
| 164   String& uri = String::Handle(); | 239   String& uri = String::Handle(); | 
| 165   String& patch_uri = String::Handle(); | 240   String& patch_uri = String::Handle(); | 
| 166   String& source = String::Handle(); | 241   String& source = String::Handle(); | 
| 167   Script& script = Script::Handle(); | 242   Script& script = Script::Handle(); | 
| 168   Library& lib = Library::Handle(); | 243   Library& lib = Library::Handle(); | 
| 169   Error& error = Error::Handle(); | 244   Error& error = Error::Handle(); | 
| 170   Dart_LibraryTagHandler saved_tag_handler = isolate->library_tag_handler(); | 245   Dart_LibraryTagHandler saved_tag_handler = isolate->library_tag_handler(); | 
| 171 | 246 | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
| 190         bootstrap_libraries[i].index_, lib); | 265         bootstrap_libraries[i].index_, lib); | 
| 191     i = i + 1; | 266     i = i + 1; | 
| 192   } | 267   } | 
| 193 | 268 | 
| 194   // Load and compile bootstrap libraries. | 269   // Load and compile bootstrap libraries. | 
| 195   i = 0; | 270   i = 0; | 
| 196   while (bootstrap_libraries[i].index_ != ObjectStore::kNone) { | 271   while (bootstrap_libraries[i].index_ != ObjectStore::kNone) { | 
| 197     uri = Symbols::New(bootstrap_libraries[i].uri_); | 272     uri = Symbols::New(bootstrap_libraries[i].uri_); | 
| 198     lib = Library::LookupLibrary(uri); | 273     lib = Library::LookupLibrary(uri); | 
| 199     ASSERT(!lib.IsNull()); | 274     ASSERT(!lib.IsNull()); | 
| 200     source = GetLibrarySource(i, false); | 275     source = GetLibrarySource(lib, uri, false); | 
|  | 276     if (source.IsNull()) { | 
|  | 277       error ^= Api::UnwrapErrorHandle( | 
|  | 278           isolate, Api::NewError("Unable to find dart source for %s", | 
|  | 279                                  uri.ToCString())).raw(); | 
|  | 280       break; | 
|  | 281     } | 
| 201     script = Script::New(uri, source, RawScript::kLibraryTag); | 282     script = Script::New(uri, source, RawScript::kLibraryTag); | 
| 202     error = Compile(lib, script); | 283     error = Compile(lib, script); | 
| 203     if (!error.IsNull()) { | 284     if (!error.IsNull()) { | 
| 204       break; | 285       break; | 
| 205     } | 286     } | 
| 206     // If a patch exists, load and patch the script. | 287     // If a patch exists, load and patch the script. | 
| 207     if (bootstrap_libraries[i].patch_source_ != NULL) { | 288     if (bootstrap_libraries[i].patch_source_ != NULL) { | 
| 208       patch_uri = String::New(bootstrap_libraries[i].patch_uri_, | 289       patch_uri = String::New(bootstrap_libraries[i].patch_uri_, | 
| 209                               Heap::kOld); | 290                               Heap::kOld); | 
| 210       source = GetLibrarySource(i, true); | 291       source = GetLibrarySource(lib, uri, true); | 
|  | 292       if (source.IsNull()) { | 
|  | 293         error ^= Api::UnwrapErrorHandle( | 
|  | 294             isolate, Api::NewError("Unable to find dart patch source for %s", | 
|  | 295                                    uri.ToCString())).raw(); | 
|  | 296         break; | 
|  | 297       } | 
| 211       script = Script::New(patch_uri, source, RawScript::kPatchTag); | 298       script = Script::New(patch_uri, source, RawScript::kPatchTag); | 
| 212       error = lib.Patch(script); | 299       error = lib.Patch(script); | 
| 213       if (!error.IsNull()) { | 300       if (!error.IsNull()) { | 
| 214         break; | 301         break; | 
| 215       } | 302       } | 
| 216     } | 303     } | 
| 217     i = i + 1; | 304     i = i + 1; | 
| 218   } | 305   } | 
| 219   if (error.IsNull()) { | 306   if (error.IsNull()) { | 
| 220     SetupNativeResolver(); | 307     SetupNativeResolver(); | 
| 221   } | 308   } | 
| 222 | 309 | 
| 223   // Exit the Dart scope. | 310   // Exit the Dart scope. | 
| 224   Dart_ExitScope(); | 311   Dart_ExitScope(); | 
| 225 | 312 | 
| 226   // Restore the library tag handler for the isolate. | 313   // Restore the library tag handler for the isolate. | 
| 227   isolate->set_library_tag_handler(saved_tag_handler); | 314   isolate->set_library_tag_handler(saved_tag_handler); | 
| 228 | 315 | 
| 229   return error.raw(); | 316   return error.raw(); | 
| 230 } | 317 } | 
| 231 | 318 | 
| 232 }  // namespace dart | 319 }  // namespace dart | 
| OLD | NEW | 
|---|