Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Typedefs | Enumerations | Functions | Variables
dart::compiler::ffi Namespace Reference

Classes

struct  AbiAlignmentDouble
 
struct  AbiAlignmentUint64
 
class  ArgumentAllocator
 
class  BaseMarshaller
 
class  BothNativeLocations
 
class  CallbackArgumentTranslator
 
class  CallbackMarshaller
 
class  CallMarshaller
 
class  FrameRebase
 
class  MultipleNativeLocations
 
class  NativeArrayType
 
class  NativeCallingConvention
 
class  NativeCompoundType
 
class  NativeFpuRegistersLocation
 
class  NativeFunctionType
 
class  NativeLocation
 
class  NativePrimitiveType
 
class  NativeRegistersLocation
 
class  NativeStackLocation
 
class  NativeStructType
 
class  NativeType
 
class  NativeUnionType
 
class  PointerToMemoryLocation
 
class  Range
 
class  RawTestCase
 
class  TestCaseBase
 
struct  VeryLargeStruct
 

Typedefs

using NativeLocations = ZoneGrowableArray< const NativeLocation * >
 
using NativeTypes = ZoneGrowableArray< const NativeType * >
 

Enumerations

enum class  Abi {
  kAndroidArm , kAndroidArm64 , kAndroidIA32 , kAndroidX64 ,
  kAndroidRiscv64 , kFuchsiaArm64 , kFuchsiaX64 , kFuchsiaRiscv64 ,
  kIOSArm , kIOSArm64 , kIOSX64 , kLinuxArm ,
  kLinuxArm64 , kLinuxIA32 , kLinuxX64 , kLinuxRiscv32 ,
  kLinuxRiscv64 , kMacOSArm64 , kMacOSX64 , kWindowsArm64 ,
  kWindowsIA32 , kWindowsX64
}
 
enum  FpuRegisterKind { kQuadFpuReg , kDoubleFpuReg , kSingleFpuReg }
 
enum  PrimitiveType {
  kInt8 , kUint8 , kInt16 , kUint16 ,
  kInt32 , kUint32 , kInt64 , kUint64 ,
  kFloat , kDouble , kHalfDouble , kInt24 ,
  kUint24 , kInt40 , kUint40 , kInt48 ,
  kUint48 , kInt56 , kUint56 , kVoid
}
 

Functions

static int Main (int argc, const char **argv)
 
Abi TargetAbi ()
 
const StringNativeCallbackFunctionName (Thread *thread, Zone *zone, const Function &dart_target, FfiCallbackKind kind)
 
FunctionPtr NativeCallbackFunction (const FunctionType &c_signature, const Function &dart_target, const Instance &exceptional_return, FfiCallbackKind kind)
 
static void EnsureFfiCallbackMetadata (Thread *thread, intptr_t callback_id)
 
void SetFfiCallbackCode (Thread *thread, const Function &ffi_trampoline, const Code &code)
 
const NativeFunctionTypeNativeFunctionTypeFromFunctionType (Zone *zone, const FunctionType &c_signature, const char **error)
 
static bool IsCompound (Zone *zone, const AbstractType &type)
 
static Representation SelectRepresentationInIL (Zone *zone, const NativeLocation &location)
 
static Location ConvertToAnyLocation (const NativeStackLocation &loc, Representation rep_in_ffi_call)
 
static Location SelectFpuLocationInIL (Zone *zone, const NativeLocation &location)
 
static bool SoftFpAbi (bool has_varargs, bool is_result)
 
static const NativeTypeConvertFloatToInt (Zone *zone, const NativeType &type)
 
static const NativeTypeConvertIfSoftFp (Zone *zone, const NativeType &type, bool has_varargs, bool is_result=false)
 
static PrimitiveType TypeForSize (intptr_t size)
 
static NativeLocationsArgumentLocations (Zone *zone, const ZoneGrowableArray< const NativeType * > &arg_reps, const NativeLocation &return_location, intptr_t var_args_index)
 
static const NativeLocationPointerToMemoryResultLocation (Zone *zone, const NativeCompoundType &payload_type)
 
static const NativeLocationResultLocation (Zone *zone, const NativeType &payload_type, bool has_varargs)
 
const NativeCallingConventionRunSignatureTest (dart::Zone *zone, const char *name, const NativeFunctionType &native_signature)
 
const NativeCallingConventionRunSignatureTest (dart::Zone *zone, const char *name, const NativeTypes &argument_types, const NativeType &return_type)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCallingConvention_int8x10)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCallingConvention_floatx20)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCallingConvention_doublex20)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCallingConvention_mixedx20)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCallingConvention_struct3bytesx10)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCallingConvention_struct16bytesHomogenousx10)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCallingConvention_struct16bytesHomogenousx10_2)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCallingConvention_union16bytesHomogenousx10)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCallingConvention_struct128bytesx1)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCallingConvention_struct8bytesx1)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCallingConvention_struct8bytesPackedx10)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCallingConvention_structPacked)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCallingConvention_union5bytesPackedx10)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCallingConvention_regress46127)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCallingConvention_struct12bytesFloatx6)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCallingConvention_regress_fuchsia105336)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCallingConvention_variadic_int)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCallingConvention_variadic_double)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCallingConvention_variadic_with_struct)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCallingConvention_variadic_with_homogenous_struct)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCallingConvention_variadic_register_alignment)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCallingConvention_regress49460)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCallingConvention_stradle_last_register)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCallingConvention_variadic_stradle_last_register)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCallingConvention_variadic_less_than_word)
 
compiler::Address NativeLocationToStackSlotAddress (const NativeStackLocation &loc)
 
static void PrintRepresentations (BaseTextBuffer *f, const NativeLocation &loc)
 
intptr_t SizeFromFpuRegisterKind (enum FpuRegisterKind kind)
 
enum FpuRegisterKind FpuRegisterKindFromSize (intptr_t size_in_bytes)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeStackLocation)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeStackLocation_Split)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeStackLocation_Equals)
 
PrimitiveType PrimitiveTypeFromSizeInBytes (intptr_t size)
 
static bool ContainsHomogeneousFloatsInternal (const NativeTypes &types)
 
static PrimitiveType split_fundamental (PrimitiveType in)
 
static PrimitiveType TypeRepresentation (classid_t class_id)
 
static const NativeTypeCompoundFromPragma (Zone *zone, const Instance &pragma, bool is_struct, const char **error)
 
static const NativeTypeAbiSpecificFromPragma (Zone *zone, const Instance &pragma, const Class &abi_specific_int, const char **error)
 
static PrimitiveType fundamental_rep (Representation rep)
 
static const char * PrimitiveTypeToCString (PrimitiveType rep)
 
static void ContainsHomogeneousFloatsRecursive (const NativeTypes &types, bool *only_float, bool *only_double)
 
const NativeCompoundTypeRunStructTest (dart::Zone *zone, const char *name, const NativeTypes &member_types, intptr_t packing=kMaxInt32)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeType)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCompoundType_int8x10)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCompoundType_floatx4)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCompoundType_VeryLargeStruct)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCompoundType_int8array)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCompoundType_floatarray)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCompoundType_packed)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCompoundType_packed_array)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCompoundType_packed_nested)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCompoundType_union_size)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCompoundType_union_primitive_members)
 
 UNIT_TEST_CASE_WITH_ZONE (NativeCompoundType_union_unaligned)
 
 ISOLATE_UNIT_TEST_CASE (Ffi_NativeType_Primitive_FromAbstractType)
 
 ISOLATE_UNIT_TEST_CASE (Ffi_NativeType_Bool_FromAbstractType)
 
 ISOLATE_UNIT_TEST_CASE (Ffi_NativeType_Struct_FromAbstractType)
 
classid_t ElementTypedDataCid (classid_t class_id)
 
classid_t ElementExternalTypedDataCid (classid_t class_id)
 
classid_t RecognizedMethodTypeArgCid (MethodRecognizer::Kind kind)
 
AlignmentType RecognizedMethodAlignment (MethodRecognizer::Kind kind)
 
MethodRecognizer::Kind FfiLoad (const NativeType &native_type)
 
MethodRecognizer::Kind FfiStore (const NativeType &native_type)
 
void WriteToFile (char *path, const char *contents)
 
void ReadFromFile (char *path, char **buffer_pointer)
 

Variables

static constexpr const char * kNone = "No Test"
 
static constexpr const char * kList = "List all Tests"
 
static constexpr const char * kAll = "Run all Tests"
 
static const char * run_filter = kNone
 
static constexpr const char * kCommandAll = "--all"
 
static constexpr const char * kCommandList = "--list"
 
static constexpr const char * kCommandUpdate = "--update"
 
static int run_matches = 0
 
const char * target_abi_name
 
const int64_t num_abis = static_cast<int64_t>(Abi::kWindowsX64) + 1
 
const intptr_t kNativeParamsStartAt = 1
 
static const intptr_t kTypedDataBaseIndex = 0
 
static const intptr_t kOffsetInBytesIndex = 1
 
const intptr_t kAfterLastArgumentIndex = kIntptrMax
 
const intptr_t kResultIndex = -1
 
const intptr_t kNoFpuRegister = -1
 
static const intptr_t fundamental_size_in_bytes [kVoid+1]
 
constexpr PrimitiveType kAddress = kInt64
 
const char * kOs = kTargetOperatingSystemName
 
const char * kArch
 

Typedef Documentation

◆ NativeLocations

Definition at line 22 of file native_calling_convention.h.

◆ NativeTypes

Definition at line 316 of file native_type.h.

Enumeration Type Documentation

◆ Abi

enum class dart::compiler::ffi::Abi
strong
Enumerator
kAndroidArm 
kAndroidArm64 
kAndroidIA32 
kAndroidX64 
kAndroidRiscv64 
kFuchsiaArm64 
kFuchsiaX64 
kFuchsiaRiscv64 
kIOSArm 
kIOSArm64 
kIOSX64 
kLinuxArm 
kLinuxArm64 
kLinuxIA32 
kLinuxX64 
kLinuxRiscv32 
kLinuxRiscv64 
kMacOSArm64 
kMacOSX64 
kWindowsArm64 
kWindowsIA32 
kWindowsX64 

Definition at line 22 of file abi.h.

◆ FpuRegisterKind

Enumerator
kQuadFpuReg 
kDoubleFpuReg 
kSingleFpuReg 

Definition at line 217 of file native_location.h.

217 {
218 kQuadFpuReg, // 16 bytes
219 kDoubleFpuReg, // 8 bytes, a double
220 kSingleFpuReg // 4 bytes, a float
221};

◆ PrimitiveType

Enumerator
kInt8 
kUint8 
kInt16 
kUint16 
kInt32 
kUint32 
kInt64 
kUint64 
kFloat 
kDouble 
kHalfDouble 
kInt24 
kUint24 
kInt40 
kUint40 
kInt48 
kUint48 
kInt56 
kUint56 
kVoid 

Definition at line 179 of file native_type.h.

179 {
180 kInt8,
181 kUint8,
182 kInt16,
183 kUint16,
184 kInt32,
185 kUint32,
186 kInt64,
187 kUint64,
188 kFloat,
189 kDouble,
190 kHalfDouble, // When doubles are split over two 32 bit locations.
191 kInt24,
192 kUint24,
193 kInt40,
194 kUint40,
195 kInt48,
196 kUint48,
197 kInt56,
198 kUint56,
199 kVoid,
200 // TODO(37470): Add packed data structures.
201};

Function Documentation

◆ AbiSpecificFromPragma()

static const NativeType * dart::compiler::ffi::AbiSpecificFromPragma ( Zone zone,
const Instance pragma,
const Class abi_specific_int,
const char **  error 
)
static

Definition at line 522 of file native_type.cc.

