private TypeDesc GetInlineArrayType(InlineArrayCandidate candidate) { TypeDesc inlineArrayType = InteropStateManager.GetInlineArrayType(candidate); Debug.Assert(inlineArrayType != null); return(inlineArrayType); }
internal static TypeDesc GetNativeTypeFromMarshallerKind(TypeDesc type, MarshallerKind kind, MarshallerKind elementMarshallerKind, InteropStateManager interopStateManager, MarshalAsDescriptor marshalAs, bool isArrayElement = false) { TypeSystemContext context = type.Context; NativeTypeKind nativeType = NativeTypeKind.Invalid; if (marshalAs != null) { nativeType = isArrayElement ? marshalAs.ArraySubType : marshalAs.Type; } switch (kind) { case MarshallerKind.BlittableValue: { switch (nativeType) { case NativeTypeKind.I1: return(context.GetWellKnownType(WellKnownType.SByte)); case NativeTypeKind.U1: return(context.GetWellKnownType(WellKnownType.Byte)); case NativeTypeKind.I2: return(context.GetWellKnownType(WellKnownType.Int16)); case NativeTypeKind.U2: return(context.GetWellKnownType(WellKnownType.UInt16)); case NativeTypeKind.I4: return(context.GetWellKnownType(WellKnownType.Int32)); case NativeTypeKind.U4: return(context.GetWellKnownType(WellKnownType.UInt32)); case NativeTypeKind.I8: return(context.GetWellKnownType(WellKnownType.Int64)); case NativeTypeKind.U8: return(context.GetWellKnownType(WellKnownType.UInt64)); case NativeTypeKind.R4: return(context.GetWellKnownType(WellKnownType.Single)); case NativeTypeKind.R8: return(context.GetWellKnownType(WellKnownType.Double)); default: return(type.UnderlyingType); } } case MarshallerKind.Bool: return(context.GetWellKnownType(WellKnownType.Int32)); case MarshallerKind.CBool: return(context.GetWellKnownType(WellKnownType.Byte)); case MarshallerKind.Enum: case MarshallerKind.BlittableStruct: case MarshallerKind.Decimal: case MarshallerKind.VoidReturn: return(type); case MarshallerKind.Struct: return(interopStateManager.GetStructMarshallingNativeType((MetadataType)type)); case MarshallerKind.BlittableStructPtr: return(type.MakePointerType()); case MarshallerKind.HandleRef: return(context.GetWellKnownType(WellKnownType.IntPtr)); case MarshallerKind.UnicodeChar: if (nativeType == NativeTypeKind.U2) { return(context.GetWellKnownType(WellKnownType.UInt16)); } else { return(context.GetWellKnownType(WellKnownType.Int16)); } case MarshallerKind.OleDateTime: return(context.GetWellKnownType(WellKnownType.Double)); case MarshallerKind.SafeHandle: case MarshallerKind.CriticalHandle: return(context.GetWellKnownType(WellKnownType.IntPtr)); case MarshallerKind.UnicodeString: case MarshallerKind.UnicodeStringBuilder: return(context.GetWellKnownType(WellKnownType.Char).MakePointerType()); case MarshallerKind.AnsiString: case MarshallerKind.AnsiStringBuilder: return(context.GetWellKnownType(WellKnownType.Byte).MakePointerType()); case MarshallerKind.BlittableArray: case MarshallerKind.Array: case MarshallerKind.AnsiCharArray: { ArrayType arrayType = type as ArrayType; Debug.Assert(arrayType != null, "Expecting array"); // // We need to construct the unsafe array from the right unsafe array element type // TypeDesc elementNativeType = GetNativeTypeFromMarshallerKind( arrayType.ElementType, elementMarshallerKind, MarshallerKind.Unknown, interopStateManager, marshalAs, isArrayElement: true); return(elementNativeType.MakePointerType()); } case MarshallerKind.AnsiChar: return(context.GetWellKnownType(WellKnownType.Byte)); case MarshallerKind.FunctionPointer: return(context.GetWellKnownType(WellKnownType.IntPtr)); case MarshallerKind.ByValUnicodeString: case MarshallerKind.ByValAnsiString: { var inlineArrayCandidate = GetInlineArrayCandidate(context.GetWellKnownType(WellKnownType.Char), elementMarshallerKind, interopStateManager, marshalAs); return(interopStateManager.GetInlineArrayType(inlineArrayCandidate)); } case MarshallerKind.ByValAnsiCharArray: case MarshallerKind.ByValArray: { ArrayType arrayType = type as ArrayType; Debug.Assert(arrayType != null, "Expecting array"); var inlineArrayCandidate = GetInlineArrayCandidate(arrayType.ElementType, elementMarshallerKind, interopStateManager, marshalAs); return(interopStateManager.GetInlineArrayType(inlineArrayCandidate)); } case MarshallerKind.Unknown: default: throw new NotSupportedException(); } }
internal static TypeDesc GetNativeTypeFromMarshallerKind(TypeDesc type, MarshallerKind kind, MarshallerKind elementMarshallerKind, #if !READYTORUN InteropStateManager interopStateManager, #endif MarshalAsDescriptor marshalAs, bool isArrayElement = false) { TypeSystemContext context = type.Context; NativeTypeKind nativeType = NativeTypeKind.Default; if (marshalAs != null) { nativeType = isArrayElement ? marshalAs.ArraySubType : marshalAs.Type; } switch (kind) { case MarshallerKind.BlittableValue: { switch (nativeType) { case NativeTypeKind.I1: return(context.GetWellKnownType(WellKnownType.SByte)); case NativeTypeKind.U1: return(context.GetWellKnownType(WellKnownType.Byte)); case NativeTypeKind.I2: return(context.GetWellKnownType(WellKnownType.Int16)); case NativeTypeKind.U2: return(context.GetWellKnownType(WellKnownType.UInt16)); case NativeTypeKind.I4: return(context.GetWellKnownType(WellKnownType.Int32)); case NativeTypeKind.U4: return(context.GetWellKnownType(WellKnownType.UInt32)); case NativeTypeKind.I8: return(context.GetWellKnownType(WellKnownType.Int64)); case NativeTypeKind.U8: return(context.GetWellKnownType(WellKnownType.UInt64)); case NativeTypeKind.R4: return(context.GetWellKnownType(WellKnownType.Single)); case NativeTypeKind.R8: return(context.GetWellKnownType(WellKnownType.Double)); default: return(type.UnderlyingType); } } case MarshallerKind.Bool: return(context.GetWellKnownType(WellKnownType.Int32)); case MarshallerKind.CBool: return(context.GetWellKnownType(WellKnownType.Byte)); case MarshallerKind.VariantBool: return(context.GetWellKnownType(WellKnownType.Int16)); case MarshallerKind.Enum: case MarshallerKind.BlittableStruct: case MarshallerKind.Decimal: case MarshallerKind.VoidReturn: return(type); #if !READYTORUN case MarshallerKind.Struct: case MarshallerKind.LayoutClass: Debug.Assert(interopStateManager is not null, "An InteropStateManager is required to look up the native representation of a non-blittable struct or class with layout."); return(interopStateManager.GetStructMarshallingNativeType((MetadataType)type)); #endif case MarshallerKind.BlittableStructPtr: return(type.MakePointerType()); case MarshallerKind.HandleRef: return(context.GetWellKnownType(WellKnownType.IntPtr)); case MarshallerKind.UnicodeChar: if (nativeType == NativeTypeKind.U2) { return(context.GetWellKnownType(WellKnownType.UInt16)); } else { return(context.GetWellKnownType(WellKnownType.Int16)); } case MarshallerKind.OleDateTime: return(context.GetWellKnownType(WellKnownType.Double)); case MarshallerKind.FailedTypeLoad: return(context.GetWellKnownType(WellKnownType.IntPtr)); case MarshallerKind.SafeHandle: case MarshallerKind.CriticalHandle: return(context.GetWellKnownType(WellKnownType.IntPtr)); case MarshallerKind.BSTRString: case MarshallerKind.UnicodeString: case MarshallerKind.UnicodeStringBuilder: return(context.GetWellKnownType(WellKnownType.Char).MakePointerType()); case MarshallerKind.AnsiBSTRString: case MarshallerKind.AnsiString: case MarshallerKind.AnsiStringBuilder: case MarshallerKind.UTF8String: return(context.GetWellKnownType(WellKnownType.Byte).MakePointerType()); case MarshallerKind.BlittableArray: case MarshallerKind.Array: case MarshallerKind.AnsiCharArray: { ArrayType arrayType = type as ArrayType; Debug.Assert(arrayType != null, "Expecting array"); // // We need to construct the unsafe array from the right unsafe array element type // TypeDesc elementNativeType = GetNativeTypeFromMarshallerKind( arrayType.ElementType, elementMarshallerKind, MarshallerKind.Unknown, #if !READYTORUN interopStateManager, #endif marshalAs, isArrayElement: true); return(elementNativeType.MakePointerType()); } case MarshallerKind.AnsiChar: return(context.GetWellKnownType(WellKnownType.Byte)); case MarshallerKind.FunctionPointer: return(context.GetWellKnownType(WellKnownType.IntPtr)); #if !READYTORUN case MarshallerKind.ByValUnicodeString: case MarshallerKind.ByValAnsiString: { var inlineArrayCandidate = GetInlineArrayCandidate(context.GetWellKnownType(WellKnownType.Char), elementMarshallerKind, interopStateManager, marshalAs); return(interopStateManager.GetInlineArrayType(inlineArrayCandidate)); } case MarshallerKind.ByValAnsiCharArray: case MarshallerKind.ByValArray: { ArrayType arrayType = type as ArrayType; Debug.Assert(arrayType != null, "Expecting array"); var inlineArrayCandidate = GetInlineArrayCandidate(arrayType.ElementType, elementMarshallerKind, interopStateManager, marshalAs); return(interopStateManager.GetInlineArrayType(inlineArrayCandidate)); } #endif case MarshallerKind.LayoutClassPtr: case MarshallerKind.AsAnyA: case MarshallerKind.AsAnyW: return(context.GetWellKnownType(WellKnownType.IntPtr)); case MarshallerKind.ComInterface: return(context.GetWellKnownType(WellKnownType.IntPtr)); #if !READYTORUN case MarshallerKind.Variant: return(InteropTypes.GetVariant(context)); case MarshallerKind.CustomMarshaler: return(context.GetWellKnownType(WellKnownType.IntPtr)); #endif case MarshallerKind.OleCurrency: return(context.GetWellKnownType(WellKnownType.Int64)); case MarshallerKind.Unknown: default: throw new NotSupportedException(); } }