Flutter Engine
The Flutter Engine
builtin_libraries.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 "builtin_libraries.h"
6
7#include <lib/fdio/namespace.h>
8#include <lib/zx/channel.h>
9
10#include <optional>
11
13#include "flutter/fml/logging.h"
15#include "third_party/dart/runtime/bin/io_natives.h"
16#include "third_party/dart/runtime/include/dart_api.h"
20
21#include "logging.h"
22
23using tonic::ToDart;
24
25namespace dart_runner {
26namespace {
27
28#define REGISTER_FUNCTION(name, count) {#name, name, count},
29#define DECLARE_FUNCTION(name, count) \
30 extern void name(Dart_NativeArguments args);
31
32#define BUILTIN_NATIVE_LIST(V) \
33 V(Logger_PrintString, 1) \
34 V(ScheduleMicrotask, 1)
35
37
38const struct NativeEntry {
39 const char* name;
42} kBuiltinEntries[] = {BUILTIN_NATIVE_LIST(REGISTER_FUNCTION)};
43
44Dart_NativeFunction BuiltinNativeLookup(Dart_Handle name,
46 bool* auto_setup_scope) {
47 const char* function_name = nullptr;
49 if (Dart_IsError(result)) {
51 }
52 FML_DCHECK(function_name != nullptr);
53 FML_DCHECK(auto_setup_scope != nullptr);
54 *auto_setup_scope = true;
55 size_t num_entries = dart_utils::ArraySize(kBuiltinEntries);
56 for (size_t i = 0; i < num_entries; i++) {
57 const NativeEntry& entry = kBuiltinEntries[i];
58 if (!strcmp(function_name, entry.name) &&
59 (entry.argument_count == argument_count)) {
60 return entry.function;
61 }
62 }
63 return nullptr;
64}
65
66const uint8_t* BuiltinNativeSymbol(Dart_NativeFunction native_function) {
67 size_t num_entries = dart_utils::ArraySize(kBuiltinEntries);
68 for (size_t i = 0; i < num_entries; i++) {
69 const NativeEntry& entry = kBuiltinEntries[i];
70 if (entry.function == native_function)
71 return reinterpret_cast<const uint8_t*>(entry.name);
72 }
73 return nullptr;
74}
75
76void Logger_PrintString(Dart_NativeArguments args) {
77 intptr_t length = 0;
78 uint8_t* chars = nullptr;
81 if (Dart_IsError(result)) {
83 } else {
84 fwrite(chars, 1, length, stdout);
85 fputc('\n', stdout);
86 fflush(stdout);
87 }
88}
89
90void ScheduleMicrotask(Dart_NativeArguments args) {
93 return;
95}
96
97} // namespace
98
99void InitBuiltinLibrariesForIsolate(const std::string& script_uri,
100 fdio_ns_t* namespc,
101 int stdoutfd,
102 int stderrfd,
103 zx::channel directory_request,
104 bool service_isolate) {
105 // dart:fuchsia --------------------------------------------------------------
106 // dart runner doesn't care about scenic view ref.
107 if (!service_isolate) {
108 fuchsia::dart::Initialize(std::move(directory_request), std::nullopt);
109 }
110
111 // dart:fuchsia.builtin ------------------------------------------------------
112
113 Dart_Handle builtin_lib = Dart_LookupLibrary(ToDart("dart:fuchsia.builtin"));
115 Dart_Handle result = Dart_SetNativeResolver(builtin_lib, BuiltinNativeLookup,
116 BuiltinNativeSymbol);
118
119 // dart:io -------------------------------------------------------------------
120
121 Dart_Handle io_lib = Dart_LookupLibrary(ToDart("dart:io"));
126
127 // dart:zircon ---------------------------------------------------------------
128
129 Dart_Handle zircon_lib = Dart_LookupLibrary(ToDart("dart:zircon"));
131 // NativeResolver already set by fuchsia::dart::Initialize().
132
133 // Core libraries ------------------------------------------------------------
134
135 Dart_Handle async_lib = Dart_LookupLibrary(ToDart("dart:async"));
137
138 Dart_Handle core_lib = Dart_LookupLibrary(ToDart("dart:core"));
140
141 Dart_Handle internal_lib = Dart_LookupLibrary(ToDart("dart:_internal"));
143
144 Dart_Handle isolate_lib = Dart_LookupLibrary(ToDart("dart:isolate"));
146
147#if !defined(AOT_RUNTIME)
148 // AOT: These steps already happened at compile time in gen_snapshot.
149
150 // We need to ensure that all the scripts loaded so far are finalized
151 // as we are about to invoke some Dart code below to set up closures.
154#endif
155
156 // Setup the internal library's 'internalPrint' function.
158 Dart_Invoke(builtin_lib, ToDart("_getPrintClosure"), 0, nullptr);
160
161 result = Dart_SetField(internal_lib, ToDart("_printClosure"), print);
163
164 // Set up the 'scheduleImmediate' closure.
165 Dart_Handle schedule_immediate_closure;
166 if (service_isolate) {
167 // Running on dart::ThreadPool.
168 schedule_immediate_closure = Dart_Invoke(
169 isolate_lib, ToDart("_getIsolateScheduleImmediateClosure"), 0, nullptr);
170 } else {
171 // Running on async::Loop.
172 schedule_immediate_closure = Dart_Invoke(
173 builtin_lib, ToDart("_getScheduleMicrotaskClosure"), 0, nullptr);
174 }
175 FML_CHECK(!tonic::CheckAndHandleError(schedule_immediate_closure));
176
177 Dart_Handle schedule_args[1];
178 schedule_args[0] = schedule_immediate_closure;
179 result = Dart_Invoke(async_lib, ToDart("_setScheduleImmediateClosure"), 1,
180 schedule_args);
182
183 // Set up the namespace in dart:io.
184 Dart_Handle namespace_type =
185 Dart_GetNonNullableType(io_lib, ToDart("_Namespace"), 0, nullptr);
186 FML_CHECK(!tonic::CheckAndHandleError(namespace_type));
187
188 Dart_Handle namespace_args[1];
189 namespace_args[0] = ToDart(reinterpret_cast<intptr_t>(namespc));
190 result =
191 Dart_Invoke(namespace_type, ToDart("_setupNamespace"), 1, namespace_args);
193
194 // Set up the namespace in dart:zircon.
195 namespace_type =
196 Dart_GetNonNullableType(zircon_lib, ToDart("_Namespace"), 0, nullptr);
197 FML_CHECK(!tonic::CheckAndHandleError(namespace_type));
198
199 result = Dart_SetField(namespace_type, ToDart("_namespace"),
200 ToDart(reinterpret_cast<intptr_t>(namespc)));
202
203 // Set up stdout and stderr.
204 Dart_Handle stdio_args[3];
205 stdio_args[0] = Dart_NewInteger(0);
206 stdio_args[1] = Dart_NewInteger(stdoutfd);
207 stdio_args[2] = Dart_NewInteger(stderrfd);
208 result = Dart_Invoke(io_lib, ToDart("_setStdioFDs"), 3, stdio_args);
210
211 // Disable some dart:io operations.
212 Dart_Handle embedder_config_type =
213 Dart_GetNonNullableType(io_lib, ToDart("_EmbedderConfig"), 0, nullptr);
214 FML_CHECK(!tonic::CheckAndHandleError(embedder_config_type));
215
216 result =
217 Dart_SetField(embedder_config_type, ToDart("_mayExit"), Dart_False());
219
220 // Set the script location.
221 result = Dart_SetField(builtin_lib, ToDart("_rawScript"), ToDart(script_uri));
223
224 // Setup the uriBase with the base uri of the fidl app.
225 Dart_Handle uri_base =
226 Dart_Invoke(io_lib, ToDart("_getUriBaseClosure"), 0, nullptr);
228
229 result = Dart_SetField(core_lib, ToDart("_uriBaseClosure"), uri_base);
231
232 Dart_Handle setup_hooks = ToDart("_setupHooks");
233 result = Dart_Invoke(builtin_lib, setup_hooks, 0, nullptr);
235 result = Dart_Invoke(io_lib, setup_hooks, 0, nullptr);
237 result = Dart_Invoke(isolate_lib, setup_hooks, 0, nullptr);
239}
240
241} // namespace dart_runner
Dart_NativeFunction function
const char * name
#define BUILTIN_NATIVE_LIST(V)
#define REGISTER_FUNCTION(name, count)
int argument_count
#define DECLARE_FUNCTION(name, count)
void ScheduleMicrotask(Dart_Handle callback)
static DartMicrotaskQueue * GetForCurrentThread()
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_SetNativeResolver(Dart_Handle library, Dart_NativeEntryResolver resolver, Dart_NativeEntrySymbol symbol)
struct _Dart_Handle * Dart_Handle
Definition: dart_api.h:258
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_GetNativeArgument(Dart_NativeArguments args, int index)
DART_EXPORT Dart_Handle Dart_LookupLibrary(Dart_Handle url)
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_FinalizeLoading(bool complete_futures)
struct _Dart_NativeArguments * Dart_NativeArguments
Definition: dart_api.h:3019
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_SetField(Dart_Handle container, Dart_Handle name, Dart_Handle value)
DART_EXPORT Dart_Handle Dart_False(void)
DART_EXPORT Dart_Handle Dart_StringToUTF8(Dart_Handle str, uint8_t **utf8_array, intptr_t *length)
DART_EXPORT Dart_Handle Dart_StringToCString(Dart_Handle str, const char **cstr)
void(* Dart_NativeFunction)(Dart_NativeArguments arguments)
Definition: dart_api.h:3207
DART_EXPORT Dart_Handle Dart_NewInteger(int64_t value)
DART_EXPORT bool Dart_IsError(Dart_Handle handle)
DART_EXPORT bool Dart_IsClosure(Dart_Handle object)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
GAsyncResult * result
#define FML_CHECK(condition)
Definition: logging.h:85
#define FML_DCHECK(condition)
Definition: logging.h:103
size_t length
const uint8_t * IONativeSymbol(Dart_NativeFunction nf)
Definition: io_natives.cc:235
Dart_NativeFunction IONativeLookup(Dart_Handle name, int argument_count, bool *auto_setup_scope)
Definition: io_natives.cc:215
void InitBuiltinLibrariesForIsolate(const std::string &script_uri, fdio_ns_t *namespc, int stdoutfd, int stderrfd, zx::channel directory_request, bool service_isolate)
size_t ArraySize(T(&array)[SIZE])
Definition: inlines.h:11
const char *const function_name
std::function< void(Dart_NativeArguments)> NativeEntry
std::function< void()> closure
Definition: closure.h:14
void Initialize(zx::channel directory_request, std::optional< zx::eventpair > view_ref)
Initializes Dart bindings for the Fuchsia application model.
Definition: fuchsia.cc:103
def print(*args, **kwargs)
Definition: run_tests.py:49
Dart_Handle ToDart(const T &object)
bool CheckAndHandleError(Dart_Handle handle)
Definition: dart_error.cc:33