525 {
526 const auto& clazz = Class::Handle(zone, pragma.clazz());
527 const auto& fields = Array::Handle(zone, clazz.fields());
528 ASSERT(fields.Length() == 1);
529 const auto& native_types_field =
530 Field::Handle(zone, Field::RawCast(fields.At(0)));
531 ASSERT(String::Handle(zone, native_types_field.name())
532 .Equals(Symbols::FfiNativeTypes()));
533 const auto& native_types =
534 Array::Handle(zone, Array::RawCast(pragma.GetField(native_types_field)));
535
536 ASSERT(native_types.Length() == num_abis);
537 const int64_t abi_index = static_cast<int64_t>(TargetAbi());
538 const auto& abi_abstract_type = AbstractType::Handle(
539 zone, AbstractType::RawCast(native_types.At(abi_index)));
540 if (abi_abstract_type.IsNull()) {
541 *error = zone->PrintToString(
542 "AbiSpecificInteger '%s' is missing mapping for '%s'.",
543 abi_specific_int.UserVisibleNameCString(), target_abi_name);
544 return nullptr;
545 }
546 return NativeType::FromAbstractType(zone, abi_abstract_type, error);
547}
const char * UserVisibleNameCString() const
Definition object.cc:3059
ObjectPtr GetField(const Field &field) const
Definition object.cc:20516
ClassPtr clazz() const
Definition object.h:13192
char * PrintToString(const char *format,...) PRINTF_ATTRIBUTE(2
Definition zone.cc:313
#define ASSERT(E)
const uint8_t uint32_t uint32_t GError ** error
Abi TargetAbi()
Definition abi.cc:88

◆ ArgumentLocations()

static NativeLocations & dart::compiler::ffi::ArgumentLocations ( Zone zone,
const ZoneGrowableArray< const NativeType * > &  arg_reps,
const NativeLocation return_location,
intptr_t  var_args_index 
)
static

Definition at line 696 of file native_calling_convention.cc.

700 {
701 intptr_t num_arguments = arg_reps.length();
702 auto& result = *new (zone) NativeLocations(zone, num_arguments);
703
704 // Loop through all arguments and assign a register or a stack location.
705 // Allocate result pointer for composite returns first.
706 const bool has_varargs =
707 var_args_index != NativeFunctionType::kNoVariadicArguments;
708 ArgumentAllocator frame_state(zone, has_varargs);
709#if !defined(TARGET_ARCH_ARM64)
710 // Arm64 allocates the pointer in R8, which is not an argument location.
711 if (return_location.IsPointerToMemory()) {
712 const auto& pointer_location =
713 return_location.AsPointerToMemory().pointer_location();
714 const auto& pointer_location_allocated =
715 frame_state.AllocateArgumentVariadic(pointer_location.payload_type());
716 ASSERT(pointer_location.Equals(pointer_location_allocated));
717 }
718#endif
719
720 for (intptr_t i = 0; i < num_arguments; i++) {
721 const NativeType& rep = *arg_reps[i];
722 const bool is_first_vararg = has_varargs && i == var_args_index;
723 const bool is_vararg = has_varargs && i >= var_args_index;
724 result.Add(
725 &frame_state.AllocateArgumentVariadic(rep, is_first_vararg, is_vararg));
726 }
727 return result;
728}
void Add(const T &value)
intptr_t length() const
const PointerToMemoryLocation & AsPointerToMemory() const
const NativeLocation & pointer_location() const
GAsyncResult * result

◆ CompoundFromPragma()

static const NativeType * dart::compiler::ffi::CompoundFromPragma ( Zone zone,
const Instance pragma,
bool  is_struct,
const char **  error 
)
static

Definition at line 443 of file native_type.cc.

446 {
447 const auto& struct_layout = pragma;
448 const auto& clazz = Class::Handle(zone, struct_layout.clazz());
449 ASSERT(String::Handle(zone, clazz.UserVisibleName())
450 .Equals(Symbols::FfiStructLayout()));
451 const auto& struct_layout_fields = Array::Handle(zone, clazz.fields());
452 ASSERT(struct_layout_fields.Length() == 2);
453 const auto& types_field =
454 Field::Handle(zone, Field::RawCast(struct_layout_fields.At(0)));
455 ASSERT(String::Handle(zone, types_field.name())
456 .Equals(Symbols::FfiFieldTypes()));
457 const auto& field_types =
458 Array::Handle(zone, Array::RawCast(struct_layout.GetField(types_field)));
459 const auto& packed_field =
460 Field::Handle(zone, Field::RawCast(struct_layout_fields.At(1)));
461 ASSERT(String::Handle(zone, packed_field.name())
462 .Equals(Symbols::FfiFieldPacking()));
463 const auto& packed_value = Integer::Handle(
464 zone, Integer::RawCast(struct_layout.GetField(packed_field)));
465 const intptr_t member_packing =
466 packed_value.IsNull() ? kMaxInt32 : packed_value.AsInt64Value();
467
468 auto& field_instance = Instance::Handle(zone);
469 auto& field_type = AbstractType::Handle(zone);
470 auto& field_native_types = *new (zone) ZoneGrowableArray<const NativeType*>(
471 zone, field_types.Length());
472 for (intptr_t i = 0; i < field_types.Length(); i++) {
473 field_instance ^= field_types.At(i);
474 if (field_instance.IsAbstractType()) {
475 // Subtype of NativeType: Struct, native integer or native float.
476 field_type ^= field_types.At(i);
477 const auto& field_native_type =
478 NativeType::FromAbstractType(zone, field_type, error);
479 if (*error != nullptr) {
480 return nullptr;
481 }
482 field_native_types.Add(field_native_type);
483 } else {
484 // Inline array.
485 const auto& struct_layout_array_class =
486 Class::Handle(zone, field_instance.clazz());
487 ASSERT(String::Handle(zone, struct_layout_array_class.UserVisibleName())
488 .Equals(Symbols::FfiStructLayoutArray()));
489 const auto& struct_layout_array_fields =
490 Array::Handle(zone, struct_layout_array_class.fields());
491 ASSERT(struct_layout_array_fields.Length() == 2);
492 const auto& element_type_field =
493 Field::Handle(zone, Field::RawCast(struct_layout_array_fields.At(0)));
494 ASSERT(String::Handle(zone, element_type_field.UserVisibleName())
495 .Equals(Symbols::FfiElementType()));
496 field_type ^= field_instance.GetField(element_type_field);
497 const auto& length_field =
498 Field::Handle(zone, Field::RawCast(struct_layout_array_fields.At(1)));
499 ASSERT(String::Handle(zone, length_field.UserVisibleName())
500 .Equals(Symbols::Length()));
501 const auto& length = Smi::Handle(
502 zone, Smi::RawCast(field_instance.GetField(length_field)));
503 const auto element_type =
504 NativeType::FromAbstractType(zone, field_type, error);
505 if (*error != nullptr) {
506 return nullptr;
507 }
508 const auto field_native_type =
509 new (zone) NativeArrayType(*element_type, length.AsInt64Value());
510 field_native_types.Add(field_native_type);
511 }
512 }
513
514 if (is_struct) {
515 return &NativeStructType::FromNativeTypes(zone, field_native_types,
516 member_packing);
517 } else {
518 return &NativeUnionType::FromNativeTypes(zone, field_native_types);
519 }
520}
const T & At(intptr_t index) const
size_t length
constexpr int32_t kMaxInt32
Definition globals.h:483

◆ ContainsHomogeneousFloatsInternal()

static bool dart::compiler::ffi::ContainsHomogeneousFloatsInternal ( const NativeTypes types)
static

Definition at line 1064 of file native_type.cc.

1064 {
1065 bool only_float = true;
1066 bool only_double = true;
1067 ContainsHomogeneousFloatsRecursive(types, &only_float, &only_double);
1068 return (only_double || only_float) && types.length() > 0;
1069}
static void ContainsHomogeneousFloatsRecursive(const NativeTypes &types, bool *only_float, bool *only_double)

◆ ContainsHomogeneousFloatsRecursive()

static void dart::compiler::ffi::ContainsHomogeneousFloatsRecursive ( const NativeTypes types,
bool *  only_float,
bool *  only_double 
)
static

Definition at line 1045 of file native_type.cc.

1047 {
1048 for (intptr_t i = 0; i < types.length(); i++) {
1049 const auto& type = *types.At(i);
1050 const auto& member_type =
1051 type.IsArray() ? type.AsArray().element_type() : type;
1052 if (member_type.IsPrimitive()) {
1053 PrimitiveType type = member_type.AsPrimitive().representation();
1054 *only_float = *only_float && (type == kFloat);
1055 *only_double = *only_double && (type == kDouble);
1056 }
1057 if (member_type.IsCompound()) {
1058 ContainsHomogeneousFloatsRecursive(member_type.AsCompound().members(),
1059 only_float, only_double);
1060 }
1061 }
1062}

◆ ConvertFloatToInt()

static const NativeType & dart::compiler::ffi::ConvertFloatToInt ( Zone zone,
const NativeType type 
)
static

Definition at line 52 of file native_calling_convention.cc.

52 {
53 ASSERT(type.IsFloat());
54 if (type.SizeInBytes() == 4) {
55 return *new (zone) NativePrimitiveType(kInt32);
56 }
57 ASSERT(type.SizeInBytes() == 8);
58 return *new (zone) NativePrimitiveType(kInt64);
59}

◆ ConvertIfSoftFp()

static const NativeType & dart::compiler::ffi::ConvertIfSoftFp ( Zone zone,
const NativeType type,
bool  has_varargs,
bool  is_result = false 
)
static

Definition at line 62 of file native_calling_convention.cc.

65 {
66 if (SoftFpAbi(has_varargs, is_result) && type.IsFloat()) {
67 return ConvertFloatToInt(zone, type);
68 }
69 return type;
70}
static const NativeType & ConvertFloatToInt(Zone *zone, const NativeType &type)
static bool SoftFpAbi(bool has_varargs, bool is_result)

◆ ConvertToAnyLocation()

static Location dart::compiler::ffi::ConvertToAnyLocation ( const NativeStackLocation loc,
Representation  rep_in_ffi_call 
)
static

Definition at line 562 of file marshaller.cc.

563 {
564 // Floating point values are never split: they are either in a single "FPU"
565 // register or a contiguous 64-bit slot on the stack. Unboxed 64-bit integer
566 // values, in contrast, can be split between any two registers on a 32-bit
567 // system.
568 //
569 // There is an exception for iOS and Android 32-bit ARM, where
570 // floating-point values are treated as integers as far as the calling
571 // convention is concerned. However, the representation of these arguments
572 // are set to kUnboxedInt32 or kUnboxedInt64 already, so we don't have to
573 // account for that here.
574 const bool is_atomic =
575 rep_in_ffi_call == kUnboxedDouble || rep_in_ffi_call == kUnboxedFloat;
576
577 if (loc.payload_type().IsPrimitive() &&
578 loc.payload_type().SizeInBytes() == 2 * compiler::target::kWordSize &&
579 !is_atomic) {
580 return Location::Pair(Location::Any(), Location::Any());
581 }
582 return Location::Any();
583}
const NativeType & payload_type() const
virtual intptr_t SizeInBytes() const =0
virtual bool IsPrimitive() const
Definition native_type.h:80

◆ ElementExternalTypedDataCid()

classid_t dart::compiler::ffi::ElementExternalTypedDataCid ( classid_t  class_id)

Definition at line 45 of file recognized_method.cc.

45 {
46 switch (class_id) {
47 case kFfiInt8Cid:
48 return kExternalTypedDataInt8ArrayCid;
49 case kFfiUint8Cid:
50 return kExternalTypedDataUint8ArrayCid;
51 case kFfiInt16Cid:
52 return kExternalTypedDataInt16ArrayCid;
53 case kFfiUint16Cid:
54 return kExternalTypedDataUint16ArrayCid;
55 case kFfiInt32Cid:
56 return kExternalTypedDataInt32ArrayCid;
57 case kFfiUint32Cid:
58 return kExternalTypedDataUint32ArrayCid;
59 case kFfiInt64Cid:
60 return kExternalTypedDataInt64ArrayCid;
61 case kFfiUint64Cid:
62 return kExternalTypedDataUint64ArrayCid;
63 case kFfiFloatCid:
64 return kExternalTypedDataFloat32ArrayCid;
65 case kFfiDoubleCid:
66 return kExternalTypedDataFloat64ArrayCid;
67 default:
69 }
70}
#define UNREACHABLE()
Definition assert.h:248

◆ ElementTypedDataCid()

classid_t dart::compiler::ffi::ElementTypedDataCid ( classid_t  class_id)

Definition at line 15 of file recognized_method.cc.

15 {
16 switch (class_id) {
17 case kFfiInt8Cid:
18 return kTypedDataInt8ArrayCid;
19 case kFfiUint8Cid:
20 return kTypedDataUint8ArrayCid;
21 case kFfiInt16Cid:
22 return kTypedDataInt16ArrayCid;
23 case kFfiUint16Cid:
24 return kTypedDataUint16ArrayCid;
25 case kFfiInt32Cid:
26 return kTypedDataInt32ArrayCid;
27 case kFfiUint32Cid:
28 return kTypedDataUint32ArrayCid;
29 case kFfiInt64Cid:
30 return kTypedDataInt64ArrayCid;
31 case kFfiUint64Cid:
32 return kTypedDataUint64ArrayCid;
33 case kPointerCid:
34 return target::kWordSize == 4 ? kTypedDataUint32ArrayCid
35 : kTypedDataUint64ArrayCid;
36 case kFfiFloatCid:
37 return kTypedDataFloat32ArrayCid;
38 case kFfiDoubleCid:
39 return kTypedDataFloat64ArrayCid;
40 default:
42 }
43}

◆ EnsureFfiCallbackMetadata()

static void dart::compiler::ffi::EnsureFfiCallbackMetadata ( Thread thread,
intptr_t  callback_id 
)
static

Definition at line 125 of file callback.cc.

125 {
126 static constexpr intptr_t kInitialCallbackIdsReserved = 16;
127
128 auto object_store = thread->isolate_group()->object_store();
129 auto zone = thread->zone();
130
131 auto& code_array =
132 GrowableObjectArray::Handle(zone, object_store->ffi_callback_code());
133 if (code_array.IsNull()) {
134 code_array =
135 GrowableObjectArray::New(kInitialCallbackIdsReserved, Heap::kOld);
136 object_store->set_ffi_callback_code(code_array);
137 }
138 if (code_array.Length() <= callback_id) {
139 // Ensure we've enough space in the arrays.
140 while (!(callback_id < code_array.Length())) {
141 code_array.Add(Code::null_object());
142 }
143 }
144
145 ASSERT(callback_id < code_array.Length());
146}
ObjectStore * object_store() const
Definition isolate.h:505
Zone * zone() const
IsolateGroup * isolate_group() const
Definition thread.h:540

◆ FfiLoad()

MethodRecognizer::Kind dart::compiler::ffi::FfiLoad ( const NativeType native_type)

Definition at line 118 of file recognized_method.cc.

118 {
119 if (native_type.IsPrimitive()) {
120 switch (native_type.AsPrimitive().representation()) {
121#define CASE(type) \
122 case k##type: \
123 return MethodRecognizer::kFfiLoad##type;
125#undef CASE
126 default:
127 break;
128 }
129 }
131}
#define CLASS_LIST_FFI_NUMERIC_FIXED_SIZE(V)
Definition class_id.h:153
const NativePrimitiveType & AsPrimitive() const
#define UNIMPLEMENTED
#define CASE(type)

◆ FfiStore()

MethodRecognizer::Kind dart::compiler::ffi::FfiStore ( const NativeType native_type)

Definition at line 133 of file recognized_method.cc.

133 {
134 if (native_type.IsPrimitive()) {
135 switch (native_type.AsPrimitive().representation()) {
136#define CASE(type) \
137 case k##type: \
138 return MethodRecognizer::kFfiStore##type;
140#undef CASE
141 default:
142 break;
143 }
144 }
146}

◆ FpuRegisterKindFromSize()

FpuRegisterKind dart::compiler::ffi::FpuRegisterKindFromSize ( intptr_t  size_in_bytes)

Definition at line 390 of file native_location.cc.

390 {
391 switch (size_in_bytes) {
392 case 16:
393 return kQuadFpuReg;
394 case 8:
395 return kDoubleFpuReg;
396 case 4:
397 return kSingleFpuReg;
398 }
399 UNREACHABLE();
400}

◆ fundamental_rep()

static PrimitiveType dart::compiler::ffi::fundamental_rep ( Representation  rep)
static

Definition at line 611 of file native_type.cc.

611 {
612 switch (rep) {
613 case kUnboxedDouble:
614 return kDouble;
615 case kUnboxedFloat:
616 return kFloat;
617 case kUnboxedInt32:
618 return kInt32;
619 case kUnboxedUint32:
620 return kUint32;
621 case kUnboxedInt64:
622 return kInt64;
623 case kUntagged:
624 case kTagged:
625 return TypeRepresentation(kPointerCid);
626 default:
627 break;
628 }
629 FATAL("Unhandled representation %u", rep);
630}
#define FATAL(error)
static PrimitiveType TypeRepresentation(classid_t class_id)

◆ IsCompound()

static bool dart::compiler::ffi::IsCompound ( Zone zone,
const AbstractType type 
)
static

Definition at line 200 of file marshaller.cc.

200 {
201 auto& compiler_state = Thread::Current()->compiler_state();
202 auto& cls = Class::Handle(zone, type.type_class());
203 if (cls.id() == compiler_state.CompoundClass().id() ||
204 cls.id() == compiler_state.ArrayClass().id()) {
205 return true;
206 }
207 cls ^= cls.SuperClass();
208 if (cls.id() == compiler_state.StructClass().id() ||
209 cls.id() == compiler_state.UnionClass().id()) {
210 return true;
211 }
212 return false;
213}

◆ ISOLATE_UNIT_TEST_CASE() [1/3]

dart::compiler::ffi::ISOLATE_UNIT_TEST_CASE ( Ffi_NativeType_Bool_FromAbstractType  )

Definition at line 35 of file native_type_vm_test.cc.

35 {
36 Zone* Z = thread->zone();
37
38 const auto& ffi_library = Library::Handle(Library::FfiLibrary());
39 const auto& bool_class = Class::Handle(GetClass(ffi_library, "Bool"));
40 const auto& bool_type = Type::Handle(bool_class.DeclarationType());
41 const char* error = nullptr;
42 const auto& bool_native_type =
43 *NativeType::FromAbstractType(Z, bool_type, &error);
44 EXPECT_NULLPTR(error);
45
46 const auto& uint8_native_type = *new (Z) NativePrimitiveType(kUint8);
47
48 EXPECT(bool_native_type.Equals(uint8_native_type));
49 EXPECT_EQ(1, bool_native_type.SizeInBytes());
50 EXPECT_STREQ("uint8", bool_native_type.ToCString());
51 EXPECT(bool_native_type.IsInt());
52 EXPECT(bool_native_type.IsPrimitive());
53}
#define EXPECT(type, expectedAlignment, expectedSize)
#define Z
ClassPtr GetClass(const Library &lib, const char *name)

◆ ISOLATE_UNIT_TEST_CASE() [2/3]

dart::compiler::ffi::ISOLATE_UNIT_TEST_CASE ( Ffi_NativeType_Primitive_FromAbstractType  )

Definition at line 14 of file native_type_vm_test.cc.

14 {
15 Zone* Z = thread->zone();
16
17 const auto& ffi_library = Library::Handle(Library::FfiLibrary());
18 const auto& int8_class = Class::Handle(GetClass(ffi_library, "Int8"));
19 const auto& int8_type = Type::Handle(int8_class.DeclarationType());
20 const char* error = nullptr;
21 const auto& native_type = *NativeType::FromAbstractType(Z, int8_type, &error);
22 EXPECT_NULLPTR(error);
23
24 EXPECT_EQ(1, native_type.SizeInBytes());
25 EXPECT_STREQ("int8", native_type.ToCString());
26 EXPECT(native_type.IsInt());
27 EXPECT(native_type.IsPrimitive());
28}

◆ ISOLATE_UNIT_TEST_CASE() [3/3]

dart::compiler::ffi::ISOLATE_UNIT_TEST_CASE ( Ffi_NativeType_Struct_FromAbstractType  )

Definition at line 56 of file native_type_vm_test.cc.

56 {
57 Zone* Z = thread->zone();
58
59 const char* kScript =
60 R"(
61 import 'dart:ffi';
62
63 final class MyStruct extends Struct {
64 @Int8()
65 external int a0;
66
67 external Pointer<Int8> a1;
68 }
69 )";
70
71 const auto& root_library = Library::Handle(LoadTestScript(kScript));
72 const auto& struct_class = Class::Handle(GetClass(root_library, "MyStruct"));
73 const auto& struct_type = Type::Handle(struct_class.DeclarationType());
74
75 const char* error = nullptr;
76 const auto& native_type =
77 NativeType::FromAbstractType(Z, struct_type, &error)->AsCompound();
78 EXPECT_NULLPTR(error);
LibraryPtr LoadTestScript(const char *script, Dart_NativeEntryResolver resolver, const char *lib_uri)

◆ Main()

static int dart::compiler::ffi::Main ( int  argc,
const char **  argv 
)
static

Definition at line 73 of file run_ffi_unit_tests.cc.

73 {
74 if (argc == 2 && strcmp(argv[1], kCommandList) == 0) {
76 // List all tests and benchmarks and exit.
77 TestCaseBase::RunAll();
78 fflush(stdout);
79 return 0;
80 }
81 if (argc > 1 && strcmp(argv[1], kCommandUpdate) == 0) {
82 TestCaseBase::update_expectations = true;
83 }
84 if (strcmp(argv[argc - 1], kCommandAll) == 0) {
85 // Run all tests.
86 run_filter = kAll;
87 } else if (argc > 1) {
88 // Run only test with specific name.
89 run_filter = argv[argc - 1];
90 }
91
92 TestCaseBase::RunAll();
93
94 // Print a warning message if no tests or benchmarks were matched.
95 if (run_matches == 0) {
96 Syslog::PrintErr("No tests matched: %s\n", run_filter);
97 return 1;
98 }
99 if (Expect::failed()) {
100 Syslog::PrintErr(
101 "Some tests failed. Run the following command to update "
102 "expectations.\ntools/test.py --vm-options=--update ffi_unit");
103 return 255;
104 }
105
106 return 0;
107}
char ** argv
Definition library.h:9
static const char * run_filter
static constexpr const char * kList

◆ NativeCallbackFunction()

FunctionPtr dart::compiler::ffi::NativeCallbackFunction ( const FunctionType c_signature,
const Function dart_target,
const Instance exceptional_return,
FfiCallbackKind  kind 
)

Definition at line 36 of file callback.cc.

39 {
40 Thread* const thread = Thread::Current();
41 Zone* const zone = thread->zone();
42 Function& function = Function::Handle(zone);
43 ASSERT(c_signature.IsCanonical());
44 ASSERT(exceptional_return.IsSmi() || exceptional_return.IsCanonical());
45
46 // Create a new Function named '<target>_FfiCallback' and stick it in the
47 // 'dart:ffi' library. Note that these functions will never be invoked by
48 // Dart, so they may have duplicate names.
49 const auto& name =
50 NativeCallbackFunctionName(thread, zone, dart_target, kind);
51 const Library& lib = Library::Handle(zone, Library::FfiLibrary());
52 const Class& owner_class = Class::Handle(zone, lib.toplevel_class());
53 auto& signature = FunctionType::Handle(zone, FunctionType::New());
54 function =
55 Function::New(signature, name, UntaggedFunction::kFfiTrampoline,
56 /*is_static=*/true,
57 /*is_const=*/false,
58 /*is_abstract=*/false,
59 /*is_external=*/false,
60 /*is_native=*/false, owner_class, TokenPosition::kNoSource);
61 function.set_is_debuggable(false);
62
63 // Set callback-specific fields which the flow-graph builder needs to generate
64 // the body.
65 function.SetFfiCSignature(c_signature);
66 function.SetFfiCallbackTarget(dart_target);
67 function.SetFfiCallbackKind(kind);
68
69 // We need to load the exceptional return value as a constant in the generated
70 // function. Even though the FE ensures that it is a constant, it could still
71 // be a literal allocated in new space. We need to copy it into old space in
72 // that case.
73 //
74 // Exceptional return values currently cannot be pointers because we don't
75 // have constant pointers.
76 ASSERT(exceptional_return.IsNull() || exceptional_return.IsNumber() ||
77 exceptional_return.IsBool());
78 if (!exceptional_return.IsSmi() && exceptional_return.IsNew()) {
79 function.SetFfiCallbackExceptionalReturn(Instance::Handle(
80 zone, exceptional_return.CopyShallowToOldSpace(thread)));
81 } else {
82 function.SetFfiCallbackExceptionalReturn(exceptional_return);
83 }
84
85 // The dart type of the FfiCallback has no arguments or type arguments and
86 // has a result type of dynamic, as the callback is never invoked via Dart,
87 // only via native calls that do not use this information. Having no Dart
88 // arguments ensures the scope builder does not add inappropriate parameter
89 // variables.
90 signature.set_result_type(Object::dynamic_type());
91 // Finalize (and thus canonicalize) the signature.
92 signature ^= ClassFinalizer::FinalizeType(signature);
93 function.SetSignature(signature);
94
95 {
96 // Ensure only one thread updates the cache of deduped ffi trampoline
97 // functions.
98 auto isolate_group = thread->isolate_group();
99 SafepointWriteRwLocker ml(thread, isolate_group->program_lock());
100
101 auto object_store = isolate_group->object_store();
102 if (object_store->ffi_callback_functions() == Array::null()) {
104 HashTables::New<FfiCallbackFunctionSet>(/*initial_capacity=*/4));
105 object_store->set_ffi_callback_functions(set.Release());
106 }
107 FfiCallbackFunctionSet set(object_store->ffi_callback_functions());
108
109 const intptr_t entry_count_before = set.NumOccupied();
110 function ^= set.InsertOrGet(function);
111 const intptr_t entry_count_after = set.NumOccupied();
112
113 object_store->set_ffi_callback_functions(set.Release());
114
115 if (entry_count_before != entry_count_after) {
116 function.AssignFfiCallbackId(entry_count_before);
117 } else {
118 ASSERT(function.FfiCallbackId() != -1);
119 }
120 }
121
122 return function.ptr();
123}
InstancePtr CopyShallowToOldSpace(Thread *thread) const
Definition object.cc:20481
ClassPtr toplevel_class() const
Definition object.h:5179
bool IsCanonical() const
Definition object.h:335
bool IsNew() const
Definition object.h:390
bool IsNull() const
Definition object.h:363
Dart_NativeFunction function
Definition fuchsia.cc:51
const char * name
Definition fuchsia.cc:50
const String & NativeCallbackFunctionName(Thread *thread, Zone *zone, const Function &dart_target, FfiCallbackKind kind)
Definition callback.cc:18

