Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
main_impl.cc
Go to the documentation of this file.
1// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
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.
4
5#include "bin/main_impl.h"
6
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10
11#include <memory>
12#include <utility>
13
14#include "bin/builtin.h"
15#include "bin/console.h"
16#include "bin/crashpad.h"
17#include "bin/dartdev_isolate.h"
18#include "bin/dartutils.h"
19#include "bin/dfe.h"
20#include "bin/error_exit.h"
21#include "bin/eventhandler.h"
22#include "bin/exe_utils.h"
23#include "bin/file.h"
24#include "bin/gzip.h"
25#include "bin/isolate_data.h"
26#include "bin/loader.h"
27#include "bin/main_options.h"
28#include "bin/platform.h"
29#include "bin/process.h"
30#include "bin/snapshot_utils.h"
31#include "bin/thread.h"
32#include "bin/utils.h"
33#include "bin/vmservice_impl.h"
35#include "include/dart_api.h"
38#include "platform/globals.h"
40#include "platform/hashmap.h"
41#include "platform/syslog.h"
43#include "platform/utils.h"
44
45extern "C" {
46extern const uint8_t kDartVmSnapshotData[];
47extern const uint8_t kDartVmSnapshotInstructions[];
48extern const uint8_t kDartCoreIsolateSnapshotData[];
49extern const uint8_t kDartCoreIsolateSnapshotInstructions[];
50}
51
52namespace dart {
53namespace bin {
54
55// Snapshot pieces we link in a snapshot.
61
62/**
63 * Global state used to control and store generation of application snapshots.
64 * An application snapshot can be generated and run using the following
65 * command
66 * dart --snapshot-kind=app-jit --snapshot=<app_snapshot_filename>
67 * <script_uri> [<script_options>]
68 * To Run the application snapshot generated above, use :
69 * dart <app_snapshot_filename> [<script_options>]
70 */
71static bool vm_run_app_snapshot = false;
72static char* app_script_uri = nullptr;
73static const uint8_t* app_isolate_snapshot_data = nullptr;
74static const uint8_t* app_isolate_snapshot_instructions = nullptr;
75static bool kernel_isolate_is_running = false;
76
77static Dart_Isolate main_isolate = nullptr;
78
79#define SAVE_ERROR_AND_EXIT(result) \
80 *error = Utils::StrDup(Dart_GetError(result)); \
81 if (Dart_IsCompilationError(result)) { \
82 *exit_code = kCompilationErrorExitCode; \
83 } else if (Dart_IsApiError(result)) { \
84 *exit_code = kApiErrorExitCode; \
85 } else { \
86 *exit_code = kErrorExitCode; \
87 } \
88 Dart_ExitScope(); \
89 Dart_ShutdownIsolate(); \
90 return nullptr;
91
92#define CHECK_RESULT(result) \
93 if (Dart_IsError(result)) { \
94 SAVE_ERROR_AND_EXIT(result); \
95 }
96
97#define CHECK_RESULT_CLEANUP(result, cleanup) \
98 if (Dart_IsError(result)) { \
99 delete (cleanup); \
100 SAVE_ERROR_AND_EXIT(result); \
101 }
102
103static void WriteDepsFile() {
104 if (Options::depfile() == nullptr) {
105 return;
106 }
107 File* file = File::Open(nullptr, Options::depfile(), File::kWriteTruncate);
108 if (file == nullptr) {
109 ErrorExit(kErrorExitCode, "Error: Unable to open snapshot depfile: %s\n\n",
110 Options::depfile());
111 }
112 bool success = true;
113 if (Options::depfile_output_filename() != nullptr) {
114 success &= file->Print("%s: ", Options::depfile_output_filename());
115 } else {
116 success &= file->Print("%s: ", Options::snapshot_filename());
117 }
121 ErrorExit(
123 "Error: Failed to fetch dependencies from kernel service: %s\n\n",
124 result.error);
125 }
126 success &= file->WriteFully(result.kernel, result.kernel_size);
127 free(result.kernel);
128 }
129 success &= file->Print("\n");
130 if (!success) {
131 ErrorExit(kErrorExitCode, "Error: Unable to write snapshot depfile: %s\n\n",
132 Options::depfile());
133 }
134 file->Release();
135}
136
137static void OnExitHook(int64_t exit_code) {
140 "A snapshot was requested, but a secondary isolate "
141 "performed a hard exit (%" Pd64 ").\n",
142 exit_code);
144 }
145 if (exit_code == 0) {
146 if (Options::gen_snapshot_kind() == kAppJIT) {
147 Snapshot::GenerateAppJIT(Options::snapshot_filename());
148 }
150 }
151}
152
154 IsolateData* isolate_data,
155 bool is_isolate_group_start,
156 bool is_kernel_isolate,
157 const char** resolved_packages_config) {
158 auto isolate_group_data = isolate_data->isolate_group_data();
159 const auto packages_file = isolate_data->packages_file();
160 const auto script_uri = isolate_group_data->script_url;
161
163
164 // Prepare builtin and other core libraries for use to resolve URIs.
165 // Set up various closures, e.g: printing, timers etc.
166 // Set up package configuration for URI resolution.
167 result = DartUtils::PrepareForScriptLoading(false, Options::trace_loading());
168 if (Dart_IsError(result)) return result;
169
170 // Setup packages config if specified.
171 result = DartUtils::SetupPackageConfig(packages_file);
172 if (Dart_IsError(result)) return result;
173 if (!Dart_IsNull(result) && resolved_packages_config != nullptr) {
174 result = Dart_StringToCString(result, resolved_packages_config);
175 if (Dart_IsError(result)) return result;
176 ASSERT(*resolved_packages_config != nullptr);
177#if !defined(DART_PRECOMPILED_RUNTIME)
178 if (is_isolate_group_start) {
179 isolate_group_data->set_resolved_packages_config(
180 *resolved_packages_config);
181 } else {
182 ASSERT(strcmp(isolate_group_data->resolved_packages_config(),
183 *resolved_packages_config) == 0);
184 }
185#endif
186 }
187
189 if (Dart_IsError(result)) return result;
190
191 // Setup the native resolver as the snapshot does not carry it.
196
197 const char* namespc = is_kernel_isolate ? nullptr : Options::namespc();
198 result =
199 DartUtils::SetupIOLibrary(namespc, script_uri, Options::exit_disabled());
200 if (Dart_IsError(result)) return result;
201
202 return Dart_Null();
203}
204
205static bool OnIsolateInitialize(void** child_callback_data, char** error) {
207 ASSERT(isolate != nullptr);
208
209 auto isolate_group_data =
211
212 auto isolate_data = new IsolateData(isolate_group_data);
213 *child_callback_data = isolate_data;
214
216 const auto script_uri = isolate_group_data->script_url;
217 const bool isolate_run_app_snapshot =
218 isolate_group_data->RunFromAppSnapshot();
219 Dart_Handle result = SetupCoreLibraries(isolate, isolate_data,
220 /*group_start=*/false,
221 /*is_kernel_isolate=*/false,
222 /*resolved_packages_config=*/nullptr);
223 if (Dart_IsError(result)) goto failed;
224
225 if (isolate_run_app_snapshot) {
226 result = Loader::InitForSnapshot(script_uri, isolate_data);
227 if (Dart_IsError(result)) goto failed;
228 } else {
230 if (Dart_IsError(result)) goto failed;
231
232 if (isolate_group_data->kernel_buffer() != nullptr) {
233 // Various core-library parts will send requests to the Loader to resolve
234 // relative URIs and perform other related tasks. We need Loader to be
235 // initialized for this to work because loading from Kernel binary
236 // bypasses normal source code loading paths that initialize it.
237 const char* resolved_script_uri = nullptr;
238 result = Dart_StringToCString(result, &resolved_script_uri);
239 if (Dart_IsError(result)) goto failed;
240 result = Loader::InitForSnapshot(resolved_script_uri, isolate_data);
241 if (Dart_IsError(result)) goto failed;
242 }
243 }
244
246 return true;
247
248failed:
251 return false;
252}
253
255 bool is_main_isolate,
256 const char* script_uri,
257 const char* packages_config,
258 bool isolate_run_app_snapshot,
260 char** error,
261 int* exit_code) {
263
264 // Set up the library tag handler for the isolate group shared by all
265 // isolates in the group.
270
271 auto isolate_data = reinterpret_cast<IsolateData*>(Dart_IsolateData(isolate));
272
273 const char* resolved_packages_config = nullptr;
274 result =
275 SetupCoreLibraries(isolate, isolate_data,
276 /*is_isolate_group_start=*/true,
277 flags->is_kernel_isolate, &resolved_packages_config);
279
280#if !defined(DART_PRECOMPILED_RUNTIME)
281 auto isolate_group_data = isolate_data->isolate_group_data();
282 const uint8_t* kernel_buffer = isolate_group_data->kernel_buffer().get();
283 intptr_t kernel_buffer_size = isolate_group_data->kernel_buffer_size();
284 if (!isolate_run_app_snapshot && kernel_buffer == nullptr &&
285 !Dart_IsKernelIsolate(isolate)) {
286 if (!dfe.CanUseDartFrontend()) {
287 const char* format = "Dart frontend unavailable to compile script %s.";
288 intptr_t len = snprintf(nullptr, 0, format, script_uri) + 1;
289 *error = reinterpret_cast<char*>(malloc(len));
290 ASSERT(error != nullptr);
291 snprintf(*error, len, format, script_uri);
292 *exit_code = kErrorExitCode;
295 return nullptr;
296 }
297 uint8_t* application_kernel_buffer = nullptr;
298 intptr_t application_kernel_buffer_size = 0;
299 // Only pass snapshot = true when generating an AppJIT snapshot to avoid
300 // duplicate null-safety info messages from the frontend when generating
301 // a kernel snapshot (this flag is instead set in
302 // Snapshot::GenerateKernel()).
303 const bool for_snapshot = Options::gen_snapshot_kind() == kAppJIT;
304 // If we compile for AppJIT the sources will not be included across app-jit
305 // snapshotting, so there's no reason CFE should embed them in the kernel.
306 const bool embed_sources = Options::gen_snapshot_kind() != kAppJIT;
307 dfe.CompileAndReadScript(script_uri, &application_kernel_buffer,
308 &application_kernel_buffer_size, error, exit_code,
309 resolved_packages_config, for_snapshot,
310 embed_sources);
311 if (application_kernel_buffer == nullptr) {
314 return nullptr;
315 }
316 isolate_group_data->SetKernelBufferNewlyOwned(
317 application_kernel_buffer, application_kernel_buffer_size);
318 kernel_buffer = application_kernel_buffer;
319 kernel_buffer_size = application_kernel_buffer_size;
320 }
321 if (kernel_buffer != nullptr) {
322 Dart_Handle uri = Dart_NewStringFromCString(script_uri);
323 CHECK_RESULT(uri);
324 Dart_Handle resolved_script_uri = DartUtils::ResolveScript(uri);
325 CHECK_RESULT(resolved_script_uri);
326 result = Dart_LoadScriptFromKernel(kernel_buffer, kernel_buffer_size);
328 }
329#endif // !defined(DART_PRECOMPILED_RUNTIME)
330
331 if (isolate_run_app_snapshot) {
332 Dart_Handle result = Loader::InitForSnapshot(script_uri, isolate_data);
334#if !defined(DART_PRECOMPILED_RUNTIME)
335 if (is_main_isolate) {
336 // Find the canonical uri of the app snapshot. We'll use this to decide if
337 // other isolates should use the app snapshot or the core snapshot.
338 const char* resolved_script_uri = nullptr;
341 &resolved_script_uri);
343 ASSERT(app_script_uri == nullptr);
344 app_script_uri = Utils::StrDup(resolved_script_uri);
345 }
346#endif // !defined(DART_PRECOMPILED_RUNTIME)
347 } else {
348#if !defined(DART_PRECOMPILED_RUNTIME)
349 // Load the specified application script into the newly created isolate.
350 Dart_Handle uri =
352 CHECK_RESULT(uri);
353 if (kernel_buffer != nullptr) {
354 // relative URIs and perform other related tasks. We need Loader to be
355 // initialized for this to work because loading from Kernel binary
356 // bypasses normal source code loading paths that initialize it.
357 const char* resolved_script_uri = nullptr;
358 result = Dart_StringToCString(uri, &resolved_script_uri);
360 result = Loader::InitForSnapshot(resolved_script_uri, isolate_data);
362 }
364 Dart_GetMainPortId(), /*flow_id_count=*/0, nullptr,
366 /*argument_count=*/0, nullptr, nullptr);
367#else
368 UNREACHABLE();
369#endif // !defined(DART_PRECOMPILED_RUNTIME)
370 }
371
372 if ((Options::gen_snapshot_kind() == kAppJIT) && is_main_isolate) {
375 }
376
377#if !defined(DART_PRECOMPILED_RUNTIME)
378 // Disable pausing the DartDev isolate on start and exit.
379 const char* isolate_name = nullptr;
380 result = Dart_StringToCString(Dart_DebugName(), &isolate_name);
382 if (strstr(isolate_name, DART_DEV_ISOLATE_NAME) != nullptr) {
385 }
386#endif // !defined(DART_PRECOMPILED_RUNTIME)
387
388 // Make the isolate runnable so that it is ready to handle messages.
392 if (*error != nullptr) {
393 Dart_EnterIsolate(isolate);
395 return nullptr;
396 }
397
398 return isolate;
399}
400
401#if !defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM)
402// Returns newly created Kernel Isolate on success, nullptr on failure.
403// For now we only support the kernel isolate coming up from an
404// application snapshot or from a .dill file.
405static Dart_Isolate CreateAndSetupKernelIsolate(const char* script_uri,
406 const char* packages_config,
408 char** error,
409 int* exit_code) {
410 // Do not start a kernel isolate if we are doing a training run
411 // to create an app JIT snapshot and a kernel file is specified
412 // as the application to run.
413 if (Options::gen_snapshot_kind() == kAppJIT) {
414 const uint8_t* kernel_buffer = nullptr;
415 intptr_t kernel_buffer_size = 0;
416 dfe.application_kernel_buffer(&kernel_buffer, &kernel_buffer_size);
417 if (kernel_buffer_size != 0) {
418 return nullptr;
419 }
420 }
421 // Create and Start the kernel isolate.
422 const char* kernel_snapshot_uri = dfe.frontend_filename();
423 const char* uri =
424 kernel_snapshot_uri != nullptr ? kernel_snapshot_uri : script_uri;
425
426 if (packages_config == nullptr) {
427 packages_config = Options::packages_file();
428 }
429
430 Dart_Isolate isolate = nullptr;
431 IsolateGroupData* isolate_group_data = nullptr;
432 IsolateData* isolate_data = nullptr;
433 bool isolate_run_app_snapshot = false;
434 AppSnapshot* app_snapshot = nullptr;
435 // Kernel isolate uses an app JIT snapshot or uses the dill file.
436 if ((kernel_snapshot_uri != nullptr) &&
437 ((app_snapshot = Snapshot::TryReadAppSnapshot(
438 kernel_snapshot_uri, /*force_load_elf_from_memory=*/false,
439 /*decode_uri=*/false)) != nullptr) &&
440 app_snapshot->IsJIT()) {
441 const uint8_t* isolate_snapshot_data = nullptr;
442 const uint8_t* isolate_snapshot_instructions = nullptr;
443 const uint8_t* ignore_vm_snapshot_data;
444 const uint8_t* ignore_vm_snapshot_instructions;
445 isolate_run_app_snapshot = true;
446 app_snapshot->SetBuffers(
447 &ignore_vm_snapshot_data, &ignore_vm_snapshot_instructions,
449 isolate_group_data = new IsolateGroupData(
450 uri, packages_config, app_snapshot, isolate_run_app_snapshot);
451 isolate_data = new IsolateData(isolate_group_data);
452 isolate = Dart_CreateIsolateGroup(
455 isolate_group_data, isolate_data, error);
456 }
457 if (isolate == nullptr) {
458 // Clear error from app snapshot and re-trying from kernel file.
459 free(*error);
460 *error = nullptr;
461 delete isolate_data;
462 delete isolate_group_data;
463
464 const uint8_t* kernel_service_buffer = nullptr;
465 intptr_t kernel_service_buffer_size = 0;
466 dfe.LoadKernelService(&kernel_service_buffer, &kernel_service_buffer_size);
467 ASSERT(kernel_service_buffer != nullptr);
468 isolate_group_data = new IsolateGroupData(uri, packages_config, nullptr,
469 isolate_run_app_snapshot);
470 isolate_group_data->SetKernelBufferUnowned(
471 const_cast<uint8_t*>(kernel_service_buffer),
472 kernel_service_buffer_size);
473 isolate_data = new IsolateData(isolate_group_data);
476 kernel_service_buffer, kernel_service_buffer_size, flags,
477 isolate_group_data, isolate_data, error);
478 }
479
480 if (isolate == nullptr) {
481 Syslog::PrintErr("%s\n", *error);
482 delete isolate_data;
483 delete isolate_group_data;
484 return nullptr;
485 }
487
488 return IsolateSetupHelper(isolate, false, uri, packages_config,
489 isolate_run_app_snapshot, flags, error, exit_code);
490}
491#endif // !defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM)
492
493// Returns newly created Service Isolate on success, nullptr on failure.
494// For now we only support the service isolate coming up from sources
495// which are compiled by the VM parser.
496static Dart_Isolate CreateAndSetupServiceIsolate(const char* script_uri,
497 const char* packages_config,
499 char** error,
500 int* exit_code) {
501#if !defined(PRODUCT)
502 ASSERT(script_uri != nullptr);
503 Dart_Isolate isolate = nullptr;
504 auto isolate_group_data =
505 new IsolateGroupData(script_uri, packages_config, nullptr, false);
506 ASSERT(flags != nullptr);
507
508#if defined(DART_PRECOMPILED_RUNTIME)
509 // AOT: The service isolate is included in any AOT snapshot in non-PRODUCT
510 // mode - so we launch the vm-service from the main app AOT snapshot.
512 const uint8_t* isolate_snapshot_instructions =
514 isolate = Dart_CreateIsolateGroup(
516 isolate_snapshot_instructions, flags, isolate_group_data,
517 /*isolate_data=*/nullptr, error);
518#else
519 // JIT: Service isolate uses the core libraries snapshot.
520
521 // Set flag to load and retain the vmservice library.
522 flags->load_vmservice_library = true;
523 flags->null_safety = true; // Service isolate runs in sound null safe mode.
525 const uint8_t* isolate_snapshot_instructions =
527 isolate = Dart_CreateIsolateGroup(
529 isolate_snapshot_instructions, flags, isolate_group_data,
530 /*isolate_data=*/nullptr, error);
531#endif // !defined(DART_PRECOMPILED_RUNTIME)
532 if (isolate == nullptr) {
533 delete isolate_group_data;
534 return nullptr;
535 }
536
538
543
544 // We do not spawn the external dds process in the following scenarios:
545 // - The DartDev CLI is disabled and VM service is enabled.
546 // - DDS is disabled.
547 bool wait_for_dds_to_advertise_service =
548 !(Options::disable_dart_dev() || Options::disable_dds());
549 bool serve_devtools =
550 Options::enable_devtools() || !Options::disable_devtools();
551 // Load embedder specific bits and return.
552 if (!VmService::Setup(
554 Options::vm_service_dev_mode(), Options::vm_service_auth_disabled(),
555 Options::vm_write_service_info_filename(), Options::trace_loading(),
556 Options::deterministic(), Options::enable_service_port_fallback(),
557 wait_for_dds_to_advertise_service, serve_devtools,
558 Options::enable_observatory(), Options::print_dtd())) {
560 return nullptr;
561 }
562 if (Options::compile_all()) {
565 }
570 return isolate;
571#else // !defined(PRODUCT)
572 return nullptr;
573#endif // !defined(PRODUCT)
574}
575
576#if !defined(DART_PRECOMPILED_RUNTIME)
577
578static Dart_Isolate CreateAndSetupDartDevIsolate(const char* script_uri,
579 const char* packages_config,
581 char** error,
582 int* exit_code) {
583 int64_t start = Dart_TimelineGetMicros();
584
586 if (dartdev_path.get() == nullptr) {
588 "Failed to start the Dart CLI isolate. Could not resolve DartDev "
589 "snapshot or kernel.\n");
590 if (error != nullptr && *error != nullptr) {
591 free(*error);
592 *error = nullptr;
593 }
594 return nullptr;
595 }
596
597 Dart_Isolate isolate = nullptr;
599 const uint8_t* isolate_snapshot_instructions =
601 IsolateGroupData* isolate_group_data = nullptr;
602 IsolateData* isolate_data = nullptr;
603 AppSnapshot* app_snapshot = nullptr;
604 bool isolate_run_app_snapshot = true;
605 // dartdev isolate uses an app JIT snapshot or uses the dill file.
606 if (((app_snapshot = Snapshot::TryReadAppSnapshot(
607 dartdev_path.get(), /*force_load_elf_from_memory=*/false,
608 /*decode_uri=*/false)) != nullptr) &&
609 app_snapshot->IsJIT()) {
610 const uint8_t* isolate_snapshot_data = nullptr;
611 const uint8_t* isolate_snapshot_instructions = nullptr;
612 const uint8_t* ignore_vm_snapshot_data;
613 const uint8_t* ignore_vm_snapshot_instructions;
614 app_snapshot->SetBuffers(
615 &ignore_vm_snapshot_data, &ignore_vm_snapshot_instructions,
617 isolate_group_data =
618 new IsolateGroupData(DART_DEV_ISOLATE_NAME, packages_config,
619 app_snapshot, isolate_run_app_snapshot);
620 isolate_data = new IsolateData(isolate_group_data);
621 isolate = Dart_CreateIsolateGroup(
623 isolate_snapshot_instructions, flags, isolate_group_data, isolate_data,
624 error);
625 }
626
627 if (isolate == nullptr) {
628 // dartdev_path was not an application snapshot, try it as a kernel file.
629 // Clear error from app snapshot and retry from kernel.
630 if (error != nullptr && *error != nullptr) {
631 free(*error);
632 *error = nullptr;
633 }
634 isolate_run_app_snapshot = false;
635 if (app_snapshot != nullptr) {
636 delete app_snapshot;
637 }
638 isolate_group_data =
639 new IsolateGroupData(DART_DEV_ISOLATE_NAME, packages_config, nullptr,
640 isolate_run_app_snapshot);
641 uint8_t* application_kernel_buffer = nullptr;
642 intptr_t application_kernel_buffer_size = 0;
643 dfe.ReadScript(dartdev_path.get(), nullptr, &application_kernel_buffer,
644 &application_kernel_buffer_size, /*decode_uri=*/false);
645 isolate_group_data->SetKernelBufferNewlyOwned(
646 application_kernel_buffer, application_kernel_buffer_size);
647
648 isolate_data = new IsolateData(isolate_group_data);
649 isolate = Dart_CreateIsolateGroup(
651 isolate_snapshot_instructions, flags, isolate_group_data, isolate_data,
652 error);
653 }
654
655 Dart_Isolate created_isolate =
656 IsolateSetupHelper(isolate, false, DART_DEV_ISOLATE_NAME, packages_config,
657 isolate_run_app_snapshot, flags, error, exit_code);
658
659 int64_t end = Dart_TimelineGetMicros();
660 Dart_RecordTimelineEvent("CreateAndSetupDartDevIsolate", start, end,
661 /*flow_id_count=*/0, nullptr,
663 /*argument_count=*/0, nullptr, nullptr);
664 return created_isolate;
665}
666
667#endif // !defined(DART_PRECOMPILED_RUNTIME)
668
669// Returns newly created Isolate on success, nullptr on failure.
671 bool is_main_isolate,
672 const char* script_uri,
673 const char* name,
674 const char* packages_config,
676 void* callback_data,
677 char** error,
678 int* exit_code) {
679 int64_t start = Dart_TimelineGetMicros();
680 ASSERT(script_uri != nullptr);
681 uint8_t* kernel_buffer = nullptr;
682 std::shared_ptr<uint8_t> kernel_buffer_ptr;
683 intptr_t kernel_buffer_size = 0;
684 AppSnapshot* app_snapshot = nullptr;
685
686#if defined(DART_PRECOMPILED_RUNTIME)
687 const uint8_t* isolate_snapshot_data = nullptr;
688 const uint8_t* isolate_snapshot_instructions = nullptr;
689 if (is_main_isolate) {
692 } else {
693 // AOT: All isolates need to be run from AOT compiled snapshots.
694 const bool kForceLoadElfFromMemory = false;
695 app_snapshot =
696 Snapshot::TryReadAppSnapshot(script_uri, kForceLoadElfFromMemory);
697 if (app_snapshot == nullptr || !app_snapshot->IsAOT()) {
699 "The uri(%s) provided to `Isolate.spawnUri()` does not "
700 "contain a valid AOT snapshot.",
701 script_uri);
702 return nullptr;
703 }
704
705 const uint8_t* ignore_vm_snapshot_data;
706 const uint8_t* ignore_vm_snapshot_instructions;
707 app_snapshot->SetBuffers(
708 &ignore_vm_snapshot_data, &ignore_vm_snapshot_instructions,
710 }
711
712 bool isolate_run_app_snapshot = true;
713#else
714 // JIT: Main isolate starts from the app snapshot, if any. Other isolates
715 // use the core libraries snapshot.
716 bool isolate_run_app_snapshot = false;
718 const uint8_t* isolate_snapshot_instructions =
720 if ((app_isolate_snapshot_data != nullptr) &&
721 (is_main_isolate || ((app_script_uri != nullptr) &&
722 (strcmp(script_uri, app_script_uri) == 0)))) {
723 isolate_run_app_snapshot = true;
726 } else if (!is_main_isolate) {
727 app_snapshot = Snapshot::TryReadAppSnapshot(script_uri);
728 if (app_snapshot != nullptr && app_snapshot->IsJITorAOT()) {
729 if (app_snapshot->IsAOT()) {
731 "The uri(%s) provided to `Isolate.spawnUri()` is an "
732 "AOT snapshot and the JIT VM cannot spawn an isolate using it.",
733 script_uri);
734 delete app_snapshot;
735 return nullptr;
736 }
737 isolate_run_app_snapshot = true;
738 const uint8_t* ignore_vm_snapshot_data;
739 const uint8_t* ignore_vm_snapshot_instructions;
740 app_snapshot->SetBuffers(
741 &ignore_vm_snapshot_data, &ignore_vm_snapshot_instructions,
743 }
744 }
745
746 if (kernel_buffer == nullptr && !isolate_run_app_snapshot) {
747 dfe.ReadScript(script_uri, app_snapshot, &kernel_buffer,
748 &kernel_buffer_size, /*decode_uri=*/true,
749 &kernel_buffer_ptr);
750 }
751 PathSanitizer script_uri_sanitizer(script_uri);
752 PathSanitizer packages_config_sanitizer(packages_config);
753#endif // !defined(DART_PRECOMPILED_RUNTIME)
754
755 auto isolate_group_data = new IsolateGroupData(
756 script_uri, packages_config, app_snapshot, isolate_run_app_snapshot);
757 if (kernel_buffer != nullptr) {
758 if (kernel_buffer_ptr) {
759 isolate_group_data->SetKernelBufferAlreadyOwned(
760 std::move(kernel_buffer_ptr), kernel_buffer_size);
761 } else {
762 isolate_group_data->SetKernelBufferNewlyOwned(kernel_buffer,
763 kernel_buffer_size);
764 }
765 }
766
767 Dart_Isolate isolate = nullptr;
768
769 IsolateData* isolate_data = nullptr;
770#if !defined(DART_PRECOMPILED_RUNTIME)
771 if (!isolate_run_app_snapshot && (isolate_snapshot_data == nullptr)) {
772 const uint8_t* platform_kernel_buffer = nullptr;
773 intptr_t platform_kernel_buffer_size = 0;
774 dfe.LoadPlatform(&platform_kernel_buffer, &platform_kernel_buffer_size);
775 if (platform_kernel_buffer == nullptr) {
776 platform_kernel_buffer = kernel_buffer;
777 platform_kernel_buffer_size = kernel_buffer_size;
778 }
779 if (platform_kernel_buffer == nullptr) {
780#if defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM)
781 FATAL(
782 "Binary built with --exclude-kernel-service. Cannot run"
783 " from source.");
784#else
785 FATAL("platform_program cannot be nullptr.");
786#endif // defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM)
787 }
788 // TODO(sivachandra): When the platform program is unavailable, check if
789 // application kernel binary is self contained or an incremental binary.
790 // Isolate should be created only if it is a self contained kernel binary.
791 isolate_data = new IsolateData(isolate_group_data);
793 script_uri, name, platform_kernel_buffer, platform_kernel_buffer_size,
794 flags, isolate_group_data, isolate_data, error);
795 } else {
796 isolate_data = new IsolateData(isolate_group_data);
799 isolate_group_data, isolate_data, error);
800 }
801#else
802 isolate_data = new IsolateData(isolate_group_data);
805 isolate_group_data, isolate_data, error);
806#endif // !defined(DART_PRECOMPILED_RUNTIME)
807
808 Dart_Isolate created_isolate = nullptr;
809 if (isolate == nullptr) {
810 delete isolate_data;
811 delete isolate_group_data;
812 } else {
813 created_isolate = IsolateSetupHelper(
814 isolate, is_main_isolate, script_uri, packages_config,
815 isolate_run_app_snapshot, flags, error, exit_code);
816 }
817 int64_t end = Dart_TimelineGetMicros();
818 Dart_RecordTimelineEvent("CreateIsolateGroupAndSetupHelper", start, end,
819 /*flow_id_count=*/0, nullptr,
821 /*argument_count=*/0, nullptr, nullptr);
822 return created_isolate;
823}
824
825#undef CHECK_RESULT
826
827static Dart_Isolate CreateIsolateGroupAndSetup(const char* script_uri,
828 const char* main,
829 const char* package_root,
830 const char* package_config,
832 void* callback_data,
833 char** error) {
834 // The VM should never call the isolate helper with a nullptr flags.
835 ASSERT(flags != nullptr);
837 ASSERT(package_root == nullptr);
838
839 if (error != nullptr) {
840 *error = nullptr;
841 }
842
843 bool dontneed_safe = true;
844#if defined(DART_HOST_OS_LINUX)
845 // This would also be true in Linux, except that Google3 overrides the default
846 // ELF interpreter to one that apparently doesn't create proper mappings.
847 dontneed_safe = false;
848#elif defined(DEBUG)
849 // If the snapshot isn't file-backed, madvise(DONT_NEED) is destructive.
850 if (Options::force_load_elf_from_memory()) {
851 dontneed_safe = false;
852 }
853#endif
854 flags->snapshot_is_dontneed_safe = dontneed_safe;
855
856 int exit_code = 0;
857#if !defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM)
858 if (strcmp(script_uri, DART_KERNEL_ISOLATE_NAME) == 0) {
859 return CreateAndSetupKernelIsolate(script_uri, package_config, flags, error,
860 &exit_code);
861 }
862#endif // !defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM)
863
864#if !defined(DART_PRECOMPILED_RUNTIME)
865 if (strcmp(script_uri, DART_DEV_ISOLATE_NAME) == 0) {
866 return CreateAndSetupDartDevIsolate(script_uri, package_config, flags,
867 error, &exit_code);
868 }
869#endif // !defined(DART_PRECOMPILED_RUNTIME)
870
871 if (strcmp(script_uri, DART_VM_SERVICE_ISOLATE_NAME) == 0) {
872 return CreateAndSetupServiceIsolate(script_uri, package_config, flags,
873 error, &exit_code);
874 }
875
876 bool is_main_isolate = false;
877 return CreateIsolateGroupAndSetupHelper(is_main_isolate, script_uri, main,
878 package_config, flags, callback_data,
879 error, &exit_code);
880}
881
882#if !defined(DART_PRECOMPILED_RUNTIME)
883static const char* RegisterKernelBlob(const uint8_t* kernel_buffer,
884 intptr_t kernel_buffer_size) {
885 return dfe.RegisterKernelBlob(kernel_buffer, kernel_buffer_size);
886}
887static void UnregisterKernelBlob(const char* kernel_blob_uri) {
888 dfe.UnregisterKernelBlob(kernel_blob_uri);
889}
890#endif // !defined(DART_PRECOMPILED_RUNTIME)
891
892static void OnIsolateShutdown(void* isolate_group_data, void* isolate_data) {
894 Dart_Handle sticky_error = Dart_GetStickyError();
895 if (!Dart_IsNull(sticky_error) && !Dart_IsFatalError(sticky_error)) {
896 Syslog::PrintErr("%s\n", Dart_GetError(sticky_error));
897 }
899}
900
901static void DeleteIsolateData(void* isolate_group_data, void* callback_data) {
902 auto isolate_data = reinterpret_cast<IsolateData*>(callback_data);
903 delete isolate_data;
904}
905
906static void DeleteIsolateGroupData(void* callback_data) {
907 auto isolate_group_data = reinterpret_cast<IsolateGroupData*>(callback_data);
908 delete isolate_group_data;
909}
910
911static constexpr const char* kStdoutStreamId = "Stdout";
912static constexpr const char* kStderrStreamId = "Stderr";
913
914static bool ServiceStreamListenCallback(const char* stream_id) {
915 if (strcmp(stream_id, kStdoutStreamId) == 0) {
916 SetCaptureStdout(true);
917 return true;
918 } else if (strcmp(stream_id, kStderrStreamId) == 0) {
919 SetCaptureStderr(true);
920 return true;
921 }
922 return false;
923}
924
925static void ServiceStreamCancelCallback(const char* stream_id) {
926 if (strcmp(stream_id, kStdoutStreamId) == 0) {
927 SetCaptureStdout(false);
928 } else if (strcmp(stream_id, kStderrStreamId) == 0) {
929 SetCaptureStderr(false);
930 }
931}
932
933static bool FileModifiedCallback(const char* url, int64_t since) {
934 auto path = File::UriToPath(url);
935 if (path == nullptr) {
936 // If it isn't a file on local disk, we don't know if it has been
937 // modified.
938 return true;
939 }
940 int64_t data[File::kStatSize];
941 File::Stat(nullptr, path.get(), data);
943 return true;
944 }
945 return data[File::kModifiedTime] > since;
946}
947
950 info->name = "Dart VM";
951 Process::GetRSSInformation(&(info->max_rss), &(info->current_rss));
952}
953
954#define CHECK_RESULT(result) \
955 if (Dart_IsError(result)) { \
956 const int exit_code = Dart_IsCompilationError(result) \
957 ? kCompilationErrorExitCode \
958 : kErrorExitCode; \
959 ErrorExit(exit_code, "%s\n", Dart_GetError(result)); \
960 }
961
962static void CompileAndSaveKernel(const char* script_name,
963 const char* package_config_override,
964 CommandLineOptions* dart_options) {
966 Syslog::PrintErr("Cannot create a script snapshot from an app snapshot.\n");
967 // The snapshot would contain references to the app snapshot instead of
968 // the core snapshot.
970 }
971 Snapshot::GenerateKernel(Options::snapshot_filename(), script_name,
972 package_config_override);
974}
975
976void RunMainIsolate(const char* script_name,
977 const char* package_config_override,
978 CommandLineOptions* dart_options) {
979 if (script_name != nullptr) {
980 const char* base_name = strrchr(script_name, '/');
981 if (base_name == nullptr) {
982 base_name = script_name;
983 } else {
984 base_name++; // Skip '/'.
985 }
986 const intptr_t kMaxNameLength = 64;
987 char name[kMaxNameLength];
988 Utils::SNPrint(name, kMaxNameLength, "dart:%s", base_name);
990 }
991
992 // Call CreateIsolateGroupAndSetup which creates an isolate and loads up
993 // the specified application script.
994 char* error = nullptr;
995 int exit_code = 0;
998 flags.is_system_isolate = Options::mark_main_isolate_as_system_isolate();
999 bool dontneed_safe = true;
1000#if defined(DART_HOST_OS_LINUX)
1001 // This would also be true in Linux, except that Google3 overrides the default
1002 // ELF interpreter to one that apparently doesn't create proper mappings.
1003 dontneed_safe = false;
1004#elif defined(DEBUG)
1005 // If the snapshot isn't file-backed, madvise(DONT_NEED) is destructive.
1006 if (Options::force_load_elf_from_memory()) {
1007 dontneed_safe = false;
1008 }
1009#endif
1010 flags.snapshot_is_dontneed_safe = dontneed_safe;
1011
1013 /* is_main_isolate */ true, script_name, "main",
1014 Options::packages_file() == nullptr ? package_config_override
1015 : Options::packages_file(),
1016 &flags, nullptr /* callback_data */, &error, &exit_code);
1017
1018 if (isolate == nullptr) {
1019 Syslog::PrintErr("%s\n", error);
1020 free(error);
1021 error = nullptr;
1023 error = Dart_Cleanup();
1024 if (error != nullptr) {
1025 Syslog::PrintErr("VM cleanup failed: %s\n", error);
1026 free(error);
1027 }
1029 Platform::Exit((exit_code != 0) ? exit_code : kErrorExitCode);
1030 }
1031 main_isolate = isolate;
1032
1033 Dart_EnterIsolate(isolate);
1034 ASSERT(isolate == Dart_CurrentIsolate());
1035 ASSERT(isolate != nullptr);
1037
1039
1040 // Kernel snapshots should have been handled before reaching this point.
1041 ASSERT(Options::gen_snapshot_kind() != kKernel);
1042 // Lookup the library of the root script.
1043 Dart_Handle root_lib = Dart_RootLibrary();
1044
1045#if !defined(DART_PRECOMPILED_RUNTIME)
1046 if (Options::compile_all()) {
1049 }
1050#endif // !defined(DART_PRECOMPILED_RUNTIME)
1051
1052 if (Dart_IsNull(root_lib)) {
1053 ErrorExit(kErrorExitCode, "Unable to find root library for '%s'\n",
1054 script_name);
1055 }
1056
1057 // Create a closure for the main entry point which is in the exported
1058 // namespace of the root library or invoke a getter of the same name
1059 // in the exported namespace and return the resulting closure.
1060 Dart_Handle main_closure =
1061 Dart_GetField(root_lib, Dart_NewStringFromCString("main"));
1062 CHECK_RESULT(main_closure);
1063 if (!Dart_IsClosure(main_closure)) {
1064 ErrorExit(kErrorExitCode, "Unable to find 'main' in root library '%s'\n",
1065 script_name);
1066 }
1067
1068 // Call _startIsolate in the isolate library to enable dispatching the
1069 // initial startup message.
1070 const intptr_t kNumIsolateArgs = 2;
1071 Dart_Handle isolate_args[kNumIsolateArgs];
1072 isolate_args[0] = main_closure; // entryPoint
1073 isolate_args[1] = dart_options->CreateRuntimeOptions(); // args
1074
1075 Dart_Handle isolate_lib =
1077 result =
1078 Dart_Invoke(isolate_lib, Dart_NewStringFromCString("_startMainIsolate"),
1079 kNumIsolateArgs, isolate_args);
1081
1082 // Keep handling messages until the last active receive port is closed.
1083 result = Dart_RunLoop();
1084 // Generate an app snapshot after execution if specified.
1085 if (Options::gen_snapshot_kind() == kAppJIT) {
1087 Snapshot::GenerateAppJIT(Options::snapshot_filename());
1088 }
1089 }
1091
1092 WriteDepsFile();
1093
1095
1096 // Shutdown the isolate.
1098}
1099
1100#undef CHECK_RESULT
1101
1102static bool CheckForInvalidPath(const char* path) {
1103 // TODO(zichangguo): "\\?\" is a prefix for paths on Windows.
1104 // Arguments passed are parsed as an URI. "\\?\" causes problems as a part
1105 // of URIs. This is a temporary workaround to prevent VM from crashing.
1106 // Issue: https://github.com/dart-lang/sdk/issues/42779
1107 if (strncmp(path, "\\\\?\\", 4) == 0) {
1108 Syslog::PrintErr("\\\\?\\ prefix is not supported");
1109 return false;
1110 }
1111 return true;
1112}
1113
1114// Observatory assets are not included in a product build.
1115#if !defined(PRODUCT)
1116extern unsigned int observatory_assets_archive_len;
1117extern const uint8_t* observatory_assets_archive;
1118
1120 uint8_t* decompressed = nullptr;
1121 intptr_t decompressed_len = 0;
1123 &decompressed, &decompressed_len);
1124 Dart_Handle tar_file =
1125 DartUtils::MakeUint8Array(decompressed, decompressed_len);
1126 // Free decompressed memory as it has been copied into a Dart array.
1127 free(decompressed);
1128 return tar_file;
1129}
1130#else // !defined(PRODUCT)
1132 nullptr;
1133#endif // !defined(PRODUCT)
1134
1135void main(int argc, char** argv) {
1136#if !defined(DART_HOST_OS_WINDOWS)
1137 // Very early so any crashes during startup can also be symbolized.
1139#endif
1140
1141 char* script_name = nullptr;
1142 // Allows the dartdev process to point to the desired package_config.
1143 char* package_config_override = nullptr;
1144 const int EXTRA_VM_ARGUMENTS = 10;
1145 CommandLineOptions vm_options(argc + EXTRA_VM_ARGUMENTS);
1146 CommandLineOptions dart_options(argc + EXTRA_VM_ARGUMENTS);
1147 bool print_flags_seen = false;
1148 bool verbose_debug_seen = false;
1149
1150 // Perform platform specific initialization.
1151 if (!Platform::Initialize()) {
1152 Syslog::PrintErr("Initialization failed\n");
1154 }
1155
1156 // Save the console state so we can restore it at shutdown.
1158
1159 // On Windows, the argv strings are code page encoded and not
1160 // utf8. We need to convert them to utf8.
1161 bool argv_converted = ShellUtils::GetUtf8Argv(argc, argv);
1162
1163#if !defined(DART_PRECOMPILED_RUNTIME)
1164 // Processing of some command line flags directly manipulates dfe.
1166#endif // !defined(DART_PRECOMPILED_RUNTIME)
1167
1168 // When running from the command line we assume that we are optimizing for
1169 // throughput, and therefore use a larger new gen semi space size and a faster
1170 // new gen growth factor unless others have been specified.
1171 if (kWordSize <= 4) {
1172 vm_options.AddArgument("--new_gen_semi_max_size=16");
1173 } else {
1174 vm_options.AddArgument("--new_gen_semi_max_size=32");
1175 }
1176 vm_options.AddArgument("--new_gen_growth_factor=4");
1177
1178 auto parse_arguments = [&](int argc, char** argv,
1179 CommandLineOptions* vm_options,
1180 CommandLineOptions* dart_options) {
1181 bool success = Options::ParseArguments(
1182 argc, argv, vm_run_app_snapshot, vm_options, &script_name, dart_options,
1183 &print_flags_seen, &verbose_debug_seen);
1184 if (!success) {
1185 if (Options::help_option()) {
1187 Platform::Exit(0);
1188 } else if (Options::version_option()) {
1190 Platform::Exit(0);
1191 } else if (print_flags_seen) {
1192 // Will set the VM flags, print them out and then we exit as no
1193 // script was specified on the command line.
1194 char* error =
1195 Dart_SetVMFlags(vm_options->count(), vm_options->arguments());
1196 if (error != nullptr) {
1197 Syslog::PrintErr("Setting VM flags failed: %s\n", error);
1198 free(error);
1200 }
1201 Platform::Exit(0);
1202 } else {
1203 // This usage error case will only be invoked when
1204 // Options::disable_dart_dev() is false.
1207 }
1208 }
1209 };
1210
1211 AppSnapshot* app_snapshot = nullptr;
1212#if defined(DART_PRECOMPILED_RUNTIME)
1213 // If the executable binary contains the runtime together with an appended
1214 // snapshot, load and run that.
1215 // Any arguments passed to such an executable are meant for the actual
1216 // application so skip all Dart VM flag parsing.
1217
1218 const size_t kPathBufSize = PATH_MAX + 1;
1219 char executable_path[kPathBufSize];
1220 if (Platform::ResolveExecutablePathInto(executable_path, kPathBufSize) > 0) {
1221 app_snapshot = Snapshot::TryReadAppendedAppSnapshotElf(executable_path);
1222 if (app_snapshot != nullptr) {
1223 script_name = argv[0];
1224
1225 // Store the executable name.
1227
1228 // Parse out options to be passed to dart main.
1229 for (int i = 1; i < argc; i++) {
1230 dart_options.AddArgument(argv[i]);
1231 }
1232
1233 // Parse DART_VM_OPTIONS options.
1234 int env_argc = 0;
1235 char** env_argv = Options::GetEnvArguments(&env_argc);
1236 if (env_argv != nullptr) {
1237 // Any Dart options that are generated based on parsing DART_VM_OPTIONS
1238 // are useless, so we'll throw them away rather than passing them along.
1239 CommandLineOptions tmp_options(env_argc + EXTRA_VM_ARGUMENTS);
1240 parse_arguments(env_argc, env_argv, &vm_options, &tmp_options);
1241 }
1242 }
1243 }
1244#endif
1245
1246 // Parse command line arguments.
1247 if (app_snapshot == nullptr) {
1248 parse_arguments(argc, argv, &vm_options, &dart_options);
1249 }
1250
1252
1253 if (Options::suppress_core_dump()) {
1255 } else {
1257 }
1258
1260
1261 auto try_load_snapshots_lambda = [&](void) -> void {
1262 if (app_snapshot == nullptr) {
1263 // For testing purposes we add a flag to debug-mode to use the
1264 // in-memory ELF loader.
1265 const bool force_load_elf_from_memory =
1266 false DEBUG_ONLY(|| Options::force_load_elf_from_memory());
1267 app_snapshot =
1268 Snapshot::TryReadAppSnapshot(script_name, force_load_elf_from_memory);
1269 }
1270 if (app_snapshot != nullptr && app_snapshot->IsJITorAOT()) {
1271 if (app_snapshot->IsAOT() && !Dart_IsPrecompiledRuntime()) {
1273 "%s is an AOT snapshot and should be run with 'dartaotruntime'\n",
1274 script_name);
1276 }
1277 vm_run_app_snapshot = true;
1278 app_snapshot->SetBuffers(&vm_snapshot_data, &vm_snapshot_instructions,
1281 }
1282 };
1283
1284 // At this point, script_name now points to a script if DartDev is disabled
1285 // or a valid file path was provided as the first non-flag argument.
1286 // Otherwise, script_name can be nullptr if DartDev should be run.
1287 if (script_name != nullptr) {
1288 if (!CheckForInvalidPath(script_name)) {
1289 Platform::Exit(0);
1290 }
1291 try_load_snapshots_lambda();
1292 }
1293
1294#if defined(DART_PRECOMPILED_RUNTIME)
1295 vm_options.AddArgument("--precompilation");
1296#endif
1297 if (Options::gen_snapshot_kind() == kAppJIT) {
1298 // App-jit snapshot can be deployed to another machine,
1299 // so generated code should not depend on the CPU features
1300 // of the system where snapshot was generated.
1301 vm_options.AddArgument("--target-unknown-cpu");
1302#if !defined(TARGET_ARCH_IA32)
1303 vm_options.AddArgument("--link_natives_lazily");
1304#endif
1305 }
1306 // If we need to write an app-jit snapshot or a depfile, then add an exit
1307 // hook that writes the snapshot and/or depfile as appropriate.
1308 if ((Options::gen_snapshot_kind() == kAppJIT) ||
1309 (Options::depfile() != nullptr)) {
1311 }
1312
1313 char* error = nullptr;
1315 Syslog::PrintErr("Standalone embedder initialization failed: %s\n", error);
1316 free(error);
1318 }
1319
1320 error = Dart_SetVMFlags(vm_options.count(), vm_options.arguments());
1321 if (error != nullptr) {
1322 Syslog::PrintErr("Setting VM flags failed: %s\n", error);
1323 free(error);
1325 }
1326
1327// Note: must read platform only *after* VM flags are parsed because
1328// they might affect how the platform is loaded.
1329#if !defined(DART_PRECOMPILED_RUNTIME)
1330 // Load vm_platform_strong.dill for dart:* source support.
1331 dfe.Init();
1333 if (script_name != nullptr) {
1334 uint8_t* application_kernel_buffer = nullptr;
1335 intptr_t application_kernel_buffer_size = 0;
1336 dfe.ReadScript(script_name, app_snapshot, &application_kernel_buffer,
1337 &application_kernel_buffer_size);
1338 if (application_kernel_buffer != nullptr) {
1339 // Since we loaded the script anyway, save it.
1340 dfe.set_application_kernel_buffer(application_kernel_buffer,
1341 application_kernel_buffer_size);
1343 }
1344 }
1345#endif
1346
1347 // Initialize the Dart VM.
1348 Dart_InitializeParams init_params;
1349 memset(&init_params, 0, sizeof(init_params));
1351 init_params.vm_snapshot_data = vm_snapshot_data;
1355 init_params.shutdown_isolate = OnIsolateShutdown;
1356 init_params.cleanup_isolate = DeleteIsolateData;
1358 init_params.file_open = DartUtils::OpenFile;
1359 init_params.file_read = DartUtils::ReadFile;
1360 init_params.file_write = DartUtils::WriteFile;
1361 init_params.file_close = DartUtils::CloseFile;
1364#if !defined(DART_PRECOMPILED_RUNTIME)
1365 init_params.start_kernel_isolate =
1367 if (init_params.start_kernel_isolate) {
1370 }
1371#else
1372 init_params.start_kernel_isolate = false;
1373#endif
1374#if defined(DART_HOST_OS_FUCHSIA)
1375#if defined(DART_PRECOMPILED_RUNTIME)
1376 init_params.vmex_resource = ZX_HANDLE_INVALID;
1377#else
1378 init_params.vmex_resource = Platform::GetVMEXResource();
1379#endif
1380#endif
1381
1382 error = Dart_Initialize(&init_params);
1383 if (error != nullptr) {
1385 Syslog::PrintErr("VM initialization failed: %s\n", error);
1386 free(error);
1388 }
1389
1394 bool ran_dart_dev = false;
1395 bool should_run_user_program = true;
1396#if !defined(DART_PRECOMPILED_RUNTIME)
1397 if (DartDevIsolate::should_run_dart_dev() && !Options::disable_dart_dev() &&
1398 Options::gen_snapshot_kind() == SnapshotKind::kNone) {
1400 CreateIsolateGroupAndSetup, &package_config_override, &script_name,
1401 &dart_options);
1403 ran_dart_dev = true;
1404 should_run_user_program =
1405 (dartdev_result == DartDevIsolate::DartDev_Result_Run);
1406 if (should_run_user_program) {
1407 try_load_snapshots_lambda();
1408 }
1409 } else if (script_name == nullptr &&
1410 Options::gen_snapshot_kind() != SnapshotKind::kNone) {
1412 "Snapshot generation should be done using the 'dart compile' "
1413 "command.\n");
1415 }
1416#endif // !defined(DART_PRECOMPILED_RUNTIME)
1417
1418 if (should_run_user_program) {
1419 if (Options::gen_snapshot_kind() == kKernel) {
1420 CompileAndSaveKernel(script_name, package_config_override, &dart_options);
1421 } else {
1422 // Run the main isolate until we aren't told to restart.
1423 RunMainIsolate(script_name, package_config_override, &dart_options);
1424 }
1425 }
1426
1427 // Terminate process exit-code handler.
1429
1430 error = Dart_Cleanup();
1431 if (error != nullptr) {
1432 Syslog::PrintErr("VM cleanup failed: %s\n", error);
1433 free(error);
1434 }
1435 const intptr_t global_exit_code = Process::GlobalExitCode();
1437
1438 delete app_snapshot;
1439 free(app_script_uri);
1440 if (ran_dart_dev && script_name != nullptr) {
1441 free(script_name);
1442 }
1443
1444 // Free copied argument strings if converted.
1445 if (argv_converted) {
1446 for (int i = 0; i < argc; i++) {
1447 free(argv[i]);
1448 }
1449 }
1450
1451 // Free environment if any.
1453
1454 Platform::Exit(global_exit_code);
1455}
1456
1457} // namespace bin
1458} // namespace dart
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
static std::string base_name(const std::string &path)
#define UNREACHABLE()
Definition assert.h:248
static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
static int SNPrint(char *str, size_t size, const char *format,...) PRINTF_ATTRIBUTE(3
static char * StrDup(const char *s)
static char * SCreate(const char *format,...) PRINTF_ATTRIBUTE(1
Definition utils.cc:231
virtual void SetBuffers(const uint8_t **vm_data_buffer, const uint8_t **vm_instructions_buffer, const uint8_t **isolate_data_buffer, const uint8_t **isolate_instructions_buffer)=0
static void SetNativeResolver(BuiltinLibraryId id)
Definition builtin.cc:28
Dart_Handle CreateRuntimeOptions()
Definition dartutils.cc:62
static void SaveConfig()
void CompileAndReadScript(const char *script_uri, uint8_t **kernel_buffer, intptr_t *kernel_buffer_size, char **error, int *exit_code, const char *package_config, bool for_snapshot, bool embed_sources)
Definition dfe.cc:204
bool CanUseDartFrontend() const
Definition dfe.cc:143
void set_use_dfe(bool value=true)
Definition dfe.h:41
void set_verbosity(Dart_KernelCompilationVerbosityLevel verbosity)
Definition dfe.h:49
void set_application_kernel_buffer(uint8_t *buffer, intptr_t size)
Definition dfe.h:60
bool UseDartFrontend() const
Definition dfe.h:42
void LoadPlatform(const uint8_t **kernel_buffer, intptr_t *kernel_buffer_size)
Definition dfe.cc:137
const char * RegisterKernelBlob(const uint8_t *kernel_buffer, intptr_t kernel_buffer_size)
Definition dfe.cc:482
void Init()
Definition dfe.cc:88
void application_kernel_buffer(const uint8_t **buffer, intptr_t *size) const
Definition dfe.h:64
void UnregisterKernelBlob(const char *uri)
Definition dfe.cc:531
void ReadScript(const char *script_uri, const AppSnapshot *app_snapshot, uint8_t **kernel_buffer, intptr_t *kernel_buffer_size, bool decode_uri=true, std::shared_ptr< uint8_t > *kernel_blob_ptr=nullptr)
Definition dfe.cc:241
void LoadKernelService(const uint8_t **kernel_service_buffer, intptr_t *kernel_service_buffer_size)
Definition dfe.cc:131
char * frontend_filename() const
Definition dfe.h:32
static bool should_run_dart_dev()
static Utils::CStringUniquePtr TryResolveDartDevSnapshotPath()
static DartDev_Result RunDartDev(Dart_IsolateGroupCreateCallback create_isolate, char **packages_file, char **script, CommandLineOptions *dart_options)
static Dart_Handle SetupPackageConfig(const char *packages_file)
Definition dartutils.cc:559
static void ReadFile(uint8_t **data, intptr_t *file_len, void *stream)
Definition dartutils.cc:277
static Dart_Handle MakeUint8Array(const void *buffer, intptr_t length)
Definition dartutils.cc:364
static Dart_Handle SetupIOLibrary(const char *namespc_path, const char *script_uri, bool disable_exit)
Definition dartutils.cc:621
static bool EntropySource(uint8_t *buffer, intptr_t length)
Definition dartutils.cc:312
static Dart_Handle EnvironmentCallback(Dart_Handle name)
Definition dartutils.cc:841
static Dart_Handle PrepareForScriptLoading(bool is_service_isolate, bool trace_loading)
Definition dartutils.cc:574
static void SetEnvironment(dart::SimpleHashMap *environment)
Definition dartutils.cc:837
static void CloseFile(void *stream)
Definition dartutils.cc:307
static void * OpenFile(const char *name, bool write)
Definition dartutils.cc:265
static Dart_Handle ResolveScript(Dart_Handle url)
Definition dartutils.cc:390
static void WriteFile(const void *buffer, intptr_t num_bytes, void *stream)
Definition dartutils.cc:298
static void LoadDartProfilerSymbols(const char *exepath)
Definition exe_utils.cc:125
static Utils::CStringUniquePtr UriToPath(const char *uri)
@ kDoesNotExist
Definition file.h:81
static void Stat(Namespace *namespc, const char *path, int64_t *data)
static File * Open(Namespace *namespc, const char *path, FileOpenMode mode)
@ kWriteTruncate
Definition file.h:60
const char * packages_file() const
IsolateGroupData * isolate_group_data() const
void SetKernelBufferNewlyOwned(uint8_t *buffer, intptr_t size)
void SetKernelBufferUnowned(uint8_t *buffer, intptr_t size)
static Dart_Handle InitForSnapshot(const char *snapshot_uri, IsolateData *isolate_data)
Definition loader.cc:26
static Dart_Handle DeferredLoadHandler(intptr_t loading_unit_id)
Definition loader.cc:131
static Dart_Handle LibraryTagHandler(Dart_LibraryTag tag, Dart_Handle library, Dart_Handle url)
Definition loader.cc:67
static void InitOnce()
Definition loader.cc:169
static void Cleanup()
static void PrintVersion()
static void set_dfe(DFE *dfe)
static DFE * dfe()
static void PrintUsage()
static Dart_KernelCompilationVerbosityLevel verbosity_level()
static bool ParseArguments(int argc, char **argv, bool vm_run_app_snapshot, CommandLineOptions *vm_options, char **script_name, CommandLineOptions *dart_options, bool *print_flags_seen, bool *verbose_debug_seen)
static const char * vm_service_server_ip()
static int vm_service_server_port()
static dart::SimpleHashMap * environment()
static void SetExecutableName(const char *executable_name)
Definition platform.h:71
static void SetProcessName(const char *name)
static DART_NORETURN void Exit(int exit_code)
static bool Initialize()
static intptr_t ResolveExecutablePathInto(char *result, size_t result_size)
static void SetCoreDumpResourceLimit(int value)
static void GetRSSInformation(int64_t *max_rss, int64_t *current_rss)
Definition process.cc:393
static void TerminateExitCodeHandler()
static int GlobalExitCode()
Definition process.h:124
static void SetExitHook(ExitHook hook)
Definition process.h:135
static bool GetUtf8Argv(int argc, char **argv)
static AppSnapshot * TryReadAppSnapshot(const char *script_uri, bool force_load_elf_from_memory=false, bool decode_uri=true)
static AppSnapshot * TryReadAppendedAppSnapshotElf(const char *container_path)
static void GenerateKernel(const char *snapshot_filename, const char *script_name, const char *package_config)
static void GenerateAppJIT(const char *snapshot_filename)
static const char * GetErrorMessage()
static void SetNativeResolver()
static bool Setup(const char *server_ip, intptr_t server_port, bool dev_mode_server, bool auth_codes_disabled, const char *write_service_info_filename, bool trace_loading, bool deterministic, bool enable_service_port_fallback, bool wait_for_dds_to_advertise_service, bool serve_devtools, bool serve_observatory, bool print_dtd)
#define DART_FLAGS_CURRENT_VERSION
Definition dart_api.h:582
#define DART_INITIALIZE_PARAMS_CURRENT_VERSION
Definition dart_api.h:839
@ Dart_KernelCompilationStatus_Ok
Definition dart_api.h:3728
#define DART_KERNEL_ISOLATE_NAME
Definition dart_api.h:3823
struct _Dart_Handle * Dart_Handle
Definition dart_api.h:258
struct _Dart_Isolate * Dart_Isolate
Definition dart_api.h:88
Dart_Handle(* Dart_GetVMServiceAssetsArchive)(void)
Definition dart_api.h:833
#define DART_VM_SERVICE_ISOLATE_NAME
Definition dart_api.h:3831
@ Dart_Timeline_Event_Async_End
@ Dart_Timeline_Event_Duration
#define DART_EMBEDDER_INFORMATION_CURRENT_VERSION
#define CHECK_RESULT(result)
#define DART_DEV_ISOLATE_NAME
#define ASSERT(E)
#define FATAL(error)
FlutterSemanticsFlag flags
glong glong end
const uint8_t uint32_t uint32_t GError ** error
GAsyncResult * result
uint32_t uint32_t * format
const uint8_t kDartVmSnapshotData[]
const uint8_t kDartVmSnapshotInstructions[]
char ** argv
Definition library.h:9
const uint8_t kDartVmSnapshotData[]
const uint8_t kDartVmSnapshotInstructions[]
const uint8_t kDartCoreIsolateSnapshotInstructions[]
const uint8_t kDartCoreIsolateSnapshotData[]
static bool FileModifiedCallback(const char *url, int64_t since)
Definition main_impl.cc:933
const uint8_t * isolate_snapshot_data
unsigned int observatory_assets_archive_len
static void DeleteIsolateGroupData(void *callback_data)
Definition main_impl.cc:906
static const char * RegisterKernelBlob(const uint8_t *kernel_buffer, intptr_t kernel_buffer_size)
Definition main_impl.cc:883
void SetCaptureStdout(bool value)
static Dart_Isolate IsolateSetupHelper(Dart_Isolate isolate, bool is_main_isolate, const char *script_uri, const char *packages_config, bool isolate_run_app_snapshot, Dart_IsolateFlags *flags, char **error, int *exit_code)
Definition main_impl.cc:254
static constexpr const char * kStderrStreamId
Definition main_impl.cc:912
static void UnregisterKernelBlob(const char *kernel_blob_uri)
Definition main_impl.cc:887
static void CompileAndSaveKernel(const char *script_name, const char *package_config_override, CommandLineOptions *dart_options)
Definition main_impl.cc:962
static Dart_Isolate CreateAndSetupServiceIsolate(const char *script_uri, const char *packages_config, Dart_IsolateFlags *flags, char **error, int *exit_code)
Definition main_impl.cc:496
const uint8_t * vm_snapshot_data
Definition main_impl.cc:56
static Dart_Isolate CreateAndSetupDartDevIsolate(const char *script_uri, const char *packages_config, Dart_IsolateFlags *flags, char **error, int *exit_code)
Definition main_impl.cc:578
static bool OnIsolateInitialize(void **child_callback_data, char **error)
Definition main_impl.cc:205
DFE dfe
Definition dfe.cc:59
const uint8_t * vm_snapshot_instructions
Definition main_impl.cc:57
void RunMainIsolate(const char *script_name, const char *package_config_override, CommandLineOptions *dart_options)
Definition main_impl.cc:976
static void ServiceStreamCancelCallback(const char *stream_id)
Definition main_impl.cc:925
static void WriteDepsFile()
Definition main_impl.cc:103
const uint8_t * core_isolate_snapshot_data
Definition main_impl.cc:58
static bool vm_run_app_snapshot
Definition main_impl.cc:71
static char * app_script_uri
Definition main_impl.cc:72
static constexpr const char * kStdoutStreamId
Definition main_impl.cc:911
static void DeleteIsolateData(void *isolate_group_data, void *callback_data)
Definition main_impl.cc:901
const uint8_t * observatory_assets_archive
constexpr int kErrorExitCode
Definition error_exit.h:18
static Dart_Isolate main_isolate
Definition main_impl.cc:77
Dart_Handle GetVMServiceAssetsArchiveCallback()
static Dart_Handle SetupCoreLibraries(Dart_Isolate isolate, IsolateData *isolate_data, bool is_isolate_group_start, bool is_kernel_isolate, const char **resolved_packages_config)
Definition main_impl.cc:153
static bool ServiceStreamListenCallback(const char *stream_id)
Definition main_impl.cc:914
static bool kernel_isolate_is_running
Definition main_impl.cc:75
const uint8_t * core_isolate_snapshot_instructions
Definition main_impl.cc:59
static void OnExitHook(int64_t exit_code)
Definition main_impl.cc:137
static Dart_Isolate CreateIsolateGroupAndSetup(const char *script_uri, const char *main, const char *package_root, const char *package_config, Dart_IsolateFlags *flags, void *callback_data, char **error)
Definition main_impl.cc:827
void InitializeCrashpadClient()
Definition crashpad.cc:77
void SetCaptureStderr(bool value)
static const uint8_t * app_isolate_snapshot_data
Definition main_impl.cc:73
static const uint8_t * app_isolate_snapshot_instructions
Definition main_impl.cc:74
void ErrorExit(int exit_code, const char *format,...)
Definition error_exit.cc:18
static void OnIsolateShutdown(void *isolate_group_data, void *isolate_data)
Definition main_impl.cc:892
static void EmbedderInformationCallback(Dart_EmbedderInformation *info)
Definition main_impl.cc:948
void Decompress(const uint8_t *input, intptr_t input_len, uint8_t **output, intptr_t *output_length)
Definition gzip.cc:15
static Dart_Isolate CreateIsolateGroupAndSetupHelper(bool is_main_isolate, const char *script_uri, const char *name, const char *packages_config, Dart_IsolateFlags *flags, void *callback_data, char **error, int *exit_code)
Definition main_impl.cc:670
static Dart_Isolate CreateAndSetupKernelIsolate(const char *script_uri, const char *packages_config, Dart_IsolateFlags *flags, char **error, int *exit_code)
Definition main_impl.cc:405
Dart_ShutdownIsolate()
const uint8_t * isolate_snapshot_instructions
static bool CheckForInvalidPath(const char *path)
bool InitOnce(char **error)
DART_EXPORT bool Dart_IsCompilationError(Dart_Handle object)
DART_EXPORT void Dart_EnterScope()
const char *const name
DART_EXPORT Dart_Port Dart_GetMainPortId()
DART_EXPORT Dart_Handle Dart_GetStickyError()
DART_EXPORT void Dart_EnterIsolate(Dart_Isolate isolate)
DART_EXPORT Dart_Handle Dart_DebugName()
DART_EXPORT char * Dart_SetServiceStreamCallbacks(Dart_ServiceStreamListenCallback listen_callback, Dart_ServiceStreamCancelCallback cancel_callback)
DART_EXPORT Dart_Handle Dart_Invoke(Dart_Handle target, Dart_Handle name, int number_of_arguments, Dart_Handle *arguments)
DART_EXPORT Dart_Handle Dart_RootLibrary()
DART_EXPORT void Dart_SetEmbedderInformationCallback(Dart_EmbedderInformationCallback callback)
void * malloc(size_t size)
Definition allocation.cc:19
DART_EXPORT void Dart_SetShouldPauseOnExit(bool should_pause)
DART_EXPORT void Dart_IsolateFlagsInitialize(Dart_IsolateFlags *flags)
DART_EXPORT Dart_Handle Dart_SetDeferredLoadHandler(Dart_DeferredLoadHandler handler)
DART_EXPORT const char * Dart_GetError(Dart_Handle handle)
DART_EXPORT void Dart_RecordTimelineEvent(const char *label, int64_t timestamp0, int64_t timestamp1_or_id, intptr_t flow_id_count, const int64_t *flow_ids, Dart_Timeline_Event_Type type, intptr_t argument_count, const char **argument_names, const char **argument_values)
DART_EXPORT char * Dart_SetFileModifiedCallback(Dart_FileModifiedCallback file_modified_callback)
DART_EXPORT char * Dart_Initialize(Dart_InitializeParams *params)
DART_EXPORT Dart_Handle Dart_GetField(Dart_Handle container, Dart_Handle name)
DART_EXPORT Dart_Isolate Dart_CurrentIsolate()
DART_EXPORT bool Dart_IsKernelIsolate(Dart_Isolate isolate)
DART_EXPORT char * Dart_Cleanup()
DART_EXPORT bool Dart_IsError(Dart_Handle handle)
DART_EXPORT void Dart_ExitIsolate()
DART_EXPORT void * Dart_IsolateData(Dart_Isolate isolate)
DART_EXPORT char * Dart_IsolateMakeRunnable(Dart_Isolate isolate)
DART_EXPORT Dart_Isolate Dart_CreateIsolateGroup(const char *script_uri, const char *name, const uint8_t *snapshot_data, const uint8_t *snapshot_instructions, Dart_IsolateFlags *flags, void *isolate_group_data, void *isolate_data, char **error)
DART_EXPORT Dart_Handle Dart_RunLoop()
DART_EXPORT void * Dart_CurrentIsolateGroupData()
DART_EXPORT bool Dart_IsPrecompiledRuntime()
DART_EXPORT Dart_Isolate Dart_CreateIsolateGroupFromKernel(const char *script_uri, const char *name, const uint8_t *kernel_buffer, intptr_t kernel_buffer_size, Dart_IsolateFlags *flags, void *isolate_group_data, void *isolate_data, char **error)
DART_EXPORT char * Dart_SetVMFlags(int argc, const char **argv)
DART_EXPORT Dart_KernelCompilationResult Dart_KernelListDependencies()
DART_EXPORT Dart_Handle Dart_SetLibraryTagHandler(Dart_LibraryTagHandler handler)
DART_EXPORT Dart_Handle Dart_SortClasses()
DART_EXPORT Dart_Handle Dart_CompileAll()
constexpr intptr_t kWordSize
Definition globals.h:509
DART_EXPORT Dart_Handle Dart_LookupLibrary(Dart_Handle url)
DART_EXPORT Dart_Handle Dart_LoadScriptFromKernel(const uint8_t *buffer, intptr_t buffer_size)
DART_EXPORT int64_t Dart_TimelineGetMicros()
DART_EXPORT bool Dart_IsNull(Dart_Handle object)
DART_EXPORT Dart_Handle Dart_SetEnvironmentCallback(Dart_EnvironmentCallback callback)
DART_EXPORT Dart_Handle Dart_Null()
static int8_t data[kExtLength]
DART_EXPORT Dart_Handle Dart_StringToCString(Dart_Handle object, const char **cstr)
DART_EXPORT bool Dart_IsClosure(Dart_Handle object)
DART_EXPORT Dart_Handle Dart_NewStringFromCString(const char *str)
DART_EXPORT bool Dart_IsFatalError(Dart_Handle object)
DART_EXPORT void Dart_SetShouldPauseOnStart(bool should_pause)
Definition main.py:1
#define DEBUG_ONLY(code)
Definition globals.h:141
#define Pd64
Definition globals.h:416
#define PATH_MAX
Definition globals.h:708
Dart_IsolateGroupCreateCallback create_group
Definition dart_api.h:924
Dart_InitializeIsolateCallback initialize_isolate
Definition dart_api.h:931
Dart_IsolateGroupCleanupCallback cleanup_group
Definition dart_api.h:949
Dart_FileReadCallback file_read
Definition dart_api.h:954
const uint8_t * vm_snapshot_data
Definition dart_api.h:910
Dart_GetVMServiceAssetsArchive get_service_assets
Definition dart_api.h:963
Dart_FileOpenCallback file_open
Definition dart_api.h:953
Dart_IsolateShutdownCallback shutdown_isolate
Definition dart_api.h:937
Dart_UnregisterKernelBlobCallback unregister_kernel_blob
Definition dart_api.h:981
Dart_FileWriteCallback file_write
Definition dart_api.h:955
Dart_EntropySource entropy_source
Definition dart_api.h:957
Dart_RegisterKernelBlobCallback register_kernel_blob
Definition dart_api.h:976
Dart_IsolateCleanupCallback cleanup_isolate
Definition dart_api.h:943
const uint8_t * vm_snapshot_instructions
Definition dart_api.h:918
Dart_FileCloseCallback file_close
Definition dart_api.h:956