Flutter Engine
 
Loading...
Searching...
No Matches
dart_runtime_hooks.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
7#include <cstdio>
8#include <cstdlib>
9#include <cstring>
10#include <iostream>
11#include <sstream>
12
15#include "flutter/fml/logging.h"
19#include "third_party/dart/runtime/include/bin/dart_io_api.h"
20#include "third_party/dart/runtime/include/dart_api.h"
21#include "third_party/dart/runtime/include/dart_tools_api.h"
30
32using tonic::ToDart;
33
34namespace flutter {
35
36static void PropagateIfError(Dart_Handle result) {
37 if (Dart_IsError(result)) {
38 FML_LOG(ERROR) << "Dart Error: " << ::Dart_GetError(result);
39 Dart_PropagateError(result);
40 }
41}
42
43static Dart_Handle InvokeFunction(Dart_Handle builtin_library,
44 const char* name) {
45 Dart_Handle getter_name = ToDart(name);
46 return Dart_Invoke(builtin_library, getter_name, 0, nullptr);
47}
48
49static void InitDartInternal(Dart_Handle builtin_library, bool is_ui_isolate) {
50 Dart_Handle print = InvokeFunction(builtin_library, "_getPrintClosure");
51
52 Dart_Handle internal_library = Dart_LookupLibrary(ToDart("dart:_internal"));
53
54 Dart_Handle result =
55 Dart_SetField(internal_library, ToDart("_printClosure"), print);
56 PropagateIfError(result);
57
58 if (is_ui_isolate) {
59 // Call |_setupHooks| to configure |VMLibraryHooks|.
60 Dart_Handle method_name = Dart_NewStringFromCString("_setupHooks");
61 result = Dart_Invoke(builtin_library, method_name, 0, NULL);
62 PropagateIfError(result);
63 }
64
65 Dart_Handle setup_hooks = Dart_NewStringFromCString("_setupHooks");
66
67 Dart_Handle io_lib = Dart_LookupLibrary(ToDart("dart:io"));
68 result = Dart_Invoke(io_lib, setup_hooks, 0, NULL);
69 PropagateIfError(result);
70
71 Dart_Handle isolate_lib = Dart_LookupLibrary(ToDart("dart:isolate"));
72 result = Dart_Invoke(isolate_lib, setup_hooks, 0, NULL);
73 PropagateIfError(result);
74}
75
76static void InitDartCore(Dart_Handle builtin, const std::string& script_uri) {
77 Dart_Handle io_lib = Dart_LookupLibrary(ToDart("dart:io"));
78 Dart_Handle get_base_url =
79 Dart_Invoke(io_lib, ToDart("_getUriBaseClosure"), 0, NULL);
80 Dart_Handle core_library = Dart_LookupLibrary(ToDart("dart:core"));
81 Dart_Handle result =
82 Dart_SetField(core_library, ToDart("_uriBaseClosure"), get_base_url);
83 PropagateIfError(result);
84}
85
86static void InitDartAsync(Dart_Handle builtin_library,
87 bool is_ui_isolate,
88 bool enable_microtask_profiling) {
89 Dart_Handle schedule_microtask;
90 if (is_ui_isolate) {
91 schedule_microtask =
92 InvokeFunction(builtin_library, "_getScheduleMicrotaskClosure");
93 } else {
94 Dart_Handle isolate_lib = Dart_LookupLibrary(ToDart("dart:isolate"));
95 Dart_Handle method_name =
96 Dart_NewStringFromCString("_getIsolateScheduleImmediateClosure");
97 schedule_microtask = Dart_Invoke(isolate_lib, method_name, 0, NULL);
98 }
99 Dart_Handle async_library = Dart_LookupLibrary(ToDart("dart:async"));
100 Dart_Handle set_schedule_microtask = ToDart("_setScheduleImmediateClosure");
101 Dart_Handle result = Dart_Invoke(async_library, set_schedule_microtask, 1,
102 &schedule_microtask);
103 PropagateIfError(result);
104
105#if !FLUTTER_RELEASE
106 if (enable_microtask_profiling) {
107 Dart_Handle microtask_mirror_queue_type_name =
108 Dart_NewStringFromCString("_MicrotaskMirrorQueue");
109 PropagateIfError(microtask_mirror_queue_type_name);
110
111 Dart_Handle microtask_mirror_queue_type =
112 Dart_GetNonNullableType(async_library, microtask_mirror_queue_type_name,
113 /*number_of_type_arguments=*/0,
114 /*type_arguments=*/nullptr);
115 PropagateIfError(microtask_mirror_queue_type);
116
117 Dart_Handle should_profile_microtasks_field_name =
118 Dart_NewStringFromCString("_shouldProfileMicrotasks");
119 PropagateIfError(should_profile_microtasks_field_name);
120
121 Dart_Handle set_field_result =
122 Dart_SetField(microtask_mirror_queue_type,
123 should_profile_microtasks_field_name, Dart_True());
124 PropagateIfError(set_field_result);
125 }
126#endif // !FLUTTER_RELEASE
127}
128
129static void InitDartIO(Dart_Handle builtin_library,
130 const std::string& script_uri) {
131 Dart_Handle io_lib = Dart_LookupLibrary(ToDart("dart:io"));
132 Dart_Handle platform_type =
133 Dart_GetNonNullableType(io_lib, ToDart("_Platform"), 0, nullptr);
134 if (!script_uri.empty()) {
135 Dart_Handle result = Dart_SetField(platform_type, ToDart("_nativeScript"),
136 ToDart(script_uri));
137 PropagateIfError(result);
138 }
139 // typedef _LocaleClosure = String Function();
140 Dart_Handle /* _LocaleClosure? */ locale_closure =
141 InvokeFunction(builtin_library, "_getLocaleClosure");
142 PropagateIfError(locale_closure);
143 // static String Function()? _localeClosure;
144 Dart_Handle result =
145 Dart_SetField(platform_type, ToDart("_localeClosure"), locale_closure);
146 PropagateIfError(result);
147
148#if !FLUTTER_RELEASE
149 // Register dart:io service extensions used for network profiling.
150 Dart_Handle network_profiling_type =
151 Dart_GetNonNullableType(io_lib, ToDart("_NetworkProfiling"), 0, nullptr);
152 PropagateIfError(network_profiling_type);
153 result = Dart_Invoke(network_profiling_type,
154 ToDart("_registerServiceExtension"), 0, nullptr);
155 PropagateIfError(result);
156#endif // !FLUTTER_RELEASE
157}
158
159void DartRuntimeHooks::Install(bool is_ui_isolate,
160 bool enable_microtask_profiling,
161 const std::string& script_uri) {
162 Dart_Handle builtin = Dart_LookupLibrary(ToDart("dart:ui"));
163 InitDartInternal(builtin, is_ui_isolate);
164 InitDartCore(builtin, script_uri);
165 InitDartAsync(builtin, is_ui_isolate, enable_microtask_profiling);
166 InitDartIO(builtin, script_uri);
167}
168
170#ifndef NDEBUG
172#endif
173}
174
176 const auto& tag = UIDartState::Current()->logger_prefix();
178
179 if (dart::bin::ShouldCaptureStdout()) {
180 std::stringstream stream;
181 if (!tag.empty()) {
182 stream << tag << ": ";
183 }
184 stream << message;
185 std::string log = stream.str();
186
187 // For now we report print output on the Stdout stream.
188 uint8_t newline[] = {'\n'};
189 Dart_ServiceSendDataEvent("Stdout", "WriteEvent",
190 reinterpret_cast<const uint8_t*>(log.c_str()),
191 log.size());
192 Dart_ServiceSendDataEvent("Stdout", "WriteEvent", newline, sizeof(newline));
193 }
194}
195
196void DartRuntimeHooks::ScheduleMicrotask(Dart_Handle closure) {
198}
199
200static std::string GetFunctionLibraryUrl(Dart_Handle closure) {
201 if (Dart_IsClosure(closure)) {
202 closure = Dart_ClosureFunction(closure);
203 PropagateIfError(closure);
204 }
205
206 if (!Dart_IsFunction(closure)) {
207 return "";
208 }
209
210 Dart_Handle url = Dart_Null();
211 Dart_Handle owner = Dart_FunctionOwner(closure);
212 if (Dart_IsInstance(owner)) {
213 owner = Dart_ClassLibrary(owner);
214 }
215 if (Dart_IsLibrary(owner)) {
216 url = Dart_LibraryUrl(owner);
217 PropagateIfError(url);
218 }
220}
221
222static std::string GetFunctionClassName(Dart_Handle closure) {
223 Dart_Handle result;
224
225 if (Dart_IsClosure(closure)) {
226 closure = Dart_ClosureFunction(closure);
227 PropagateIfError(closure);
228 }
229
230 if (!Dart_IsFunction(closure)) {
231 return "";
232 }
233
234 bool is_static = false;
235 result = Dart_FunctionIsStatic(closure, &is_static);
236 PropagateIfError(result);
237 if (!is_static) {
238 return "";
239 }
240
241 result = Dart_FunctionOwner(closure);
242 PropagateIfError(result);
243
244 if (Dart_IsLibrary(result) || !Dart_IsInstance(result)) {
245 return "";
246 }
247 return DartConverter<std::string>::FromDart(Dart_ClassName(result));
248}
249
250static std::string GetFunctionName(Dart_Handle func) {
251 if (Dart_IsClosure(func)) {
252 func = Dart_ClosureFunction(func);
253 PropagateIfError(func);
254 }
255
256 if (!Dart_IsFunction(func)) {
257 return "";
258 }
259
260 bool is_static = false;
261 Dart_Handle result = Dart_FunctionIsStatic(func, &is_static);
262 PropagateIfError(result);
263 if (!is_static) {
264 return "";
265 }
266
267 result = Dart_FunctionName(func);
268 PropagateIfError(result);
269
271}
272
273Dart_Handle DartRuntimeHooks::GetCallbackHandle(Dart_Handle func) {
274 std::string name = GetFunctionName(func);
275 std::string class_name = GetFunctionClassName(func);
276 std::string library_path = GetFunctionLibraryUrl(func);
277
278 // `name` is empty if `func` can't be used as a callback. This is the case
279 // when `func` is not a function object or is not a static function. Anonymous
280 // closures (e.g. `(int a, int b) => a + b;`) also cannot be used as
281 // callbacks, so `func` must be a tear-off of a named static function.
282 if (!Dart_IsTearOff(func) || name.empty()) {
283 return Dart_Null();
284 }
286 DartCallbackCache::GetCallbackHandle(name, class_name, library_path));
287}
288
289Dart_Handle DartRuntimeHooks::GetCallbackFromHandle(int64_t handle) {
290 Dart_Handle result = DartCallbackCache::GetCallback(handle);
291 PropagateIfError(result);
292 return result;
293}
294
299
300} // namespace flutter
static int64_t GetCallbackHandle(const std::string &name, const std::string &class_name, const std::string &library_path)
static Dart_Handle GetCallback(int64_t handle)
static Dart_Handle GetCallbackHandle(Dart_Handle func)
static Dart_Handle GetCallbackFromHandle(int64_t handle)
static void ScheduleMicrotask(Dart_Handle closure)
static void Logger_PrintDebugString(const std::string &message)
static void Install(bool is_ui_isolate, bool enable_microtask_profiling, const std::string &script_uri)
static void Logger_PrintString(const std::string &message)
const std::string & logger_prefix() const
void ScheduleMicrotask(Dart_Handle handle)
void LogMessage(const std::string &tag, const std::string &message) const
static UIDartState * Current()
G_BEGIN_DECLS GBytes * message
#define FML_LOG(severity)
Definition logging.h:101
static void InitDartIO(Dart_Handle builtin_library, const std::string &script_uri)
static std::string GetFunctionClassName(Dart_Handle closure)
void DartPluginRegistrant_EnsureInitialized()
static std::string GetFunctionName(Dart_Handle func)
static void InitDartInternal(Dart_Handle builtin_library, bool is_ui_isolate)
static void PropagateIfError(Dart_Handle result)
DEF_SWITCHES_START aot vmservice shared library name
Definition switch_defs.h:27
static void InitDartAsync(Dart_Handle builtin_library, bool is_ui_isolate, bool enable_microtask_profiling)
static std::string GetFunctionLibraryUrl(Dart_Handle closure)
static void InitDartCore(Dart_Handle builtin, const std::string &script_uri)
bool FindAndInvokeDartPluginRegistrant()
static Dart_Handle InvokeFunction(Dart_Handle builtin_library, const char *name)
Dart_Handle ToDart(const T &object)