◆ NativeCallbackFunctionName()

const String & dart::compiler::ffi::NativeCallbackFunctionName ( Thread thread,
Zone zone,
const Function dart_target,
FfiCallbackKind  kind 
)

Definition at line 18 of file callback.cc.

21 {
22 switch (kind) {
23 case FfiCallbackKind::kAsyncCallback:
24 return Symbols::FfiAsyncCallback();
25 case FfiCallbackKind::kIsolateLocalClosureCallback:
26 return Symbols::FfiIsolateLocalCallback();
27 case FfiCallbackKind::kIsolateLocalStaticCallback:
28 return String::Handle(
29 zone, Symbols::FromConcat(thread, Symbols::FfiCallback(),
30 String::Handle(zone, dart_target.name())));
31 default:
33 }
34}
StringPtr name() const
Definition object.h:2972

◆ NativeFunctionTypeFromFunctionType()

const NativeFunctionType * dart::compiler::ffi::NativeFunctionTypeFromFunctionType ( Zone zone,
const FunctionType c_signature,
const char **  error 
)

Definition at line 34 of file marshaller.cc.

37 {
38 ASSERT(c_signature.NumOptionalParameters() == 0);
39 ASSERT(c_signature.NumOptionalPositionalParameters() == 0);
40 ObjectStore* object_store = IsolateGroup::Current()->object_store();
41
42 const intptr_t num_arguments =
44 auto& argument_representations =
45 *new ZoneGrowableArray<const NativeType*>(zone, num_arguments);
46 AbstractType& arg_type = AbstractType::Handle(zone);
47 intptr_t variadic_arguments_index = NativeFunctionType::kNoVariadicArguments;
48 for (intptr_t i = 0; i < num_arguments; i++) {
49 arg_type = c_signature.ParameterTypeAt(i + kNativeParamsStartAt);
50 const bool varargs = arg_type.type_class() == object_store->varargs_class();
51 if (varargs) {
52 arg_type = TypeArguments::Handle(zone, Type::Cast(arg_type).arguments())
53 .TypeAt(0);
54 variadic_arguments_index = i;
55 ASSERT(arg_type.IsRecordType());
56 const auto& record_type = RecordType::Cast(arg_type);
57 const intptr_t num_fields = record_type.NumFields();
58 auto& field_type = AbstractType::Handle(zone);
59 for (intptr_t i = 0; i < num_fields; i++) {
60 field_type ^= record_type.FieldTypeAt(i);
61 const auto rep = NativeType::FromAbstractType(zone, field_type, error);
62 if (*error != nullptr) {
63 return nullptr;
64 }
65 argument_representations.Add(rep);
66 }
67 } else {
68 const auto rep = NativeType::FromAbstractType(zone, arg_type, error);
69 if (*error != nullptr) {
70 return nullptr;
71 }
72 argument_representations.Add(rep);
73 }
74 }
75
76 const auto& result_type =
77 AbstractType::Handle(zone, c_signature.result_type());
78 const auto result_representation =
79 NativeType::FromAbstractType(zone, result_type, error);
80 if (*error != nullptr) {
81 return nullptr;
82 }
83
84 const auto result = new (zone)
85 NativeFunctionType(argument_representations, *result_representation,
86 variadic_arguments_index);
87 return result;
88}
virtual ClassPtr type_class() const
Definition object.cc:21083
AbstractTypePtr ParameterTypeAt(intptr_t index) const
Definition object.cc:8643
AbstractTypePtr result_type() const
Definition object.h:9650
intptr_t NumOptionalPositionalParameters() const
Definition object.h:9614
intptr_t num_fixed_parameters() const
Definition object.h:9575
intptr_t NumOptionalParameters() const
Definition object.h:9605
const intptr_t kNativeParamsStartAt
Definition marshaller.cc:31

◆ NativeLocationToStackSlotAddress()

compiler::Address dart::compiler::ffi::NativeLocationToStackSlotAddress ( const NativeStackLocation loc)

◆ PointerToMemoryResultLocation()

static const NativeLocation & dart::compiler::ffi::PointerToMemoryResultLocation ( Zone zone,
const NativeCompoundType payload_type 
)
static

