blob: 33c609ee23b8072ee5f884a1b4fb57213d4a5185 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
namespace Internal.TypeSystem.Interop
{
public static class MarshalUtils
{
/// <summary>
/// Returns true if this type has a common representation in both managed and unmanaged memory
/// and does not require special handling by the interop marshaler.
/// </summary>
public static bool IsBlittableType(TypeDesc type)
{
if (!type.IsDefType)
{
return false;
}
DefType baseType = type.BaseType;
bool hasNonTrivialParent = baseType != null
&& !baseType.IsWellKnownType(WellKnownType.Object)
&& !baseType.IsWellKnownType(WellKnownType.ValueType);
// Type is blittable only if parent is also blittable.
if (hasNonTrivialParent && !IsBlittableType(baseType))
{
return false;
}
var mdType = (MetadataType)type;
if (!mdType.IsSequentialLayout && !mdType.IsExplicitLayout)
{
return false;
}
foreach (FieldDesc field in type.GetFields())
{
if (field.IsStatic)
{
continue;
}
MarshallerKind marshallerKind = MarshalHelpers.GetMarshallerKind(
field.FieldType,
parameterIndex : null,
customModifierData: null,
field.GetMarshalAsDescriptor(),
isReturn: false,
isAnsi: mdType.PInvokeStringFormat == PInvokeStringFormat.AnsiClass,
MarshallerType.Field,
elementMarshallerKind: out var _);
if (marshallerKind != MarshallerKind.Enum
&& marshallerKind != MarshallerKind.BlittableValue
&& marshallerKind != MarshallerKind.BlittableStruct
&& marshallerKind != MarshallerKind.UnicodeChar)
{
return false;
}
}
return true;
}
}
}
|