Welcome to mirror list, hosted at ThFree Co, Russian Federation.

MarshalHelpers.Aot.cs « IL « Interop « TypeSystem « Common « tools « coreclr « src - github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: b047f29e9ec64f24f9ce82a8c41a20cf1c2308ec (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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;

using Internal.IL;
using Internal.IL.Stubs;

using Debug = System.Diagnostics.Debug;

namespace Internal.TypeSystem.Interop
{
    public static partial class MarshalHelpers
    {
        public static bool IsStructMarshallingRequired(TypeDesc typeDesc)
        {
            if (typeDesc is ByRefType)
            {
                typeDesc = typeDesc.GetParameterType();
            }

            typeDesc = typeDesc.UnderlyingType;

            // TODO: There are primitive types which require marshalling, such as bool, char.
            if (typeDesc.IsPrimitive)
            {
                return false;
            }

            MetadataType type = typeDesc as MetadataType;
            if (type == null)
            {
                return false;
            }

            //
            // For struct marshalling it is required to have either Sequential
            // or Explicit layout. For Auto layout the P/Invoke marshalling code
            // will throw appropriate error message.
            //
            if (!type.HasLayout())
                return false;

            if (!type.IsValueType)
                return true;

            // If it is not blittable we will need struct marshalling
            return !MarshalUtils.IsBlittableType(type);
        }

        internal static TypeDesc GetNativeMethodParameterType(TypeDesc type, MarshalAsDescriptor marshalAs, InteropStateManager interopStateManager, bool isReturn, bool isAnsi)
        {
            MarshallerKind elementMarshallerKind;
            MarshallerKind marshallerKind = MarshalHelpers.GetMarshallerKind(type,
                                                null,   /* parameterIndex */
                                                null,   /* customModifierData */
                                                marshalAs,
                                                isReturn,
                                                isAnsi,
                                                MarshallerType.Argument,
                                                out elementMarshallerKind);

            return GetNativeTypeFromMarshallerKind(type,
                marshallerKind,
                elementMarshallerKind,
                interopStateManager,
                marshalAs);
        }

        internal static TypeDesc GetNativeStructFieldType(TypeDesc type, MarshalAsDescriptor marshalAs, InteropStateManager interopStateManager, bool isAnsi)
        {
            MarshallerKind elementMarshallerKind;
            MarshallerKind marshallerKind = MarshalHelpers.GetMarshallerKind(type,
                                                null,   /* parameterIndex */
                                                null,   /* customModifierData */
                                                marshalAs,
                                                false,  /*  isReturn */
                                                isAnsi, /*    isAnsi */
                                                MarshallerType.Field,
                                                out elementMarshallerKind);

            return GetNativeTypeFromMarshallerKind(type,
                marshallerKind,
                elementMarshallerKind,
                interopStateManager,
                marshalAs);
        }

        internal static InlineArrayCandidate GetInlineArrayCandidate(TypeDesc managedElementType, MarshallerKind elementMarshallerKind, InteropStateManager interopStateManager, MarshalAsDescriptor marshalAs)
        {
            TypeDesc nativeType = GetNativeTypeFromMarshallerKind(
                                                managedElementType,
                                                elementMarshallerKind,
                                                MarshallerKind.Unknown,
                                                interopStateManager,
                                                null);

            var elementNativeType = nativeType as MetadataType;
            if (elementNativeType == null)
            {
                Debug.Assert(nativeType.IsPointer || nativeType.IsFunctionPointer);

                // If it is a pointer type we will create InlineArray for IntPtr
                elementNativeType = (MetadataType)managedElementType.Context.GetWellKnownType(WellKnownType.IntPtr);
            }
            Debug.Assert(marshalAs != null && marshalAs.SizeConst.HasValue);

            // if SizeConst is not specified, we will default to 1.
            // the marshaller will throw appropriate exception
            uint size = 1;
            if (marshalAs.SizeConst.HasValue)
            {
                size = marshalAs.SizeConst.Value;
            }
            return new InlineArrayCandidate(elementNativeType, size);

        }

        //TODO: https://github.com/dotnet/corert/issues/2675
        // This exception messages need to localized
        // TODO: Log as warning
        public static MethodIL EmitExceptionBody(string message, MethodDesc method)
        {
            ILEmitter emitter = new ILEmitter();

            TypeSystemContext context = method.Context;
            MethodSignature ctorSignature = new MethodSignature(0, 0, context.GetWellKnownType(WellKnownType.Void),
                new TypeDesc[] { context.GetWellKnownType(WellKnownType.String) });
            MethodDesc exceptionCtor = InteropTypes.GetMarshalDirectiveException(context).GetKnownMethod(".ctor", ctorSignature);

            ILCodeStream codeStream = emitter.NewCodeStream();
            codeStream.Emit(ILOpcode.ldstr, emitter.NewToken(message));
            codeStream.Emit(ILOpcode.newobj, emitter.NewToken(exceptionCtor));
            codeStream.Emit(ILOpcode.throw_);

            return new PInvokeILStubMethodIL((ILStubMethodIL)emitter.Link(method), isStubRequired: true);
        }
    }
}