| File: parent\parent\Common\TypeSystem\Interop\IL\MarshalHelpers.Aot.cs | Web Access |
| Project: ILCompiler.Compiler.csproj (ILCompiler.Compiler) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. 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; if (typeDesc.IsPrimitive) { return typeDesc.Category is TypeFlags.Boolean or TypeFlags.Char; } MetadataType type = typeDesc as MetadataType; if (type == null) { return false; } // // For struct marshalling it is required to not have Auto layout. // For Auto layout the P/Invoke marshalling code // will throw appropriate error message. // if (type.IsAutoLayout) 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 = 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 = 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"u8, 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); } } }