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 <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/log.h" | 17 #include "bin/log.h" |
18 #include "bin/thread.h" | 18 #include "bin/thread.h" |
19 | 19 |
20 #include "platform/globals.h" | 20 #include "platform/globals.h" |
21 | 21 |
22 | 22 |
23 namespace dart { | 23 namespace dart { |
24 namespace bin { | 24 namespace bin { |
25 | 25 |
26 #define CHECK_RESULT(result) \ | 26 #define CHECK_RESULT(result) \ |
27 if (Dart_IsError(result)) { \ | 27 if (Dart_IsError(result)) { \ |
28 free(snapshot_buffer); \ | |
29 Log::PrintErr("Error: %s", Dart_GetError(result)); \ | 28 Log::PrintErr("Error: %s", Dart_GetError(result)); \ |
30 Dart_ExitScope(); \ | 29 Dart_ExitScope(); \ |
31 Dart_ShutdownIsolate(); \ | 30 Dart_ShutdownIsolate(); \ |
32 exit(255); \ | 31 exit(255); \ |
33 } \ | 32 } \ |
34 | 33 |
35 | 34 |
36 // Global state that indicates whether a snapshot is to be created and | 35 // Global state that indicates whether a snapshot is to be created and |
37 // if so which file to write the snapshot into. | 36 // if so which file to write the snapshot into. |
38 static const char* snapshot_filename = NULL; | 37 static const char* vm_isolate_snapshot_filename = NULL; |
| 38 static const char* isolate_snapshot_filename = NULL; |
39 static const char* package_root = NULL; | 39 static const char* package_root = NULL; |
40 static uint8_t* snapshot_buffer = NULL; | |
41 | 40 |
42 | 41 |
43 // Global state which contains a pointer to the script name for which | 42 // Global state which contains a pointer to the script name for which |
44 // a snapshot needs to be created (NULL would result in the creation | 43 // a snapshot needs to be created (NULL would result in the creation |
45 // of a generic snapshot that contains only the corelibs). | 44 // of a generic snapshot that contains only the corelibs). |
46 static char* app_script_name = NULL; | 45 static char* app_script_name = NULL; |
47 | 46 |
48 | 47 |
49 // Global state that captures the URL mappings specified on the command line. | 48 // Global state that captures the URL mappings specified on the command line. |
50 static CommandLineOptions* url_mapping = NULL; | 49 static CommandLineOptions* url_mapping = NULL; |
51 | 50 |
52 static bool IsValidFlag(const char* name, | 51 static bool IsValidFlag(const char* name, |
53 const char* prefix, | 52 const char* prefix, |
54 intptr_t prefix_length) { | 53 intptr_t prefix_length) { |
55 intptr_t name_length = strlen(name); | 54 intptr_t name_length = strlen(name); |
56 return ((name_length > prefix_length) && | 55 return ((name_length > prefix_length) && |
57 (strncmp(name, prefix, prefix_length) == 0)); | 56 (strncmp(name, prefix, prefix_length) == 0)); |
58 } | 57 } |
59 | 58 |
60 | 59 |
61 static const char* ProcessOption(const char* option, const char* name) { | 60 static const char* ProcessOption(const char* option, const char* name) { |
62 const intptr_t length = strlen(name); | 61 const intptr_t length = strlen(name); |
63 if (strncmp(option, name, length) == 0) { | 62 if (strncmp(option, name, length) == 0) { |
64 return (option + length); | 63 return (option + length); |
65 } | 64 } |
66 return NULL; | 65 return NULL; |
67 } | 66 } |
68 | 67 |
69 | 68 |
70 static bool ProcessSnapshotOption(const char* option) { | 69 static bool ProcessVmIsolateSnapshotOption(const char* option) { |
71 const char* name = ProcessOption(option, "--snapshot="); | 70 const char* name = ProcessOption(option, "--vm_isolate_snapshot="); |
72 if (name != NULL) { | 71 if (name != NULL) { |
73 snapshot_filename = name; | 72 vm_isolate_snapshot_filename = name; |
74 return true; | 73 return true; |
75 } | 74 } |
76 return false; | 75 return false; |
77 } | 76 } |
78 | 77 |
79 | 78 |
| 79 static bool ProcessIsolateSnapshotOption(const char* option) { |
| 80 const char* name = ProcessOption(option, "--isolate_snapshot="); |
| 81 if (name != NULL) { |
| 82 isolate_snapshot_filename = name; |
| 83 return true; |
| 84 } |
| 85 return false; |
| 86 } |
| 87 |
| 88 |
80 static bool ProcessPackageRootOption(const char* option) { | 89 static bool ProcessPackageRootOption(const char* option) { |
81 const char* name = ProcessOption(option, "--package_root="); | 90 const char* name = ProcessOption(option, "--package_root="); |
82 if (name != NULL) { | 91 if (name != NULL) { |
83 package_root = name; | 92 package_root = name; |
84 return true; | 93 return true; |
85 } | 94 } |
86 return false; | 95 return false; |
87 } | 96 } |
88 | 97 |
89 | 98 |
(...skipping 17 matching lines...) Expand all Loading... |
107 CommandLineOptions* vm_options, | 116 CommandLineOptions* vm_options, |
108 char** script_name) { | 117 char** script_name) { |
109 const char* kPrefix = "--"; | 118 const char* kPrefix = "--"; |
110 const intptr_t kPrefixLen = strlen(kPrefix); | 119 const intptr_t kPrefixLen = strlen(kPrefix); |
111 | 120 |
112 // Skip the binary name. | 121 // Skip the binary name. |
113 int i = 1; | 122 int i = 1; |
114 | 123 |
115 // Parse out the vm options. | 124 // Parse out the vm options. |
116 while ((i < argc) && IsValidFlag(argv[i], kPrefix, kPrefixLen)) { | 125 while ((i < argc) && IsValidFlag(argv[i], kPrefix, kPrefixLen)) { |
117 if (ProcessSnapshotOption(argv[i]) || | 126 if (ProcessVmIsolateSnapshotOption(argv[i]) || |
| 127 ProcessIsolateSnapshotOption(argv[i]) || |
118 ProcessURLmappingOption(argv[i]) || | 128 ProcessURLmappingOption(argv[i]) || |
119 ProcessPackageRootOption(argv[i])) { | 129 ProcessPackageRootOption(argv[i])) { |
120 i += 1; | 130 i += 1; |
121 continue; | 131 continue; |
122 } | 132 } |
123 vm_options->AddArgument(argv[i]); | 133 vm_options->AddArgument(argv[i]); |
124 i += 1; | 134 i += 1; |
125 } | 135 } |
126 | 136 |
127 // Get the script name. | 137 // Get the script name. |
128 if (i < argc) { | 138 if (i < argc) { |
129 *script_name = argv[i]; | 139 *script_name = argv[i]; |
130 i += 1; | 140 i += 1; |
131 } else { | 141 } else { |
132 *script_name = NULL; | 142 *script_name = NULL; |
133 } | 143 } |
134 | 144 |
135 if (snapshot_filename == NULL) { | 145 if (vm_isolate_snapshot_filename == NULL) { |
136 Log::PrintErr("No snapshot output file specified.\n\n"); | 146 Log::PrintErr("No vm isolate snapshot output file specified.\n\n"); |
| 147 return -1; |
| 148 } |
| 149 |
| 150 if (isolate_snapshot_filename == NULL) { |
| 151 Log::PrintErr("No isolate snapshot output file specified.\n\n"); |
137 return -1; | 152 return -1; |
138 } | 153 } |
139 | 154 |
140 return 0; | 155 return 0; |
141 } | 156 } |
142 | 157 |
143 | 158 |
144 static void WriteSnapshotFile(const uint8_t* buffer, const intptr_t size) { | 159 static void WriteSnapshotFile(const char* filename, |
145 File* file = File::Open(snapshot_filename, File::kWriteTruncate); | 160 const uint8_t* buffer, |
| 161 const intptr_t size) { |
| 162 File* file = File::Open(filename, File::kWriteTruncate); |
146 ASSERT(file != NULL); | 163 ASSERT(file != NULL); |
147 if (!file->WriteFully(buffer, size)) { | 164 if (!file->WriteFully(buffer, size)) { |
148 Log::PrintErr("Error: Failed to write full snapshot.\n\n"); | 165 Log::PrintErr("Error: Failed to write snapshot file.\n\n"); |
149 } | 166 } |
150 delete file; | 167 delete file; |
151 } | 168 } |
152 | 169 |
153 | 170 |
154 class UriResolverIsolateScope { | 171 class UriResolverIsolateScope { |
155 public: | 172 public: |
156 UriResolverIsolateScope() { | 173 UriResolverIsolateScope() { |
157 ASSERT(isolate != NULL); | 174 ASSERT(isolate != NULL); |
158 snapshotted_isolate_ = Dart_CurrentIsolate(); | 175 snapshotted_isolate_ = Dart_CurrentIsolate(); |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
431 Dart_ExitScope(); | 448 Dart_ExitScope(); |
432 Dart_ShutdownIsolate(); | 449 Dart_ShutdownIsolate(); |
433 exit(255); | 450 exit(255); |
434 } | 451 } |
435 ASSERT(Dart_IsLibrary(library)); | 452 ASSERT(Dart_IsLibrary(library)); |
436 } | 453 } |
437 | 454 |
438 | 455 |
439 static void CreateAndWriteSnapshot() { | 456 static void CreateAndWriteSnapshot() { |
440 Dart_Handle result; | 457 Dart_Handle result; |
441 uint8_t* buffer = NULL; | 458 uint8_t* vm_isolate_buffer = NULL; |
442 intptr_t size = 0; | 459 intptr_t vm_isolate_size = 0; |
| 460 uint8_t* isolate_buffer = NULL; |
| 461 intptr_t isolate_size = 0; |
443 | 462 |
444 // First create a snapshot. | 463 // First create a snapshot. |
445 result = Dart_CreateSnapshot(&buffer, &size); | 464 result = Dart_CreateSnapshot(&vm_isolate_buffer, |
| 465 &vm_isolate_size, |
| 466 &isolate_buffer, |
| 467 &isolate_size); |
446 CHECK_RESULT(result); | 468 CHECK_RESULT(result); |
447 | 469 |
448 // Now write the snapshot out to specified file and exit. | 470 // Now write the vm isolate and isolate snapshots out to the |
449 WriteSnapshotFile(buffer, size); | 471 // specified file and exit. |
| 472 WriteSnapshotFile(vm_isolate_snapshot_filename, |
| 473 vm_isolate_buffer, |
| 474 vm_isolate_size); |
| 475 WriteSnapshotFile(isolate_snapshot_filename, |
| 476 isolate_buffer, |
| 477 isolate_size); |
450 Dart_ExitScope(); | 478 Dart_ExitScope(); |
451 | 479 |
452 // Shutdown the isolate. | 480 // Shutdown the isolate. |
453 Dart_ShutdownIsolate(); | 481 Dart_ShutdownIsolate(); |
454 } | 482 } |
455 | 483 |
456 | 484 |
457 static void SetupForUriResolution() { | 485 static void SetupForUriResolution() { |
458 // Set up the library tag handler for this isolate. | 486 // Set up the library tag handler for this isolate. |
459 Dart_Handle result = Dart_SetLibraryTagHandler(DartUtils::LibraryTagHandler); | 487 Dart_Handle result = Dart_SetLibraryTagHandler(DartUtils::LibraryTagHandler); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
503 } | 531 } |
504 | 532 |
505 Thread::InitOnce(); | 533 Thread::InitOnce(); |
506 DartUtils::SetOriginalWorkingDirectory(); | 534 DartUtils::SetOriginalWorkingDirectory(); |
507 | 535 |
508 Dart_SetVMFlags(vm_options.count(), vm_options.arguments()); | 536 Dart_SetVMFlags(vm_options.count(), vm_options.arguments()); |
509 | 537 |
510 // Initialize the Dart VM. | 538 // Initialize the Dart VM. |
511 // Note: We don't expect isolates to be created from dart code during | 539 // Note: We don't expect isolates to be created from dart code during |
512 // snapshot generation. | 540 // snapshot generation. |
513 if (!Dart_Initialize(NULL, NULL, NULL, NULL, | 541 if (!Dart_Initialize(NULL, |
| 542 NULL, NULL, NULL, NULL, |
514 DartUtils::OpenFile, | 543 DartUtils::OpenFile, |
515 DartUtils::ReadFile, | 544 DartUtils::ReadFile, |
516 DartUtils::WriteFile, | 545 DartUtils::WriteFile, |
517 DartUtils::CloseFile, | 546 DartUtils::CloseFile, |
518 DartUtils::EntropySource)) { | 547 DartUtils::EntropySource)) { |
519 Log::PrintErr("VM initialization failed\n"); | 548 Log::PrintErr("VM initialization failed\n"); |
520 return 255; | 549 return 255; |
521 } | 550 } |
522 | 551 |
523 char* error; | 552 char* error; |
524 Dart_Isolate isolate = Dart_CreateIsolate(NULL, NULL, NULL, NULL, &error); | 553 Dart_Isolate isolate = Dart_CreateIsolate(NULL, NULL, NULL, NULL, &error); |
525 if (isolate == NULL) { | 554 if (isolate == NULL) { |
526 Log::PrintErr("Error: %s", error); | 555 Log::PrintErr("Error: %s", error); |
527 free(error); | 556 free(error); |
528 exit(255); | 557 exit(255); |
529 } | 558 } |
530 | 559 |
531 Dart_Handle result; | 560 Dart_Handle result; |
532 Dart_Handle library; | 561 Dart_Handle library; |
533 Dart_EnterScope(); | 562 Dart_EnterScope(); |
534 | 563 |
535 ASSERT(snapshot_filename != NULL); | 564 ASSERT(vm_isolate_snapshot_filename != NULL); |
| 565 ASSERT(isolate_snapshot_filename != NULL); |
536 // Load up the script before a snapshot is created. | 566 // Load up the script before a snapshot is created. |
537 if (app_script_name != NULL) { | 567 if (app_script_name != NULL) { |
538 // This is the case of a custom embedder (e.g: dartium) trying to | 568 // This is the case of a custom embedder (e.g: dartium) trying to |
539 // create a full snapshot. The current isolate is set up so that we can | 569 // create a full snapshot. The current isolate is set up so that we can |
540 // invoke the dart uri resolution code like _resolveURI. App script is | 570 // invoke the dart uri resolution code like _resolveURI. App script is |
541 // loaded into a separate isolate. | 571 // loaded into a separate isolate. |
542 | 572 |
543 SetupForUriResolution(); | 573 SetupForUriResolution(); |
544 | 574 |
545 // Get handle to builtin library. | 575 // Get handle to builtin library. |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
589 } | 619 } |
590 return 0; | 620 return 0; |
591 } | 621 } |
592 | 622 |
593 } // namespace bin | 623 } // namespace bin |
594 } // namespace dart | 624 } // namespace dart |
595 | 625 |
596 int main(int argc, char** argv) { | 626 int main(int argc, char** argv) { |
597 return dart::bin::main(argc, argv); | 627 return dart::bin::main(argc, argv); |
598 } | 628 } |
OLD | NEW |