Definition at line 731 of file native_calling_convention.cc.

733 {
734 const auto& pointer_type = *new (zone) NativePrimitiveType(kAddress);
735 const auto& pointer_location = *new (zone) NativeRegistersLocation(
736 zone, pointer_type, pointer_type,
737 CallingConventions::kPointerToReturnStructRegisterCall);
738 const auto& pointer_return_location = *new (zone) NativeRegistersLocation(
739 zone, pointer_type, pointer_type,
740 CallingConventions::kPointerToReturnStructRegisterReturn);
741 return *new (zone) PointerToMemoryLocation(
742 pointer_location, pointer_return_location, payload_type);
743}

◆ PrimitiveTypeFromSizeInBytes()

PrimitiveType dart::compiler::ffi::PrimitiveTypeFromSizeInBytes ( intptr_t  size)

Definition at line 29 of file native_type.cc.

29 {
30 ASSERT(size <= 8);
31 ASSERT(size > 0);
32 switch (size) {
33 case 1:
34 return kUint8;
35 case 2:
36 return kUint16;
37 case 4:
38 return kUint32;
39 case 8:
40 // Dart unboxed Representation for unsigned and signed is equal.
41 return kInt64;
42 }
44}

◆ PrimitiveTypeToCString()

static const char * dart::compiler::ffi::PrimitiveTypeToCString ( PrimitiveType  rep)
static

Definition at line 668 of file native_type.cc.

668 {
669 switch (rep) {
670 case kInt8:
671 return "int8";
672 case kUint8:
673 return "uint8";
674 case kInt16:
675 return "int16";
676 case kUint16:
677 return "uint16";
678 case kInt32:
679 return "int32";
680 case kUint32:
681 return "uint32";
682 case kInt64:
683 return "int64";
684 case kUint64:
685 return "uint64";
686 case kFloat:
687 return "float";
688 case kDouble:
689 return "double";
690 case kHalfDouble:
691 return "half-double";
692 case kInt24:
693 return "int24";
694 case kUint24:
695 return "uint24";
696 case kInt40:
697 return "int40";
698 case kUint40:
699 return "uint40";
700 case kInt48:
701 return "int48";
702 case kUint48:
703 return "uint48";
704 case kInt56:
705 return "int56";
706 case kUint56:
707 return "uint56";
708 case kVoid:
709 return "void";
710 default:
711 UNREACHABLE();
712 }
713}

◆ PrintRepresentations()

static void dart::compiler::ffi::PrintRepresentations ( BaseTextBuffer f,
const NativeLocation loc 
)
static

Definition at line 277 of file native_location.cc.

277 {
278 f->AddString(" ");
279 loc.container_type().PrintTo(f, /*multi_line=*/false, /*verbose=*/false);
280 if (!loc.container_type().Equals(loc.payload_type())) {
281 f->AddString("[");
282 loc.payload_type().PrintTo(f, /*multi_line=*/false, /*verbose=*/false);
283 f->AddString("]");
284 }
285}
const NativeType & container_type() const
virtual void PrintTo(BaseTextBuffer *f, bool multi_line=false, bool verbose=true) const
virtual bool Equals(const NativeType &other) const

◆ ReadFromFile()

void dart::compiler::ffi::ReadFromFile ( char *  path,
char **  buffer_pointer 
)

Definition at line 31 of file unit_test.cc.

31 {
32 FILE* file = fopen(path, "rb");
33 if (file == nullptr) {
34 Syslog::Print("Error %d \n", errno);
35 return;
36 }
37
38 fseek(file, 0, SEEK_END);
39 size_t size = ftell(file);
40 rewind(file);
41
42 char* buffer = reinterpret_cast<char*>(malloc(sizeof(char) * (size + 1)));
43
44 fread(buffer, 1, size, file);
45 buffer[size] = 0;
46
47 fclose(file);
48 *buffer_pointer = buffer;
49}
static bool rewind(EdgeList *activeEdges, Vertex **current, Vertex *dst, const Comparator &c)
static const uint8_t buffer[]
void * malloc(size_t size)
Definition allocation.cc:19

◆ RecognizedMethodAlignment()

AlignmentType dart::compiler::ffi::RecognizedMethodAlignment ( MethodRecognizer::Kind  kind)

Definition at line 99 of file recognized_method.cc.

99 {
100 switch (kind) {
101#define LOAD_STORE(type) \
102 case MethodRecognizer::kFfiLoad##type: \
103 case MethodRecognizer::kFfiStore##type: \
104 return kAlignedAccess;
107#undef LOAD_STORE
108 case MethodRecognizer::kFfiLoadFloatUnaligned:
109 case MethodRecognizer::kFfiStoreFloatUnaligned:
110 case MethodRecognizer::kFfiLoadDoubleUnaligned:
111 case MethodRecognizer::kFfiStoreDoubleUnaligned:
112 return kUnalignedAccess;
113 default:
114 UNREACHABLE();
115 }
116}
@ kUnalignedAccess
Definition il.h:6721
#define LOAD_STORE(type)

◆ RecognizedMethodTypeArgCid()

classid_t dart::compiler::ffi::RecognizedMethodTypeArgCid ( MethodRecognizer::Kind  kind)

Definition at line 72 of file recognized_method.cc.

72 {
73 switch (kind) {
74#define LOAD_STORE(type) \
75 case MethodRecognizer::kFfiLoad##type: \
76 case MethodRecognizer::kFfiStore##type: \
77 return kFfi##type##Cid;
79#undef LOAD_STORE
80 case MethodRecognizer::kFfiLoadFloatUnaligned:
81 case MethodRecognizer::kFfiStoreFloatUnaligned:
82 return kFfiFloatCid;
83 case MethodRecognizer::kFfiLoadDoubleUnaligned:
84 case MethodRecognizer::kFfiStoreDoubleUnaligned:
85 return kFfiDoubleCid;
86 case MethodRecognizer::kFfiLoadPointer:
87 case MethodRecognizer::kFfiStorePointer:
88 return kPointerCid;
89#define AS_EXTERNAL_TYPED_DATA(type) \
90 case MethodRecognizer::kFfiAsExternalTypedData##type: \
91 return kFfi##type##Cid;
93#undef AS_EXTERNAL_TYPED_DATA
94 default:
96 }
97}
#define AS_EXTERNAL_TYPED_DATA(type)

◆ ResultLocation()

static const NativeLocation & dart::compiler::ffi::ResultLocation ( Zone zone,
const NativeType payload_type,
bool  has_varargs 
)
static

Definition at line 949 of file native_calling_convention.cc.

951 {
952 const auto& payload_type_converted =
953 ConvertIfSoftFp(zone, payload_type, has_varargs, /*is_result*/ true);
954 const auto& container_type = payload_type_converted.Extend(
955 zone, CallingConventions::kReturnRegisterExtension);
956
957 if (container_type.IsFloat()) {
958 return *new (zone) NativeFpuRegistersLocation(
959 payload_type, container_type, CallingConventions::kReturnFpuReg);
960 }
961
962 if (container_type.IsInt() || container_type.IsVoid()) {
963 if (container_type.SizeInBytes() == 8 && target::kWordSize == 4) {
964 return *new (zone) NativeRegistersLocation(
965 zone, payload_type, container_type, CallingConventions::kReturnReg,
966 CallingConventions::kSecondReturnReg);
967 }
968
969 ASSERT(container_type.SizeInBytes() <= target::kWordSize);
970 return *new (zone) NativeRegistersLocation(
971 zone, payload_type, container_type, CallingConventions::kReturnReg);
972 }
973
974 // Compounds are laid out differently per ABI, so they are implemented
975 // per ABI.
976 const auto& compound_type = payload_type.AsCompound();
977 return CompoundResultLocation(zone, compound_type, has_varargs);
978}
const NativeCompoundType & AsCompound() const
static const NativeType & ConvertIfSoftFp(Zone *zone, const NativeType &type, bool has_varargs, bool is_result=false)

◆ RunSignatureTest() [1/2]

const NativeCallingConvention & dart::compiler::ffi::RunSignatureTest ( dart::Zone zone,
const char *  name,
const NativeFunctionType native_signature 
)

Definition at line 14 of file native_calling_convention_test.cc.

17 {
18 const auto& native_calling_convention =
19 NativeCallingConvention::FromSignature(zone, native_signature);
20
21 const char* test_result =
22 native_calling_convention.ToCString(zone, /*multi_line=*/true);
23
24 const int kFilePathLength = 100;
25 char expectation_file_path[kFilePathLength];
26 Utils::SNPrint(expectation_file_path, kFilePathLength,
27 "runtime/vm/compiler/ffi/unit_tests/%s/%s_%s.expect", name,
28 kTargetArchitectureName, kOs);
29
30 if (TestCaseBase::update_expectations) {
31 Syslog::Print("Updating %s\n", expectation_file_path);
32 WriteToFile(expectation_file_path, test_result);
33 }
34
35 char* expectation_file_contents = nullptr;
36 ReadFromFile(expectation_file_path, &expectation_file_contents);
37 EXPECT_NOTNULL(expectation_file_contents);
38 if (expectation_file_contents != nullptr) {
39 EXPECT_STREQ(expectation_file_contents, test_result);
40 free(expectation_file_contents);
41 }
42
43 return native_calling_convention;
44}
void WriteToFile(char *path, const char *contents)
Definition unit_test.cc:20

◆ RunSignatureTest() [2/2]

const NativeCallingConvention & dart::compiler::ffi::RunSignatureTest ( dart::Zone zone,
const char *  name,
const NativeTypes argument_types,
const NativeType return_type 
)

Definition at line 46 of file native_calling_convention_test.cc.

50 {
51 const auto& native_signature =
52 *new (zone) NativeFunctionType(argument_types, return_type);
53
54 return RunSignatureTest(zone, name, native_signature);
55}
const NativeCallingConvention & RunSignatureTest(dart::Zone *zone, const char *name, const NativeFunctionType &native_signature)

◆ RunStructTest()

const NativeCompoundType & dart::compiler::ffi::RunStructTest ( dart::Zone zone,
const char *  name,
const NativeTypes member_types,
intptr_t  packing = kMaxInt32 
)

Definition at line 15 of file native_type_test.cc.

18 {
19 const auto& struct_type =
20 NativeStructType::FromNativeTypes(zone, member_types, packing);
21
22 const char* test_result = struct_type.ToCString(zone, /*multi_line=*/true);
23
24 const int kFilePathLength = 100;
25 char expectation_file_path[kFilePathLength];
26 Utils::SNPrint(expectation_file_path, kFilePathLength,
27 "runtime/vm/compiler/ffi/unit_tests/%s/%s_%s.expect", name,
28 kTargetArchitectureName, kOs);
29
30 if (TestCaseBase::update_expectations) {
31 Syslog::Print("Updating %s\n", expectation_file_path);
32 WriteToFile(expectation_file_path, test_result);
33 }
34
35 char* expectation_file_contents = nullptr;
36 ReadFromFile(expectation_file_path, &expectation_file_contents);
37 EXPECT_NOTNULL(expectation_file_contents);
38 if (expectation_file_contents != nullptr) {
39 EXPECT_STREQ(expectation_file_contents, test_result);
40 free(expectation_file_contents);
41 }
42
43 return struct_type;
44}

◆ SelectFpuLocationInIL()

static Location dart::compiler::ffi::SelectFpuLocationInIL ( Zone zone,
const NativeLocation location 
)
static

Definition at line 585 of file marshaller.cc.

586 {
587 ASSERT((location.IsFpuRegisters()));
588#if defined(TARGET_ARCH_ARM)
589 // Only pin FPU register if it is the lowest bits.
590 const auto& fpu_loc = location.AsFpuRegisters();
591 if (fpu_loc.IsLowestBits()) {
592 return fpu_loc.WidenToQFpuRegister(zone).AsLocation();
593 }
594 return Location::Any();
595#endif // defined(TARGET_ARCH_ARM)
596
597 return location.AsLocation();
598}
virtual Location AsLocation() const
const NativeFpuRegistersLocation & AsFpuRegisters() const

◆ SelectRepresentationInIL()

static Representation dart::compiler::ffi::SelectRepresentationInIL ( Zone zone,
const NativeLocation location 
)
static

Definition at line 422 of file marshaller.cc.

423 {
424 if (location.container_type().IsInt() && location.payload_type().IsFloat()) {
425 // IL can only pass integers to integer Locations, so pass as integer if
426 // the Location requires it to be an integer.
427 return location.container_type().AsRepresentationOverApprox(zone);
428 }
429 // Representations do not support 8 or 16 bit ints, over approximate to 32
430 // bits.
431 return location.payload_type().AsRepresentationOverApprox(zone);
432}
Representation AsRepresentationOverApprox(Zone *zone_) const
virtual bool IsInt() const
Definition native_type.h:89
virtual bool IsFloat() const
Definition native_type.h:90

◆ SetFfiCallbackCode()

void dart::compiler::ffi::SetFfiCallbackCode ( Thread thread,
const Function ffi_trampoline,
const Code code 
)

Definition at line 148 of file callback.cc.

150 {
151 auto zone = thread->zone();
152
153 const intptr_t callback_id = ffi_trampoline.FfiCallbackId();
154 EnsureFfiCallbackMetadata(thread, callback_id);
155
156 auto object_store = thread->isolate_group()->object_store();
157 const auto& code_array =
158 GrowableObjectArray::Handle(zone, object_store->ffi_callback_code());
159 code_array.SetAt(callback_id, code);
160}
int32_t FfiCallbackId() const
Definition object.cc:8390
static void EnsureFfiCallbackMetadata(Thread *thread, intptr_t callback_id)
Definition callback.cc:125

◆ SizeFromFpuRegisterKind()

intptr_t dart::compiler::ffi::SizeFromFpuRegisterKind ( enum FpuRegisterKind  kind)

Definition at line 379 of file native_location.cc.

379 {
380 switch (kind) {
381 case kQuadFpuReg:
382 return 16;
383 case kDoubleFpuReg:
384 return 8;
385 case kSingleFpuReg:
386 return 4;
387 }
388 UNREACHABLE();
389}

◆ SoftFpAbi()

static bool dart::compiler::ffi::SoftFpAbi ( bool  has_varargs,
bool  is_result 
)
static

Definition at line 26 of file native_calling_convention.cc.

