| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 // Generate a snapshot file after loading all the scripts specified on the | 5 // Generate a snapshot file after loading all the scripts specified on the |
| 6 // command line. | 6 // command line. |
| 7 | 7 |
| 8 #include <stdlib.h> | 8 #include <stdlib.h> |
| 9 #include <string.h> | 9 #include <string.h> |
| 10 #include <stdio.h> | 10 #include <stdio.h> |
| 11 | 11 |
| 12 #include "include/dart_api.h" | 12 #include "include/dart_api.h" |
| 13 | 13 |
| 14 #include "bin/builtin.h" | 14 #include "bin/builtin.h" |
| 15 #include "bin/dartutils.h" | 15 #include "bin/dartutils.h" |
| 16 #include "bin/file.h" | 16 #include "bin/file.h" |
| 17 #include "bin/globals.h" | 17 #include "bin/globals.h" |
| 18 #include "bin/process_script.h" | |
| 19 | 18 |
| 20 // Global state that indicates whether a snapshot is to be created and | 19 // Global state that indicates whether a snapshot is to be created and |
| 21 // if so which file to write the snapshot into. | 20 // if so which file to write the snapshot into. |
| 22 static const char* snapshot_filename = NULL; | 21 static const char* snapshot_filename = NULL; |
| 23 | 22 |
| 24 // Global state that captures the URL mappings specified on the command line. | 23 // Global state that captures the URL mappings specified on the command line. |
| 25 static CommandLineOptions* url_mapping = NULL; | 24 static CommandLineOptions* url_mapping = NULL; |
| 26 | 25 |
| 27 static bool IsValidFlag(const char* name, | 26 static bool IsValidFlag(const char* name, |
| 28 const char* prefix, | 27 const char* prefix, |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 const bool kWritable = true; | 101 const bool kWritable = true; |
| 103 File* file = File::Open(snapshot_filename, kWritable); | 102 File* file = File::Open(snapshot_filename, kWritable); |
| 104 ASSERT(file != NULL); | 103 ASSERT(file != NULL); |
| 105 for (intptr_t i = 0; i < size; i++) { | 104 for (intptr_t i = 0; i < size; i++) { |
| 106 file->WriteByte(buffer[i]); | 105 file->WriteByte(buffer[i]); |
| 107 } | 106 } |
| 108 delete file; | 107 delete file; |
| 109 } | 108 } |
| 110 | 109 |
| 111 | 110 |
| 112 static bool MapLibraryUrl(const char* url_chars, | |
| 113 const char** mapped_url_chars) { | |
| 114 *mapped_url_chars = url_chars; | |
| 115 if (url_mapping != NULL) { | |
| 116 // We need to check if the passed in url is found in the url_mapping array, | |
| 117 // in that case use the mapped entry. | |
| 118 int len = strlen(url_chars); | |
| 119 for (int idx = 0; idx < url_mapping->count(); idx++) { | |
| 120 const char* url_name = url_mapping->GetArgument(idx); | |
| 121 if (!strncmp(url_chars, url_name, len) && | |
| 122 (url_name[len] == ',')) { | |
| 123 const char* url_mapped_name = url_name + len + 1; | |
| 124 if (strlen(url_mapped_name) != 0) { | |
| 125 *mapped_url_chars = url_mapped_name; | |
| 126 return true; // Found a mapping for this URL. | |
| 127 } | |
| 128 } | |
| 129 } | |
| 130 } | |
| 131 return false; // Did not find any mapping for this URL. | |
| 132 } | |
| 133 | |
| 134 | |
| 135 static Dart_Handle CreateSnapshotLibraryTagHandler(Dart_LibraryTag tag, | 111 static Dart_Handle CreateSnapshotLibraryTagHandler(Dart_LibraryTag tag, |
| 136 Dart_Handle library, | 112 Dart_Handle library, |
| 137 Dart_Handle url) { | 113 Dart_Handle url) { |
| 138 if (!Dart_IsLibrary(library)) { | 114 if (!Dart_IsLibrary(library)) { |
| 139 return Dart_Error("not a library"); | 115 return Dart_Error("not a library"); |
| 140 } | 116 } |
| 141 if (!Dart_IsString8(url)) { | 117 if (!Dart_IsString8(url)) { |
| 142 return Dart_Error("url is not a string"); | 118 return Dart_Error("url is not a string"); |
| 143 } | 119 } |
| 144 const char* url_chars = NULL; | 120 const char* url_string = NULL; |
| 145 Dart_Handle result = Dart_StringToCString(url, &url_chars); | 121 Dart_Handle result = Dart_StringToCString(url, &url_string); |
| 146 if (Dart_IsError(result)) { | 122 if (Dart_IsError(result)) { |
| 147 return Dart_Error("accessing url characters failed"); | 123 return Dart_Error("accessing url characters failed"); |
| 148 } | 124 } |
| 149 | 125 |
| 150 // If the URL starts with "dart:" then it is handled specially. | 126 // If the URL starts with "dart:" then it is handled specially. |
| 151 static const char* kDartScheme = "dart:"; | 127 bool is_dart_scheme_url = DartUtils::IsDartSchemeURL(url_string); |
| 152 static const intptr_t kDartSchemeLen = strlen(kDartScheme); | |
| 153 bool is_dart_scheme_url = | |
| 154 (strncmp(url_chars, kDartScheme, kDartSchemeLen) == 0); | |
| 155 | |
| 156 if (tag == kCanonicalizeUrl) { | 128 if (tag == kCanonicalizeUrl) { |
| 157 if (is_dart_scheme_url) { | 129 if (is_dart_scheme_url) { |
| 158 return url; | 130 return url; |
| 159 } | 131 } |
| 160 // Get the url of the calling library. | 132 return DartUtils::CanonicalizeURL(url_mapping, library, url_string); |
| 161 Dart_Handle library_url = Dart_LibraryUrl(library); | |
| 162 if (Dart_IsError(library_url)) { | |
| 163 return Dart_Error("accessing library url failed"); | |
| 164 } | |
| 165 if (!Dart_IsString8(library_url)) { | |
| 166 return Dart_Error("library url is not a string"); | |
| 167 } | |
| 168 const char* library_url_chars = NULL; | |
| 169 result = Dart_StringToCString(library_url, &library_url_chars); | |
| 170 if (Dart_IsError(result)) { | |
| 171 return Dart_Error("accessing library url characters failed"); | |
| 172 } | |
| 173 const char* mapped_library_url_chars; | |
| 174 MapLibraryUrl(library_url_chars, &mapped_library_url_chars); | |
| 175 const char* canon_url_chars = GetCanonicalPath(mapped_library_url_chars, | |
| 176 url_chars); | |
| 177 Dart_Handle canon_url = Dart_NewString(canon_url_chars); | |
| 178 free(const_cast<char*>(canon_url_chars)); | |
| 179 | |
| 180 return canon_url; // canon_url has error string in case of errors. | |
| 181 } | 133 } |
| 182 if (is_dart_scheme_url) { | 134 return DartUtils::LoadSource(url_mapping, library, url, tag, url_string); |
| 183 const char* mapped_url_chars; | |
| 184 bool url_is_mapped = MapLibraryUrl(url_chars, &mapped_url_chars); | |
| 185 if (url_is_mapped) { | |
| 186 // We have a URL mapping specified, just read the file that the | |
| 187 // URL mapping specifies and load it. | |
| 188 url_chars = mapped_url_chars; | |
| 189 } else { | |
| 190 return Dart_Error("Do not know how to load %s", url_chars); | |
| 191 } | |
| 192 } | |
| 193 // The tag is either an import or a source tag. Read the file pointed to by | |
| 194 // url_chars and load it. | |
| 195 Dart_Handle source = ReadStringFromFile(url_chars); | |
| 196 if (Dart_IsError(source)) { | |
| 197 return source; // source contains the error string. | |
| 198 } | |
| 199 if (tag == kImportTag) { | |
| 200 return Dart_LoadLibrary(url, source); | |
| 201 } else if (tag == kSourceTag) { | |
| 202 return Dart_LoadSource(library, url, source); | |
| 203 } | |
| 204 return Dart_Error("wrong tag"); | |
| 205 } | 135 } |
| 206 | 136 |
| 207 | 137 |
| 208 static Dart_Handle LoadSnapshotCreationScript(const char* script_name) { | 138 static Dart_Handle LoadSnapshotCreationScript(const char* script_name) { |
| 209 Dart_Handle source = ReadStringFromFile(script_name); | 139 Dart_Handle source = DartUtils::ReadStringFromFile(script_name); |
| 210 if (Dart_IsError(source)) { | 140 if (Dart_IsError(source)) { |
| 211 return source; // source contains the error string. | 141 return source; // source contains the error string. |
| 212 } | 142 } |
| 213 Dart_Handle url = Dart_NewString(script_name); | 143 Dart_Handle url = Dart_NewString(script_name); |
| 214 | 144 |
| 215 return Dart_LoadScript(url, source, CreateSnapshotLibraryTagHandler); | 145 return Dart_LoadScript(url, source, CreateSnapshotLibraryTagHandler); |
| 216 } | 146 } |
| 217 | 147 |
| 218 | 148 |
| 219 static Dart_Handle BuiltinSnapshotLibraryTagHandler(Dart_LibraryTag tag, | 149 static Dart_Handle BuiltinLibraryTagHandler(Dart_LibraryTag tag, |
| 220 Dart_Handle library, | 150 Dart_Handle library, |
| 221 Dart_Handle url) { | 151 Dart_Handle url) { |
| 222 if (!Dart_IsLibrary(library)) { | 152 if (!Dart_IsLibrary(library)) { |
| 223 return Dart_Error("not a library"); | 153 return Dart_Error("not a library"); |
| 224 } | 154 } |
| 225 if (!Dart_IsString8(url)) { | 155 if (!Dart_IsString8(url)) { |
| 226 return Dart_Error("url is not a string"); | 156 return Dart_Error("url is not a string"); |
| 227 } | 157 } |
| 228 const char* url_chars = NULL; | 158 const char* url_string = NULL; |
| 229 Dart_Handle result = Dart_StringToCString(url, &url_chars); | 159 Dart_Handle result = Dart_StringToCString(url, &url_string); |
| 230 if (Dart_IsError(result)) { | 160 if (Dart_IsError(result)) { |
| 231 return Dart_Error("accessing url characters failed"); | 161 return Dart_Error("accessing url characters failed"); |
| 232 } | 162 } |
| 233 // We only support canonicalization of "dart:". | 163 // We only support canonicalization of "dart:". |
| 234 static const char* kDartScheme = "dart:"; | 164 if (DartUtils::IsDartSchemeURL(url_string)) { |
| 235 static const intptr_t kDartSchemeLen = strlen(kDartScheme); | |
| 236 if (strncmp(url_chars, kDartScheme, kDartSchemeLen) == 0) { | |
| 237 if (tag == kCanonicalizeUrl) { | 165 if (tag == kCanonicalizeUrl) { |
| 238 return url; | 166 return url; |
| 239 } | 167 } |
| 240 return Dart_Error("unexpected tag encountered %d", tag); | 168 return Dart_Error("unsupported url encountered %s", url_string); |
| 241 } | 169 } |
| 242 return Dart_Error("unsupported url encountered %s", url_chars); | 170 return Dart_Error("unexpected tag encountered %d", tag); |
| 243 } | 171 } |
| 244 | 172 |
| 245 | 173 |
| 246 static Dart_Handle LoadGenericSnapshotCreationScript() { | 174 static Dart_Handle LoadGenericSnapshotCreationScript() { |
| 247 Dart_Handle source = Builtin_Source(); | 175 Dart_Handle source = Builtin_Source(); |
| 248 if (Dart_IsError(source)) { | 176 if (Dart_IsError(source)) { |
| 249 return source; // source contains the error string. | 177 return source; // source contains the error string. |
| 250 } | 178 } |
| 251 Dart_Handle url = Dart_NewString(DartUtils::kBuiltinLibURL); | 179 Dart_Handle url = Dart_NewString(DartUtils::kBuiltinLibURL); |
| 252 Dart_Handle lib = Dart_LoadScript(url, | 180 Dart_Handle lib = Dart_LoadScript(url, source, BuiltinLibraryTagHandler); |
| 253 source, | |
| 254 BuiltinSnapshotLibraryTagHandler); | |
| 255 if (!Dart_IsError(lib)) { | 181 if (!Dart_IsError(lib)) { |
| 256 Builtin_SetupLibrary(lib); | 182 Builtin_SetupLibrary(lib); |
| 257 } | 183 } |
| 258 return lib; | 184 return lib; |
| 259 } | 185 } |
| 260 | 186 |
| 261 | 187 |
| 262 static void* SnapshotCreateCallback(void* data) { | 188 static void* SnapshotCreateCallback(void* data) { |
| 263 const char* script_name = reinterpret_cast<const char*>(data); | 189 const char* script_name = reinterpret_cast<const char*>(data); |
| 264 Dart_Handle result; | 190 Dart_Handle result; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 339 // and writes out a snapshot. | 265 // and writes out a snapshot. |
| 340 Dart_Isolate isolate = Dart_CreateIsolate(NULL, script_name); | 266 Dart_Isolate isolate = Dart_CreateIsolate(NULL, script_name); |
| 341 if (isolate == NULL) { | 267 if (isolate == NULL) { |
| 342 return 255; | 268 return 255; |
| 343 } | 269 } |
| 344 | 270 |
| 345 // Shutdown the isolate. | 271 // Shutdown the isolate. |
| 346 Dart_ShutdownIsolate(); | 272 Dart_ShutdownIsolate(); |
| 347 return 0; | 273 return 0; |
| 348 } | 274 } |
| OLD | NEW |