Flutter Engine
The Flutter Engine
ffi.cc
Go to the documentation of this file.
1// Copyright (c) 2019, 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_api.h"
9#include "platform/globals.h"
11#include "vm/exceptions.h"
12#include "vm/flags.h"
13#include "vm/heap/gc_shared.h"
14#include "vm/log.h"
15#include "vm/native_arguments.h"
16#include "vm/native_entry.h"
17#include "vm/object.h"
18#include "vm/object_store.h"
19#include "vm/symbols.h"
20
21#if !defined(DART_PRECOMPILED_RUNTIME)
26#endif // !defined(DART_PRECOMPILED_RUNTIME)
27
28namespace dart {
29
30DEFINE_NATIVE_ENTRY(Ffi_createNativeCallableListener, 1, 2) {
31 const auto& send_function =
32 Function::CheckedHandle(zone, arguments->NativeArg0());
33 const auto& port =
34 ReceivePort::CheckedHandle(zone, arguments->NativeArgAt(1));
35 return Pointer::New(
36 isolate->CreateAsyncFfiCallback(zone, send_function, port.Id()));
37}
38
39DEFINE_NATIVE_ENTRY(Ffi_createNativeCallableIsolateLocal, 1, 3) {
40 const auto& trampoline =
41 Function::CheckedHandle(zone, arguments->NativeArg0());
42 const auto& target = Closure::CheckedHandle(zone, arguments->NativeArgAt(1));
43 const bool keep_isolate_alive =
44 Bool::CheckedHandle(zone, arguments->NativeArgAt(2)).value();
45 return Pointer::New(isolate->CreateIsolateLocalFfiCallback(
46 zone, trampoline, target, keep_isolate_alive));
47}
48
49DEFINE_NATIVE_ENTRY(Ffi_deleteNativeCallable, 1, 1) {
50 const auto& pointer = Pointer::CheckedHandle(zone, arguments->NativeArg0());
51 isolate->DeleteFfiCallback(pointer.NativeAddress());
52 return Object::null();
53}
54
55DEFINE_NATIVE_ENTRY(Ffi_updateNativeCallableKeepIsolateAliveCounter, 1, 1) {
56 const int64_t delta =
57 Integer::CheckedHandle(zone, arguments->NativeArg0()).AsInt64Value();
58 isolate->UpdateNativeCallableKeepIsolateAliveCounter(delta);
59 return Object::null();
60}
61
62DEFINE_NATIVE_ENTRY(DartNativeApiFunctionPointer, 0, 1) {
63 GET_NON_NULL_NATIVE_ARGUMENT(String, name_dart, arguments->NativeArgAt(0));
64 const char* name = name_dart.ToCString();
65
66#define RETURN_FUNCTION_ADDRESS(function_name, R, A) \
67 if (strcmp(name, #function_name) == 0) { \
68 return Integer::New(reinterpret_cast<intptr_t>(function_name)); \
69 }
71#undef RETURN_FUNCTION_ADDRESS
72
74 String::NewFormatted("Unknown dart_native_api.h symbol: %s.", name));
76}
77
78DEFINE_NATIVE_ENTRY(DartApiDLMajorVersion, 0, 0) {
80}
81
82DEFINE_NATIVE_ENTRY(DartApiDLMinorVersion, 0, 0) {
84}
85
87#define ENTRY(name, R, A) \
88 DartApiEntry{#name, reinterpret_cast<void (*)()>(name)},
90#undef ENTRY
91 DartApiEntry{nullptr, nullptr}};
92
93static const DartApi dart_api_data = {
95
96DEFINE_NATIVE_ENTRY(DartApiDLInitializeData, 0, 0) {
97 return Integer::New(reinterpret_cast<intptr_t>(&dart_api_data));
98}
99
100DEFINE_FFI_NATIVE_ENTRY(FinalizerEntry_SetExternalSize,
101 void,
102 (Dart_Handle entry_handle, intptr_t external_size)) {
103 Thread* const thread = Thread::Current();
104 TransitionNativeToVM transition(thread);
105 Zone* const zone = thread->zone();
106 const auto& entry_object =
107 Object::Handle(zone, Api::UnwrapHandle(entry_handle));
108 const auto& entry = FinalizerEntry::Cast(entry_object);
109
110 Heap::Space space;
111 intptr_t external_size_diff;
112 {
113 NoSafepointScope no_safepoint;
114 space = SpaceForExternal(entry.ptr());
115 const intptr_t external_size_old = entry.external_size();
116 if (FLAG_trace_finalizers) {
117 THR_Print("Setting external size from %" Pd " to %" Pd
118 " bytes in %s space\n",
119 external_size_old, external_size, space == 0 ? "new" : "old");
120 }
121 external_size_diff = external_size - external_size_old;
122 if (external_size_diff == 0) {
123 return;
124 }
125 entry.set_external_size(external_size);
126 }
127 // The next call cannot be in safepoint.
128 if (external_size_diff > 0) {
129 if (!thread->isolate_group()->heap()->AllocatedExternal(external_size_diff,
130 space)) {
132 }
133 } else {
134 thread->isolate_group()->heap()->FreedExternal(-external_size_diff, space);
135 }
136};
137
138namespace {
139struct AsTypedListFinalizerData {
140 void (*callback)(void*);
141 void* token;
142};
143} // namespace
144
145DEFINE_FFI_NATIVE_ENTRY(Pointer_asTypedListFinalizerAllocateData, void*, ()) {
146 auto* result = malloc(sizeof(AsTypedListFinalizerData));
147 // Initialized with FFI stores.
148 MSAN_UNPOISON(result, sizeof(AsTypedListFinalizerData));
149 return result;
150};
151
153 const auto* data = reinterpret_cast<AsTypedListFinalizerData*>(peer);
154 data->callback(data->token);
155 free(peer);
156}
157
158DEFINE_FFI_NATIVE_ENTRY(Pointer_asTypedListFinalizerCallbackPointer,
159 void*,
160 ()) {
161 return reinterpret_cast<void*>(&AsTypedListFinalizerCallback);
162};
163
164} // namespace dart
static ObjectPtr UnwrapHandle(Dart_Handle object)
static DART_NORETURN void ThrowOOM()
Definition: exceptions.cc:1066
static DART_NORETURN void ThrowArgumentError(const Instance &arg)
Definition: exceptions.cc:1082
bool AllocatedExternal(intptr_t size, Space space)
Definition: heap.cc:180
void FreedExternal(intptr_t size, Space space)
Definition: heap.cc:201
static IntegerPtr New(const String &str, Heap::Space space=Heap::kNew)
Definition: object.cc:22984
Heap * heap() const
Definition: isolate.h:296
static ObjectPtr null()
Definition: object.h:433
static Object & Handle()
Definition: object.h:407
static PointerPtr New(uword native_address, Heap::Space space=Heap::kNew)
Definition: object.cc:25726
static StringPtr NewFormatted(const char *format,...) PRINTF_ATTRIBUTE(1
Definition: object.cc:24004
Zone * zone() const
Definition: thread_state.h:37
static Thread * Current()
Definition: thread.h:362
IsolateGroup * isolate_group() const
Definition: thread.h:541
#define THR_Print(format,...)
Definition: log.h:20
struct _Dart_Handle * Dart_Handle
Definition: dart_api.h:258
#define DART_NATIVE_API_DL_SYMBOLS(F)
Definition: dart_api_dl.h:50
#define DART_API_ALL_DL_SYMBOLS(F)
Definition: dart_api_dl.h:123
#define DART_API_DL_MAJOR_VERSION
Definition: dart_version.h:13
#define DART_API_DL_MINOR_VERSION
Definition: dart_version.h:14
#define ENTRY(name, R, A)
#define RETURN_FUNCTION_ADDRESS(function_name, R, A)
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
const uint8_t uint32_t uint32_t GError ** error
GAsyncResult * result
uint32_t * target
#define MSAN_UNPOISON(ptr, len)
Definition: dart_vm.cc:33
const char *const name
void * malloc(size_t size)
Definition: allocation.cc:19
static const DartApi dart_api_data
Definition: ffi.cc:93
static const DartApiEntry dart_api_entries[]
Definition: ffi.cc:86
DEFINE_FFI_NATIVE_ENTRY(FinalizerEntry_SetExternalSize, void,(Dart_Handle entry_handle, intptr_t external_size))
Definition: ffi.cc:100
void AsTypedListFinalizerCallback(void *peer)
Definition: ffi.cc:152
DEFINE_NATIVE_ENTRY(List_allocate, 0, 2)
Definition: array.cc:13
Heap::Space SpaceForExternal(FinalizerEntryPtr raw_entry)
Definition: gc_shared.cc:42
static int8_t data[kExtLength]
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service port
Definition: switches.h:87
#define GET_NON_NULL_NATIVE_ARGUMENT(type, name, value)
Definition: native_entry.h:74
#define Pd
Definition: globals.h:408