OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 <stdio.h> | 8 #include <stdio.h> |
9 #include <stdlib.h> | 9 #include <stdlib.h> |
10 #include <string.h> | 10 #include <string.h> |
(...skipping 16 matching lines...) Expand all Loading... |
27 | 27 |
28 #include "platform/globals.h" | 28 #include "platform/globals.h" |
29 #include "platform/growable_array.h" | 29 #include "platform/growable_array.h" |
30 #include "platform/hashmap.h" | 30 #include "platform/hashmap.h" |
31 | 31 |
32 namespace dart { | 32 namespace dart { |
33 namespace bin { | 33 namespace bin { |
34 | 34 |
35 DFE dfe; | 35 DFE dfe; |
36 | 36 |
| 37 // Option processing helpers. |
| 38 // TODO(dartbug.com/30534) share option processing between main.cc and |
| 39 // gen_snapshot.cc |
| 40 |
| 41 static const char* ProcessOption(const char* option, const char* name) { |
| 42 const intptr_t length = strlen(name); |
| 43 for (intptr_t i = 0; i < length; i++) { |
| 44 if (option[i] != name[i]) { |
| 45 if (name[i] == '_' && option[i] == '-') { |
| 46 continue; |
| 47 } |
| 48 return NULL; |
| 49 } |
| 50 } |
| 51 return option + length; |
| 52 } |
| 53 |
| 54 typedef bool (*OptionProcessorCallback)(const char* arg); |
| 55 |
| 56 class OptionProcessor { |
| 57 public: |
| 58 OptionProcessor() : next_(first_) { first_ = this; } |
| 59 |
| 60 virtual ~OptionProcessor() {} |
| 61 |
| 62 virtual bool Process(const char* option) = 0; |
| 63 |
| 64 static bool TryProcess(const char* option) { |
| 65 for (OptionProcessor* p = first_; p != NULL; p = p->next_) { |
| 66 if (p->Process(option)) { |
| 67 return true; |
| 68 } |
| 69 } |
| 70 return false; |
| 71 } |
| 72 |
| 73 private: |
| 74 static OptionProcessor* first_; |
| 75 OptionProcessor* next_; |
| 76 }; |
| 77 |
| 78 class CallbackOptionProcessor : public OptionProcessor { |
| 79 public: |
| 80 explicit CallbackOptionProcessor(OptionProcessorCallback cb) : cb_(cb) {} |
| 81 virtual bool Process(const char* option) { return cb_(option); } |
| 82 |
| 83 private: |
| 84 OptionProcessorCallback cb_; |
| 85 }; |
| 86 |
| 87 OptionProcessor* OptionProcessor::first_ = NULL; |
| 88 |
| 89 #define DEFINE_CB_OPTION(callback) \ |
| 90 static CallbackOptionProcessor option_##callback(&callback); |
| 91 |
| 92 #define DEFINE_STRING_OPTION_CB(name, callback) \ |
| 93 class OptionProcessor_##name : public OptionProcessor { \ |
| 94 public: \ |
| 95 virtual bool Process(const char* option) { \ |
| 96 const char* value = ProcessOption(option, "--" #name "="); \ |
| 97 if (value == NULL) { \ |
| 98 return false; \ |
| 99 } \ |
| 100 if (*value == '\0') { \ |
| 101 Log::PrintErr("Empty value for option " #name "\n"); \ |
| 102 return false; \ |
| 103 } \ |
| 104 callback; \ |
| 105 return true; \ |
| 106 } \ |
| 107 }; \ |
| 108 static OptionProcessor_##name option_##name; |
| 109 |
| 110 #define DEFINE_ENUM_OPTION(name, enum_name, variable) \ |
| 111 DEFINE_STRING_OPTION_CB(name, { \ |
| 112 const char** kNames = k##enum_name##Names; \ |
| 113 for (intptr_t i = 0; kNames[i] != NULL; i++) { \ |
| 114 if (strcmp(value, kNames[i]) == 0) { \ |
| 115 variable = static_cast<enum_name>(i); \ |
| 116 return true; \ |
| 117 } \ |
| 118 } \ |
| 119 Log::PrintErr( \ |
| 120 "Unrecognized value for " #name ": '%s'\nValid values are: ", value); \ |
| 121 for (intptr_t i = 0; kNames[i] != NULL; i++) { \ |
| 122 Log::PrintErr("%s%s", i > 0 ? ", " : "", kNames[i]); \ |
| 123 } \ |
| 124 Log::PrintErr("\n"); \ |
| 125 }) |
| 126 |
| 127 #define DEFINE_STRING_OPTION(name, variable) \ |
| 128 static const char* variable = NULL; \ |
| 129 DEFINE_STRING_OPTION_CB(name, { variable = value; }) |
| 130 |
| 131 #define DEFINE_BOOL_OPTION(name, variable) \ |
| 132 static bool variable = false; \ |
| 133 class OptionProcessor_##name : public OptionProcessor { \ |
| 134 public: \ |
| 135 virtual bool Process(const char* option) { \ |
| 136 const char* value = ProcessOption(option, "--" #name); \ |
| 137 if (value == NULL) { \ |
| 138 return false; \ |
| 139 } \ |
| 140 if (*value == '=') { \ |
| 141 Log::PrintErr("Non-empty value for option " #name "\n"); \ |
| 142 return false; \ |
| 143 } \ |
| 144 if (*value != '\0') { \ |
| 145 return false; \ |
| 146 } \ |
| 147 variable = true; \ |
| 148 return true; \ |
| 149 } \ |
| 150 }; \ |
| 151 static OptionProcessor_##name option_##name; |
| 152 |
37 // Exit code indicating an API error. | 153 // Exit code indicating an API error. |
38 static const int kApiErrorExitCode = 253; | 154 static const int kApiErrorExitCode = 253; |
39 // Exit code indicating a compilation error. | 155 // Exit code indicating a compilation error. |
40 static const int kCompilationErrorExitCode = 254; | 156 static const int kCompilationErrorExitCode = 254; |
41 // Exit code indicating an unhandled error that is not a compilation error. | 157 // Exit code indicating an unhandled error that is not a compilation error. |
42 static const int kErrorExitCode = 255; | 158 static const int kErrorExitCode = 255; |
43 | 159 |
44 #define CHECK_RESULT(result) \ | 160 #define CHECK_RESULT(result) \ |
45 if (Dart_IsError(result)) { \ | 161 if (Dart_IsError(result)) { \ |
46 intptr_t exit_code = 0; \ | 162 intptr_t exit_code = 0; \ |
(...skipping 18 matching lines...) Expand all Loading... |
65 // Global state that indicates whether a snapshot is to be created and | 181 // Global state that indicates whether a snapshot is to be created and |
66 // if so which file to write the snapshot into. | 182 // if so which file to write the snapshot into. |
67 enum SnapshotKind { | 183 enum SnapshotKind { |
68 kCore, | 184 kCore, |
69 kCoreJIT, | 185 kCoreJIT, |
70 kScript, | 186 kScript, |
71 kAppAOTBlobs, | 187 kAppAOTBlobs, |
72 kAppAOTAssembly, | 188 kAppAOTAssembly, |
73 }; | 189 }; |
74 static SnapshotKind snapshot_kind = kCore; | 190 static SnapshotKind snapshot_kind = kCore; |
75 static const char* vm_snapshot_data_filename = NULL; | |
76 static const char* vm_snapshot_instructions_filename = NULL; | |
77 static const char* isolate_snapshot_data_filename = NULL; | |
78 static const char* isolate_snapshot_instructions_filename = NULL; | |
79 static const char* assembly_filename = NULL; | |
80 static const char* script_snapshot_filename = NULL; | |
81 static bool dependencies_only = false; | |
82 static bool print_dependencies = false; | |
83 static const char* dependencies_filename = NULL; | |
84 | |
85 // Value of the --load-compilation-trace flag. | |
86 // (This pointer points into an argv buffer and does not need to be | |
87 // free'd.) | |
88 static const char* load_compilation_trace_filename = NULL; | |
89 | |
90 // Value of the --package-root flag. | |
91 // (This pointer points into an argv buffer and does not need to be | |
92 // free'd.) | |
93 static const char* commandline_package_root = NULL; | |
94 | |
95 // Value of the --packages flag. | |
96 // (This pointer points into an argv buffer and does not need to be | |
97 // free'd.) | |
98 static const char* commandline_packages_file = NULL; | |
99 | 191 |
100 // Global state which contains a pointer to the script name for which | 192 // Global state which contains a pointer to the script name for which |
101 // a snapshot needs to be created (NULL would result in the creation | 193 // a snapshot needs to be created (NULL would result in the creation |
102 // of a generic snapshot that contains only the corelibs). | 194 // of a generic snapshot that contains only the corelibs). |
103 static char* app_script_name = NULL; | 195 static char* app_script_name = NULL; |
104 | 196 |
105 // Global state that captures the entry point manifest files specified on the | 197 // Global state that captures the entry point manifest files specified on the |
106 // command line. | 198 // command line. |
107 static CommandLineOptions* entry_points_files = NULL; | 199 static CommandLineOptions* entry_points_files = NULL; |
108 | 200 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 } | 281 } |
190 if (value != NULL) { | 282 if (value != NULL) { |
191 result = Dart_NewStringFromUTF8(reinterpret_cast<const uint8_t*>(value), | 283 result = Dart_NewStringFromUTF8(reinterpret_cast<const uint8_t*>(value), |
192 strlen(value)); | 284 strlen(value)); |
193 } | 285 } |
194 free(name_chars); | 286 free(name_chars); |
195 } | 287 } |
196 return result; | 288 return result; |
197 } | 289 } |
198 | 290 |
199 static const char* ProcessOption(const char* option, const char* name) { | 291 static const char* kSnapshotKindNames[] = { |
200 const intptr_t length = strlen(name); | 292 "core", "core-jit", "script", "app-aot-blobs", "app-aot-assembly", NULL, |
201 if (strncmp(option, name, length) == 0) { | 293 }; |
202 return (option + length); | |
203 } | |
204 return NULL; | |
205 } | |
206 | 294 |
207 static bool ProcessSnapshotKindOption(const char* option) { | 295 DEFINE_ENUM_OPTION(snapshot_kind, SnapshotKind, snapshot_kind); |
208 const char* kind = ProcessOption(option, "--snapshot_kind="); | 296 DEFINE_STRING_OPTION(vm_snapshot_data, vm_snapshot_data_filename); |
209 if (kind == NULL) { | 297 DEFINE_STRING_OPTION(vm_snapshot_instructions, |
210 kind = ProcessOption(option, "--snapshot-kind="); | 298 vm_snapshot_instructions_filename); |
211 } | 299 DEFINE_STRING_OPTION(isolate_snapshot_data, isolate_snapshot_data_filename); |
212 if (kind == NULL) { | 300 DEFINE_STRING_OPTION(isolate_snapshot_instructions, |
213 return false; | 301 isolate_snapshot_instructions_filename); |
214 } | 302 DEFINE_STRING_OPTION(assembly, assembly_filename); |
215 if (strcmp(kind, "core-jit") == 0) { | 303 DEFINE_STRING_OPTION(script_snapshot, script_snapshot_filename); |
216 snapshot_kind = kCoreJIT; | 304 DEFINE_STRING_OPTION(dependencies, dependencies_filename); |
217 return true; | 305 DEFINE_BOOL_OPTION(dependencies_only, dependencies_only); |
218 } else if (strcmp(kind, "core") == 0) { | 306 DEFINE_BOOL_OPTION(print_dependencies, print_dependencies); |
219 snapshot_kind = kCore; | 307 DEFINE_STRING_OPTION_CB(embedder_entry_points_manifest, |
220 return true; | 308 { entry_points_files->AddArgument(value); }); |
221 } else if (strcmp(kind, "script") == 0) { | 309 DEFINE_STRING_OPTION(load_compilation_trace, load_compilation_trace_filename); |
222 snapshot_kind = kScript; | 310 DEFINE_STRING_OPTION(package_root, commandline_package_root); |
223 return true; | 311 DEFINE_STRING_OPTION(packages, commandline_packages_file); |
224 } else if (strcmp(kind, "app-aot-blobs") == 0) { | 312 DEFINE_STRING_OPTION_CB(url_mapping, |
225 snapshot_kind = kAppAOTBlobs; | 313 { DartUtils::url_mapping->AddArgument(value); }); |
226 return true; | 314 DEFINE_CB_OPTION(ProcessEnvironmentOption); |
227 } else if (strcmp(kind, "app-aot-assembly") == 0) { | 315 DEFINE_BOOL_OPTION(obfuscate, obfuscate); |
228 snapshot_kind = kAppAOTAssembly; | 316 DEFINE_STRING_OPTION(save_obfuscation_map, obfuscation_map_filename); |
229 return true; | |
230 } | |
231 Log::PrintErr( | |
232 "Unrecognized snapshot kind: '%s'\nValid kinds are: " | |
233 "core, script, app-aot-blobs, app-aot-assembly\n", | |
234 kind); | |
235 return false; | |
236 } | |
237 | |
238 static bool ProcessVmSnapshotDataOption(const char* option) { | |
239 const char* name = ProcessOption(option, "--vm_snapshot_data="); | |
240 if (name == NULL) { | |
241 name = ProcessOption(option, "--vm-snapshot-data="); | |
242 } | |
243 if (name != NULL) { | |
244 vm_snapshot_data_filename = name; | |
245 return true; | |
246 } | |
247 return false; | |
248 } | |
249 | |
250 static bool ProcessVmSnapshotInstructionsOption(const char* option) { | |
251 const char* name = ProcessOption(option, "--vm_snapshot_instructions="); | |
252 if (name == NULL) { | |
253 name = ProcessOption(option, "--vm-snapshot-instructions="); | |
254 } | |
255 if (name != NULL) { | |
256 vm_snapshot_instructions_filename = name; | |
257 return true; | |
258 } | |
259 return false; | |
260 } | |
261 | |
262 static bool ProcessIsolateSnapshotDataOption(const char* option) { | |
263 const char* name = ProcessOption(option, "--isolate_snapshot_data="); | |
264 if (name == NULL) { | |
265 name = ProcessOption(option, "--isolate-snapshot-data="); | |
266 } | |
267 if (name != NULL) { | |
268 isolate_snapshot_data_filename = name; | |
269 return true; | |
270 } | |
271 return false; | |
272 } | |
273 | |
274 static bool ProcessIsolateSnapshotInstructionsOption(const char* option) { | |
275 const char* name = ProcessOption(option, "--isolate_snapshot_instructions="); | |
276 if (name == NULL) { | |
277 name = ProcessOption(option, "--isolate-snapshot-instructions="); | |
278 } | |
279 if (name != NULL) { | |
280 isolate_snapshot_instructions_filename = name; | |
281 return true; | |
282 } | |
283 return false; | |
284 } | |
285 | |
286 static bool ProcessAssemblyOption(const char* option) { | |
287 const char* name = ProcessOption(option, "--assembly="); | |
288 if (name != NULL) { | |
289 assembly_filename = name; | |
290 return true; | |
291 } | |
292 return false; | |
293 } | |
294 | |
295 static bool ProcessScriptSnapshotOption(const char* option) { | |
296 const char* name = ProcessOption(option, "--script_snapshot="); | |
297 if (name == NULL) { | |
298 name = ProcessOption(option, "--script-snapshot="); | |
299 } | |
300 if (name != NULL) { | |
301 script_snapshot_filename = name; | |
302 return true; | |
303 } | |
304 return false; | |
305 } | |
306 | |
307 static bool ProcessDependenciesOption(const char* option) { | |
308 const char* name = ProcessOption(option, "--dependencies="); | |
309 if (name != NULL) { | |
310 dependencies_filename = name; | |
311 return true; | |
312 } | |
313 return false; | |
314 } | |
315 | |
316 static bool ProcessDependenciesOnlyOption(const char* option) { | |
317 const char* name = ProcessOption(option, "--dependencies_only"); | |
318 if (name == NULL) { | |
319 name = ProcessOption(option, "--dependencies-only"); | |
320 } | |
321 if (name != NULL) { | |
322 dependencies_only = true; | |
323 return true; | |
324 } | |
325 return false; | |
326 } | |
327 | |
328 static bool ProcessPrintDependenciesOption(const char* option) { | |
329 const char* name = ProcessOption(option, "--print_dependencies"); | |
330 if (name == NULL) { | |
331 name = ProcessOption(option, "--print-dependencies"); | |
332 } | |
333 if (name != NULL) { | |
334 print_dependencies = true; | |
335 return true; | |
336 } | |
337 return false; | |
338 } | |
339 | |
340 static bool ProcessEmbedderEntryPointsManifestOption(const char* option) { | |
341 const char* name = ProcessOption(option, "--embedder_entry_points_manifest="); | |
342 if (name == NULL) { | |
343 name = ProcessOption(option, "--embedder-entry-points-manifest="); | |
344 } | |
345 if (name != NULL) { | |
346 entry_points_files->AddArgument(name); | |
347 return true; | |
348 } | |
349 return false; | |
350 } | |
351 | |
352 static bool ProcessLoadCompilationTraceOption(const char* option) { | |
353 const char* name = ProcessOption(option, "--load_compilation_trace="); | |
354 if (name == NULL) { | |
355 name = ProcessOption(option, "--load-compilation-trace="); | |
356 } | |
357 if (name != NULL) { | |
358 load_compilation_trace_filename = name; | |
359 return true; | |
360 } | |
361 return false; | |
362 } | |
363 | |
364 static bool ProcessPackageRootOption(const char* option) { | |
365 const char* name = ProcessOption(option, "--package_root="); | |
366 if (name == NULL) { | |
367 name = ProcessOption(option, "--package-root="); | |
368 } | |
369 if (name != NULL) { | |
370 commandline_package_root = name; | |
371 return true; | |
372 } | |
373 return false; | |
374 } | |
375 | |
376 static bool ProcessPackagesOption(const char* option) { | |
377 const char* name = ProcessOption(option, "--packages="); | |
378 if (name != NULL) { | |
379 commandline_packages_file = name; | |
380 return true; | |
381 } | |
382 return false; | |
383 } | |
384 | |
385 static bool ProcessURLmappingOption(const char* option) { | |
386 const char* mapping = ProcessOption(option, "--url_mapping="); | |
387 if (mapping == NULL) { | |
388 mapping = ProcessOption(option, "--url-mapping="); | |
389 } | |
390 if (mapping != NULL) { | |
391 DartUtils::url_mapping->AddArgument(mapping); | |
392 return true; | |
393 } | |
394 return false; | |
395 } | |
396 | 317 |
397 static bool IsSnapshottingForPrecompilation() { | 318 static bool IsSnapshottingForPrecompilation() { |
398 return (snapshot_kind == kAppAOTBlobs) || (snapshot_kind == kAppAOTAssembly); | 319 return (snapshot_kind == kAppAOTBlobs) || (snapshot_kind == kAppAOTAssembly); |
399 } | 320 } |
400 | 321 |
401 // Parse out the command line arguments. Returns -1 if the arguments | 322 // Parse out the command line arguments. Returns -1 if the arguments |
402 // are incorrect, 0 otherwise. | 323 // are incorrect, 0 otherwise. |
403 static int ParseArguments(int argc, | 324 static int ParseArguments(int argc, |
404 char** argv, | 325 char** argv, |
405 CommandLineOptions* vm_options, | 326 CommandLineOptions* vm_options, |
406 char** script_name) { | 327 char** script_name) { |
407 const char* kPrefix = "-"; | 328 const char* kPrefix = "-"; |
408 const intptr_t kPrefixLen = strlen(kPrefix); | 329 const intptr_t kPrefixLen = strlen(kPrefix); |
409 | 330 |
410 // Skip the binary name. | 331 // Skip the binary name. |
411 int i = 1; | 332 int i = 1; |
412 | 333 |
413 // Parse out the vm options. | 334 // Parse out the vm options. |
414 while ((i < argc) && IsValidFlag(argv[i], kPrefix, kPrefixLen)) { | 335 while ((i < argc) && IsValidFlag(argv[i], kPrefix, kPrefixLen)) { |
415 if (ProcessSnapshotKindOption(argv[i]) || | 336 if (OptionProcessor::TryProcess(argv[i])) { |
416 ProcessVmSnapshotDataOption(argv[i]) || | |
417 ProcessVmSnapshotInstructionsOption(argv[i]) || | |
418 ProcessIsolateSnapshotDataOption(argv[i]) || | |
419 ProcessIsolateSnapshotInstructionsOption(argv[i]) || | |
420 ProcessAssemblyOption(argv[i]) || | |
421 ProcessScriptSnapshotOption(argv[i]) || | |
422 ProcessDependenciesOption(argv[i]) || | |
423 ProcessDependenciesOnlyOption(argv[i]) || | |
424 ProcessPrintDependenciesOption(argv[i]) || | |
425 ProcessEmbedderEntryPointsManifestOption(argv[i]) || | |
426 ProcessURLmappingOption(argv[i]) || | |
427 ProcessLoadCompilationTraceOption(argv[i]) || | |
428 ProcessPackageRootOption(argv[i]) || ProcessPackagesOption(argv[i]) || | |
429 ProcessEnvironmentOption(argv[i])) { | |
430 i += 1; | 337 i += 1; |
431 continue; | 338 continue; |
432 } | 339 } |
433 vm_options->AddArgument(argv[i]); | 340 vm_options->AddArgument(argv[i]); |
434 i += 1; | 341 i += 1; |
435 } | 342 } |
436 | 343 |
437 // Get the script name. | 344 // Get the script name. |
438 if (i < argc) { | 345 if (i < argc) { |
439 *script_name = argv[i]; | 346 *script_name = argv[i]; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
513 } | 420 } |
514 } | 421 } |
515 | 422 |
516 if (IsSnapshottingForPrecompilation() && (entry_points_files->count() == 0)) { | 423 if (IsSnapshottingForPrecompilation() && (entry_points_files->count() == 0)) { |
517 Log::PrintErr( | 424 Log::PrintErr( |
518 "Building an AOT snapshot requires at least one embedder " | 425 "Building an AOT snapshot requires at least one embedder " |
519 "entry points manifest.\n\n"); | 426 "entry points manifest.\n\n"); |
520 return -1; | 427 return -1; |
521 } | 428 } |
522 | 429 |
| 430 if (!obfuscate && obfuscation_map_filename != NULL) { |
| 431 Log::PrintErr( |
| 432 "--obfuscation_map=<...> should only be specified when obfuscation is " |
| 433 "enabled by --obfuscate flag.\n\n"); |
| 434 return -1; |
| 435 } |
| 436 |
| 437 if (obfuscate && !IsSnapshottingForPrecompilation()) { |
| 438 Log::PrintErr( |
| 439 "Obfuscation can only be enabled when building AOT snapshot.\n\n"); |
| 440 return -1; |
| 441 } |
| 442 |
523 return 0; | 443 return 0; |
524 } | 444 } |
525 | 445 |
526 static void WriteFile(const char* filename, | 446 static void WriteFile(const char* filename, |
527 const uint8_t* buffer, | 447 const uint8_t* buffer, |
528 const intptr_t size) { | 448 const intptr_t size) { |
529 File* file = File::Open(filename, File::kWriteTruncate); | 449 File* file = File::Open(filename, File::kWriteTruncate); |
530 if (file == NULL) { | 450 if (file == NULL) { |
531 Log::PrintErr("Error: Unable to write snapshot file: %s\n\n", filename); | 451 Log::PrintErr("Error: Unable to write snapshot file: %s\n\n", filename); |
532 Dart_ExitScope(); | 452 Dart_ExitScope(); |
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
963 " is created. \n" | 883 " is created. \n" |
964 " \n" | 884 " \n" |
965 " To create an AOT application snapshot as blobs suitable for loading with \n" | 885 " To create an AOT application snapshot as blobs suitable for loading with \n" |
966 " mmap: \n" | 886 " mmap: \n" |
967 " --snapshot_kind=app-aot-blobs \n" | 887 " --snapshot_kind=app-aot-blobs \n" |
968 " --vm_snapshot_data=<output-file> \n" | 888 " --vm_snapshot_data=<output-file> \n" |
969 " --vm_snapshot_instructions=<output-file> \n" | 889 " --vm_snapshot_instructions=<output-file> \n" |
970 " --isolate_snapshot_data=<output-file> \n" | 890 " --isolate_snapshot_data=<output-file> \n" |
971 " --isolate_snapshot_instructions=<output-file> \n" | 891 " --isolate_snapshot_instructions=<output-file> \n" |
972 " {--embedder_entry_points_manifest=<input-file>} \n" | 892 " {--embedder_entry_points_manifest=<input-file>} \n" |
| 893 " [--obfuscate] \n" |
| 894 " [--save-obfuscation-map=<map-filename>] \n" |
973 " <dart-script-file> \n" | 895 " <dart-script-file> \n" |
974 " \n" | 896 " \n" |
975 " To create an AOT application snapshot as assembly suitable for compilation \n" | 897 " To create an AOT application snapshot as assembly suitable for compilation \n" |
976 " as a static or dynamic library: \n" | 898 " as a static or dynamic library: \n" |
977 " mmap: \n" | 899 " mmap: \n" |
978 " --snapshot_kind=app-aot-blobs \n" | 900 " --snapshot_kind=app-aot-blobs \n" |
979 " --assembly=<output-file> \n" | 901 " --assembly=<output-file> \n" |
980 " {--embedder_entry_points_manifest=<input-file>} \n" | 902 " {--embedder_entry_points_manifest=<input-file>} \n" |
| 903 " [--obfuscate] \n" |
| 904 " [--save-obfuscation-map=<map-filename>] \n" |
981 " <dart-script-file> \n" | 905 " <dart-script-file> \n" |
982 " \n" | 906 " \n" |
983 " AOT snapshots require entry points manifest files, which list the places \n" | 907 " AOT snapshots require entry points manifest files, which list the places \n" |
984 " in the Dart program the embedder calls from the C API (Dart_Invoke, etc). \n" | 908 " in the Dart program the embedder calls from the C API (Dart_Invoke, etc). \n" |
985 " Not specifying these may cause the tree shaker to remove them from the \n" | 909 " Not specifying these may cause the tree shaker to remove them from the \n" |
986 " program. The format of this manifest is as follows. Each line in the \n" | 910 " program. The format of this manifest is as follows. Each line in the \n" |
987 " manifest is a comma separated list of three elements. The first entry is \n" | 911 " manifest is a comma separated list of three elements. The first entry is \n" |
988 " the library URI, the second entry is the class name and the final entry \n" | 912 " the library URI, the second entry is the class name and the final entry \n" |
989 " the function name. The file must be terminated with a newline character. \n" | 913 " the function name. The file must be terminated with a newline character. \n" |
990 " \n" | 914 " \n" |
991 " Example: \n" | 915 " Example: \n" |
992 " dart:something,SomeClass,doSomething \n" | 916 " dart:something,SomeClass,doSomething \n" |
| 917 " \n" |
| 918 " AOT snapshots can be obfuscated: that is all identifiers will be renamed \n" |
| 919 " during compilation. This mode is enabled with --obfuscate flag. Mapping \n" |
| 920 " between original and obfuscated names can be serialized as a JSON array \n" |
| 921 " using --save-obfuscation-map=<filename> option. See dartbug.com/30524 \n" |
| 922 " for implementation details and limitations of the obfuscation pass. \n" |
| 923 " \n" |
993 "\n"); | 924 "\n"); |
994 } | 925 } |
995 // clang-format on | 926 // clang-format on |
996 | 927 |
997 static const char StubNativeFunctionName[] = "StubNativeFunction"; | 928 static const char StubNativeFunctionName[] = "StubNativeFunction"; |
998 | 929 |
999 void StubNativeFunction(Dart_NativeArguments arguments) { | 930 void StubNativeFunction(Dart_NativeArguments arguments) { |
1000 // This is a stub function for the resolver | 931 // This is a stub function for the resolver |
1001 Dart_SetReturnValue( | 932 Dart_SetReturnValue( |
1002 arguments, Dart_NewApiError("<EMBEDDER DID NOT SETUP NATIVE RESOLVER>")); | 933 arguments, Dart_NewApiError("<EMBEDDER DID NOT SETUP NATIVE RESOLVER>")); |
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1460 WriteFile(vm_snapshot_data_filename, vm_snapshot_data_buffer, | 1391 WriteFile(vm_snapshot_data_filename, vm_snapshot_data_buffer, |
1461 vm_snapshot_data_size); | 1392 vm_snapshot_data_size); |
1462 WriteFile(vm_snapshot_instructions_filename, | 1393 WriteFile(vm_snapshot_instructions_filename, |
1463 vm_snapshot_instructions_buffer, vm_snapshot_instructions_size); | 1394 vm_snapshot_instructions_buffer, vm_snapshot_instructions_size); |
1464 WriteFile(isolate_snapshot_data_filename, isolate_snapshot_data_buffer, | 1395 WriteFile(isolate_snapshot_data_filename, isolate_snapshot_data_buffer, |
1465 isolate_snapshot_data_size); | 1396 isolate_snapshot_data_size); |
1466 WriteFile(isolate_snapshot_instructions_filename, | 1397 WriteFile(isolate_snapshot_instructions_filename, |
1467 isolate_snapshot_instructions_buffer, | 1398 isolate_snapshot_instructions_buffer, |
1468 isolate_snapshot_instructions_size); | 1399 isolate_snapshot_instructions_size); |
1469 } | 1400 } |
| 1401 |
| 1402 // Serialize obfuscation map if requested. |
| 1403 if (obfuscation_map_filename != NULL) { |
| 1404 ASSERT(obfuscate); |
| 1405 uint8_t* buffer = NULL; |
| 1406 intptr_t size = 0; |
| 1407 result = Dart_GetObfuscationMap(&buffer, &size); |
| 1408 CHECK_RESULT(result); |
| 1409 WriteFile(obfuscation_map_filename, buffer, size); |
| 1410 } |
1470 } | 1411 } |
1471 | 1412 |
1472 static void SetupForUriResolution() { | 1413 static void SetupForUriResolution() { |
1473 // Set up the library tag handler for this isolate. | 1414 // Set up the library tag handler for this isolate. |
1474 Dart_Handle result = Dart_SetLibraryTagHandler(Loader::LibraryTagHandler); | 1415 Dart_Handle result = Dart_SetLibraryTagHandler(Loader::LibraryTagHandler); |
1475 if (Dart_IsError(result)) { | 1416 if (Dart_IsError(result)) { |
1476 Log::PrintErr("%s\n", Dart_GetError(result)); | 1417 Log::PrintErr("%s\n", Dart_GetError(result)); |
1477 Dart_ExitScope(); | 1418 Dart_ExitScope(); |
1478 Dart_ShutdownIsolate(); | 1419 Dart_ShutdownIsolate(); |
1479 exit(kErrorExitCode); | 1420 exit(kErrorExitCode); |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1657 } | 1598 } |
1658 } | 1599 } |
1659 | 1600 |
1660 char* error = Dart_Initialize(&init_params); | 1601 char* error = Dart_Initialize(&init_params); |
1661 if (error != NULL) { | 1602 if (error != NULL) { |
1662 Log::PrintErr("VM initialization failed: %s\n", error); | 1603 Log::PrintErr("VM initialization failed: %s\n", error); |
1663 free(error); | 1604 free(error); |
1664 return kErrorExitCode; | 1605 return kErrorExitCode; |
1665 } | 1606 } |
1666 | 1607 |
| 1608 Dart_IsolateFlags flags; |
| 1609 Dart_IsolateFlagsInitialize(&flags); |
| 1610 |
| 1611 Dart_QualifiedFunctionName* entry_points = |
| 1612 ParseEntryPointsManifestIfPresent(); |
| 1613 |
1667 IsolateData* isolate_data = new IsolateData(NULL, commandline_package_root, | 1614 IsolateData* isolate_data = new IsolateData(NULL, commandline_package_root, |
1668 commandline_packages_file, NULL); | 1615 commandline_packages_file, NULL); |
1669 Dart_Isolate isolate = Dart_CreateIsolate(NULL, NULL, isolate_snapshot_data, | 1616 Dart_Isolate isolate = Dart_CreateIsolate(NULL, NULL, isolate_snapshot_data, |
1670 isolate_snapshot_instructions, NULL, | 1617 isolate_snapshot_instructions, NULL, |
1671 isolate_data, &error); | 1618 isolate_data, &error); |
1672 if (isolate == NULL) { | 1619 if (isolate == NULL) { |
1673 Log::PrintErr("Error: %s\n", error); | 1620 Log::PrintErr("Error: %s\n", error); |
1674 free(error); | 1621 free(error); |
1675 exit(kErrorExitCode); | 1622 exit(kErrorExitCode); |
1676 } | 1623 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1711 Dart_ExitIsolate(); | 1658 Dart_ExitIsolate(); |
1712 | 1659 |
1713 // Now we create an isolate into which we load all the code that needs to | 1660 // Now we create an isolate into which we load all the code that needs to |
1714 // be in the snapshot. | 1661 // be in the snapshot. |
1715 isolate_data = new IsolateData(app_script_name, commandline_package_root, | 1662 isolate_data = new IsolateData(app_script_name, commandline_package_root, |
1716 commandline_packages_file, NULL); | 1663 commandline_packages_file, NULL); |
1717 if ((dependencies_filename != NULL) || print_dependencies) { | 1664 if ((dependencies_filename != NULL) || print_dependencies) { |
1718 isolate_data->set_dependencies(new MallocGrowableArray<char*>()); | 1665 isolate_data->set_dependencies(new MallocGrowableArray<char*>()); |
1719 } | 1666 } |
1720 | 1667 |
| 1668 if (IsSnapshottingForPrecompilation()) { |
| 1669 flags.obfuscate = obfuscate; |
| 1670 flags.entry_points = entry_points; |
| 1671 } |
| 1672 |
1721 Dart_Isolate isolate = NULL; | 1673 Dart_Isolate isolate = NULL; |
1722 void* kernel_program = dfe.ReadScript(app_script_name); | 1674 void* kernel_program = dfe.ReadScript(app_script_name); |
1723 if (kernel_program != NULL) { | 1675 if (kernel_program != NULL) { |
1724 isolate = Dart_CreateIsolateFromKernel(NULL, NULL, kernel_program, NULL, | 1676 isolate = Dart_CreateIsolateFromKernel(NULL, NULL, kernel_program, NULL, |
1725 isolate_data, &error); | 1677 isolate_data, &error); |
1726 } else { | 1678 } else { |
1727 isolate = Dart_CreateIsolate(NULL, NULL, isolate_snapshot_data, | 1679 isolate = Dart_CreateIsolate(NULL, NULL, isolate_snapshot_data, |
1728 isolate_snapshot_instructions, NULL, | 1680 isolate_snapshot_instructions, &flags, |
1729 isolate_data, &error); | 1681 isolate_data, &error); |
1730 } | 1682 } |
1731 if (isolate == NULL) { | 1683 if (isolate == NULL) { |
1732 Log::PrintErr("%s\n", error); | 1684 Log::PrintErr("%s\n", error); |
1733 free(error); | 1685 free(error); |
1734 exit(kErrorExitCode); | 1686 exit(kErrorExitCode); |
1735 } | 1687 } |
1736 Dart_EnterScope(); | 1688 Dart_EnterScope(); |
1737 result = Dart_SetEnvironmentCallback(EnvironmentCallback); | 1689 result = Dart_SetEnvironmentCallback(EnvironmentCallback); |
1738 CHECK_RESULT(result); | 1690 CHECK_RESULT(result); |
1739 | 1691 |
1740 // Set up the library tag handler in such a manner that it will use the | 1692 // Set up the library tag handler in such a manner that it will use the |
1741 // URL mapping specified on the command line to load the libraries. | 1693 // URL mapping specified on the command line to load the libraries. |
1742 result = Dart_SetLibraryTagHandler(CreateSnapshotLibraryTagHandler); | 1694 result = Dart_SetLibraryTagHandler(CreateSnapshotLibraryTagHandler); |
1743 CHECK_RESULT(result); | 1695 CHECK_RESULT(result); |
1744 | 1696 |
1745 if (commandline_packages_file != NULL) { | 1697 if (commandline_packages_file != NULL) { |
1746 AddDependency(commandline_packages_file); | 1698 AddDependency(commandline_packages_file); |
1747 } | 1699 } |
1748 | 1700 |
1749 Dart_QualifiedFunctionName* entry_points = | |
1750 ParseEntryPointsManifestIfPresent(); | |
1751 | |
1752 if (kernel_program != NULL) { | 1701 if (kernel_program != NULL) { |
1753 Dart_Handle resolved_uri = ResolveUriInWorkingDirectory(app_script_name); | 1702 Dart_Handle resolved_uri = ResolveUriInWorkingDirectory(app_script_name); |
1754 CHECK_RESULT(resolved_uri); | 1703 CHECK_RESULT(resolved_uri); |
1755 Dart_Handle library = | 1704 Dart_Handle library = |
1756 Dart_LoadScript(resolved_uri, Dart_Null(), | 1705 Dart_LoadScript(resolved_uri, Dart_Null(), |
1757 reinterpret_cast<Dart_Handle>(kernel_program), 0, 0); | 1706 reinterpret_cast<Dart_Handle>(kernel_program), 0, 0); |
1758 CHECK_RESULT(library); | 1707 CHECK_RESULT(library); |
1759 } else { | 1708 } else { |
1760 // Set up the library tag handler in such a manner that it will use the | 1709 // Set up the library tag handler in such a manner that it will use the |
1761 // URL mapping specified on the command line to load the libraries. | 1710 // URL mapping specified on the command line to load the libraries. |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1840 delete mapped_isolate_snapshot_instructions; | 1789 delete mapped_isolate_snapshot_instructions; |
1841 return 0; | 1790 return 0; |
1842 } | 1791 } |
1843 | 1792 |
1844 } // namespace bin | 1793 } // namespace bin |
1845 } // namespace dart | 1794 } // namespace dart |
1846 | 1795 |
1847 int main(int argc, char** argv) { | 1796 int main(int argc, char** argv) { |
1848 return dart::bin::main(argc, argv); | 1797 return dart::bin::main(argc, argv); |
1849 } | 1798 } |
OLD | NEW |