Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
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 isolate_lib = Dart_LookupLibrary(ToDart("dart:isolate"));
68 result = Dart_Invoke(isolate_lib, setup_hooks, 0, NULL);
69 PropagateIfError(result);
70}
71
72static void InitDartCore(Dart_Handle builtin, const std::string& script_uri) {
73 Dart_Handle io_lib = Dart_LookupLibrary(ToDart("dart:io"));
74 Dart_Handle get_base_url =
75 Dart_Invoke(io_lib, ToDart("_getUriBaseClosure"), 0, NULL);
76 Dart_Handle core_library = Dart_LookupLibrary(ToDart("dart:core"));
77 Dart_Handle result =
78 Dart_SetField(core_library, ToDart("_uriBaseClosure"), get_base_url);
79 PropagateIfError(result);
80}
81
82static void InitDartAsync(Dart_Handle builtin_library,
83 bool is_ui_isolate,
84 bool enable_microtask_profiling) {
85 Dart_Handle schedule_microtask;
86 if (is_ui_isolate) {
87 schedule_microtask =
88 InvokeFunction(builtin_library, "_getScheduleMicrotaskClosure");
89 } else {
90 Dart_Handle isolate_lib = Dart_LookupLibrary(ToDart("dart:isolate"));
91 Dart_Handle method_name =
92 Dart_NewStringFromCString("_getIsolateScheduleImmediateClosure");
93 schedule_microtask = Dart_Invoke(isolate_lib, method_name, 0, NULL);
94 }
95 Dart_Handle async_library = Dart_LookupLibrary(ToDart("dart:async"));
96 Dart_Handle set_schedule_microtask = ToDart("_setScheduleImmediateClosure");
97 Dart_Handle result = Dart_Invoke(async_library, set_schedule_microtask, 1,
98 &schedule_microtask);
99 PropagateIfError(result);
100
101#if !FLUTTER_RELEASE
102 if (enable_microtask_profiling) {
103 Dart_Handle microtask_mirror_queue_type_name =
104 Dart_NewStringFromCString("_MicrotaskMirrorQueue");
105 PropagateIfError(microtask_mirror_queue_type_name);
106
107 Dart_Handle microtask_mirror_queue_type =
108 Dart_GetNonNullableType(async_library, microtask_mirror_queue_type_name,
109 /*number_of_type_arguments=*/0,
110 /*type_arguments=*/nullptr);
111 PropagateIfError(microtask_mirror_queue_type);
112
113 Dart_Handle should_profile_microtasks_field_name =
114 Dart_NewStringFromCString("_shouldProfileMicrotasks");
115 PropagateIfError(should_profile_microtasks_field_name);
116
117 Dart_Handle set_field_result =
118 Dart_SetField(microtask_mirror_queue_type,
119 should_profile_microtasks_field_name, Dart_True());
120 PropagateIfError(set_field_result);
121 }
122#endif // !FLUTTER_RELEASE
123}
124
125void DartRuntimeHooks::Install(bool is_ui_isolate,
126 bool enable_microtask_profiling,
127 const std::string& script_uri) {
128 Dart_Handle builtin = Dart_LookupLibrary(ToDart("dart:ui"));
129 InitDartInternal(builtin, is_ui_isolate);
130 InitDartCore(builtin, script_uri);
131 InitDartAsync(builtin, is_ui_isolate, enable_microtask_profiling);
132}
133
135#ifndef NDEBUG
137#endif
138}
139
141 const auto& tag = UIDartState::Current()->logger_prefix();
143
144 if (dart::bin::ShouldCaptureStdout()) {
145 std::stringstream stream;
146 if (!tag.empty()) {
147 stream << tag << ": ";
148 }
149 stream << message;
150 std::string log = stream.str();
151
152 // For now we report print output on the Stdout stream.
153 uint8_t newline[] = {'\n'};
154 Dart_ServiceSendDataEvent("Stdout", "WriteEvent",
155 reinterpret_cast<const uint8_t*>(log.c_str()),
156 log.size());
157 Dart_ServiceSendDataEvent("Stdout", "WriteEvent", newline, sizeof(newline));
158 }
159}
160
161void DartRuntimeHooks::ScheduleMicrotask(Dart_Handle closure) {
163}
164
165static std::string GetFunctionLibraryUrl(Dart_Handle closure) {
166 if (Dart_IsClosure(closure)) {
167 closure = Dart_ClosureFunction(closure);
168 PropagateIfError(closure);
169 }
170
171 if (!Dart_IsFunction(closure)) {
172 return "";
173 }
174
175 Dart_Handle url = Dart_Null();
176 Dart_Handle owner = Dart_FunctionOwner(closure);
177 if (Dart_IsInstance(owner)) {
178 owner = Dart_ClassLibrary(owner);
179 }
180 if (Dart_IsLibrary(owner)) {
181 url = Dart_LibraryUrl(owner);
182 PropagateIfError(url);
183 }
185}
186
187static std::string GetFunctionClassName(Dart_Handle closure) {
188 Dart_Handle result;
189
190 if (Dart_IsClosure(closure)) {
191 closure = Dart_ClosureFunction(closure);
192 PropagateIfError(closure);
193 }
194
195 if (!Dart_IsFunction(closure)) {
196 return "";
197 }
198
199 bool is_static = false;
200 result = Dart_FunctionIsStatic(closure, &is_static);
201 PropagateIfError(result);
202 if (!is_static) {
203 return "";
204 }
205
206 result = Dart_FunctionOwner(closure);
207 PropagateIfError(result);
208
209 if (Dart_IsLibrary(result) || !Dart_IsInstance(result)) {
210 return "";
211 }
212 return DartConverter<std::string>::FromDart(Dart_ClassName(result));
213}
214
215static std::string GetFunctionName(Dart_Handle func) {
216 if (Dart_IsClosure(func)) {
217 func = Dart_ClosureFunction(func);
218 PropagateIfError(func);
219 }
220
221 if (!Dart_IsFunction(func)) {
222 return "";
223 }
224
225 bool is_static = false;
226 Dart_Handle result = Dart_FunctionIsStatic(func, &is_static);
227 PropagateIfError(result);
228 if (!is_static) {
229 return "";
230 }
231
232 result = Dart_FunctionName(func);
233 PropagateIfError(result);
234
236}
237
238Dart_Handle DartRuntimeHooks::GetCallbackHandle(Dart_Handle func) {
239 std::string name = GetFunctionName(func);
240 std::string class_name = GetFunctionClassName(func);
241 std::string library_path = GetFunctionLibraryUrl(func);
242
243 // `name` is empty if `func` can't be used as a callback. This is the case
244 // when `func` is not a function object or is not a static function. Anonymous
245 // closures (e.g. `(int a, int b) => a + b;`) also cannot be used as
246 // callbacks, so `func` must be a tear-off of a named static function.
247 if (!Dart_IsTearOff(func) || name.empty()) {
248 return Dart_Null();
249 }
251 DartCallbackCache::GetCallbackHandle(name, class_name, library_path));
252}
253
254Dart_Handle DartRuntimeHooks::GetCallbackFromHandle(int64_t handle) {
255 Dart_Handle result = DartCallbackCache::GetCallback(handle);
256 PropagateIfError(result);
257 return result;
258}
259
264
265} // 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()
const char * message
#define FML_LOG(severity)
Definition logging.h:101
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)