1// Copyright (c) 2018, 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 "include/dart_embedder_api.h"
6
7#include "bin/dartutils.h"
8#include "bin/eventhandler.h"
9#include "bin/isolate_data.h"
10#include "bin/process.h"
11#include "bin/secure_socket_filter.h"
12#include "bin/thread.h"
13#include "bin/utils.h"
14#include "bin/vmservice_impl.h"
15
16namespace dart {
17namespace embedder {
18
19static char* MallocFormatedString(const char* format, ...) {
20 va_list args;
21 va_start(args, format);
22 intptr_t len = vsnprintf(NULL, 0, format, args);
23 va_end(args);
24
25 char* buffer = reinterpret_cast<char*>(malloc(len + 1));
26 MSAN_UNPOISON(buffer, (len + 1));
27 va_list args2;
28 va_start(args2, format);
29 vsnprintf(buffer, (len + 1), format, args2);
30 va_end(args2);
31 return buffer;
32}
33
34bool InitOnce(char** error) {
35 if (!bin::DartUtils::SetOriginalWorkingDirectory()) {
36 bin::OSError err;
37 *error = MallocFormatedString("Error determining current directory: %s\n",
38 err.message());
39 return false;
40 }
41 bin::TimerUtils::InitOnce();
42 bin::Process::Init();
43#if !defined(DART_IO_SECURE_SOCKET_DISABLED)
44 bin::SSLFilter::Init();
45#endif
46 bin::EventHandler::Start();
47 return true;
48}
49
50void Cleanup() {
51 bin::Process::ClearAllSignalHandlers();
52
53 bin::EventHandler::Stop();
54#if !defined(DART_IO_SECURE_SOCKET_DISABLED)
55 bin::SSLFilter::Cleanup();
56#endif
57 bin::Process::Cleanup();
58}
59
60Dart_Isolate CreateKernelServiceIsolate(const IsolateCreationData& data,
61 const uint8_t* buffer,
62 intptr_t buffer_size,
63 char** error) {
64 Dart_Isolate kernel_isolate = Dart_CreateIsolateGroupFromKernel(
65 data.script_uri, data.main, buffer, buffer_size, data.flags,
66 data.isolate_group_data, data.isolate_data, error);
67 if (kernel_isolate == nullptr) {
68 return nullptr;
69 }
70
71 Dart_EnterScope();
72 Dart_Handle result = Dart_LoadScriptFromKernel(buffer, buffer_size);
73 if (Dart_IsError(result)) {
74 *error = Utils::StrDup(Dart_GetError(result));
75 Dart_ExitScope();
76 Dart_ShutdownIsolate();
77 return nullptr;
78 }
79 result = bin::DartUtils::PrepareForScriptLoading(/*is_service_isolate=*/false,
80 /*trace_loading=*/false);
81 Dart_ExitScope();
82 Dart_ExitIsolate();
83 return kernel_isolate;
84}
85
86Dart_Isolate CreateVmServiceIsolate(const IsolateCreationData& data,
87 const VmServiceConfiguration& config,
88 const uint8_t* isolate_data,
89 const uint8_t* isolate_instr,
90 char** error) {
91 if (data.flags == nullptr) {
92 *error = Utils::StrDup("Expected non-null flags");
93 return nullptr;
94 }
95 data.flags->load_vmservice_library = true;
96
97 Dart_Isolate service_isolate = Dart_CreateIsolateGroup(
98 data.script_uri, data.main, isolate_data, isolate_instr, data.flags,
99 data.isolate_group_data, data.isolate_data, error);
100 if (service_isolate == nullptr) {
101 return nullptr;
102 }
103
104 Dart_EnterScope();
105 // Load embedder specific bits and return.
106 if (!bin::VmService::Setup(config.ip, config.port, config.dev_mode,
107 config.disable_auth_codes,
108 config.write_service_info_filename,
109 /*trace_loading=*/false, config.deterministic,
110 /*enable_service_port_fallback=*/false)) {
111 *error = Utils::StrDup(bin::VmService::GetErrorMessage());
112 return nullptr;
113 }
114
115 Dart_ExitScope();
116 Dart_ExitIsolate();
117 return service_isolate;
118}
119
120Dart_Isolate CreateVmServiceIsolateFromKernel(
121 const IsolateCreationData& data,
122 const VmServiceConfiguration& config,
123 const uint8_t* kernel_buffer,
124 intptr_t kernel_buffer_size,
125 char** error) {
126 if (data.flags == nullptr) {
127 *error = Utils::StrDup("Expected non-null flags");
128 return nullptr;
129 }
130 data.flags->load_vmservice_library = true;
131
132 Dart_Isolate service_isolate = Dart_CreateIsolateGroupFromKernel(
133 data.script_uri, data.main, kernel_buffer, kernel_buffer_size, data.flags,
134 data.isolate_group_data, data.isolate_data, error);
135 if (service_isolate == nullptr) {
136 return nullptr;
137 }
138
139 Dart_EnterScope();
140 // Load embedder specific bits and return.
141 if (!bin::VmService::Setup(config.ip, config.port, config.dev_mode,
142 config.disable_auth_codes,
143 config.write_service_info_filename,
144 /*trace_loading=*/false, config.deterministic,
145 /*enable_service_port_fallback=*/false)) {
146 *error = Utils::StrDup(bin::VmService::GetErrorMessage());
147 return nullptr;
148 }
149
150 Dart_ExitScope();
151 Dart_ExitIsolate();
152 return service_isolate;
153}
154
155} // namespace embedder
156} // namespace dart
157