Chromium Code Reviews| 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/file.h" | 15 #include "bin/file.h" |
| 16 #include "bin/globals.h" | 16 #include "bin/globals.h" |
| 17 #include "bin/process_script.h" | 17 #include "bin/process_script.h" |
| 18 | 18 |
| 19 // 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 |
| 20 // if so which file to write the snapshot into. | 20 // if so which file to write the snapshot into. |
| 21 static const char* snapshot_filename = NULL; | 21 static const char* snapshot_filename = NULL; |
| 22 | 22 |
| 23 // Global state that captures the URL mappings specified on the command line. | |
| 24 static CommandLineOptions* url_mapping = NULL; | |
| 25 | |
| 23 static bool IsValidFlag(const char* name, | 26 static bool IsValidFlag(const char* name, |
| 24 const char* prefix, | 27 const char* prefix, |
| 25 intptr_t prefix_length) { | 28 intptr_t prefix_length) { |
| 26 intptr_t name_length = strlen(name); | 29 intptr_t name_length = strlen(name); |
| 27 return ((name_length > prefix_length) && | 30 return ((name_length > prefix_length) && |
| 28 (strncmp(name, prefix, prefix_length) == 0)); | 31 (strncmp(name, prefix, prefix_length) == 0)); |
| 29 } | 32 } |
| 30 | 33 |
| 31 | 34 |
| 32 static const char* ProcessOption(const char* option, const char* name) { | 35 static const char* ProcessOption(const char* option, const char* name) { |
| 33 const intptr_t length = strlen(name); | 36 const intptr_t length = strlen(name); |
| 34 if (strncmp(option, name, length) == 0) { | 37 if (strncmp(option, name, length) == 0) { |
| 35 return (option + length); | 38 return (option + length); |
| 36 } | 39 } |
| 37 return NULL; | 40 return NULL; |
| 38 } | 41 } |
| 39 | 42 |
| 40 | 43 |
| 41 static bool ProcessSnapshotOption(const char* option) { | 44 static bool ProcessSnapshotOption(const char* option) { |
| 42 const char* kSnapshotOption = "--snapshot="; | 45 const char* kSnapshotOption = "--snapshot="; |
| 43 snapshot_filename = ProcessOption(option, kSnapshotOption); | 46 const char* name = ProcessOption(option, kSnapshotOption); |
| 44 return snapshot_filename != NULL; | 47 if (name != NULL) { |
| 48 snapshot_filename = name; | |
| 49 return true; | |
| 50 } | |
| 51 return false; | |
| 52 } | |
| 53 | |
| 54 | |
| 55 static bool ProcessURLmappingOption(const char* option) { | |
| 56 const char* kURLmappingOption = "--url_mapping="; | |
| 57 const char* mapping = ProcessOption(option, kURLmappingOption); | |
| 58 if (mapping != NULL) { | |
| 59 url_mapping->AddArgument(mapping); | |
| 60 return true; | |
| 61 } | |
| 62 return false; | |
| 45 } | 63 } |
| 46 | 64 |
| 47 | 65 |
| 48 // Parse out the command line arguments. Returns -1 if the arguments | 66 // Parse out the command line arguments. Returns -1 if the arguments |
| 49 // are incorrect, 0 otherwise. | 67 // are incorrect, 0 otherwise. |
| 50 static int ParseArguments(int argc, | 68 static int ParseArguments(int argc, |
| 51 char** argv, | 69 char** argv, |
| 52 CommandLineOptions* vm_options, | 70 CommandLineOptions* vm_options, |
| 53 char** script_name) { | 71 char** script_name) { |
| 54 const char* kPrefix = "--"; | 72 const char* kPrefix = "--"; |
| 55 const intptr_t kPrefixLen = strlen(kPrefix); | 73 const intptr_t kPrefixLen = strlen(kPrefix); |
| 56 | 74 |
| 57 // Skip the binary name. | 75 // Skip the binary name. |
| 58 int i = 1; | 76 int i = 1; |
| 59 | 77 |
| 60 // Parse out the vm options. | 78 // Parse out the vm options. |
| 61 while ((i < argc) && IsValidFlag(argv[i], kPrefix, kPrefixLen)) { | 79 while ((i < argc) && IsValidFlag(argv[i], kPrefix, kPrefixLen)) { |
| 62 if (ProcessSnapshotOption(argv[i])) { | 80 if (ProcessSnapshotOption(argv[i]) || ProcessURLmappingOption(argv[i])) { |
| 63 i += 1; | 81 i += 1; |
| 64 continue; | 82 continue; |
| 65 } | 83 } |
| 66 vm_options->AddArgument(argv[i]); | 84 vm_options->AddArgument(argv[i]); |
| 67 i += 1; | 85 i += 1; |
| 68 } | 86 } |
| 69 | 87 |
| 70 // Get the script name. | 88 // Get the script name. |
| 71 if (i < argc) { | 89 if (i < argc) { |
| 72 *script_name = argv[i]; | 90 *script_name = argv[i]; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 83 const bool kWritable = true; | 101 const bool kWritable = true; |
| 84 File* file = File::Open(snapshot_filename, kWritable); | 102 File* file = File::Open(snapshot_filename, kWritable); |
| 85 ASSERT(file != NULL); | 103 ASSERT(file != NULL); |
| 86 for (intptr_t i = 0; i < size; i++) { | 104 for (intptr_t i = 0; i < size; i++) { |
| 87 file->WriteByte(buffer[i]); | 105 file->WriteByte(buffer[i]); |
| 88 } | 106 } |
| 89 delete file; | 107 delete file; |
| 90 } | 108 } |
| 91 | 109 |
| 92 | 110 |
| 111 static const char* MapLibraryUrl(const char* library_url_chars) { | |
| 112 const char* mapped_url_chars = library_url_chars; | |
| 113 if (url_mapping != NULL) { | |
| 114 // We need to check if the passed in url is found in the url_mapping array, | |
| 115 // in that case use the mapped entry. | |
| 116 int len = strlen(library_url_chars); | |
| 117 for (int idx = 0; idx < url_mapping->count(); idx++) { | |
| 118 const char* url_name = url_mapping->GetArgument(idx); | |
| 119 if (!strncmp(library_url_chars, url_name, len) && | |
| 120 (url_name[len] == ',')) { | |
| 121 const char* url_mapped_name = url_name + len + 1; | |
| 122 if (strlen(url_mapped_name) != 0) { | |
| 123 mapped_url_chars = url_mapped_name; | |
| 124 } | |
| 125 break; | |
| 126 } | |
| 127 } | |
| 128 } | |
| 129 return mapped_url_chars; | |
| 130 } | |
| 131 | |
| 132 | |
| 133 static Dart_Handle CanonicalizeUrl(const char* library_url_chars, | |
| 134 const char* url_chars) { | |
| 135 // Create the full path based on the including library and the url. | |
|
Anton Muhin
2011/11/15 12:34:32
nit: those comments can probably go away now.
siva
2011/11/15 21:00:27
Done.
| |
| 136 | |
| 137 // Calculate the canonical path. | |
| 138 const char* canonical_filename = GetCanonicalPath(library_url_chars, | |
| 139 url_chars); | |
| 140 Dart_Handle canon_url = Dart_NewString(canonical_filename); | |
| 141 free(const_cast<char*>(canonical_filename)); | |
| 142 return canon_url; | |
| 143 } | |
| 144 | |
| 145 | |
| 146 static Dart_Handle CreateSnapshotLibraryTagHandler(Dart_LibraryTag tag, | |
| 147 Dart_Handle library, | |
| 148 Dart_Handle url) { | |
| 149 if (!Dart_IsLibrary(library)) { | |
| 150 return Dart_Error("not a library"); | |
| 151 } | |
| 152 if (!Dart_IsString8(url)) { | |
| 153 return Dart_Error("url is not a string"); | |
| 154 } | |
| 155 const char* url_chars = NULL; | |
| 156 Dart_Handle result = Dart_StringToCString(url, &url_chars); | |
| 157 if (Dart_IsError(result)) { | |
| 158 return Dart_Error("accessing url characters failed"); | |
| 159 } | |
| 160 | |
| 161 // If the URL starts with "dart:" then it is handled specially. | |
| 162 static const char* kDartScheme = "dart:"; | |
| 163 static const intptr_t kDartSchemeLen = strlen(kDartScheme); | |
| 164 if (strncmp(url_chars, kDartScheme, kDartSchemeLen) == 0) { | |
| 165 if (tag == kCanonicalizeUrl) { | |
| 166 return Dart_NewString(url_chars); | |
| 167 } | |
| 168 const char* mapped_url_chars = MapLibraryUrl(url_chars); | |
| 169 if (mapped_url_chars != NULL) { | |
|
Anton Muhin
2011/11/15 12:34:32
it looks like MapLibraryUrl will never return NULL
siva
2011/11/15 21:00:27
Good catch, changed MapLibraryUrl to initialize ma
| |
| 170 // We have a URL mapping specified, just return the mapped version. | |
| 171 return Dart_NewString(mapped_url_chars); | |
|
Anton Muhin
2011/11/15 12:34:32
is it ok? you have kImportTag/kSourceTag, but do
siva
2011/11/15 21:00:27
In this case we found a mapping on the command lin
Anton Muhin
2011/11/16 12:45:36
Looks like you've submitted it, so let me just exp
| |
| 172 } | |
| 173 } | |
| 174 // Get the url of the calling library. | |
| 175 Dart_Handle library_url = Dart_LibraryUrl(library); | |
| 176 if (Dart_IsError(library_url)) { | |
| 177 return Dart_Error("accessing library url failed"); | |
| 178 } | |
| 179 if (!Dart_IsString8(library_url)) { | |
| 180 return Dart_Error("library url is not a string"); | |
| 181 } | |
| 182 const char* library_url_chars = NULL; | |
| 183 result = Dart_StringToCString(library_url, &library_url_chars); | |
| 184 if (Dart_IsError(result)) { | |
| 185 return Dart_Error("accessing library url characters failed"); | |
| 186 } | |
| 187 library_url_chars = MapLibraryUrl(library_url_chars); | |
| 188 Dart_Handle canon_url = CanonicalizeUrl(library_url_chars, url_chars); | |
| 189 if (Dart_IsError(canon_url)) { | |
| 190 return canon_url; // canon_url contains the error string. | |
| 191 } | |
| 192 if (tag == kCanonicalizeUrl) { | |
| 193 return canon_url; | |
| 194 } | |
| 195 result = Dart_StringToCString(canon_url, &url_chars); | |
| 196 if (Dart_IsError(result)) { | |
| 197 return Dart_Error("accessing canon url characters failed"); | |
| 198 } | |
| 199 // The tag is either an import or a source tag. Read the file based on the | |
| 200 // url chars. | |
| 201 Dart_Handle source = ReadStringFromFile(url_chars); | |
| 202 if (Dart_IsError(source)) { | |
| 203 return source; // source contains the error string. | |
| 204 } | |
| 205 if (tag == kImportTag) { | |
| 206 return Dart_LoadLibrary(url, source); | |
| 207 } else if (tag == kSourceTag) { | |
| 208 return Dart_LoadSource(library, url, source); | |
| 209 } | |
| 210 return Dart_Error("wrong tag"); | |
| 211 } | |
| 212 | |
| 213 | |
| 214 static Dart_Handle LoadSnapshotCreationScript(const char* script_name) { | |
| 215 Dart_Handle source = ReadStringFromFile(script_name); | |
| 216 if (Dart_IsError(source)) { | |
| 217 return source; // source contains the error string. | |
| 218 } | |
| 219 Dart_Handle url = Dart_NewString(script_name); | |
| 220 | |
| 221 return Dart_LoadScript(url, source, CreateSnapshotLibraryTagHandler); | |
| 222 } | |
| 223 | |
| 224 | |
| 93 static void* SnapshotCreateCallback(void* data) { | 225 static void* SnapshotCreateCallback(void* data) { |
| 94 const char* script_name = reinterpret_cast<const char*>(data); | 226 const char* script_name = reinterpret_cast<const char*>(data); |
| 95 Dart_Handle result; | 227 Dart_Handle result; |
| 96 Dart_EnterScope(); | 228 Dart_EnterScope(); |
| 97 | 229 |
| 98 ASSERT(snapshot_filename != NULL); | 230 ASSERT(snapshot_filename != NULL); |
| 99 | 231 |
| 100 // If a file is specified on the command line, load it up before a snapshot | 232 // If a file is specified on the command line, load it up before a snapshot |
| 101 // is created. | 233 // is created. |
| 102 if (script_name != NULL) { | 234 if (script_name != NULL) { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 144 fprintf(stderr, | 276 fprintf(stderr, |
| 145 "dart [<vm-flags>] " | 277 "dart [<vm-flags>] " |
| 146 "[<dart-script-file>]\n"); | 278 "[<dart-script-file>]\n"); |
| 147 } | 279 } |
| 148 | 280 |
| 149 | 281 |
| 150 int main(int argc, char** argv) { | 282 int main(int argc, char** argv) { |
| 151 CommandLineOptions vm_options(argc); | 283 CommandLineOptions vm_options(argc); |
| 152 char* script_name; | 284 char* script_name; |
| 153 | 285 |
| 286 // Initialize the URL mapping array. | |
| 287 CommandLineOptions url_mapping_array(argc); | |
| 288 url_mapping = &url_mapping_array; | |
| 289 | |
| 154 // Parse command line arguments. | 290 // Parse command line arguments. |
| 155 if (ParseArguments(argc, | 291 if (ParseArguments(argc, |
| 156 argv, | 292 argv, |
| 157 &vm_options, | 293 &vm_options, |
| 158 &script_name) < 0) { | 294 &script_name) < 0) { |
| 159 PrintUsage(); | 295 PrintUsage(); |
| 160 return 255; | 296 return 255; |
| 161 } | 297 } |
| 162 | 298 |
| 163 if (snapshot_filename == NULL) { | 299 if (snapshot_filename == NULL) { |
| 164 fprintf(stderr, "No snapshot output file specified\n"); | 300 fprintf(stderr, "No snapshot output file specified\n"); |
| 165 return 255; | 301 return 255; |
| 166 } | 302 } |
| 167 | 303 |
| 168 // Initialize the Dart VM. | 304 // Initialize the Dart VM (TODO(asiva) - remove const_cast once |
| 305 // dart API is fixed to take a const char** in Dart_Initialize). | |
| 169 Dart_Initialize(vm_options.count(), | 306 Dart_Initialize(vm_options.count(), |
| 170 vm_options.arguments(), | 307 const_cast<char**>(vm_options.arguments()), |
| 171 SnapshotCreateCallback); | 308 SnapshotCreateCallback); |
| 172 | 309 |
| 173 // Create an isolate. As a side effect, SnapshotCreateCallback | 310 // Create an isolate. As a side effect, SnapshotCreateCallback |
| 174 // gets called, which loads the script (if one is specified), its libraries | 311 // gets called, which loads the script (if one is specified), its libraries |
| 175 // and writes out a snapshot. | 312 // and writes out a snapshot. |
| 176 Dart_Isolate isolate = Dart_CreateIsolate(NULL, script_name); | 313 Dart_Isolate isolate = Dart_CreateIsolate(NULL, script_name); |
| 177 if (isolate == NULL) { | 314 if (isolate == NULL) { |
| 178 return 255; | 315 return 255; |
| 179 } | 316 } |
| 180 | 317 |
| 181 // Shutdown the isolate. | 318 // Shutdown the isolate. |
| 182 Dart_ShutdownIsolate(); | 319 Dart_ShutdownIsolate(); |
| 183 return 0; | 320 return 0; |
| 184 } | 321 } |
| OLD | NEW |