Flutter Engine
The Flutter Engine
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
5#include "flutter/lib/ui/dart_runtime_hooks.h"
6
7#include <cstdio>
8#include <cstdlib>
9#include <cstring>
10#include <iostream>
11#include <sstream>
12
13#include "flutter/common/settings.h"
14#include "flutter/fml/build_config.h"
15#include "flutter/fml/logging.h"
16#include "flutter/lib/ui/plugins/callback_cache.h"
17#include "flutter/lib/ui/ui_dart_state.h"
18#include "flutter/runtime/dart_plugin_registrant.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
37 if (Dart_IsError(result)) {
38 FML_LOG(ERROR) << "Dart Error: " << ::Dart_GetError(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
55 Dart_SetField(internal_library, ToDart("_printClosure"), print);
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);
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);
70
71 Dart_Handle isolate_lib = Dart_LookupLibrary(ToDart("dart:isolate"));
72 result = Dart_Invoke(isolate_lib, setup_hooks, 0, NULL);
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"));
82 Dart_SetField(core_library, ToDart("_uriBaseClosure"), get_base_url);
84}
85
86static void InitDartAsync(Dart_Handle builtin_library, bool is_ui_isolate) {
87 Dart_Handle schedule_microtask;
88 if (is_ui_isolate) {
89 schedule_microtask =
90 InvokeFunction(builtin_library, "_getScheduleMicrotaskClosure");
91 } else {
92 Dart_Handle isolate_lib = Dart_LookupLibrary(ToDart("dart:isolate"));
93 Dart_Handle method_name =
94 Dart_NewStringFromCString("_getIsolateScheduleImmediateClosure");
95 schedule_microtask = Dart_Invoke(isolate_lib, method_name, 0, NULL);
96 }
97 Dart_Handle async_library = Dart_LookupLibrary(ToDart("dart:async"));
98 Dart_Handle set_schedule_microtask = ToDart("_setScheduleImmediateClosure");
99 Dart_Handle result = Dart_Invoke(async_library, set_schedule_microtask, 1,
100 &schedule_microtask);
102}
103
104static void InitDartIO(Dart_Handle builtin_library,
105 const std::string& script_uri) {
106 Dart_Handle io_lib = Dart_LookupLibrary(ToDart("dart:io"));
107 Dart_Handle platform_type =
108 Dart_GetNonNullableType(io_lib, ToDart("_Platform"), 0, nullptr);
109 if (!script_uri.empty()) {
110 Dart_Handle result = Dart_SetField(platform_type, ToDart("_nativeScript"),
111 ToDart(script_uri));
113 }
114 // typedef _LocaleClosure = String Function();
115 Dart_Handle /* _LocaleClosure? */ locale_closure =
116 InvokeFunction(builtin_library, "_getLocaleClosure");
117 PropagateIfError(locale_closure);
118 // static String Function()? _localeClosure;
120 Dart_SetField(platform_type, ToDart("_localeClosure"), locale_closure);
122
123#if !FLUTTER_RELEASE
124 // Register dart:io service extensions used for network profiling.
125 Dart_Handle network_profiling_type =
126 Dart_GetNonNullableType(io_lib, ToDart("_NetworkProfiling"), 0, nullptr);
127 PropagateIfError(network_profiling_type);
128 result = Dart_Invoke(network_profiling_type,
129 ToDart("_registerServiceExtension"), 0, nullptr);
131#endif // !FLUTTER_RELEASE
132}
133
134void DartRuntimeHooks::Install(bool is_ui_isolate,
135 const std::string& script_uri) {
136 Dart_Handle builtin = Dart_LookupLibrary(ToDart("dart:ui"));
137 InitDartInternal(builtin, is_ui_isolate);
138 InitDartCore(builtin, script_uri);
139 InitDartAsync(builtin, is_ui_isolate);
140 InitDartIO(builtin, script_uri);
141}
142
144#ifndef NDEBUG
146#endif
147}
148
150 const auto& tag = UIDartState::Current()->logger_prefix();
152
154 std::stringstream stream;
155 if (!tag.empty()) {
156 stream << tag << ": ";
157 }
158 stream << message;
159 std::string log = stream.str();
160
161 // For now we report print output on the Stdout stream.
162 uint8_t newline[] = {'\n'};
163 Dart_ServiceSendDataEvent("Stdout", "WriteEvent",
164 reinterpret_cast<const uint8_t*>(log.c_str()),
165 log.size());
166 Dart_ServiceSendDataEvent("Stdout", "WriteEvent", newline, sizeof(newline));
167 }
168}
169
172}
173
175 if (Dart_IsClosure(closure)) {
178 }
179
180 if (!Dart_IsFunction(closure)) {
181 return "";
182 }
183
184 Dart_Handle url = Dart_Null();
186 if (Dart_IsInstance(owner)) {
187 owner = Dart_ClassLibrary(owner);
188 }
189 if (Dart_IsLibrary(owner)) {
190 url = Dart_LibraryUrl(owner);
191 PropagateIfError(url);
192 }
194}
195
198
199 if (Dart_IsClosure(closure)) {
202 }
203
204 if (!Dart_IsFunction(closure)) {
205 return "";
206 }
207
208 bool is_static = false;
209 result = Dart_FunctionIsStatic(closure, &is_static);
211 if (!is_static) {
212 return "";
213 }
214
217
219 return "";
220 }
222}
223
224static std::string GetFunctionName(Dart_Handle func) {
225 if (Dart_IsClosure(func)) {
226 func = Dart_ClosureFunction(func);
227 PropagateIfError(func);
228 }
229
230 if (!Dart_IsFunction(func)) {
231 return "";
232 }
233
234 bool is_static = false;
235 Dart_Handle result = Dart_FunctionIsStatic(func, &is_static);
237 if (!is_static) {
238 return "";
239 }
240
243
245}
246
248 std::string name = GetFunctionName(func);
249 std::string class_name = GetFunctionClassName(func);
250 std::string library_path = GetFunctionLibraryUrl(func);
251
252 // `name` is empty if `func` can't be used as a callback. This is the case
253 // when `func` is not a function object or is not a static function. Anonymous
254 // closures (e.g. `(int a, int b) => a + b;`) also cannot be used as
255 // callbacks, so `func` must be a tear-off of a named static function.
256 if (!Dart_IsTearOff(func) || name.empty()) {
257 return Dart_Null();
258 }
261}
262
266 return result;
267}
268
270 tonic::DartApiScope api_scope;
272}
273
274} // 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 Logger_PrintString(const std::string &message)
static void Install(bool is_ui_isolate, const std::string &script_uri)
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()
DART_EXPORT Dart_Handle Dart_FunctionIsStatic(Dart_Handle function, bool *is_static)
DART_EXPORT Dart_Handle Dart_GetNonNullableType(Dart_Handle library, Dart_Handle class_name, intptr_t number_of_type_arguments, Dart_Handle *type_arguments)
DART_EXPORT Dart_Handle Dart_FunctionOwner(Dart_Handle function)
DART_EXPORT bool Dart_IsInstance(Dart_Handle object)
struct _Dart_Handle * Dart_Handle
Definition: dart_api.h:258
DART_EXPORT Dart_Handle Dart_ClassName(Dart_Handle cls_type)
DART_EXPORT bool Dart_IsFunction(Dart_Handle handle)
DART_EXPORT void Dart_PropagateError(Dart_Handle handle)
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_Invoke(Dart_Handle target, Dart_Handle name, int number_of_arguments, Dart_Handle *arguments)
DART_EXPORT Dart_Handle Dart_FunctionName(Dart_Handle function)
DART_EXPORT Dart_Handle Dart_LookupLibrary(Dart_Handle url)
DART_EXPORT Dart_Handle Dart_ClosureFunction(Dart_Handle closure)
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_SetField(Dart_Handle container, Dart_Handle name, Dart_Handle value)
DART_EXPORT Dart_Handle Dart_Null(void)
DART_EXPORT Dart_Handle Dart_NewStringFromCString(const char *str)
DART_EXPORT Dart_Handle Dart_LibraryUrl(Dart_Handle library)
DART_EXPORT bool Dart_IsError(Dart_Handle handle)
DART_EXPORT const char * Dart_GetError(Dart_Handle handle)
DART_EXPORT Dart_Handle Dart_ClassLibrary(Dart_Handle cls_type)
DART_EXPORT bool Dart_IsClosure(Dart_Handle object)
DART_EXPORT bool Dart_IsLibrary(Dart_Handle object)
DART_EXPORT bool Dart_IsTearOff(Dart_Handle object)
DART_EXPORT char * Dart_ServiceSendDataEvent(const char *stream_id, const char *event_kind, const uint8_t *bytes, intptr_t bytes_length)
GAsyncResult * result
#define FML_LOG(severity)
Definition: logging.h:82
Win32Message message
bool ShouldCaptureStdout()
Definition: file_support.cc:33
const char *const class_name
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: switches.h:32
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)
static void InitDartAsync(Dart_Handle builtin_library, bool is_ui_isolate)
std::function< void()> closure
Definition: closure.h:14
def print(*args, **kwargs)
Definition: run_tests.py:49
Dart_Handle ToDart(const T &object)
#define ERROR(message)
Definition: elf_loader.cc:260