Add some targeted by-value struct passing tests.
authorPat Gavlin <pagavlin@microsoft.com>
Thu, 5 Nov 2015 19:32:13 +0000 (11:32 -0800)
committerPat Gavlin <pagavlin@microsoft.com>
Thu, 5 Nov 2015 21:02:53 +0000 (13:02 -0800)
These tests target the SysV AMD64 ABI in particular, which relies on
field types to decide how to pass by-value structs.

tests/buildtest.cmd
tests/src/JIT/Directed/StructABI/CMakeLists.txt [new file with mode: 0644]
tests/src/JIT/Directed/StructABI/StructABI.c [new file with mode: 0644]
tests/src/JIT/Directed/StructABI/StructABI.cs [new file with mode: 0644]
tests/src/JIT/Directed/StructABI/StructABI.csproj [new file with mode: 0644]
tests/src/JIT/Directed/StructABI/project.json [new file with mode: 0644]
tests/src/dir.props

index 6d4f16c..b13ddd5 100644 (file)
@@ -12,10 +12,12 @@ set "__RootBinDir=%__ProjectDir%\bin"
 set "__LogsDir=%__RootBinDir%\Logs"
 
 :: Default to highest Visual Studio version available
-set __VSVersion=vs2015
+if not defined __VSVersion (
+    set __VSVersion=vs2015
 
-if defined VS120COMNTOOLS set __VSVersion=vs2013
-if defined VS140COMNTOOLS set __VSVersion=vs2015
+    if defined VS120COMNTOOLS set __VSVersion=vs2013
+    if defined VS140COMNTOOLS set __VSVersion=vs2015
+)
 
 :Arg_Loop
 if "%1" == "" goto ArgsDone
