Skip to content

Commit

Permalink
[Coop] Cominterop and marshal conversion. (#9503)
Browse files Browse the repository at this point in the history
* [Coop] Convert ves_icall_System_Runtime_InteropServices_Marshal_IsComObject.

* [Coop] cominterop and marshalling partial conversion and cleanup.

* Some refinement/correction/commenting to mono_string_to_utf8str_handle.

* Fix index out of bounds.

* Fix error handling.

* Remove some mono_error_set_pending_exception.

* Fix icall interface -- string vs. ptr/len.

* tweaks

* Restore the corlib interface, and maybe address the apidiff gate.

* cleanup

* Fix PtrToStructure GC assertion failure tests/marshal2 interpreter.

* Fix merge.

* Revert "Restore the corlib interface, and maybe address the apidiff gate."

This reverts commit ca8456a.

* Try harder to support fixed in array copying.

* Allow for overlap.

* Put mono_ in front of type and fix Windows.

* Fix small problems on Windows build.

* Fix Windows and support larger data.

* [arm64] Make OP_CHECK_THIS read only a byte, to prevent unaligned access errors.

* Bump corlib higher.

* Merge with https://github.com/mono/mono/pull/9430/files.

* Bump API snapshot submodule
  • Loading branch information
jaykrell authored and akoeplinger committed Jul 14, 2018
1 parent 70f8348 commit 18b6846
Show file tree
Hide file tree
Showing 16 changed files with 766 additions and 676 deletions.
2 changes: 1 addition & 1 deletion configure.ac
Expand Up @@ -40,7 +40,7 @@ MONO_VERSION_BUILD=`echo $VERSION | cut -d . -f 3`
# This can be reset to 0 when Mono's version number is bumped
# since it's part of the corlib version (the prefix '1' in the full
# version number is to ensure the number isn't treated as octal in C)
MONO_CORLIB_COUNTER=17
MONO_CORLIB_COUNTER=21
MONO_CORLIB_VERSION=`printf "1%02d%02d%02d%03d" $MONO_VERSION_MAJOR $MONO_VERSION_MINOR 0 $MONO_CORLIB_COUNTER`

AC_DEFINE_UNQUOTED(MONO_CORLIB_VERSION,$MONO_CORLIB_VERSION,[Version of the corlib-runtime interface])
Expand Down
2 changes: 1 addition & 1 deletion external/api-snapshot
190 changes: 145 additions & 45 deletions mcs/class/corlib/System.Runtime.InteropServices/Marshal.cs
Expand Up @@ -110,92 +110,174 @@ public static void ChangeWrapperHandleStrength (object otp, bool fIsWeak)
throw new NotImplementedException ();
}

