Flutter Engine
The Flutter Engine
marshaller.h
Go to the documentation of this file.
1// Copyright (c) 2020, 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#ifndef RUNTIME_VM_COMPILER_FFI_MARSHALLER_H_
6#define RUNTIME_VM_COMPILER_FFI_MARSHALLER_H_
7
8#if defined(DART_PRECOMPILED_RUNTIME)
9#error "AOT runtime should not use compiler sources (including header files)"
10#endif // defined(DART_PRECOMPILED_RUNTIME)
11
12#include <platform/globals.h>
13
19#include "vm/object.h"
20
21namespace dart {
22
23namespace compiler {
24
25namespace ffi {
26
27// Values below 0 index result (result might be multiple if composite).
28const intptr_t kResultIndex = -1;
29
30// Inspects the function signature and transitively any class and field
31// definitions and annotations.
33 Zone* zone,
34 const FunctionType& c_signature,
35 const char** error);
36
37// Provides the mapping from the native calling convention to the Dart calling
38// convention.
39//
40// This class is set up in a query-able way so that it's underlying logic can
41// be extended to support more native ABI features and calling conventions.
43 public:
44 intptr_t num_args() const {
46 }
47
48 // Number of definitions passed to FfiCall, number of NativeParams, or number
49 // of definitions passed to NativeReturn in IL.
50 //
51 // All non-struct values have 1 definition, struct values can have either 1
52 // or multiple definitions. If a struct has multiple definitions, they either
53 // correspond to the number of native locations in the native ABI or to word-
54 // sized chunks.
55 //
56 // `arg_index` is the index of an argument.
57 // `def_index_in_argument` is the definition in one argument.
58 // `def_index_global` is the index of the definition in all arguments.
59 intptr_t NumArgumentDefinitions() const;
60 virtual intptr_t NumDefinitions(intptr_t arg_index) const;
61 virtual intptr_t NumReturnDefinitions() const = 0;
62 bool ArgumentIndexIsReturn(intptr_t arg_index) const;
63 bool DefinitionIndexIsReturn(intptr_t def_index_global) const;
64 intptr_t ArgumentIndex(intptr_t def_index_global) const;
65 intptr_t FirstDefinitionIndex(intptr_t arg_index) const;
66 intptr_t DefinitionInArgument(intptr_t def_index_global,
67 intptr_t arg_index) const;
68 intptr_t DefinitionIndex(intptr_t def_index_in_arg, intptr_t arg_index) const;
69
70 // The location of the argument at `arg_index`.
71 const NativeLocation& Location(intptr_t arg_index) const {
72 if (arg_index == kResultIndex) {
74 }
76 }
77
78 // Unboxed representation on how the value is passed or received from regular
79 // Dart code.
80 //
81 // Implemented in BaseMarshaller because most Representations are the same
82 // in Calls and Callbacks.
83 Representation RepInDart(intptr_t arg_index) const;
84
85 // Representation on how the value is passed to or received from the FfiCall
86 // instruction or StaticCall, NativeParameter, and NativeReturn instructions.
87 virtual Representation RepInFfiCall(intptr_t def_index_global) const;
88 void RepsInFfiCall(intptr_t arg_index,
90
91 // Bitcasting floats to ints, only required in SoftFP.
92 bool RequiresBitCast(intptr_t index) const {
93 return Location(index).payload_type().IsFloat() &&
94 Location(index).container_type().IsInt();
95 }
96
97 // 8 or 16 bit int value to sign extend from.
98 const NativeType& SignExtendFrom(intptr_t arg_index) const {
99 return Location(arg_index).payload_type();
100 }
101
102 // The C Type (expressed in a Dart Type) of the argument at `arg_index`.
103 //
104 // Excluding the #0 argument which is the function pointer.
105 //
106 // Recurses into VarArgs if needed.
107 AbstractTypePtr CType(intptr_t arg_index) const;
108
109 AbstractTypePtr DartType(intptr_t arg_index) const;
110
111 protected:
112 bool IsPointerDartType(intptr_t arg_index) const;
113 bool IsPointerCType(intptr_t arg_index) const;
114
115 public:
116 // The Dart and C Type is Pointer.
117 //
118 // Requires boxing or unboxing the Pointer object to int.
119 bool IsPointerPointer(intptr_t arg_index) const;
120
121 // The Dart type is TypedData and the C type is Pointer.
122 //
123 // Requires passing the typed data base in as tagged pointer.
124 //
125 // TODO(https://dartbug.com/55444): The typed data address load could be
126 // done in IL.
127 bool IsTypedDataPointer(intptr_t arg_index) const;
128
129 // The Dart type is a compound (for example an Array or a TypedData+offset),
130 // and the C type is Pointer.
131 //
132 // Requires passing in two definitions in IL: TypedDataBase + offset.
133 //
134 // TODO(https://dartbug.com/55444): The typed data address load could be
135 // done in IL.
136 bool IsCompoundPointer(intptr_t arg_index) const;
137
138 // The C type is Handle, the Dart type can be anything.
139 //
140 // Requires passing the pointer to the Dart object in a handle.
141 bool IsHandleCType(intptr_t arg_index) const;
142
143 // The Dart and C Types are boolean.
144 //
145 // Requires converting the boolean into an int in IL.
146 bool IsBool(intptr_t arg_index) const;
147
148 // The Dart and C Types are compound (pass by value).
149 bool IsCompoundCType(intptr_t arg_index) const;
150
151 // Treated as a null constant in Dart.
152 bool IsVoid(intptr_t arg_index) const {
153 return AbstractType::Handle(zone_, CType(arg_index)).type_class_id() ==
154 kFfiVoidCid;
155 }
156
157 bool ContainsHandles() const;
158
159 bool contains_varargs() const {
161 }
162
163 // Note that the Dart arguments are indexed starting at
164 // `dart_signature_params_start_at()`.
165 //
166 // Closures created by `asFunction` have the pointer as first parameter.
167 // `@Native`s don't have an implicit first parameter.
168 const Function& dart_signature() const { return dart_signature_; }
171 }
172 const FunctionType& c_signature() const { return c_signature_; }
173 StringPtr function_name() const { return dart_signature_.name(); }
174
175 protected:
180 const NativeCallingConvention& native_calling_convention)
181 : zone_(zone),
185 native_calling_convention_(native_calling_convention) {}
186
188
190 // Contains the function pointer as argument #0.
191 // The Dart signature is used for the function and argument names.
196};
197
199 public:
200 static CallMarshaller* FromFunction(Zone* zone,
201 const Function& function,
202 intptr_t function_params_start_at,
204 const char** error);
205
210 const NativeCallingConvention& native_calling_convention)
211 : BaseMarshaller(zone,
215 native_calling_convention) {}
216
217 virtual intptr_t NumDefinitions(intptr_t arg_index) const;
218 virtual intptr_t NumReturnDefinitions() const;
219
220 virtual Representation RepInFfiCall(intptr_t def_index_global) const;
221
222 // The location of the inputs to the IL FfiCall instruction.
223 dart::Location LocInFfiCall(intptr_t def_index_global) const;
224
225 // Allocate a TypedData before the FfiCall and pass it into the FfiCall so
226 // that it can be populated in assembly.
227 bool ReturnsCompound() const;
228 intptr_t CompoundReturnSizeInBytes() const;
229
230 // We allocate space for PointerToMemory arguments and PointerToMemory return
231 // locations on the stack. This is faster than allocation ExternalTypedData.
232 // Normal TypedData is not an option, as these might be relocated by GC
233 // during FFI calls.
234 intptr_t PassByPointerStackOffset(intptr_t arg_index) const;
235
236 // The total amount of stack space required for FFI trampolines.
237 intptr_t RequiredStackSpaceInBytes() const;
238
239 protected:
241};
242
244 public:
246 const Function& function,
247 const char** error);
248
252 const NativeCallingConvention& native_calling_convention,
253 const NativeLocations& callback_locs)
254 : BaseMarshaller(zone,
256 /*dart_signature_params_start_at=*/0,
258 native_calling_convention),
259 callback_locs_(callback_locs) {}
260
261 virtual Representation RepInFfiCall(intptr_t def_index_global) const;
262
263 virtual intptr_t NumDefinitions(intptr_t arg_index) const;
264 virtual intptr_t NumReturnDefinitions() const;
265
266 // All parameters are saved on stack to do safe-point transition.
268 intptr_t def_index) const;
269
270 // All parameters are saved on stack to do safe-point transition.
271 dart::Location LocationOfNativeParameter(intptr_t def_index) const {
272 const auto& native_loc = NativeLocationOfNativeParameter(def_index);
273 if (native_loc.IsPointerToMemory()) {
274 return native_loc.AsPointerToMemory().pointer_location().AsLocation();
275 }
276 return native_loc.AsLocation();
277 }
278
279 protected:
281
283};
284
285} // namespace ffi
286
287} // namespace compiler
288
289} // namespace dart
290
291#endif // RUNTIME_VM_COMPILER_FFI_MARSHALLER_H_
const T & At(intptr_t index) const
intptr_t length() const
StringPtr name() const
Definition: object.h:2992
static Object & Handle()
Definition: object.h:407
bool IsPointerPointer(intptr_t arg_index) const
Definition: marshaller.cc:171
bool IsCompoundPointer(intptr_t arg_index) const
Definition: marshaller.cc:215
bool IsBool(intptr_t arg_index) const
Definition: marshaller.cc:234
bool IsPointerDartType(intptr_t arg_index) const
Definition: marshaller.cc:166
BaseMarshaller(Zone *zone, const Function &dart_signature, intptr_t dart_signature_params_start_at, const FunctionType &c_signature, const NativeCallingConvention &native_calling_convention)
Definition: marshaller.h:176
intptr_t DefinitionIndex(intptr_t def_index_in_arg, intptr_t arg_index) const
Definition: marshaller.cc:412
const Function & dart_signature() const
Definition: marshaller.h:168
const FunctionType & c_signature() const
Definition: marshaller.h:172
bool ArgumentIndexIsReturn(intptr_t arg_index) const
Definition: marshaller.cc:357
intptr_t dart_signature_params_start_at() const
Definition: marshaller.h:169
bool IsPointerCType(intptr_t arg_index) const
Definition: marshaller.cc:161
const NativeCallingConvention & native_calling_convention_
Definition: marshaller.h:195
bool IsCompoundCType(intptr_t arg_index) const
Definition: marshaller.cc:240
bool RequiresBitCast(intptr_t index) const
Definition: marshaller.h:92
void RepsInFfiCall(intptr_t arg_index, GrowableArray< Representation > *out) const
Definition: marshaller.cc:551
bool DefinitionIndexIsReturn(intptr_t def_index_global) const
Definition: marshaller.cc:363
virtual intptr_t NumReturnDefinitions() const =0
intptr_t FirstDefinitionIndex(intptr_t arg_index) const
Definition: marshaller.cc:385
const FunctionType & c_signature_
Definition: marshaller.h:194
virtual Representation RepInFfiCall(intptr_t def_index_global) const
Definition: marshaller.cc:444
const intptr_t dart_signature_params_start_at_
Definition: marshaller.h:193
Representation RepInDart(intptr_t arg_index) const
Definition: marshaller.cc:434
bool IsTypedDataPointer(intptr_t arg_index) const
Definition: marshaller.cc:180
intptr_t ArgumentIndex(intptr_t def_index_global) const
Definition: marshaller.cc:367
const NativeLocation & Location(intptr_t arg_index) const
Definition: marshaller.h:71
bool IsHandleCType(intptr_t arg_index) const
Definition: marshaller.cc:229
bool IsVoid(intptr_t arg_index) const
Definition: marshaller.h:152
virtual intptr_t NumDefinitions(intptr_t arg_index) const
Definition: marshaller.cc:257
const NativeType & SignExtendFrom(intptr_t arg_index) const
Definition: marshaller.h:98
intptr_t NumArgumentDefinitions() const
Definition: marshaller.cc:249
AbstractTypePtr CType(intptr_t arg_index) const
Definition: marshaller.cc:108
intptr_t DefinitionInArgument(intptr_t def_index_global, intptr_t arg_index) const
Definition: marshaller.cc:397
AbstractTypePtr DartType(intptr_t arg_index) const
Definition: marshaller.cc:148
virtual intptr_t NumDefinitions(intptr_t arg_index) const
Definition: marshaller.cc:293
CallMarshaller(Zone *zone, const Function &dart_signature, intptr_t dart_signature_params_start_at, const FunctionType &c_signature, const NativeCallingConvention &native_calling_convention)
Definition: marshaller.h:206
intptr_t PassByPointerStackOffset(intptr_t arg_index) const
Definition: marshaller.cc:695
dart::Location LocInFfiCall(intptr_t def_index_global) const
Definition: marshaller.cc:600
virtual intptr_t NumReturnDefinitions() const
Definition: marshaller.cc:319
intptr_t RequiredStackSpaceInBytes() const
Definition: marshaller.cc:741
static CallMarshaller * FromFunction(Zone *zone, const Function &function, intptr_t function_params_start_at, const FunctionType &c_signature, const char **error)
Definition: marshaller.cc:90
virtual Representation RepInFfiCall(intptr_t def_index_global) const
Definition: marshaller.cc:480
intptr_t CompoundReturnSizeInBytes() const
Definition: marshaller.cc:684
const NativeLocation & NativeLocationOfNativeParameter(intptr_t def_index) const
Definition: marshaller.cc:900
virtual intptr_t NumDefinitions(intptr_t arg_index) const
Definition: marshaller.cc:306
virtual Representation RepInFfiCall(intptr_t def_index_global) const
Definition: marshaller.cc:523
const NativeLocations & callback_locs_
Definition: marshaller.h:282
static CallbackMarshaller * FromFunction(Zone *zone, const Function &function, const char **error)
Definition: marshaller.cc:879
CallbackMarshaller(Zone *zone, const Function &dart_signature, const FunctionType &c_signature, const NativeCallingConvention &native_calling_convention, const NativeLocations &callback_locs)
Definition: marshaller.h:249
dart::Location LocationOfNativeParameter(intptr_t def_index) const
Definition: marshaller.h:271
virtual intptr_t NumReturnDefinitions() const
Definition: marshaller.cc:331
const NativeType & container_type() const
const NativeType & payload_type() const
virtual bool IsInt() const
Definition: native_type.h:89
virtual bool IsFloat() const
Definition: native_type.h:90
const uint8_t uint32_t uint32_t GError ** error
Dart_NativeFunction function
Definition: fuchsia.cc:51
const intptr_t kResultIndex
Definition: marshaller.h:28
const NativeFunctionType * NativeFunctionTypeFromFunctionType(Zone *zone, const FunctionType &c_signature, const char **error)
Definition: marshaller.cc:34
Definition: dart_vm.cc:33
Representation
Definition: locations.h:66