| 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 |