// 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 #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* 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* 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* ArgumentLocations( const ZoneGrowableArray& arg_reps); // Number of stack slots used in 'locations'. intptr_t NumStackSlots(const ZoneGrowableArray& 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* HostArgumentLocations( const ZoneGrowableArray& 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& 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* TranslateArgumentLocations( const ZoneGrowableArray& 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_