26 {
27#if defined(TARGET_ARCH_ARM)
28 if (has_varargs) {
29 return true;
30 }
31 return !TargetCPUFeatures::hardfp_supported();
32#elif defined(TARGET_ARCH_ARM64) && defined(DART_TARGET_OS_WINDOWS)
33 return has_varargs && !is_result;
34#else
35 return false;
36#endif
37}

◆ split_fundamental()

static PrimitiveType dart::compiler::ffi::split_fundamental ( PrimitiveType  in)
static

Definition at line 375 of file native_type.cc.

375 {
376 switch (in) {
377 case kInt16:
378 return kInt8;
379 case kInt32:
380 return kInt16;
381 case kInt64:
382 return kInt32;
383 case kUint16:
384 return kUint8;
385 case kUint32:
386 return kUint16;
387 case kUint64:
388 return kUint32;
389 case kDouble:
390 return kHalfDouble;
391 default:
392 UNREACHABLE();
393 }
394}

◆ TargetAbi()

Abi dart::compiler::ffi::TargetAbi ( )

Definition at line 88 of file abi.cc.

88 {
89 return Abi::ABI_ENUM_VALUE3;
90}

◆ TypeForSize()

static PrimitiveType dart::compiler::ffi::TypeForSize ( intptr_t  size)
static

Definition at line 72 of file native_calling_convention.cc.

72 {
73 switch (size) {
74 case 8:
75 return kUint64;
76 case 7:
77 return kUint56;
78 case 6:
79 return kUint48;
80 case 5:
81 return kUint40;
82 case 4:
83 return kUint32;
84 case 3:
85 return kUint24;
86 case 2:
87 return kUint16;
88 case 1:
89 return kUint8;
90 default:
92 return kVoid;
93 }
94}

◆ TypeRepresentation()

static PrimitiveType dart::compiler::ffi::TypeRepresentation ( classid_t  class_id)
static

Definition at line 403 of file native_type.cc.

403 {
404 switch (class_id) {
405 case kFfiInt8Cid:
406 return kInt8;
407 case kFfiInt16Cid:
408 return kInt16;
409 case kFfiInt32Cid:
410 return kInt32;
411 case kFfiBoolCid:
412 case kFfiUint8Cid:
413 return kUint8;
414 case kFfiUint16Cid:
415 return kUint16;
416 case kFfiUint32Cid:
417 return kUint32;
418 case kFfiInt64Cid:
419 case kFfiUint64Cid:
420 return kInt64;
421 case kFfiFloatCid:
422 return kFloat;
423 case kFfiDoubleCid:
424 return kDouble;
425 case kPointerCid:
426 case kFfiHandleCid:
427 return kAddress;
428 case kFfiVoidCid:
429 return kVoid;
430 default:
431 UNREACHABLE();
432 }
433}
constexpr PrimitiveType kAddress

◆ UNIT_TEST_CASE_WITH_ZONE() [1/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCallingConvention_doublex20  )

Definition at line 103 of file native_calling_convention_test.cc.

103 {
104 const auto& doubleType = *new (Z) NativePrimitiveType(kDouble);
105
106 auto& arguments = *new (Z) NativeTypes(Z, 20);
107 arguments.Add(&doubleType);
108 arguments.Add(&doubleType);
109 arguments.Add(&doubleType);
110 arguments.Add(&doubleType);
111 arguments.Add(&doubleType);
112 arguments.Add(&doubleType);
113 arguments.Add(&doubleType);
114 arguments.Add(&doubleType);
115 arguments.Add(&doubleType);
116 arguments.Add(&doubleType);
117 arguments.Add(&doubleType);
118 arguments.Add(&doubleType);
119 arguments.Add(&doubleType);
120 arguments.Add(&doubleType);
121 arguments.Add(&doubleType);
122 arguments.Add(&doubleType);
123 arguments.Add(&doubleType);
124 arguments.Add(&doubleType);
125 arguments.Add(&doubleType);
126 arguments.Add(&doubleType);
127
128 RunSignatureTest(Z, "doublex20", arguments, doubleType);
129}

◆ UNIT_TEST_CASE_WITH_ZONE() [2/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCallingConvention_floatx20  )

Definition at line 75 of file native_calling_convention_test.cc.

75 {
76 const auto& floatType = *new (Z) NativePrimitiveType(kFloat);
77
78 auto& arguments = *new (Z) NativeTypes(Z, 20);
79 arguments.Add(&floatType);
80 arguments.Add(&floatType);
81 arguments.Add(&floatType);
82 arguments.Add(&floatType);
83 arguments.Add(&floatType);
84 arguments.Add(&floatType);
85 arguments.Add(&floatType);
86 arguments.Add(&floatType);
87 arguments.Add(&floatType);
88 arguments.Add(&floatType);
89 arguments.Add(&floatType);
90 arguments.Add(&floatType);
91 arguments.Add(&floatType);
92 arguments.Add(&floatType);
93 arguments.Add(&floatType);
94 arguments.Add(&floatType);
95 arguments.Add(&floatType);
96 arguments.Add(&floatType);
97 arguments.Add(&floatType);
98 arguments.Add(&floatType);
99
100 RunSignatureTest(Z, "floatx20", arguments, floatType);
101}

◆ UNIT_TEST_CASE_WITH_ZONE() [3/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCallingConvention_int8x10  )

Definition at line 57 of file native_calling_convention_test.cc.

57 {
58 const auto& int8type = *new (Z) NativePrimitiveType(kInt8);
59
60 auto& arguments = *new (Z) NativeTypes(Z, 10);
61 arguments.Add(&int8type);
62 arguments.Add(&int8type);
63 arguments.Add(&int8type);
64 arguments.Add(&int8type);
65 arguments.Add(&int8type);
66 arguments.Add(&int8type);
67 arguments.Add(&int8type);
68 arguments.Add(&int8type);
69 arguments.Add(&int8type);
70 arguments.Add(&int8type);
71
72 RunSignatureTest(Z, "int8x10", arguments, int8type);
73}

◆ UNIT_TEST_CASE_WITH_ZONE() [4/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCallingConvention_mixedx20  )

Definition at line 131 of file native_calling_convention_test.cc.

131 {
132#if defined(TARGET_ARCH_IS_32_BIT)
133 const auto& intptrType = *new (Z) NativePrimitiveType(kInt32);
134#elif defined(TARGET_ARCH_IS_64_BIT)
135 const auto& intptrType = *new (Z) NativePrimitiveType(kInt64);
136#endif
137 const auto& floatType = *new (Z) NativePrimitiveType(kFloat);
138 const auto& doubleType = *new (Z) NativePrimitiveType(kDouble);
139
140 auto& arguments = *new (Z) NativeTypes(Z, 20);
141 arguments.Add(&intptrType);
142 arguments.Add(&floatType);
143 arguments.Add(&intptrType);
144 arguments.Add(&doubleType);
145 arguments.Add(&intptrType);
146 arguments.Add(&floatType);
147 arguments.Add(&intptrType);
148 arguments.Add(&doubleType);
149 arguments.Add(&intptrType);
150 arguments.Add(&floatType);
151 arguments.Add(&intptrType);
152 arguments.Add(&doubleType);
153 arguments.Add(&intptrType);
154 arguments.Add(&floatType);
155 arguments.Add(&intptrType);
156 arguments.Add(&doubleType);
157 arguments.Add(&intptrType);
158 arguments.Add(&floatType);
159 arguments.Add(&intptrType);
160 arguments.Add(&doubleType);
161
162 RunSignatureTest(Z, "mixedx20", arguments, doubleType);
163}

◆ UNIT_TEST_CASE_WITH_ZONE() [5/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCallingConvention_regress46127  )

Definition at line 653 of file native_calling_convention_test.cc.

653 {
654 const auto& uint64_type = *new (Z) NativePrimitiveType(kUint64);
655
656 auto& member_types = *new (Z) NativeTypes(Z, 1);
657 member_types.Add(&uint64_type);
658 const auto& struct_type = NativeStructType::FromNativeTypes(Z, member_types);
659
660 EXPECT_EQ(8, struct_type.SizeInBytes());
661
662 auto& arguments = *new (Z) NativeTypes(Z, 0);
663
664 const auto& native_calling_convention =
665 RunSignatureTest(Z, "regress46127", arguments, struct_type);
666
667#if defined(TARGET_ARCH_IA32) && \
668 (defined(DART_TARGET_OS_ANDROID) || defined(DART_TARGET_OS_LINUX))
669 // We must count the result pointer passed on the stack as well.
670 EXPECT_EQ(4, native_calling_convention.StackTopInBytes());
671#else
672 EXPECT_EQ(0, native_calling_convention.StackTopInBytes());
673#endif
674}

◆ UNIT_TEST_CASE_WITH_ZONE() [6/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCallingConvention_regress49460  )

Definition at line 889 of file native_calling_convention_test.cc.

889 {
890 const auto& int32_type = *new (Z) NativePrimitiveType(kInt32);
891 const auto& int64_type = *new (Z) NativePrimitiveType(kInt64);
892#if defined(TARGET_ARCH_IS_32_BIT)
893 const auto& intptr_type = *new (Z) NativePrimitiveType(kInt32);
894#elif defined(TARGET_ARCH_IS_64_BIT)
895 const auto& intptr_type = *new (Z) NativePrimitiveType(kInt64);
896#endif
897
898 auto& arguments = *new (Z) NativeTypes(Z, 3);
899 arguments.Add(&int32_type);
900 arguments.Add(&int64_type);
901 arguments.Add(&intptr_type); // pointer
902
903 const auto& native_signature = *new (Z) NativeFunctionType(
904 arguments, int32_type, /*variadic_arguments_index=*/2);
905
906 RunSignatureTest(Z, "regress49460", native_signature);
907}

◆ UNIT_TEST_CASE_WITH_ZONE() [7/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCallingConvention_regress_fuchsia105336  )

Definition at line 717 of file native_calling_convention_test.cc.

717 {
718#if defined(TARGET_ARCH_IS_32_BIT)
719 const auto& intptr_type = *new (Z) NativePrimitiveType(kInt32);
720#elif defined(TARGET_ARCH_IS_64_BIT)
721 const auto& intptr_type = *new (Z) NativePrimitiveType(kInt64);
722#endif
723 const auto& double_type = *new (Z) NativePrimitiveType(kDouble);
724 const auto& int32_type = *new (Z) NativePrimitiveType(kInt32);
725 const auto& void_type = *new (Z) NativePrimitiveType(kVoid);
726
727 auto& arguments = *new (Z) NativeTypes(Z, 6);
728 arguments.Add(&intptr_type);
729 arguments.Add(&double_type);
730 arguments.Add(&int32_type);
731 arguments.Add(&double_type);
732 arguments.Add(&int32_type);
733 arguments.Add(&intptr_type); // pointer
734 arguments.Add(&intptr_type); // pointer
735
736 RunSignatureTest(Z, "regress_fuchsia105336", arguments, void_type);
737}

◆ UNIT_TEST_CASE_WITH_ZONE() [8/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCallingConvention_stradle_last_register  )

Definition at line 913 of file native_calling_convention_test.cc.

913 {
914#if defined(TARGET_ARCH_IS_32_BIT)
915 const auto& intptr_type = *new (Z) NativePrimitiveType(kInt32);
916 const auto& halfptr_type = *new (Z) NativePrimitiveType(kInt16);
917#elif defined(TARGET_ARCH_IS_64_BIT)
918 const auto& intptr_type = *new (Z) NativePrimitiveType(kInt64);
919 const auto& halfptr_type = *new (Z) NativePrimitiveType(kInt32);
920#endif
921
922 auto& member_types = *new (Z) NativeTypes(Z, 3);
923 member_types.Add(&halfptr_type);
924 member_types.Add(&halfptr_type);
925 member_types.Add(&halfptr_type);
926 const auto& struct_type = NativeStructType::FromNativeTypes(Z, member_types);
927
928 auto& arguments = *new (Z) NativeTypes(Z, CallingConventions::kNumArgRegs);
929 for (intptr_t i = 1; i < CallingConventions::kNumArgRegs; i++) {
930 arguments.Add(&intptr_type);
931 }
932 arguments.Add(&struct_type);
933
934 const auto& native_signature =
935 *new (Z) NativeFunctionType(arguments, intptr_type);
936
937 RunSignatureTest(Z, "stradle_last_register", native_signature);
938}

◆ UNIT_TEST_CASE_WITH_ZONE() [9/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCallingConvention_struct128bytesx1  )

Definition at line 347 of file native_calling_convention_test.cc.

347 {
348 const auto& int32_type = *new (Z) NativePrimitiveType(kInt32);
349 const auto& int64_type = *new (Z) NativePrimitiveType(kInt64);
350
351 auto& member_types = *new (Z) NativeTypes(Z, 16);
352 member_types.Add(&int64_type);
353 member_types.Add(&int64_type);
354 member_types.Add(&int64_type);
355 member_types.Add(&int64_type);
356 member_types.Add(&int64_type);
357 member_types.Add(&int64_type);
358 member_types.Add(&int64_type);
359 member_types.Add(&int64_type);
360 member_types.Add(&int64_type);
361 member_types.Add(&int64_type);
362 member_types.Add(&int64_type);
363 member_types.Add(&int64_type);
364 member_types.Add(&int64_type);
365 member_types.Add(&int64_type);
366 member_types.Add(&int64_type);
367 member_types.Add(&int64_type);
368 const auto& struct_type = NativeStructType::FromNativeTypes(Z, member_types);
369
370 auto& arguments = *new (Z) NativeTypes(Z, 2);
371 arguments.Add(&struct_type);
372 arguments.Add(&int32_type); // Check integer register backfilling, if any.
373
374 RunSignatureTest(Z, "struct128bytesx1", arguments, struct_type);
375}

◆ UNIT_TEST_CASE_WITH_ZONE() [10/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCallingConvention_struct12bytesFloatx6  )

Definition at line 681 of file native_calling_convention_test.cc.

