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 | |
16 | namespace dart { |
17 | namespace embedder { |
18 | |
19 | static 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 | |
34 | bool 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 | |
50 | void 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 | |
60 | Dart_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 | |
86 | Dart_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 | |
120 | Dart_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 | |