summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorJeremy Koritzinsky <jkoritzinsky@gmail.com>2019-01-14 16:33:37 -0800
committerGitHub <noreply@github.com>2019-01-14 16:33:37 -0800
commit9cdde2f3f410673e42b541fe86e6a3f9acc86272 (patch)
tree2dc61ca37a3efb2f265e5b56b274ea47762d3d2e /tests
parent26db28cbe8db8693f22c3ebc225e32ef925b3b0a (diff)
downloadcoreclr-9cdde2f3f410673e42b541fe86e6a3f9acc86272.tar.gz
coreclr-9cdde2f3f410673e42b541fe86e6a3f9acc86272.tar.bz2
coreclr-9cdde2f3f410673e42b541fe86e6a3f9acc86272.zip
Add test calling a NativeCallable via an unmanaged calli. (#21984)
Diffstat (limited to 'tests')
-rw-r--r--tests/src/Interop/NativeCallable/NativeCallableTest.cs49
1 files changed, 49 insertions, 0 deletions
diff --git a/tests/src/Interop/NativeCallable/NativeCallableTest.cs b/tests/src/Interop/NativeCallable/NativeCallableTest.cs
index 49b670f2a9..36b2600779 100644
--- a/tests/src/Interop/NativeCallable/NativeCallableTest.cs
+++ b/tests/src/Interop/NativeCallable/NativeCallableTest.cs
@@ -32,6 +32,7 @@ public class Program
NegativeTest_ViaDelegate();
NegativeTest_NonBlittable();
NegativeTest_GenericArguments();
+ NativeCallableViaUnmanagedCalli();
if (args.Length != 0 && args[0].Equals("calli"))
{
@@ -254,4 +255,52 @@ public class Program
// located in src/vm/dllimportcallback.cpp.
testNativeMethod();
}
+
+ [NativeCallable(CallingConvention = CallingConvention.StdCall)]
+ public static int CallbackViaUnmanagedCalli(int val)
+ {
+ return DoubleImpl(val);
+ }
+
+ public static void NativeCallableViaUnmanagedCalli()
+ {
+ Console.WriteLine($"{nameof(NativeCallableAttribute)} function via calli instruction with unmanaged calling convention.");
+
+ /*
+ void TestNativeCallableViaCalli()
+ {
+ .locals init (native int V_0)
+ IL_0000: nop
+ IL_0001: ldftn int CallbackViaUnmanagedCalli(int32)
+ IL_0007: stloc.0
+
+ IL_0008: ldc.i4 1234
+ IL_000d: ldloc.0
+ IL_000e: calli int32 stdcall(int32)
+
+ IL_0014: ret
+ }
+ */
+ DynamicMethod testNativeCallable = new DynamicMethod("TestNativeCallableViaUnmanagedCalli", typeof(int), null, typeof(Program).Module);
+ ILGenerator il = testNativeCallable.GetILGenerator();
+ il.DeclareLocal(typeof(IntPtr));
+ il.Emit(OpCodes.Nop);
+
+ // Get native function pointer of the callback
+ il.Emit(OpCodes.Ldftn, typeof(Program).GetMethod(nameof(CallbackViaUnmanagedCalli)));
+ il.Emit(OpCodes.Stloc_0);
+
+ int n = 1234;
+
+ il.Emit(OpCodes.Ldc_I4, n);
+ il.Emit(OpCodes.Ldloc_0);
+ il.EmitCalli(OpCodes.Calli, CallingConvention.StdCall, typeof(int), new Type[] { typeof(int) });
+
+ il.Emit(OpCodes.Ret);
+
+ IntNativeMethodInvoker testNativeMethod = (IntNativeMethodInvoker)testNativeCallable.CreateDelegate(typeof(IntNativeMethodInvoker));
+
+ int expected = DoubleImpl(n);
+ Assert.AreEqual(expected, testNativeMethod());
+ }
}