| // Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| #ifndef RUNTIME_VM_COMPILER_FFI_H_ |
| #define RUNTIME_VM_COMPILER_FFI_H_ |
| |
| #include <platform/globals.h> |
| |
| #include "../class_id.h" |
| #include "../object.h" |
| #include "../raw_object.h" |
| #include "backend/locations.h" |
| |
| namespace dart { |
| |
| namespace compiler { |
| |
| namespace ffi { |
| |
| // On all supported platforms, the minimum width an argument must be sign- or |
| // zero-extended to is 4 bytes. |
| constexpr intptr_t kMinimumArgumentWidth = 4; |
| |
| // Storage size for an FFI type (extends 'ffi.NativeType'). |
| size_t ElementSizeInBytes(intptr_t class_id); |
| |
| // Unboxed representation of an FFI type (extends 'ffi.NativeType'). |
| Representation TypeRepresentation(const AbstractType& result_type); |
| |
| // Unboxed representation of an FFI type (extends 'ffi.NativeType') for 8 and 16 |
| // bit integers. |
| SmallRepresentation TypeSmallRepresentation(const AbstractType& result_type); |
| |
| // Whether a type which extends 'ffi.NativeType' also extends 'ffi.Pointer'. |
| bool NativeTypeIsPointer(const AbstractType& result_type); |
| |
| // Whether a type is 'ffi.Void'. |
| bool NativeTypeIsVoid(const AbstractType& result_type); |
| |
| // Location for the result of a C signature function. |
| Location ResultLocation(Representation result_rep); |
| |
| #if !defined(TARGET_ARCH_DBC) |
| |
| // Unboxed representations of the arguments to a C signature function. |
| ZoneGrowableArray<Representation>* ArgumentRepresentations( |
| const Function& signature); |
| |
| // Unboxed representation of the result of a C signature function. |
| Representation ResultRepresentation(const Function& signature); |
| |
| #endif // !defined(TARGET_ARCH_DBC) |
| |
| #if defined(USING_SIMULATOR) |
| |
| // Unboxed host representations of the arguments to a C signature function. |
| ZoneGrowableArray<Representation>* ArgumentHostRepresentations( |
| const Function& signature); |
| |
| // Unboxed host representation of the result of a C signature function. |
| Representation ResultHostRepresentation(const Function& signature); |
| |
| #endif // defined(USING_SIMULATOR) |
| |
| // Location for the arguments of a C signature function. |
| ZoneGrowableArray<Location>* ArgumentLocations( |
| const ZoneGrowableArray<Representation>& arg_reps); |
| |
| // Number of stack slots used in 'locations'. |
| intptr_t NumStackSlots(const ZoneGrowableArray<Location>& locations); |
| |
| #if defined(TARGET_ARCH_DBC) |
| |
| // The first argument to a ffi trampoline is the function address, the arguments |
| // to the call follow the function address. |
| const intptr_t kFunctionAddressRegister = 0; |
| const intptr_t kFirstArgumentRegister = 1; |
| |
| // Location in host for the arguments of a C signature function. |
| ZoneGrowableArray<HostLocation>* HostArgumentLocations( |
| const ZoneGrowableArray<Representation>& arg_reps); |
| |
| // A signature descriptor consists of the signature length, argument locations, |
| // and result representation. |
| class FfiSignatureDescriptor : public ValueObject { |
| public: |
| explicit FfiSignatureDescriptor(const TypedData& typed_data) |
| : typed_data_(typed_data) {} |
| |
| static RawTypedData* New( |
| const ZoneGrowableArray<HostLocation>& arg_host_locations, |
| const Representation result_representation); |
| |
| intptr_t length() const; |
| intptr_t num_stack_slots() const; |
| HostLocation LocationAt(intptr_t index) const; |
| Representation ResultRepresentation() const; |
| |
| private: |
| const TypedData& typed_data_; |
| |
| static const intptr_t kOffsetNumArguments = 0; |
| static const intptr_t kOffsetNumStackSlots = 1; |
| static const intptr_t kOffsetResultRepresentation = 2; |
| static const intptr_t kOffsetArgumentLocations = 3; |
| }; |
| |
| #endif // defined(TARGET_ARCH_DBC) |
| |
| // This classes translates the ABI location of arguments into the locations they |
| // will inhabit after entry-frame setup in the invocation of a native callback. |
| // |
| // Native -> Dart callbacks must push all the arguments before executing any |
| // Dart code because the reading the Thread from TLS requires calling a native |
| // stub, and the argument registers are volatile on all ABIs we support. |
| // |
| // To avoid complicating initial definitions, all callback arguments are read |
| // off the stack from their pushed locations, so this class updates the argument |
| // positions to account for this. |
| // |
| // See 'NativeEntryInstr::EmitNativeCode' for details. |
| class CallbackArgumentTranslator : public ValueObject { |
| public: |
| static ZoneGrowableArray<Location>* TranslateArgumentLocations( |
| const ZoneGrowableArray<Location>& arg_locs); |
| |
| private: |
| void AllocateArgument(Location arg); |
| Location TranslateArgument(Location arg); |
| |
| intptr_t argument_slots_used_ = 0; |
| intptr_t argument_slots_required_ = 0; |
| }; |
| |
| } // namespace ffi |
| |
| } // namespace compiler |
| |
| } // namespace dart |
| |
| #endif // RUNTIME_VM_COMPILER_FFI_H_ |