681 {
682 const auto& float_type = *new (Z) NativePrimitiveType(kFloat);
683 const auto& int64_type = *new (Z) NativePrimitiveType(kInt64);
684
685 auto& member_types = *new (Z) NativeTypes(Z, 3);
686 member_types.Add(&float_type);
687 member_types.Add(&float_type);
688 member_types.Add(&float_type);
689 const auto& struct_type = NativeStructType::FromNativeTypes(Z, member_types);
690
691#if defined(TARGET_ARCH_ARM64) && \
692 (defined(DART_TARGET_OS_MACOS) || defined(DART_TARGET_OS_MACOS_IOS))
693 EXPECT_EQ(4, struct_type.AlignmentInBytesStack());
694#endif
695
696 auto& arguments = *new (Z) NativeTypes(Z, 6);
697 arguments.Add(&struct_type);
698 arguments.Add(&struct_type);
699 arguments.Add(&struct_type);
700 arguments.Add(&struct_type);
701 arguments.Add(&struct_type);
702 arguments.Add(&struct_type);
703
704 RunSignatureTest(Z, "struct12bytesFloatx6", arguments, int64_type);
705}

◆ UNIT_TEST_CASE_WITH_ZONE() [11/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCallingConvention_struct16bytesHomogenousx10  )

Definition at line 212 of file native_calling_convention_test.cc.

212 {
213 const auto& float_type = *new (Z) NativePrimitiveType(kFloat);
214 const auto& int8type = *new (Z) NativePrimitiveType(kInt8);
215
216 // If passed in FPU registers, uses an even amount of them.
217 auto& member_types = *new (Z) NativeTypes(Z, 4);
218 member_types.Add(&float_type);
219 member_types.Add(&float_type);
220 member_types.Add(&float_type);
221 member_types.Add(&float_type);
222 const auto& struct_type = NativeStructType::FromNativeTypes(Z, member_types);
223
224 auto& arguments = *new (Z) NativeTypes(Z, 13);
225 arguments.Add(&struct_type);
226 arguments.Add(&float_type); // Claim a single FPU register.
227 arguments.Add(&struct_type);
228 arguments.Add(&struct_type);
229 arguments.Add(&struct_type);
230 arguments.Add(&struct_type);
231 arguments.Add(&struct_type);
232 arguments.Add(&struct_type);
233 arguments.Add(&struct_type);
234 arguments.Add(&struct_type);
235 arguments.Add(&float_type); // Check float register back filling, if any.
236 arguments.Add(&int8type); // Check integer register back filling, if any.
237 arguments.Add(&struct_type); // Check stack alignment of struct.
238
239 RunSignatureTest(Z, "struct16bytesHomogenousx10", arguments, struct_type);
240}

◆ UNIT_TEST_CASE_WITH_ZONE() [12/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCallingConvention_struct16bytesHomogenousx10_2  )

Definition at line 247 of file native_calling_convention_test.cc.

247 {
248 const auto& float_type = *new (Z) NativePrimitiveType(kFloat);
249 const auto& int8type = *new (Z) NativePrimitiveType(kInt8);
250
251 const auto& float_1_array_type = *new (Z) NativeArrayType(float_type, 1);
252
253 const auto& float_2_array_type = *new (Z) NativeArrayType(float_type, 2);
254 auto& full_float_member_types = *new (Z) NativeTypes(Z, 1);
255 full_float_member_types.Add(&float_2_array_type);
256 const auto& float_array_struct_type =
257 NativeStructType::FromNativeTypes(Z, full_float_member_types);
258
259 auto& member_types = *new (Z) NativeTypes(Z, 3);
260 member_types.Add(&float_1_array_type);
261 member_types.Add(&float_array_struct_type);
262 member_types.Add(&float_type);
263 const auto& struct_type = NativeStructType::FromNativeTypes(Z, member_types);
264
265 auto& arguments = *new (Z) NativeTypes(Z, 13);
266 arguments.Add(&struct_type);
267 arguments.Add(&float_type); // Claim a single FPU register.
268 arguments.Add(&struct_type);
269 arguments.Add(&struct_type);
270 arguments.Add(&struct_type);
271 arguments.Add(&struct_type);
272 arguments.Add(&struct_type);
273 arguments.Add(&struct_type);
274 arguments.Add(&struct_type);
275 arguments.Add(&struct_type);
276 arguments.Add(&float_type); // Check float register back filling, if any.
277 arguments.Add(&int8type); // Check integer register back filling, if any.
278 arguments.Add(&struct_type); // Check stack alignment of struct.
279
280 // Identical expectation files as previous test, struct contains the same
281 // members, but nested in arrays and nested structs.
282 RunSignatureTest(Z, "struct16bytesHomogenousx10", arguments, struct_type);
283}

◆ UNIT_TEST_CASE_WITH_ZONE() [13/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCallingConvention_struct3bytesx10  )

Definition at line 173 of file native_calling_convention_test.cc.

173 {
174 const auto& int8type = *new (Z) NativePrimitiveType(kInt8);
175
176 auto& member_types = *new (Z) NativeTypes(Z, 3);
177 member_types.Add(&int8type);
178 member_types.Add(&int8type);
179 member_types.Add(&int8type);
180 const auto& struct_type = NativeStructType::FromNativeTypes(Z, member_types);
181
182 auto& arguments = *new (Z) NativeTypes(Z, 10);
183 arguments.Add(&struct_type);
184 arguments.Add(&struct_type);
185 arguments.Add(&struct_type);
186 arguments.Add(&struct_type);
187 arguments.Add(&struct_type);
188 arguments.Add(&struct_type);
189 arguments.Add(&struct_type);
190 arguments.Add(&struct_type);
191 arguments.Add(&struct_type);
192 arguments.Add(&struct_type);
193
194 RunSignatureTest(Z, "struct3bytesx10", arguments, struct_type);
195}

◆ UNIT_TEST_CASE_WITH_ZONE() [14/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCallingConvention_struct8bytesPackedx10  )

Definition at line 533 of file native_calling_convention_test.cc.

533 {
534 const auto& int8_type = *new (Z) NativePrimitiveType(kInt8);
535 const auto& int32_type = *new (Z) NativePrimitiveType(kInt32);
536
537 auto& member_types = *new (Z) NativeTypes(Z, 5);
538 member_types.Add(&int8_type);
539 member_types.Add(&int32_type);
540 member_types.Add(&int8_type);
541 member_types.Add(&int8_type);
542 member_types.Add(&int8_type);
543 const auto& struct_type =
544 NativeStructType::FromNativeTypes(Z, member_types, /*packing=*/1);
545 EXPECT_EQ(8, struct_type.SizeInBytes());
546 EXPECT(struct_type.ContainsUnalignedMembers());
547
548 auto& arguments = *new (Z) NativeTypes(Z, 10);
549 arguments.Add(&struct_type);
550 arguments.Add(&struct_type);
551 arguments.Add(&struct_type);
552 arguments.Add(&struct_type);
553 arguments.Add(&struct_type);
554 arguments.Add(&struct_type);
555 arguments.Add(&struct_type);
556 arguments.Add(&struct_type);
557 arguments.Add(&struct_type);
558 arguments.Add(&struct_type);
559
560 RunSignatureTest(Z, "struct8bytesPackedx10", arguments, struct_type);
561}

◆ UNIT_TEST_CASE_WITH_ZONE() [15/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCallingConvention_struct8bytesx1  )

Definition at line 504 of file native_calling_convention_test.cc.

504 {
505 const auto& int8type = *new (Z) NativePrimitiveType(kInt8);
506
507 auto& member_types = *new (Z) NativeTypes(Z, 4);
508 member_types.Add(&int8type);
509 member_types.Add(&int8type);
510 member_types.Add(&int8type);
511 member_types.Add(&int8type);
512 member_types.Add(&int8type);
513 member_types.Add(&int8type);
514 member_types.Add(&int8type);
515 member_types.Add(&int8type);
516 const auto& struct_type = NativeStructType::FromNativeTypes(Z, member_types);
517
518 auto& arguments = *new (Z) NativeTypes(Z, 1);
519 arguments.Add(&struct_type);
520
521 RunSignatureTest(Z, "struct8bytesx1", arguments, struct_type);
522}

◆ UNIT_TEST_CASE_WITH_ZONE() [16/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCallingConvention_structPacked  )

Definition at line 574 of file native_calling_convention_test.cc.

574 {
575 const auto& int8_type = *new (Z) NativePrimitiveType(kInt8);
576 const auto& int32_type = *new (Z) NativePrimitiveType(kInt32);
577 const auto& double_type = *new (Z) NativePrimitiveType(kDouble);
578
579 auto& member_types = *new (Z) NativeTypes(Z, 2);
580 member_types.Add(&int8_type);
581 member_types.Add(&double_type);
582 const auto& struct_type =
583 NativeStructType::FromNativeTypes(Z, member_types, /*packing=*/1);
584 EXPECT_EQ(9, struct_type.SizeInBytes());
585 EXPECT(struct_type.ContainsUnalignedMembers());
586
587 auto& arguments = *new (Z) NativeTypes(Z, 13);
588 arguments.Add(&struct_type);
589 arguments.Add(&struct_type);
590 arguments.Add(&struct_type);
591 arguments.Add(&struct_type);
592 arguments.Add(&struct_type);
593 arguments.Add(&struct_type);
594 arguments.Add(&struct_type);
595 arguments.Add(&struct_type);
596 arguments.Add(&struct_type);
597 arguments.Add(&struct_type);
598 arguments.Add(&double_type); // Backfilling float registers.
599 arguments.Add(&int32_type); // Backfilling int registers.
600 arguments.Add(&int32_type); // Backfilling int registers.
601
602 RunSignatureTest(Z, "structPacked", arguments, double_type);
603}

◆ UNIT_TEST_CASE_WITH_ZONE() [17/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCallingConvention_union16bytesHomogenousx10  )

Definition at line 294 of file native_calling_convention_test.cc.

294 {
295 const auto& float_type = *new (Z) NativePrimitiveType(kFloat);
296 const auto& int8type = *new (Z) NativePrimitiveType(kInt8);
297
298 const auto& float_array_type = *new (Z) NativeArrayType(float_type, 3);
299
300 auto& struct_member_types = *new (Z) NativeTypes(Z, 4);
301 struct_member_types.Add(&float_type);
302 struct_member_types.Add(&float_type);
303 struct_member_types.Add(&float_type);
304 struct_member_types.Add(&float_type);
305 const auto& struct_type =
306 NativeStructType::FromNativeTypes(Z, struct_member_types);
307
308 auto& member_types = *new (Z) NativeTypes(Z, 2);
309 member_types.Add(&float_array_type);
310 member_types.Add(&struct_type);
311 const auto& union_type = NativeUnionType::FromNativeTypes(Z, member_types);
312
313 EXPECT_EQ(16, union_type.SizeInBytes());
314 EXPECT(union_type.ContainsHomogeneousFloats());
315
316 auto& arguments = *new (Z) NativeTypes(Z, 13);
317 arguments.Add(&union_type);
318 arguments.Add(&union_type);
319 arguments.Add(&union_type);
320 arguments.Add(&union_type);
321 arguments.Add(&union_type);
322 arguments.Add(&union_type);
323 arguments.Add(&union_type);
324 arguments.Add(&union_type);
325 arguments.Add(&union_type);
326 arguments.Add(&int8type); // Check integer register back filling, if any.
327 arguments.Add(&union_type); // Check stack alignment of struct.
328
329 // Identical expectation files as previous test, struct contains the same
330 // members, but nested in arrays and nested structs.
331 RunSignatureTest(Z, "union16bytesHomogenousx10", arguments, union_type);
332}

◆ UNIT_TEST_CASE_WITH_ZONE() [18/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCallingConvention_union5bytesPackedx10  )

Definition at line 614 of file native_calling_convention_test.cc.

614 {
615 const auto& uint8_type = *new (Z) NativePrimitiveType(kUint8);
616 const auto& uint32_type = *new (Z) NativePrimitiveType(kUint32);
617
618 auto& inner_members = *new (Z) NativeTypes(Z, 2);
619 inner_members.Add(&uint8_type);
620 inner_members.Add(&uint32_type);
621 const intptr_t packing = 1;
622 const auto& struct_type =
623 NativeStructType::FromNativeTypes(Z, inner_members, packing);
624
625 const auto& array_type = *new (Z) NativeArrayType(uint8_type, 5);
626
627 auto& member_types = *new (Z) NativeTypes(Z, 2);
628 member_types.Add(&array_type);
629 member_types.Add(&struct_type);
630 const auto& union_type = NativeUnionType::FromNativeTypes(Z, member_types);
631
632 EXPECT_EQ(5, union_type.SizeInBytes());
633 EXPECT_EQ(1, union_type.AlignmentInBytesField());
634
635 auto& arguments = *new (Z) NativeTypes(Z, 10);
636 arguments.Add(&union_type);
637 arguments.Add(&union_type);
638 arguments.Add(&union_type);
639 arguments.Add(&union_type);
640 arguments.Add(&union_type);
641 arguments.Add(&union_type);
642 arguments.Add(&union_type);
643 arguments.Add(&union_type);
644 arguments.Add(&union_type);
645 arguments.Add(&union_type);
646
647 RunSignatureTest(Z, "union5bytesPackedx10", arguments, union_type);
648}

◆ UNIT_TEST_CASE_WITH_ZONE() [19/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCallingConvention_variadic_double  )

Definition at line 767 of file native_calling_convention_test.cc.

767 {
768 const auto& double_type = *new (Z) NativePrimitiveType(kDouble);
769
770 auto& arguments = *new (Z) NativeTypes(Z, 5);
771 arguments.Add(&double_type);
772 arguments.Add(&double_type);
773 arguments.Add(&double_type);
774 arguments.Add(&double_type);
775 arguments.Add(&double_type);
776
777 const auto& native_signature = *new (Z) NativeFunctionType(
778 arguments, double_type, /*variadic_arguments_index=*/1);
779
780 RunSignatureTest(Z, "variadic_double", native_signature);
781}

◆ UNIT_TEST_CASE_WITH_ZONE() [20/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCallingConvention_variadic_int  )

Definition at line 743 of file native_calling_convention_test.cc.

743 {
744#if defined(TARGET_ARCH_IS_32_BIT)
745 const auto& intptr_type = *new (Z) NativePrimitiveType(kInt32);
746#elif defined(TARGET_ARCH_IS_64_BIT)
747 const auto& intptr_type = *new (Z) NativePrimitiveType(kInt64);
748#endif
749
750 auto& arguments = *new (Z) NativeTypes(Z, 5);
751 arguments.Add(&intptr_type);
752 arguments.Add(&intptr_type);
753 arguments.Add(&intptr_type);
754 arguments.Add(&intptr_type);
755 arguments.Add(&intptr_type);
756
757 const auto& native_signature = *new (Z) NativeFunctionType(
758 arguments, intptr_type, /*variadic_arguments_index=*/1);
759
760 RunSignatureTest(Z, "variadic_int", native_signature);
761}