[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static void copy_to_unmanaged (Array source, int startIndex,
IntPtr destination, int length);
unsafe internal static void copy_to_unmanaged (Array source, int startIndex,
IntPtr destination, int length)
{
copy_to_unmanaged_fixed (source, startIndex, destination, length, null);
}

[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static void copy_from_unmanaged (IntPtr source, int startIndex,
Array destination, int length);
unsafe private extern static void copy_to_unmanaged_fixed (Array source, int startIndex,
IntPtr destination, int length, void* fixed_source_element);

static private bool skip_fixed (System.Array array, int startIndex)
{
// In particular, we see length == 0 && startIndex == array.Length, and fixed fails.
return startIndex < 0 || startIndex >= array.Length;
}

public static void Copy (byte[] source, int startIndex, IntPtr destination, int length)
unsafe internal static void copy_to_unmanaged (byte[] source, int startIndex, IntPtr destination, int length)
{
copy_to_unmanaged (source, startIndex, destination, length);
if (skip_fixed (source, startIndex))
copy_to_unmanaged (source, startIndex, destination, length);

This comment has been minimized.

Copy link
@lambdageek

lambdageek Jul 16, 2018

Member

@jaykrell We missed an infinite loop

This comment has been minimized.

Copy link
@jaykrell

jaykrell Jul 16, 2018

Author Contributor

I see. This function doesn't quite follow the pattern of the surroundings. Had I optimized all of them to inline the call to ..fixed(...null) this wouldn't have happened. :(

else fixed (void* fixed_source = &source [startIndex])
copy_to_unmanaged_fixed (source, startIndex, destination, length, fixed_source);
}

public static void Copy (char[] source, int startIndex, IntPtr destination, int length)
unsafe internal static void copy_to_unmanaged (char[] source, int startIndex,
IntPtr destination, int length)
{
copy_to_unmanaged (source, startIndex, destination, length);
if (skip_fixed (source, startIndex))
copy_to_unmanaged (source, startIndex, destination, length);
else fixed (void* fixed_source = &source [startIndex])
copy_to_unmanaged_fixed (source, startIndex, destination, length, fixed_source);
}

public static void Copy (short[] source, int startIndex, IntPtr destination, int length)
public unsafe static void Copy (byte[] source, int startIndex, IntPtr destination, int length)
{
copy_to_unmanaged (source, startIndex, destination, length);
if (skip_fixed (source, startIndex))
copy_to_unmanaged (source, startIndex, destination, length);
else fixed (void* fixed_source = &source [startIndex])
copy_to_unmanaged_fixed (source, startIndex, destination, length, fixed_source);
}

public static void Copy (int[] source, int startIndex, IntPtr destination, int length)
public unsafe static void Copy (char[] source, int startIndex, IntPtr destination, int length)
{
copy_to_unmanaged (source, startIndex, destination, length);
if (skip_fixed (source, startIndex))
copy_to_unmanaged (source, startIndex, destination, length);
else fixed (void* fixed_source = &source [startIndex])
copy_to_unmanaged_fixed (source, startIndex, destination, length, fixed_source);
}

public static void Copy (long[] source, int startIndex, IntPtr destination, int length)
public unsafe static void Copy (short[] source, int startIndex, IntPtr destination, int length)
{
copy_to_unmanaged (source, startIndex, destination, length);
if (skip_fixed (source, startIndex))
copy_to_unmanaged (source, startIndex, destination, length);
else fixed (void* fixed_source = &source [startIndex])
copy_to_unmanaged_fixed (source, startIndex, destination, length, fixed_source);
}

public static void Copy (float[] source, int startIndex, IntPtr destination, int length)
public unsafe static void Copy (int[] source, int startIndex, IntPtr destination, int length)
{
copy_to_unmanaged (source, startIndex, destination, length);
if (skip_fixed (source, startIndex))
copy_to_unmanaged (source, startIndex, destination, length);
else fixed (void* fixed_source = &source [startIndex])
copy_to_unmanaged_fixed (source, startIndex, destination, length, fixed_source);
}

public static void Copy (double[] source, int startIndex, IntPtr destination, int length)
public unsafe static void Copy (long[] source, int startIndex, IntPtr destination, int length)
{
copy_to_unmanaged (source, startIndex, destination, length);
if (skip_fixed (source, startIndex))
copy_to_unmanaged (source, startIndex, destination, length);
else fixed (void* fixed_source = &source [startIndex])
copy_to_unmanaged_fixed (source, startIndex, destination, length, fixed_source);
}

public static void Copy (IntPtr[] source, int startIndex, IntPtr destination, int length)
public unsafe static void Copy (float[] source, int startIndex, IntPtr destination, int length)
{
copy_to_unmanaged (source, startIndex, destination, length);
if (skip_fixed (source, startIndex))
copy_to_unmanaged (source, startIndex, destination, length);
else fixed (void* fixed_source = &source [startIndex])
copy_to_unmanaged_fixed (source, startIndex, destination, length, fixed_source);
}

public static void Copy (IntPtr source, byte[] destination, int startIndex, int length)
public unsafe static void Copy (double[] source, int startIndex, IntPtr destination, int length)
{
copy_from_unmanaged (source, startIndex, destination, length);
if (skip_fixed (source, startIndex))
copy_to_unmanaged (source, startIndex, destination, length);
else fixed (void* fixed_source = &source [startIndex])
copy_to_unmanaged_fixed (source, startIndex, destination, length, fixed_source);
}

public static void Copy (IntPtr source, char[] destination, int startIndex, int length)
public unsafe static void Copy (IntPtr[] source, int startIndex, IntPtr destination, int length)
{
copy_from_unmanaged (source, startIndex, destination, length);
if (skip_fixed (source, startIndex))
copy_to_unmanaged (source, startIndex, destination, length);
else fixed (void* fixed_source = &source [startIndex])
copy_to_unmanaged_fixed (source, startIndex, destination, length, fixed_source);
}

public static void Copy (IntPtr source, short[] destination, int startIndex, int length)
unsafe internal static void copy_from_unmanaged (IntPtr source, int startIndex, Array destination, int length)
{
copy_from_unmanaged (source, startIndex, destination, length);
copy_from_unmanaged_fixed (source, startIndex, destination, length, null);
}

public static void Copy (IntPtr source, int[] destination, int startIndex, int length)
[MethodImplAttribute(MethodImplOptions.InternalCall)]
unsafe private extern static void copy_from_unmanaged_fixed (IntPtr source, int startIndex,
Array destination, int length, void* fixed_destination_element);

public unsafe static void Copy (IntPtr source, byte[] destination, int startIndex, int length)
{
copy_from_unmanaged (source, startIndex, destination, length);
if (skip_fixed (destination, startIndex))
copy_from_unmanaged (source, startIndex, destination, length);
else fixed (void* fixed_destination = &destination [startIndex])
copy_from_unmanaged_fixed (source, startIndex, destination, length, fixed_destination);
}

public static void Copy (IntPtr source, long[] destination, int startIndex, int length)
public unsafe static void Copy (IntPtr source, char[] destination, int startIndex, int length)
{
copy_from_unmanaged (source, startIndex, destination, length);
if (skip_fixed (destination, startIndex))
copy_from_unmanaged (source, startIndex, destination, length);
else fixed (void* fixed_destination = &destination [startIndex])
copy_from_unmanaged_fixed (source, startIndex, destination, length, fixed_destination);
}

public static void Copy (IntPtr source, float[] destination, int startIndex, int length)
public unsafe static void Copy (IntPtr source, short[] destination, int startIndex, int length)
{
copy_from_unmanaged (source, startIndex, destination, length);
if (skip_fixed (destination, startIndex))
copy_from_unmanaged (source, startIndex, destination, length);
else fixed (void* fixed_destination = &destination [startIndex])
copy_from_unmanaged_fixed (source, startIndex, destination, length, fixed_destination);
}

public static void Copy (IntPtr source, double[] destination, int startIndex, int length)
public unsafe static void Copy (IntPtr source, int[] destination, int startIndex, int length)
{
copy_from_unmanaged (source, startIndex, destination, length);
if (skip_fixed (destination, startIndex))
copy_from_unmanaged (source, startIndex, destination, length);
else fixed (void* fixed_destination = &destination [startIndex])
copy_from_unmanaged_fixed (source, startIndex, destination, length, fixed_destination);
}

public static void Copy (IntPtr source, IntPtr[] destination, int startIndex, int length)
public unsafe static void Copy (IntPtr source, long[] destination, int startIndex, int length)
{
copy_from_unmanaged (source, startIndex, destination, length);
if (skip_fixed (destination, startIndex))
copy_from_unmanaged (source, startIndex, destination, length);
else fixed (void* fixed_destination = &destination [startIndex])
copy_from_unmanaged_fixed (source, startIndex, destination, length, fixed_destination);
}

public unsafe static void Copy (IntPtr source, float[] destination, int startIndex, int length)
{
if (skip_fixed (destination, startIndex))
copy_from_unmanaged (source, startIndex, destination, length);
else fixed (void* fixed_destination = &destination [startIndex])
copy_from_unmanaged_fixed (source, startIndex, destination, length, fixed_destination);
}

public unsafe static void Copy (IntPtr source, double[] destination, int startIndex, int length)
{
if (skip_fixed (destination, startIndex))
copy_from_unmanaged (source, startIndex, destination, length);
else fixed (void* fixed_destination = &destination [startIndex])
copy_from_unmanaged_fixed (source, startIndex, destination, length, fixed_destination);
}

public unsafe static void Copy (IntPtr source, IntPtr[] destination, int startIndex, int length)
{
if (skip_fixed (destination, startIndex))
copy_from_unmanaged (source, startIndex, destination, length);
else fixed (void* fixed_destination = &destination [startIndex])
copy_from_unmanaged_fixed (source, startIndex, destination, length, fixed_destination);
}

public static IntPtr CreateAggregatedObject (IntPtr pOuter,
Expand Down Expand Up @@ -1070,8 +1152,13 @@ internal static uint SizeOfType (Type type)
return (size + 3) & (~((uint)3));
}

[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern static IntPtr StringToBSTR (string s);
public unsafe static IntPtr StringToBSTR (string s)
{
if (s == null)
return IntPtr.Zero;
fixed (char* fixed_s = s)
return BufferToBSTR (fixed_s, s.Length);
}

public static IntPtr StringToCoTaskMemAnsi (string s)
{
Expand All @@ -1098,7 +1185,13 @@ public static IntPtr StringToCoTaskMemUni (string s)
}

[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern static IntPtr StringToHGlobalAnsi (string s);
unsafe extern static IntPtr StringToHGlobalAnsi (char* s, int length);

public unsafe static IntPtr StringToHGlobalAnsi (string s)
{
fixed (char* fixed_s = s)
return StringToHGlobalAnsi (fixed_s, (s != null) ? s.Length : 0);
}

unsafe public static IntPtr StringToAllocatedMemoryUTF8(String s)
{
Expand Down Expand Up @@ -1134,9 +1227,15 @@ public static IntPtr StringToHGlobalAuto (string s)
}

[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern static IntPtr StringToHGlobalUni (string s);
unsafe extern static IntPtr StringToHGlobalUni (char* s, int length);

public static IntPtr SecureStringToBSTR (SecureString s)
public unsafe static IntPtr StringToHGlobalUni (string s)
{
fixed (char* fixed_s = s)
return StringToHGlobalUni (fixed_s, (s != null) ? s.Length : 0);
}

public unsafe static IntPtr SecureStringToBSTR (SecureString s)
{
if (s == null)
throw new ArgumentNullException ("s");
Expand All @@ -1153,8 +1252,9 @@ public static IntPtr SecureStringToBSTR (SecureString s)
buffer[i + 1] = b;
}
}
return BufferToBSTR (buffer, len);
}
fixed (byte* fixed_buffer = buffer)
return BufferToBSTR ((char*)fixed_buffer, len);
}

public static IntPtr SecureStringToCoTaskMemAnsi (SecureString s)
{
Expand Down Expand Up @@ -1243,7 +1343,7 @@ public static IntPtr SecureStringToGlobalAllocUnicode (SecureString s)


[MethodImplAttribute(MethodImplOptions.InternalCall)]
extern static IntPtr BufferToBSTR (Array ptr, int slen);
extern unsafe static IntPtr BufferToBSTR (char* ptr, int slen);

[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern static IntPtr UnsafeAddrOfPinnedArrayElement (Array arr, int index);
Expand Down
5 changes: 2 additions & 3 deletions mcs/class/corlib/System.Runtime.InteropServices/SafeBuffer.cs
Expand Up @@ -145,7 +145,7 @@ public void Initialize (uint numElements, uint sizeOfEachElement)

[CLSCompliant (false)]
[ReliabilityContract (Consistency.WillNotCorruptState, Cer.MayFail)]
public void WriteArray<T> (ulong byteOffset, T[] array, int index, int count) where T : struct
public unsafe void WriteArray<T> (ulong byteOffset, T[] array, int index, int count) where T : struct

This comment has been minimized.

Copy link
@jaykrell

jaykrell Jul 15, 2018

Author Contributor

Adding unsafe maybe leftover from earlier edit and not needed.

{
if (!inited)
throw new InvalidOperationException ();
Expand All @@ -155,10 +155,9 @@ public void Initialize (uint numElements, uint sizeOfEachElement)
int size = Marshal.SizeOf (typeof (T)) * count;
if (target >= last_byte || target + size > last_byte)
throw new ArgumentException ("would overrite");

Marshal.copy_to_unmanaged (array, index, (IntPtr) target, count);
}
}
}
}

0 comments on commit 18b6846

Please sign in to comment.