diff --git a/tests/src/JIT/Directed/StructABI/CMakeLists.txt b/tests/src/JIT/Directed/StructABI/CMakeLists.txt
new file mode 100644 (file)
index 0000000..23c9352
--- /dev/null
@@ -0,0 +1,11 @@
+cmake_minimum_required (VERSION 2.6)
+project (StructABILib)
+include_directories(${INC_PLATFORM_DIR})
+
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
+
+# add the executable
+add_library (StructABILib SHARED StructABI.c)
+
+# add the install targets
+install (TARGETS StructABILib DESTINATION bin)
diff --git a/tests/src/JIT/Directed/StructABI/StructABI.c b/tests/src/JIT/Directed/StructABI/StructABI.c
new file mode 100644 (file)
index 0000000..09b5813
--- /dev/null
@@ -0,0 +1,328 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdint.h>
+
+#ifdef _MSC_VER
+#define DLLEXPORT __declspec(dllexport)
+#else
+#define DLLEXPORT __attribute__((visibility("default")))
+#endif // _MSC_VER
+
+struct SingleByte
+{
+       uint8_t Byte;
+};
+
+struct SingleLong
+{
+       uint64_t Long;
+};
+
+struct SingleFloat
+{
+       float Float;
+};
+
+struct SingleDouble
+{
+       double Double;
+};
+
+struct ByteAndFloat
+{
+       uint8_t Byte;
+       float Float;
+};
+
+struct FloatAndByte
+{
+       float Float;
+       uint8_t Byte;
+};
+
+struct LongAndFloat
+{
+       uint64_t Long;
+       float Float;
+};
+
+struct ByteAndDouble
+{
+       uint8_t Byte;
+       double Double;
+};
+
+struct DoubleAndByte
+{
+       double Double;
+       uint8_t Byte;
+};
+
+struct PointerAndByte
+{
+       void* Pointer;
+       uint8_t Byte;
+};
+
+struct ByteAndPointer
+{
+       uint8_t Byte;
+       void* Pointer;
+};
+
+struct ByteFloatAndPointer
+{
+       uint8_t Byte;
+       float Float;
+       void* Pointer;
+};
+
+struct PointerFloatAndByte
+{
+       void* Pointer;
+       float Float;
+       uint8_t Byte;
+};
+
+struct TwoFloats
+{
+       float Float1;
+       float Float2;
+};
+
+struct TwoDoubles
+{
+       double Double1;
+       double Double2;
+};
+
+struct InlineArray1
+{
+       uint8_t Array[16];
+};
+
+struct InlineArray2
+{
+       float Array[4];
+};
+
+struct InlineArray3
+{
+       float Array[3];
+};
+
+struct InlineArray4
+{
+       uint16_t Array[5];
+};
+
+struct InlineArray5
+{
+       uint8_t Array[9];
+};
+
+struct InlineArray6
+{
+       double Array[1];
+};
+
+struct Nested1
+{
+       struct LongAndFloat Field1;
+       struct LongAndFloat Field2;
+};
+
+struct Nested2
+{
+       struct ByteAndFloat Field1;
+       struct FloatAndByte Field2;
+};
+
+struct Nested3
+{
+       void* Field1;
+       struct FloatAndByte Field2;
+};
+
+struct Nested4
+{
+       struct InlineArray5 Field1;
+       uint16_t Field2;
+};
+
+struct Nested5
+{
+       uint16_t Field1;
+       struct InlineArray5 Field2;
+};
+
+struct Nested6
+{
+       struct InlineArray4 Field1;
+       uint32_t Field2;
+};
+
+struct Nested7
+{
+       uint32_t Field1;
+       struct InlineArray4 Field2;
+};
+
+struct Nested8
+{
+       struct InlineArray4 Field1;
+       uint16_t Field2;
+};
+
+struct Nested9
+{
+       uint16_t Field1;
+       struct InlineArray4 Field2;
+};
+
+DLLEXPORT struct SingleByte EchoSingleByte(struct SingleByte value)
+{
+       return value;
+}
+
+DLLEXPORT struct SingleLong EchoSingleLong(struct SingleLong value)
+{
+       return value;
+}
+
+DLLEXPORT struct SingleFloat EchoSingleFloat(struct SingleFloat value)
+{
+       return value;
+}
+
+DLLEXPORT struct SingleDouble EchoSingleDouble(struct SingleDouble value)
+{
+       return value;
+}
+
+DLLEXPORT struct ByteAndFloat EchoByteAndFloat(struct ByteAndFloat value)
+{
+       return value;
+}
+
+DLLEXPORT struct LongAndFloat EchoLongAndFloat(struct LongAndFloat value)
+{
+       return value;
+}
+
+DLLEXPORT struct ByteAndDouble EchoByteAndDouble(struct ByteAndDouble value)
+{
+       return value;
+}
+
+DLLEXPORT struct DoubleAndByte EchoDoubleAndByte(struct DoubleAndByte value)
+{
+       return value;
+}
+
+DLLEXPORT struct PointerAndByte EchoPointerAndByte(struct PointerAndByte value)
+{
+       return value;
+}
+
+DLLEXPORT struct ByteAndPointer EchoByteAndPointer(struct ByteAndPointer value)
+{
+       return value;
+}
+
+DLLEXPORT struct ByteFloatAndPointer EchoByteFloatAndPointer(struct ByteFloatAndPointer value)
+{
+       return value;
+}
+
+DLLEXPORT struct PointerFloatAndByte EchoPointerFloatAndByte(struct PointerFloatAndByte value)
+{
+       return value;
+}
+
+DLLEXPORT struct TwoFloats EchoTwoFloats(struct TwoFloats value)
+{
+       return value;
+}
+
+DLLEXPORT struct TwoDoubles EchoTwoDoubles(struct TwoDoubles value)
+{
+       return value;
+}
+
+DLLEXPORT struct InlineArray1 EchoInlineArray1(struct InlineArray1 value)
+{
+       return value;
+}
+
+DLLEXPORT struct InlineArray2 EchoInlineArray2(struct InlineArray2 value)
+{
+       return value;
+}
+
+DLLEXPORT struct InlineArray3 EchoInlineArray3(struct InlineArray3 value)
+{
+       return value;
+}
+
+DLLEXPORT struct InlineArray4 EchoInlineArray4(struct InlineArray4 value)
+{
+       return value;
+}
+
+DLLEXPORT struct InlineArray5 EchoInlineArray5(struct InlineArray5 value)
+{
+       return value;
+}
+
+DLLEXPORT struct InlineArray6 EchoInlineArray6(struct InlineArray6 value)
+{
+       return value;
+}
+
+DLLEXPORT struct Nested1 EchoNested1(struct Nested1 value)
+{
+       return value;
+}
+
+DLLEXPORT struct Nested2 EchoNested2(struct Nested2 value)
+{
+       return value;
+}
+
+DLLEXPORT struct Nested3 EchoNested3(struct Nested3 value)
+{
+       return value;
+}
+
+DLLEXPORT struct Nested4 EchoNested4(struct Nested4 value)
+{
+       return value;
+}
+
+DLLEXPORT struct Nested5 EchoNested5(struct Nested5 value)
+{
+       return value;
+}
+
+DLLEXPORT struct Nested6 EchoNested6(struct Nested6 value)
+{
+       return value;
+}
+
+DLLEXPORT struct Nested7 EchoNested7(struct Nested7 value)
+{
+       return value;
+}
+
+DLLEXPORT struct Nested8 EchoNested8(struct Nested8 value)
+{
+       return value;
+}
+
+DLLEXPORT struct Nested9 EchoNested9(struct Nested9 value)
+{
+       return value;
+}
+
diff --git a/tests/src/JIT/Directed/StructABI/StructABI.cs b/tests/src/JIT/Directed/StructABI/StructABI.cs
new file mode 100644 (file)
index 0000000..6ec2832
--- /dev/null
@@ -0,0 +1,920 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.Runtime.InteropServices;
+
+struct SingleByte
+{
+       public byte Byte;
+
+       public static SingleByte Get()
+       {
+               return new SingleByte { Byte = 42 };
+       }
+
+       public bool Equals(SingleByte other)
+       {
+               return Byte == other.Byte;
+       }
+}
+
+struct SingleLong
+{
+       public ulong Long;
+
+       public static SingleLong Get()
+       {
+               return new SingleLong { Long = 0xfeedfaceabadf00d };
+       }
+
+       public bool Equals(SingleLong other)
+       {
+               return Long == other.Long;
+       }
+}
+
+struct SingleFloat
+{
+       public float Float;
+
+       public static SingleFloat Get()
+       {
+               return new SingleFloat { Float = 3.14159f };
+       }
+
+       public bool Equals(SingleFloat other)
+       {
+               return Float == other.Float;
+       }
+}
+
+struct SingleDouble
+{
+       public double Double;
+
+       public static SingleDouble Get()
+       {
+               return new SingleDouble { Double = 3.14159d };
+       }
+
+       public bool Equals(SingleDouble other)
+       {
+               return Double == other.Double;
+       }
+}
+
+struct ByteAndFloat
+{
+       public byte Byte;
+       public float Float;
+
+       public static ByteAndFloat Get()
+       {
+               return new ByteAndFloat { Byte = 42, Float = 3.14159f };
+       }
+
+       public bool Equals(ByteAndFloat other)
+       {
+               return Byte == other.Byte && Float == other.Float;
+       }
+}
+
+struct FloatAndByte
+{
+       public float Float;
+       public byte Byte;
+
+       public static FloatAndByte Get()
+       {
+               return new FloatAndByte { Byte = 42, Float = 3.14159f };
+       }
+
+       public bool Equals(FloatAndByte other)
+       {
+               return Byte == other.Byte && Float == other.Float;
+       }
+}
+
+struct LongAndFloat
+{
+       public ulong Long;
+       public float Float;
+
+       public static LongAndFloat Get()
+       {
+               return new LongAndFloat { Long = 0xfeedfaceabadf00d, Float = 3.14159f };
+       }
+
+       public bool Equals(LongAndFloat other)
+       {
+               return Long == other.Long && Float == other.Float;
+       }
+}
+
+struct ByteAndDouble
+{
+       public byte Byte;
+       public double Double;
+
+       public static ByteAndDouble Get()
+       {
+               return new ByteAndDouble { Byte = 42, Double = 3.14159d };
+       }
+
+       public bool Equals(ByteAndDouble other)
+       {
+               return Byte == other.Byte && Double == other.Double;
+       }
+}
+
+struct DoubleAndByte
+{
+       public double Double;
+       public byte Byte;
+
+       public static DoubleAndByte Get()
+       {
+               return new DoubleAndByte { Byte = 42, Double = 3.14159d };
+       }
+
+       public bool Equals(DoubleAndByte other)
+       {
+               return Byte == other.Byte && Double == other.Double;
+       }
+}
+
+unsafe struct PointerAndByte
+{
+       public void* Pointer;
+       public byte Byte;
+
+       public static PointerAndByte Get()
+       {
+               byte unused;
+               return new PointerAndByte { Pointer = &unused, Byte = 42 };
+       }
+
+       public bool Equals(PointerAndByte other)
+       {
+               return Pointer == other.Pointer && Byte == other.Byte;
+       }
+}
+
+unsafe struct ByteAndPointer
+{
+       public byte Byte;
+       public void* Pointer;
+
+       public static ByteAndPointer Get()
+       {
+               byte unused;
+               return new ByteAndPointer { Pointer = &unused, Byte = 42 };
+       }
+
+       public bool Equals(ByteAndPointer other)
+       {
+               return Pointer == other.Pointer && Byte == other.Byte;
+       }
+}
+
+unsafe struct ByteFloatAndPointer
+{
+       public byte Byte;
+       public float Float;
+       public void* Pointer;
+
+       public static ByteFloatAndPointer Get()
+       {
+               byte unused;
+               return new ByteFloatAndPointer { Pointer = &unused, Float = 3.14159f, Byte = 42 };
+       }
+
+       public bool Equals(ByteFloatAndPointer other)
+       {
+               return Pointer == other.Pointer && Float == other.Float && Byte == other.Byte;
+       }
+}
+
+unsafe struct PointerFloatAndByte
+{
+       public void* Pointer;
+       public float Float;
+       public byte Byte;
+
+       public static PointerFloatAndByte Get()
+       {
+               byte unused;
+               return new PointerFloatAndByte { Pointer = &unused, Float = 3.14159f, Byte = 42 };
+       }
+
+       public bool Equals(PointerFloatAndByte other)
+       {
+               return Pointer == other.Pointer && Float == other.Float && Byte == other.Byte;
+       }
+}
+
+struct TwoFloats
+{
+       public float Float1;
+       public float Float2;
+
+       public static TwoFloats Get()
+       {
+               return new TwoFloats { Float1 = 3.14159f, Float2 = 2.71828f };
+       }
+
+       public bool Equals(TwoFloats other)
+       {
+               return Float1 == other.Float1 && Float2 == other.Float2;
+       }
+}
+
+struct TwoDoubles
+{
+       public double Double1;
+       public double Double2;
+
+       public static TwoDoubles Get()
+       {
+               return new TwoDoubles { Double1 = 3.14159d, Double2 = 2.71828d };
+       }
+
+       public bool Equals(TwoDoubles other)
+       {
+               return Double1 == other.Double1 && Double2 == other.Double2;
+       }
+}
+
+unsafe struct InlineArray1
+{
+       public fixed byte Array[16];
+
+       public static InlineArray1 Get()
+       {
+               var val = new InlineArray1();
+               for (int i = 0; i < 16; i++)
+               {
+                       val.Array[i] = (byte)(i + 1);
+               }
+
+               return val;
+       }
+
+       public bool Equals(InlineArray1 other)
+       {
+               fixed (byte* arr = Array)
+               {
+                       for (int i = 0; i < 16; i++)
+                       {
+                               if (arr[i] != other.Array[i])
+                               {
+                                       return false;
+                               }
+                       }
+               }
+
+               return true;
+       }
+}
+
+unsafe struct InlineArray2
+{
+       public fixed float Array[4];
+
+       public static InlineArray2 Get()
+       {
+               var val = new InlineArray2();
+               for (int i = 0; i < 4; i++)
+               {
+                       val.Array[i] = (float)(i + 1);
+               }
+
+               return val;
+       }
+
+       public bool Equals(InlineArray2 other)
+       {
+               fixed (float* arr = Array)
+               {
+                       for (int i = 0; i < 4; i++)
+                       {
+                               if (arr[i] != other.Array[i])
+                               {
+                                       return false;
+                               }
+                       }
+               }
+
+               return true;
+       }
+}
+
+unsafe struct InlineArray3
+{
+       public fixed float Array[3];
+
+       public static InlineArray3 Get()
+       {
+               var val = new InlineArray3();
+               for (int i = 0; i < 3; i++)
+               {
+                       val.Array[i] = (float)(i + 1);
+               }
+
+               return val;
+       }
+
+       public bool Equals(InlineArray3 other)
+       {
+               fixed (float* arr = Array)
+               {
+                       for (int i = 0; i < 3; i++)
+                       {
+                               if (arr[i] != other.Array[i])
+                               {
+                                       return false;
+                               }
+                       }
+               }
+
+               return true;
+       }
+}
+
+unsafe struct InlineArray4
+{
+       public fixed ushort Array[5];
+
+       public static InlineArray4 Get()
+       {
+               var val = new InlineArray4();
+               for (int i = 0; i < 5; i++)
+               {
+                       val.Array[i] = (ushort)(i + 1);
+               }
+
+               return val;
+       }
+
+       public bool Equals(InlineArray4 other)
+       {
+               fixed (ushort* arr = Array)
+               {
+                       for (int i = 0; i < 5; i++)
+                       {
+                               if (arr[i] != other.Array[i])
+                               {
+                                       return false;
+                               }
+                       }
+               }
+
+               return true;
+       }
+}
+
+unsafe struct InlineArray5
+{
+       public fixed byte Array[9];
+
+       public static InlineArray5 Get()
+       {
+               var val = new InlineArray5();
+               for (int i = 0; i < 9; i++)
+               {
+                       val.Array[i] = (byte)(i + 1);
+               }
+
+               return val;
+       }
+
+       public bool Equals(InlineArray5 other)
+       {
+               fixed (byte* arr = Array)
+               {
+                       for (int i = 0; i < 9; i++)
+                       {
+                               if (arr[i] != other.Array[i])
+                               {
+                                       return false;
+                               }
+                       }
+               }
+
+               return true;
+       }
+}
+
+unsafe struct InlineArray6
+{
+       public fixed double Array[1];
+
+       public static InlineArray6 Get()
+       {
+               var val = new InlineArray6();
+               for (int i = 0; i < 1; i++)
+               {
+                       val.Array[i] = (double)(i + 1);
+               }
+
+               return val;
+       }
+
+       public bool Equals(InlineArray6 other)
+       {
+               fixed (double* arr = Array)
+               {
+                       for (int i = 0; i < 1; i++)
+                       {
+                               if (arr[i] != other.Array[i])
+                               {
+                                       return false;
+                               }
+                       }
+               }
+
+               return true;
+       }
+}
+
+struct Nested1
+{
+       public LongAndFloat Field1;
+       public LongAndFloat Field2;
+
+       public static Nested1 Get()
+       {
+               return new Nested1
+               {
+                       Field1 = new LongAndFloat { Long = 0xfeedfaceabadf00d, Float = 3.14159f },
+                       Field2 = new LongAndFloat { Long = 0xbeeff00fdeadcafe, Float = 2.71928f }
+               };
+       }
+
+       public bool Equals(Nested1 other)
+       {
+               return Field1.Equals(other.Field1) && Field2.Equals(other.Field2);
+       }
+}
+
+struct Nested2
+{
+       public ByteAndFloat Field1;
+       public FloatAndByte Field2;
+
+       public static Nested2 Get()
+       {
+               return new Nested2
+               {
+                       Field1 = new ByteAndFloat { Byte = 42, Float = 3.14159f },
+                       Field2 = new FloatAndByte { Byte = 24, Float = 2.71928f }
+               };
+       }
+
+       public bool Equals(Nested2 other)
+       {
+               return Field1.Equals(other.Field1) && Field2.Equals(other.Field2);
+       }
+}
+
+unsafe struct Nested3
+{
+       public void* Field1;
+       public FloatAndByte Field2;
+
+       public static Nested3 Get()
+       {
+               byte unused;
+               return new Nested3 { Field1 = &unused, Field2 = FloatAndByte.Get() };
+       }
+
+       public bool Equals(Nested3 other)
+       {
+               return Field1 == other.Field1 && Field2.Equals(other.Field2);
+       }
+}
+
+struct Nested4
+{
+       public InlineArray5 Field1;
+       public ushort Field2;
+
+       public static Nested4 Get()
+       {
+               return new Nested4 { Field1 = InlineArray5.Get(), Field2 = 0xcafe };
+       }
+
+       public bool Equals(Nested4 other)
+       {
+               return Field1.Equals(other.Field1) && Field2 == other.Field2;
+       }
+}
+
+struct Nested5
+{
+       public ushort Field1;
+       public InlineArray5 Field2;
+
+       public static Nested5 Get()
+       {
+               return new Nested5 { Field2 = InlineArray5.Get(), Field1 = 0xcafe };
+       }
+
+       public bool Equals(Nested5 other)
+       {
+               return Field1 == other.Field1 && Field2.Equals(other.Field2);
+       }
+}
+
+struct Nested6
+{
+       public InlineArray4 Field1;
+       public uint Field2;
+
+       public static Nested6 Get()
+       {
+               return new Nested6 { Field1 = InlineArray4.Get(), Field2 = 0xcafef00d };
+       }
+
+       public bool Equals(Nested6 other)
+       {
+               return Field1.Equals(other.Field1) && Field2 == other.Field2;
+       }
+}
+
+struct Nested7
+{
+       public uint Field1;
+       public InlineArray4 Field2;
+
+       public static Nested7 Get()
+       {
+               return new Nested7 { Field2 = InlineArray4.Get(), Field1 = 0xcafef00d };
+       }
+
+       public bool Equals(Nested7 other)
+       {
+               return Field1 == other.Field1 && Field2.Equals(other.Field2);
+       }
+}
+
+struct Nested8
+{
+       public InlineArray4 Field1;
+       public ushort Field2;
+
+       public static Nested8 Get()
+       {
+               return new Nested8 { Field1 = InlineArray4.Get(), Field2 = 0xcafe };
+       }
+
+       public bool Equals(Nested8 other)
+       {
+               return Field1.Equals(other.Field1) && Field2 == other.Field2;
+       }
+}
+
+struct Nested9
+{
+       public ushort Field1;
+       public InlineArray4 Field2;
+
+       public static Nested9 Get()
+       {
+               return new Nested9 { Field2 = InlineArray4.Get(), Field1 = 0xcafe };
+       }
+
+       public bool Equals(Nested9 other)
+       {
+               return Field1 == other.Field1 && Field2.Equals(other.Field2);
+       }
+}
+
+public static partial class StructABI
+{
+       [DllImport(StructABILib)]
+       static extern SingleByte EchoSingleByte(SingleByte value);
+
+       [DllImport(StructABILib)]
+       static extern SingleLong EchoSingleLong(SingleLong value);
+
+       [DllImport(StructABILib)]
+       static extern SingleFloat EchoSingleFloat(SingleFloat value);
+
+       [DllImport(StructABILib)]
+       static extern SingleDouble EchoSingleDouble(SingleDouble value);
+
+       [DllImport(StructABILib)]
+       static extern ByteAndFloat EchoByteAndFloat(ByteAndFloat value);
+
+       [DllImport(StructABILib)]
+       static extern LongAndFloat EchoLongAndFloat(LongAndFloat value);
+
+       [DllImport(StructABILib)]
+       static extern ByteAndDouble EchoByteAndDouble(ByteAndDouble value);
+
+       [DllImport(StructABILib)]
+       static extern DoubleAndByte EchoDoubleAndByte(DoubleAndByte value);
+
+       [DllImport(StructABILib)]
+       static extern PointerAndByte EchoPointerAndByte(PointerAndByte value);
+
+       [DllImport(StructABILib)]
+       static extern ByteAndPointer EchoByteAndPointer(ByteAndPointer value);
+
+       [DllImport(StructABILib)]
+       static extern ByteFloatAndPointer EchoByteFloatAndPointer(ByteFloatAndPointer value);
+
+       [DllImport(StructABILib)]
+       static extern PointerFloatAndByte EchoPointerFloatAndByte(PointerFloatAndByte value);
+
+       [DllImport(StructABILib)]
+       static extern TwoFloats EchoTwoFloats(TwoFloats value);
+
+       [DllImport(StructABILib)]
+       static extern TwoDoubles EchoTwoDoubles(TwoDoubles value);
+
+       [DllImport(StructABILib)]
+       static extern InlineArray1 EchoInlineArray1(InlineArray1 value);
+
+       [DllImport(StructABILib)]
+       static extern InlineArray2 EchoInlineArray2(InlineArray2 value);
+
+       [DllImport(StructABILib)]
+       static extern InlineArray3 EchoInlineArray3(InlineArray3 value);
+
+       [DllImport(StructABILib)]
+       static extern InlineArray4 EchoInlineArray4(InlineArray4 value);
+
+       [DllImport(StructABILib)]
+       static extern InlineArray5 EchoInlineArray5(InlineArray5 value);
+
+       [DllImport(StructABILib)]
+       static extern InlineArray6 EchoInlineArray6(InlineArray6 value);
+
+       [DllImport(StructABILib)]
+       static extern Nested1 EchoNested1(Nested1 value);
+
+       [DllImport(StructABILib)]
+       static extern Nested2 EchoNested2(Nested2 value);
+
+       [DllImport(StructABILib)]
+       static extern Nested3 EchoNested3(Nested3 value);
+
+       [DllImport(StructABILib)]
+       static extern Nested4 EchoNested4(Nested4 value);
+
+       [DllImport(StructABILib)]
+       static extern Nested5 EchoNested5(Nested5 value);
+
+       [DllImport(StructABILib)]
+       static extern Nested6 EchoNested6(Nested6 value);
+
+       [DllImport(StructABILib)]
+       static extern Nested7 EchoNested7(Nested7 value);
+
+       [DllImport(StructABILib)]
+       static extern Nested8 EchoNested8(Nested8 value);
+
+       [DllImport(StructABILib)]
+       static extern Nested9 EchoNested9(Nested9 value);
+
+       static int Main()
+       {
+               var ok = true;
+               SingleByte expectedSingleByte = SingleByte.Get();
+               SingleByte actualSingleByte = EchoSingleByte(expectedSingleByte);
+               if (!expectedSingleByte.Equals(actualSingleByte))
+               {
+                       Console.WriteLine("EchoSingleByte failed");
+                       ok = false;
+               }
+
+               SingleLong expectedSingleLong = SingleLong.Get();
+               SingleLong actualSingleLong = EchoSingleLong(expectedSingleLong);
+               if (!expectedSingleLong.Equals(actualSingleLong))
+               {
+                       Console.WriteLine("EchoSingleLong failed");
+                       ok = false;
+               }
+
+               SingleFloat expectedSingleFloat = SingleFloat.Get();
+               SingleFloat actualSingleFloat = EchoSingleFloat(expectedSingleFloat);
+               if (!expectedSingleFloat.Equals(actualSingleFloat))
+               {
+                       Console.WriteLine("EchoSingleFloat failed");
+                       ok = false;
+               }
+
+               SingleDouble expectedSingleDouble = SingleDouble.Get();
+               SingleDouble actualSingleDouble = EchoSingleDouble(expectedSingleDouble);
+               if (!expectedSingleDouble.Equals(actualSingleDouble))
+               {
+                       Console.WriteLine("EchoSingleDouble failed");
+                       ok = false;
+               }
+
+               ByteAndFloat expectedByteAndFloat = ByteAndFloat.Get();
+               ByteAndFloat actualByteAndFloat = EchoByteAndFloat(expectedByteAndFloat);
+               if (!expectedByteAndFloat.Equals(actualByteAndFloat))
+               {
+                       Console.WriteLine("EchoByteAndFloat failed");
+                       ok = false;
+               }
+
+               LongAndFloat expectedLongAndFloat = LongAndFloat.Get();
+               LongAndFloat actualLongAndFloat = EchoLongAndFloat(expectedLongAndFloat);
+               if (!expectedLongAndFloat.Equals(actualLongAndFloat))
+               {
+                       Console.WriteLine("EchoLongAndFloat failed");
+                       ok = false;
+               }
+
+               ByteAndDouble expectedByteAndDouble = ByteAndDouble.Get();
+               ByteAndDouble actualByteAndDouble = EchoByteAndDouble(expectedByteAndDouble);
+               if (!expectedByteAndDouble.Equals(actualByteAndDouble))
+               {
+                       Console.WriteLine("EchoByteAndDouble failed");
+                       ok = false;
+               }
+
+               DoubleAndByte expectedDoubleAndByte = DoubleAndByte.Get();
+               DoubleAndByte actualDoubleAndByte = EchoDoubleAndByte(expectedDoubleAndByte);
+               if (!expectedDoubleAndByte.Equals(actualDoubleAndByte))
+               {
+                       Console.WriteLine("EchoDoubleAndByte failed");
+                       ok = false;
+               }
+
+               PointerAndByte expectedPointerAndByte = PointerAndByte.Get();
+               PointerAndByte actualPointerAndByte = EchoPointerAndByte(expectedPointerAndByte);
+               if (!expectedPointerAndByte.Equals(actualPointerAndByte))
+               {
+                       Console.WriteLine("EchoPointerAndByte failed");
+                       ok = false;
+               }
+
+               ByteAndPointer expectedByteAndPointer = ByteAndPointer.Get();
+               ByteAndPointer actualByteAndPointer = EchoByteAndPointer(expectedByteAndPointer);
+               if (!expectedByteAndPointer.Equals(actualByteAndPointer))
+               {
+                       Console.WriteLine("EchoByteAndPointer failed");
+                       ok = false;
+               }
+
+               ByteFloatAndPointer expectedByteFloatAndPointer = ByteFloatAndPointer.Get();
+               ByteFloatAndPointer actualByteFloatAndPointer = EchoByteFloatAndPointer(expectedByteFloatAndPointer);
+               if (!expectedByteFloatAndPointer.Equals(actualByteFloatAndPointer))
+               {
+                       Console.WriteLine("EchoByteFloatAndPointer failed");
+                       ok = false;
+               }
+
+               PointerFloatAndByte expectedPointerFloatAndByte = PointerFloatAndByte.Get();
+               PointerFloatAndByte actualPointerFloatAndByte = EchoPointerFloatAndByte(expectedPointerFloatAndByte);
+               if (!expectedPointerFloatAndByte.Equals(actualPointerFloatAndByte))
+               {
+                       Console.WriteLine("EchoPointerFloatAndByte failed");
+                       ok = false;
+               }
+
+               TwoFloats expectedTwoFloats = TwoFloats.Get();
+               TwoFloats actualTwoFloats = EchoTwoFloats(expectedTwoFloats);
+               if (!expectedTwoFloats.Equals(actualTwoFloats))
+               {
+                       Console.WriteLine("EchoTwoFloats failed");
+                       ok = false;
+               }
+
+               TwoDoubles expectedTwoDoubles = TwoDoubles.Get();
+               TwoDoubles actualTwoDoubles = EchoTwoDoubles(expectedTwoDoubles);
+               if (!expectedTwoDoubles.Equals(actualTwoDoubles))
+               {
+                       Console.WriteLine("EchoTwoDoubles failed");
+                       ok = false;
+               }
+
+               InlineArray1 expectedInlineArray1 = InlineArray1.Get();
+               InlineArray1 actualInlineArray1 = EchoInlineArray1(expectedInlineArray1);
+               if (!expectedInlineArray1.Equals(actualInlineArray1))
+               {
+                       Console.WriteLine("EchoInlineArray1 failed");
+                       ok = false;
+               }
+
+               InlineArray2 expectedInlineArray2 = InlineArray2.Get();
+               InlineArray2 actualInlineArray2 = EchoInlineArray2(expectedInlineArray2);
+               if (!expectedInlineArray2.Equals(actualInlineArray2))
+               {
+                       Console.WriteLine("EchoInlineArray2 failed");
+                       ok = false;
+               }
+
+               InlineArray3 expectedInlineArray3 = InlineArray3.Get();
+               InlineArray3 actualInlineArray3 = EchoInlineArray3(expectedInlineArray3);
+               if (!expectedInlineArray3.Equals(actualInlineArray3))
+               {
+                       Console.WriteLine("EchoInlineArray3 failed");
+                       ok = false;
+               }
+
+               InlineArray4 expectedInlineArray4 = InlineArray4.Get();
+               InlineArray4 actualInlineArray4 = EchoInlineArray4(expectedInlineArray4);
+               if (!expectedInlineArray4.Equals(actualInlineArray4))
+               {
+                       Console.WriteLine("EchoInlineArray4 failed");
+                       ok = false;
+               }
+
+               InlineArray5 expectedInlineArray5 = InlineArray5.Get();
+               InlineArray5 actualInlineArray5 = EchoInlineArray5(expectedInlineArray5);
+               if (!expectedInlineArray5.Equals(actualInlineArray5))
+               {
+                       Console.WriteLine("EchoInlineArray5 failed");
+                       ok = false;
+               }
+
+               InlineArray6 expectedInlineArray6 = InlineArray6.Get();
+               InlineArray6 actualInlineArray6 = EchoInlineArray6(expectedInlineArray6);
+               if (!expectedInlineArray6.Equals(actualInlineArray6))
+               {
+                       Console.WriteLine("EchoInlineArray6 failed");
+                       ok = false;
+               }
+
+               Nested1 expectedNested1 = Nested1.Get();
+               Nested1 actualNested1 = EchoNested1(expectedNested1);
+               if (!expectedNested1.Equals(actualNested1))
+               {
+                       Console.WriteLine("EchoNested1 failed");
+                       ok = false;
+               }
+
+               Nested2 expectedNested2 = Nested2.Get();
+               Nested2 actualNested2 = EchoNested2(expectedNested2);
+               if (!expectedNested2.Equals(actualNested2))
+               {
+                       Console.WriteLine("EchoNested2 failed");
+                       ok = false;
+               }
+
+               Nested3 expectedNested3 = Nested3.Get();
+               Nested3 actualNested3 = EchoNested3(expectedNested3);
+               if (!expectedNested3.Equals(actualNested3))
+               {
+                       Console.WriteLine("EchoNested3 failed");
+                       ok = false;
+               }
+
+               Nested4 expectedNested4 = Nested4.Get();
+               Nested4 actualNested4 = EchoNested4(expectedNested4);
+               if (!expectedNested4.Equals(actualNested4))
+               {
+                       Console.WriteLine("EchoNested4 failed");
+                       ok = false;
+               }
+
+               Nested5 expectedNested5 = Nested5.Get();
+               Nested5 actualNested5 = EchoNested5(expectedNested5);
+               if (!expectedNested5.Equals(actualNested5))
+               {
+                       Console.WriteLine("EchoNested5 failed");
+                       ok = false;
+               }
+
+               Nested6 expectedNested6 = Nested6.Get();
+               Nested6 actualNested6 = EchoNested6(expectedNested6);
+               if (!expectedNested6.Equals(actualNested6))
+               {
+                       Console.WriteLine("EchoNested6 failed");
+                       ok = false;
+               }
+
+               Nested7 expectedNested7 = Nested7.Get();
+               Nested7 actualNested7 = EchoNested7(expectedNested7);
+               if (!expectedNested7.Equals(actualNested7))
+               {
+                       Console.WriteLine("EchoNested7 failed");
+                       ok = false;
+               }
+
+               Nested8 expectedNested8 = Nested8.Get();
+               Nested8 actualNested8 = EchoNested8(expectedNested8);
+               if (!expectedNested8.Equals(actualNested8))
+               {
+                       Console.WriteLine("EchoNested8 failed");
+                       ok = false;
+               }
+
+               Nested9 expectedNested9 = Nested9.Get();
+               Nested9 actualNested9 = EchoNested9(expectedNested9);
+               if (!expectedNested9.Equals(actualNested9))
+               {
+                       Console.WriteLine("EchoNested9 failed");
+                       ok = false;
+               }
+
+               return ok ? 100 : -1;
+       }
+}
diff --git a/tests/src/JIT/Directed/StructABI/StructABI.csproj b/tests/src/JIT/Directed/StructABI/StructABI.csproj
new file mode 100644 (file)
index 0000000..b23f7f8
--- /dev/null
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <AssemblyName>StructABI</AssemblyName>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{4B4B0F32-3E78-40B7-A0AD-B844F36CB3B2}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+  </PropertyGroup>
+  <!-- Default configurations to help VS understand the configurations -->
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+  </PropertyGroup>
+  <ItemGroup>
+    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+      <Visible>False</Visible>
+    </CodeAnalysisDependentAssemblyPaths>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="StructABI.cs" />
+
+    <Compile Include="StructABI.Windows.cs" Condition="'$(OSGroup)' == 'Windows_NT'" />
+    <Compile Include="StructABI.Unix.cs" Condition="'$(OSGroup)' == 'Linux' Or '$(OSGroup)' == 'FreeBSD'" />
+    <Compile Include="StructABI.OSX.cs" Condition="'$(OSGroup)' == 'OSX'" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="project.json" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="CMakeLists.txt" />
+  </ItemGroup>
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/JIT/Directed/StructABI/project.json b/tests/src/JIT/Directed/StructABI/project.json
new file mode 100644 (file)
index 0000000..f8f0568
--- /dev/null
@@ -0,0 +1,10 @@
+{
+  "dependencies": {
+    "System.Runtime": "4.0.20-beta-23302",
+    "System.Runtime.InteropServices": "4.0.20-beta-23302",
+    "System.Console": "4.0.0-beta-23302",
+  },
+  "frameworks": {
+    "dnxcore50": {}
+  }
+}
index 8803c7f..40d9019 100644 (file)
     <SkipSigning Condition="'$(CrossGen)' == 'true'">true</SkipSigning>
   </PropertyGroup>
 
+  <!-- Expose the target OS in a more convenient fashion -->
+  <PropertyGroup>
+    <OSGroup Condition="'$(OSGroup)'=='' and $(Configuration.StartsWith('Windows'))">Windows_NT</OSGroup>
+    <OSGroup Condition="'$(OSGroup)'=='' and $(Configuration.StartsWith('Linux'))">Linux</OSGroup>
+    <OSGroup Condition="'$(OSGroup)'=='' and $(Configuration.StartsWith('OSX'))">OSX</OSGroup>
+    <OSGroup Condition="'$(OSGroup)'=='' and $(Configuration.StartsWith('FreeBSD'))">FreeBSD</OSGroup>
+    <OSGroup Condition="'$(OSGroup)'==''">Windows_NT</OSGroup>
+  </PropertyGroup>
+
 </Project>