◆ UNIT_TEST_CASE_WITH_ZONE() [21/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCallingConvention_variadic_less_than_word  )

Definition at line 976 of file native_calling_convention_test.cc.

976 {
977#if defined(TARGET_ARCH_IS_32_BIT)
978 const auto& halfptr_type = *new (Z) NativePrimitiveType(kInt16);
979#elif defined(TARGET_ARCH_IS_64_BIT)
980 const auto& halfptr_type = *new (Z) NativePrimitiveType(kInt32);
981#endif
982
983 auto& arguments = *new (Z) NativeTypes(Z, 12);
984 for (intptr_t i = 0; i < 12; i++) {
985 arguments.Add(&halfptr_type);
986 }
987
988 const auto& native_signature = *new (Z) NativeFunctionType(
989 arguments, halfptr_type, /*variadic_arguments_index=*/1);
990
991 RunSignatureTest(Z, "variadic_less_than_word", native_signature);
992}

◆ UNIT_TEST_CASE_WITH_ZONE() [22/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCallingConvention_variadic_register_alignment  )

Definition at line 856 of file native_calling_convention_test.cc.

856 {
857 const auto& double_type = *new (Z) NativePrimitiveType(kDouble);
858
859 auto& member_types = *new (Z) NativeTypes(Z, 4);
860 member_types.Add(&double_type);
861 member_types.Add(&double_type);
862 member_types.Add(&double_type);
863 member_types.Add(&double_type);
864 const auto& struct_type = NativeStructType::FromNativeTypes(Z, member_types);
865
866 auto& arguments = *new (Z) NativeTypes(Z, 13);
867 arguments.Add(&double_type);
868 arguments.Add(&double_type); // Passed in int register pair on RISC-V 32.
869 arguments.Add(
870 &struct_type); // Passed using single integer register on RISC-V 32.
871 arguments.Add(
872 &double_type); // Passed in _aligned_ int register pair on RISC-V 32.
873
874 const auto& native_signature = *new (Z) NativeFunctionType(
875 arguments, double_type, /*variadic_arguments_index=*/1);
876
877 RunSignatureTest(Z, "variadic_register_alignment", native_signature);
878}

◆ UNIT_TEST_CASE_WITH_ZONE() [23/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCallingConvention_variadic_stradle_last_register  )

Definition at line 944 of file native_calling_convention_test.cc.

945 {
946#if defined(TARGET_ARCH_IS_32_BIT)
947 const auto& intptr_type = *new (Z) NativePrimitiveType(kInt32);
948 const auto& halfptr_type = *new (Z) NativePrimitiveType(kInt16);
949#elif defined(TARGET_ARCH_IS_64_BIT)
950 const auto& intptr_type = *new (Z) NativePrimitiveType(kInt64);
951 const auto& halfptr_type = *new (Z) NativePrimitiveType(kInt32);
952#endif
953
954 auto& member_types = *new (Z) NativeTypes(Z, 3);
955 member_types.Add(&halfptr_type);
956 member_types.Add(&halfptr_type);
957 member_types.Add(&halfptr_type);
958 const auto& struct_type = NativeStructType::FromNativeTypes(Z, member_types);
959
960 auto& arguments = *new (Z) NativeTypes(Z, CallingConventions::kNumArgRegs);
961 for (intptr_t i = 1; i < CallingConventions::kNumArgRegs; i++) {
962 arguments.Add(&intptr_type);
963 }
964 arguments.Add(&struct_type);
965
966 const auto& native_signature = *new (Z) NativeFunctionType(
967 arguments, intptr_type, /*variadic_arguments_index=*/1);
968
969 RunSignatureTest(Z, "variadic_stradle_last_register", native_signature);
970}

◆ UNIT_TEST_CASE_WITH_ZONE() [24/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCallingConvention_variadic_with_homogenous_struct  )

Definition at line 815 of file native_calling_convention_test.cc.

816 {
817 const auto& double_type = *new (Z) NativePrimitiveType(kDouble);
818 const auto& float_type = *new (Z) NativePrimitiveType(kFloat);
819 const auto& int64_type = *new (Z) NativePrimitiveType(kInt64);
820 const auto& int32_type = *new (Z) NativePrimitiveType(kInt32);
821
822 auto& member_types = *new (Z) NativeTypes(Z, 3);
823 member_types.Add(&float_type);
824 member_types.Add(&float_type);
825 member_types.Add(&float_type);
826 const auto& struct_type = NativeStructType::FromNativeTypes(Z, member_types);
827
828 auto& arguments = *new (Z) NativeTypes(Z, 13);
829 arguments.Add(&double_type);
830 arguments.Add(&double_type);
831 arguments.Add(&double_type);
832 arguments.Add(&double_type);
833 arguments.Add(&double_type);
834 arguments.Add(&double_type);
835 arguments.Add(&double_type);
836 arguments.Add(&double_type); // Exhaust FPU registers
837 arguments.Add(&float_type); // Misalign stack.
838 arguments.Add(
839 &struct_type); // Homogenous struct, not aligned to wordsize on stack.
840 arguments.Add(&int64_type); // Start varargs.
841 arguments.Add(&int32_type); // Misalign stack again.
842 arguments.Add(
843 &struct_type); // Homogenous struct, aligned to wordsize on stack.
844
845 const auto& native_signature = *new (Z) NativeFunctionType(
846 arguments, double_type, /*variadic_arguments_index=*/11);
847
848 RunSignatureTest(Z, "variadic_with_homogenous_struct", native_signature);
849}

◆ UNIT_TEST_CASE_WITH_ZONE() [25/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCallingConvention_variadic_with_struct  )

Definition at line 787 of file native_calling_convention_test.cc.

787 {
788 const auto& double_type = *new (Z) NativePrimitiveType(kDouble);
789 const auto& float_type = *new (Z) NativePrimitiveType(kFloat);
790
791 auto& member_types = *new (Z) NativeTypes(Z, 5);
792 member_types.Add(&float_type);
793 member_types.Add(&float_type);
794 member_types.Add(&float_type);
795 member_types.Add(&float_type);
796 member_types.Add(&float_type);
797 const auto& struct_type = NativeStructType::FromNativeTypes(Z, member_types);
798
799 auto& arguments = *new (Z) NativeTypes(Z, 3);
800 arguments.Add(&double_type);
801 arguments.Add(&struct_type);
802 arguments.Add(&double_type);
803
804 const auto& native_signature = *new (Z) NativeFunctionType(
805 arguments, double_type, /*variadic_arguments_index=*/1);
806
807 RunSignatureTest(Z, "variadic_with_struct", native_signature);
808}

◆ UNIT_TEST_CASE_WITH_ZONE() [26/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCompoundType_floatarray  )

Definition at line 176 of file native_type_test.cc.

176 {
177 const auto& float_type = *new (Z) NativePrimitiveType(kFloat);
178
179 const auto& inner_array_type = *new (Z) NativeArrayType(float_type, 2);
180
181 auto& inner_struct_members = *new (Z) NativeTypes(Z, 1);
182 inner_struct_members.Add(&inner_array_type);
183 const auto& inner_struct =
184 NativeStructType::FromNativeTypes(Z, inner_struct_members);
185
186 const auto& array_type = *new (Z) NativeArrayType(inner_struct, 2);
187
188 auto& members = *new (Z) NativeTypes(Z, 1);
189 members.Add(&array_type);
190
191 const auto& struct_type = RunStructTest(Z, "struct_floatarray", members);
192
193 EXPECT_EQ(16, struct_type.SizeInBytes());
194 EXPECT(struct_type.ContainsHomogeneousFloats());
195 EXPECT(struct_type.ContainsOnlyFloats(Range::StartAndEnd(0, 8)));
196 EXPECT_EQ(16 / compiler::target::kWordSize,
197 struct_type.NumberOfWordSizeChunksOnlyFloat());
198}
const NativeCompoundType & RunStructTest(dart::Zone *zone, const char *name, const NativeTypes &member_types, intptr_t packing=kMaxInt32)

◆ UNIT_TEST_CASE_WITH_ZONE() [27/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCompoundType_floatx4  )

Definition at line 82 of file native_type_test.cc.

82 {
83 const auto& float_type = *new (Z) NativePrimitiveType(kFloat);
84
85 auto& members = *new (Z) NativeTypes(Z, 4);
86 members.Add(&float_type);
87 members.Add(&float_type);
88 members.Add(&float_type);
89 members.Add(&float_type);
90
91 const auto& struct_type = RunStructTest(Z, "struct_floatx4", members);
92
93 // This is a homogenous float in the arm and arm64 ABIs.
94 //
95 // On Arm64 iOS stack alignment of homogenous floats is not word size see
96 // runtime/vm/compiler/ffi/unit_tests/struct_floatx4/arm64_ios.expect.
97 EXPECT(struct_type.ContainsHomogeneousFloats());
98
99 // On x64, 8-byte parts of the chunks contain only floats and will be passed
100 // in FPU registers.
101 EXPECT(struct_type.ContainsOnlyFloats(Range::StartAndEnd(0, 8)));
102 EXPECT(struct_type.ContainsOnlyFloats(Range::StartAndEnd(8, 16)));
103 EXPECT_EQ(struct_type.SizeInBytes() / compiler::target::kWordSize,
104 struct_type.NumberOfWordSizeChunksOnlyFloat());
105 EXPECT_EQ(0, struct_type.NumberOfWordSizeChunksNotOnlyFloat());
106}

◆ UNIT_TEST_CASE_WITH_ZONE() [28/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCompoundType_int8array  )

Definition at line 157 of file native_type_test.cc.

157 {
158 const auto& int8type = *new (Z) NativePrimitiveType(kInt8);
159 const auto& array_type = *new (Z) NativeArrayType(int8type, 8);
160
161 auto& members = *new (Z) NativeTypes(Z, 1);
162 members.Add(&array_type);
163
164 const auto& struct_type = RunStructTest(Z, "struct_int8array", members);
165
166 EXPECT_EQ(8, struct_type.SizeInBytes());
167 EXPECT(!struct_type.ContainsHomogeneousFloats());
168 EXPECT(!struct_type.ContainsOnlyFloats(Range::StartAndEnd(0, 8)));
169 EXPECT_EQ(0, struct_type.NumberOfWordSizeChunksOnlyFloat());
170 EXPECT_EQ(
171 Utils::RoundUp(struct_type.SizeInBytes(), compiler::target::kWordSize) /
172 compiler::target::kWordSize,
173 struct_type.NumberOfWordSizeChunksNotOnlyFloat());
174}

◆ UNIT_TEST_CASE_WITH_ZONE() [29/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCompoundType_int8x10  )

Definition at line 56 of file native_type_test.cc.

56 {
57 const auto& int8type = *new (Z) NativePrimitiveType(kInt8);
58
59 auto& members = *new (Z) NativeTypes(Z, 10);
60 members.Add(&int8type);
61 members.Add(&int8type);
62 members.Add(&int8type);
63 members.Add(&int8type);
64 members.Add(&int8type);
65 members.Add(&int8type);
66 members.Add(&int8type);
67 members.Add(&int8type);
68 members.Add(&int8type);
69 members.Add(&int8type);
70
71 const auto& struct_type = RunStructTest(Z, "struct_int8x10", members);
72
73 EXPECT(!struct_type.ContainsHomogeneousFloats());
74 EXPECT(!struct_type.ContainsOnlyFloats(Range::StartAndEnd(0, 8)));
75 EXPECT_EQ(0, struct_type.NumberOfWordSizeChunksOnlyFloat());
76 EXPECT_EQ(
77 Utils::RoundUp(struct_type.SizeInBytes(), compiler::target::kWordSize) /
78 compiler::target::kWordSize,
79 struct_type.NumberOfWordSizeChunksNotOnlyFloat());
80}

◆ UNIT_TEST_CASE_WITH_ZONE() [30/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCompoundType_packed  )

Definition at line 200 of file native_type_test.cc.

200 {
201 const auto& uint8_type = *new (Z) NativePrimitiveType(kUint8);
202 const auto& uint16_type = *new (Z) NativePrimitiveType(kUint16);
203
204 auto& members = *new (Z) NativeTypes(Z, 2);
205 members.Add(&uint8_type);
206 members.Add(&uint16_type);
207 const intptr_t packing = 1;
208
209 const auto& struct_type =
210 NativeStructType::FromNativeTypes(Z, members, packing);
211
212 // Should be 3 bytes on every platform.
213 EXPECT_EQ(3, struct_type.SizeInBytes());
214 EXPECT(struct_type.ContainsUnalignedMembers());
215}

◆ UNIT_TEST_CASE_WITH_ZONE() [31/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCompoundType_packed_array  )

Definition at line 217 of file native_type_test.cc.

217 {
218 const auto& uint8_type = *new (Z) NativePrimitiveType(kUint8);
219 const auto& uint16_type = *new (Z) NativePrimitiveType(kUint16);
220
221 auto& inner_members = *new (Z) NativeTypes(Z, 2);
222 inner_members.Add(&uint16_type);
223 inner_members.Add(&uint8_type);
224 const intptr_t packing = 1;
225 const auto& inner_struct_type =
226 NativeStructType::FromNativeTypes(Z, inner_members, packing);
227
228 EXPECT_EQ(3, inner_struct_type.SizeInBytes());
229 // Non-windows x64 considers this struct as all members aligned, even though
230 // its size is not a multiple of its individual member alignment.
231 EXPECT(!inner_struct_type.ContainsUnalignedMembers());
232
233 const auto& array_type = *new (Z) NativeArrayType(inner_struct_type, 2);
234
235 auto& members = *new (Z) NativeTypes(Z, 1);
236 members.Add(&array_type);
237 const auto& struct_type = NativeStructType::FromNativeTypes(Z, members);
238
239 EXPECT_EQ(6, struct_type.SizeInBytes());
240 // Non-windows x64 passes this as a struct with unaligned members, because
241 // the second element of the array contains unaligned members.
242 EXPECT(struct_type.ContainsUnalignedMembers());
243}

◆ UNIT_TEST_CASE_WITH_ZONE() [32/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCompoundType_packed_nested  )

Definition at line 245 of file native_type_test.cc.

245 {
246 const auto& uint8_type = *new (Z) NativePrimitiveType(kUint8);
247 const auto& uint32_type = *new (Z) NativePrimitiveType(kUint32);
248
249 auto& inner_members = *new (Z) NativeTypes(Z, 2);
250 inner_members.Add(&uint32_type);
251 inner_members.Add(&uint8_type);
252 const intptr_t packing = 1;
253 const auto& inner_struct_type =
254 NativeStructType::FromNativeTypes(Z, inner_members, packing);
255
256 EXPECT_EQ(5, inner_struct_type.SizeInBytes());
257 // Non-windows x64 considers this struct as all members aligned, even though
258 // its size is not a multiple of its individual member alignment.
259 EXPECT(!inner_struct_type.ContainsUnalignedMembers());
260
261 auto& members = *new (Z) NativeTypes(Z, 2);
262 members.Add(&uint8_type);
263 members.Add(&inner_struct_type);
264 const auto& struct_type = NativeStructType::FromNativeTypes(Z, members);
265
266 EXPECT_EQ(6, struct_type.SizeInBytes());
267 // Non-windows x64 passes this as a struct with unaligned members, even
268 // though the nested struct itself has all its members aligned in isolation.
269 EXPECT(struct_type.ContainsUnalignedMembers());
270}

◆ UNIT_TEST_CASE_WITH_ZONE() [33/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCompoundType_union_primitive_members  )

Definition at line 291 of file native_type_test.cc.

291 {
292 const auto& float_type = *new (Z) NativePrimitiveType(kFloat);
293
294 const auto& float_array_type = *new (Z) NativeArrayType(float_type, 3);
295
296 auto& struct_member_types = *new (Z) NativeTypes(Z, 4);
297 struct_member_types.Add(&float_type);
298 struct_member_types.Add(&float_type);
299 struct_member_types.Add(&float_type);
300 struct_member_types.Add(&float_type);
301 const auto& struct_type =
302 NativeStructType::FromNativeTypes(Z, struct_member_types);
303
304 auto& member_types = *new (Z) NativeTypes(Z, 2);
305 member_types.Add(&float_array_type);
306 member_types.Add(&struct_type);
307 const auto& union_type = NativeUnionType::FromNativeTypes(Z, member_types);
308
309 EXPECT_EQ(16, union_type.SizeInBytes());
310
311 EXPECT_EQ(4, union_type.NumPrimitiveMembersRecursive());
312 EXPECT(union_type.FirstPrimitiveMember().Equals(float_type));
313 EXPECT(union_type.ContainsHomogeneousFloats());
314
315 EXPECT(!union_type.ContainsUnalignedMembers());
316}

◆ UNIT_TEST_CASE_WITH_ZONE() [34/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCompoundType_union_size  )

Definition at line 272 of file native_type_test.cc.

272 {
273 const auto& uint8_type = *new (Z) NativePrimitiveType(kUint8);
274 const auto& uint32_type = *new (Z) NativePrimitiveType(kUint32);
275
276 const auto& array8_bytes = *new (Z) NativeArrayType(uint32_type, 2);
277 const auto& array9_bytes = *new (Z) NativeArrayType(uint8_type, 9);
278
279 auto& members = *new (Z) NativeTypes(Z, 2);
280 members.Add(&array8_bytes);
281 members.Add(&array9_bytes);
282 const auto& union_type = NativeUnionType::FromNativeTypes(Z, members);
283
284 // The alignment requirements of the first member and the size of the second
285 // member force the size to be rounded up to 12.
286 EXPECT_EQ(12, union_type.SizeInBytes());
287
288 EXPECT(!union_type.ContainsUnalignedMembers());
289}

◆ UNIT_TEST_CASE_WITH_ZONE() [35/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCompoundType_union_unaligned  )

Definition at line 318 of file native_type_test.cc.

318 {
319 const auto& uint8_type = *new (Z) NativePrimitiveType(kUint8);
320 const auto& uint32_type = *new (Z) NativePrimitiveType(kUint32);
321
322 auto& inner_members = *new (Z) NativeTypes(Z, 2);
323 inner_members.Add(&uint8_type);
324 inner_members.Add(&uint32_type);
325 const intptr_t packing = 1;
326 const auto& struct_type =
327 NativeStructType::FromNativeTypes(Z, inner_members, packing);
328
329 const auto& array_type = *new (Z) NativeArrayType(uint8_type, 5);
330
331 auto& member_types = *new (Z) NativeTypes(Z, 2);
332 member_types.Add(&array_type);
333 member_types.Add(&struct_type);
334 const auto& union_type = NativeUnionType::FromNativeTypes(Z, member_types);
335
336 EXPECT_EQ(5, union_type.SizeInBytes());
337 EXPECT_EQ(1, union_type.AlignmentInBytesField());
338
339 EXPECT(union_type.ContainsUnalignedMembers());
340}

◆ UNIT_TEST_CASE_WITH_ZONE() [36/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeCompoundType_VeryLargeStruct  )

Definition at line 133 of file native_type_test.cc.

133 {
134 const auto& intptr_type = *new (Z) NativePrimitiveType(
135 compiler::target::kWordSize == 4 ? kInt32 : kInt64);
136
137 auto& members = *new (Z) NativeTypes(Z, 15);
138 members.Add(new (Z) NativePrimitiveType(kInt8));
139 members.Add(new (Z) NativePrimitiveType(kInt16));
140 members.Add(new (Z) NativePrimitiveType(kInt32));
141 members.Add(new (Z) NativePrimitiveType(kInt64));
142 members.Add(new (Z) NativePrimitiveType(kUint8));
143 members.Add(new (Z) NativePrimitiveType(kUint16));
144 members.Add(new (Z) NativePrimitiveType(kUint32));
145 members.Add(new (Z) NativePrimitiveType(kUint64));
146 members.Add(&intptr_type);
147 members.Add(new (Z) NativePrimitiveType(kDouble));
148 members.Add(new (Z) NativePrimitiveType(kFloat));
149 members.Add(&intptr_type);
150 members.Add(&intptr_type);
151 members.Add(&intptr_type);
152 members.Add(new (Z) NativePrimitiveType(kInt8));
153
154 RunStructTest(Z, "struct_VeryLargeStruct", members);
155}

◆ UNIT_TEST_CASE_WITH_ZONE() [37/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeStackLocation  )

Definition at line 13 of file native_location_test.cc.

13 {
14 const auto& native_type = *new (Z) NativePrimitiveType(kInt8);
15
16 const int kUnalignedStackLocation = 17;
17
18 const auto& native_location = *new (Z) NativeStackLocation(
19 native_type, native_type, SPREG, kUnalignedStackLocation);
20
21 EXPECT_EQ(kUnalignedStackLocation + native_type.SizeInBytes(),
22 native_location.StackTopInBytes());
23}

◆ UNIT_TEST_CASE_WITH_ZONE() [38/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeStackLocation_Equals  )

Definition at line 40 of file native_location_test.cc.

40 {
41 const auto& native_type = *new (Z) NativePrimitiveType(kInt8);
42
43 // Two FPU registers of the same kind and number are equal.
44 {
45 const auto& native_location1 = *new (Z) NativeFpuRegistersLocation(
46 native_type, native_type, kQuadFpuReg,
47 /*fpu_register=*/0);
48
49 const auto& native_location2 = *new (Z) NativeFpuRegistersLocation(
50 native_type, native_type, kQuadFpuReg,
51 /*fpu_register=*/0);
52
53 EXPECT(native_location1.Equals(native_location2));
54 }
55
56 // Two FPU registers with different numbers are NOT equal.
57 {
58 const auto& native_location1 = *new (Z) NativeFpuRegistersLocation(
59 native_type, native_type, kQuadFpuReg,
60 /*fpu_register=*/2);
61
62 const auto& native_location2 = *new (Z) NativeFpuRegistersLocation(
63 native_type, native_type, kQuadFpuReg,
64 /*fpu_register=*/4);
65
66 EXPECT(!native_location1.Equals(native_location2));
67 }
68
69 // Two FPU registers with different kinds are NOT equal.
70 {
71 const auto& native_location1 = *new (Z) NativeFpuRegistersLocation(
72 native_type, native_type, kQuadFpuReg,
73 /*fpu_register=*/3);
74
75 const auto& native_location2 = *new (Z) NativeFpuRegistersLocation(
76 native_type, native_type, kDoubleFpuReg,
77 /*fpu_register=*/3);
78
79 EXPECT(!native_location1.Equals(native_location2));
80 }
81}

◆ UNIT_TEST_CASE_WITH_ZONE() [39/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeStackLocation_Split  )

Definition at line 25 of file native_location_test.cc.

25 {
26 const auto& native_type = *new (Z) NativePrimitiveType(kInt64);
27
28 const auto& native_location =
29 *new (Z) NativeStackLocation(native_type, native_type, SPREG, 0);
30
31 const auto& half_0 = native_location.Split(Z, 2, 0);
32 const auto& half_1 = native_location.Split(Z, 2, 1);
33
34 EXPECT_EQ(0, half_0.offset_in_bytes());
35 EXPECT_EQ(4, half_1.offset_in_bytes());
36}
virtual NativeStackLocation & Split(Zone *zone, intptr_t num_parts, intptr_t index) const

◆ UNIT_TEST_CASE_WITH_ZONE() [40/40]

dart::compiler::ffi::UNIT_TEST_CASE_WITH_ZONE ( NativeType  )

Definition at line 46 of file native_type_test.cc.

46 {
47 const auto& native_type = *new (Z) NativePrimitiveType(kInt8);
48
49 EXPECT_EQ(1, native_type.SizeInBytes());
50 EXPECT(native_type.IsInt());
51 EXPECT(native_type.IsPrimitive());
52
53 EXPECT_STREQ("int8", native_type.ToCString(Z));
54}

◆ WriteToFile()

void dart::compiler::ffi::WriteToFile ( char *  path,
const char *  contents 
)

Definition at line 20 of file unit_test.cc.

20 {
21 FILE* file;
22 file = fopen(path, "w");
23 if (file != nullptr) {
24 fprintf(file, "%s", contents);
25 } else {
26 Syslog::Print("Error %d \n", errno);
27 }
28 fclose(file);
29}

Variable Documentation

◆ fundamental_size_in_bytes

const intptr_t dart::compiler::ffi::fundamental_size_in_bytes[kVoid+1]
static
Initial value:
= {
1,
1,
2,
2,
4,
4,
8,
8,
4,
8,
4,
3,
3,
5,
5,
6,
6,
7,
7,
0,
}

Definition at line 127 of file native_type.cc.

127 {
128 1, // kInt8,
129 1, // kUint8,
130 2, // kInt16,
131 2, // kUint16,
132 4, // kInt32,
133 4, // kUint32,
134 8, // kInt64,
135 8, // kUint64,
136 4, // kFloat,
137 8, // kDouble,
138 4, // kHalfDouble
139 3, // kInt24,
140 3, // kUint24,
141 5, // kInt40,
142 5, // kUint40,
143 6, // kInt48,
144 6, // kUint48,
145 7, // kInt56,
146 7, // kUint56,
147 0, // kVoid,
148};

◆ kAddress

constexpr PrimitiveType dart::compiler::ffi::kAddress = kInt64
constexpr

Definition at line 210 of file native_type.h.

◆ kAfterLastArgumentIndex

const intptr_t dart::compiler::ffi::kAfterLastArgumentIndex = kIntptrMax

Definition at line 693 of file marshaller.cc.

◆ kAll

constexpr const char* dart::compiler::ffi::kAll = "Run all Tests"
staticconstexpr

Definition at line 22 of file run_ffi_unit_tests.cc.

◆ kArch

const char* dart::compiler::ffi::kArch
extern

◆ kCommandAll

constexpr const char* dart::compiler::ffi::kCommandAll = "--all"
staticconstexpr

Definition at line 25 of file run_ffi_unit_tests.cc.

◆ kCommandList

constexpr const char* dart::compiler::ffi::kCommandList = "--list"
staticconstexpr

Definition at line 26 of file run_ffi_unit_tests.cc.

◆ kCommandUpdate

constexpr const char* dart::compiler::ffi::kCommandUpdate = "--update"
staticconstexpr

Definition at line 27 of file run_ffi_unit_tests.cc.

◆ kList

constexpr const char* dart::compiler::ffi::kList = "List all Tests"
staticconstexpr

Definition at line 21 of file run_ffi_unit_tests.cc.

◆ kNativeParamsStartAt

const intptr_t dart::compiler::ffi::kNativeParamsStartAt = 1

Definition at line 31 of file marshaller.cc.

◆ kNoFpuRegister

const intptr_t dart::compiler::ffi::kNoFpuRegister = -1

Definition at line 21 of file native_calling_convention.cc.

◆ kNone

constexpr const char* dart::compiler::ffi::kNone = "No Test"
staticconstexpr

Definition at line 20 of file run_ffi_unit_tests.cc.

◆ kOffsetInBytesIndex

const intptr_t dart::compiler::ffi::kOffsetInBytesIndex = 1
static

Definition at line 478 of file marshaller.cc.

◆ kOs

const char * dart::compiler::ffi::kOs = kTargetOperatingSystemName

Definition at line 17 of file unit_test.cc.

◆ kResultIndex

const intptr_t dart::compiler::ffi::kResultIndex = -1

Definition at line 28 of file marshaller.h.

◆ kTypedDataBaseIndex

const intptr_t dart::compiler::ffi::kTypedDataBaseIndex = 0
static

Definition at line 477 of file marshaller.cc.

◆ num_abis

const int64_t dart::compiler::ffi::num_abis = static_cast<int64_t>(Abi::kWindowsX64) + 1

Definition at line 47 of file abi.h.

◆ run_filter

const char* dart::compiler::ffi::run_filter = kNone
static

Definition at line 23 of file run_ffi_unit_tests.cc.

◆ run_matches

int dart::compiler::ffi::run_matches = 0
static

Definition at line 29 of file run_ffi_unit_tests.cc.

◆ target_abi_name

const char * dart::compiler::ffi::target_abi_name
Initial value:
=
kTargetOperatingSystemName "_" kTargetArchitectureName

Definition at line 92 of file abi.cc.