summaryrefslogtreecommitdiff
path: root/tests/src/readytorun/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests/src/readytorun/tests')
-rw-r--r--tests/src/readytorun/tests/fieldgetter.il215
-rw-r--r--tests/src/readytorun/tests/fieldgetter.ilproj30
-rw-r--r--tests/src/readytorun/tests/generics.cs650
-rw-r--r--tests/src/readytorun/tests/generics.csproj32
-rw-r--r--tests/src/readytorun/tests/genericsload/callgenericctor.cs35
-rw-r--r--tests/src/readytorun/tests/genericsload/callgenericctor.csproj50
-rw-r--r--tests/src/readytorun/tests/genericsload/genericslib.il58
-rw-r--r--tests/src/readytorun/tests/genericsload/genericslib.ilproj37
-rw-r--r--tests/src/readytorun/tests/genericsload/usegenericfield.cs39
-rw-r--r--tests/src/readytorun/tests/genericsload/usegenericfield.csproj50
-rw-r--r--tests/src/readytorun/tests/main.cs494
-rw-r--r--tests/src/readytorun/tests/mainv1.csproj56
-rw-r--r--tests/src/readytorun/tests/mainv2.csproj59
-rw-r--r--tests/src/readytorun/tests/test.cs412
-rw-r--r--tests/src/readytorun/tests/testv1/test.csproj32
-rw-r--r--tests/src/readytorun/tests/testv2/test.csproj32
16 files changed, 2281 insertions, 0 deletions
diff --git a/tests/src/readytorun/tests/fieldgetter.il b/tests/src/readytorun/tests/fieldgetter.il
new file mode 100644
index 0000000000..c2eff200af
--- /dev/null
+++ b/tests/src/readytorun/tests/fieldgetter.il
@@ -0,0 +1,215 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+.assembly extern System.Console { }
+.assembly extern mscorlib { }
+.assembly extern test { }
+
+.assembly fieldgetter { }
+.module fieldgetter.dll
+
+//==========================================================================================
+
+.class public auto ansi beforefieldinit Gen`1<T>
+ extends [mscorlib]System.Object
+{
+ .field public int32 m_Field1
+ .field public string m_Field2
+ .field public !T m_Field3
+ .field public static class [mscorlib]System.Collections.Generic.List`1<!T> m_Field4
+ .field public static valuetype [mscorlib]System.Collections.Generic.KeyValuePair`2<!T,int32> m_Field5
+
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method Gen`1::.ctor
+} // end of class Gen`1
+
+.class interface public abstract auto ansi IFieldGetter
+{
+ .method public hidebysig newslot abstract virtual
+ instance class [mscorlib]System.Reflection.FieldInfo
+ GetGenT_Field1() cil managed
+ {
+ } // end of method IFieldGetter::GetGenT_Field1
+
+ .method public hidebysig newslot abstract virtual
+ instance class [mscorlib]System.Reflection.FieldInfo
+ GetGenT_Field2() cil managed
+ {
+ } // end of method IFieldGetter::GetGenT_Field2
+
+ .method public hidebysig newslot abstract virtual
+ instance class [mscorlib]System.Reflection.FieldInfo
+ GetGenT_Field3() cil managed
+ {
+ } // end of method IFieldGetter::GetGenT_Field3
+
+ .method public hidebysig newslot abstract virtual
+ instance class [mscorlib]System.Reflection.FieldInfo
+ GetGenT_Field4() cil managed
+ {
+ } // end of method IFieldGetter::GetGenT_Field4
+
+ .method public hidebysig newslot abstract virtual
+ instance class [mscorlib]System.Reflection.FieldInfo
+ GetGenT_Field5() cil managed
+ {
+ } // end of method IFieldGetter::GetGenT_Field5
+
+ .method public hidebysig newslot abstract virtual
+ instance class [mscorlib]System.Reflection.FieldInfo
+ GetGenDllT_Field1() cil managed
+ {
+ } // end of method IFieldGetter::GetGenDllT_Field1
+
+ .method public hidebysig newslot abstract virtual
+ instance class [mscorlib]System.Reflection.FieldInfo
+ GetGenDllT_Field2() cil managed
+ {
+ } // end of method IFieldGetter::GetGenDllT_Field2
+
+ .method public hidebysig newslot abstract virtual
+ instance class [mscorlib]System.Reflection.FieldInfo
+ GetGenDllT_Field3() cil managed
+ {
+ } // end of method IFieldGetter::GetGenDllT_Field3
+
+ .method public hidebysig newslot abstract virtual
+ instance class [mscorlib]System.Reflection.FieldInfo
+ GetGenDllT_Field4() cil managed
+ {
+ } // end of method IFieldGetter::GetGenDllT_Field4
+
+ .method public hidebysig newslot abstract virtual
+ instance class [mscorlib]System.Reflection.FieldInfo
+ GetGenDllT_Field5() cil managed
+ {
+ } // end of method IFieldGetter::GetGenDllT_Field5
+
+} // end of class IFieldGetter
+
+.class public auto ansi beforefieldinit FieldGetter`1<T>
+ extends [mscorlib]System.Object
+ implements IFieldGetter
+{
+ .method public hidebysig newslot virtual final
+ instance class [mscorlib]System.Reflection.FieldInfo
+ GetGenT_Field1() cil managed
+ {
+ ldtoken field int32 class Gen`1<!0>::m_Field1
+ ldtoken class Gen`1<!0>
+ call class [mscorlib]System.Reflection.FieldInfo [mscorlib]System.Reflection.FieldInfo::GetFieldFromHandle(valuetype [mscorlib]System.RuntimeFieldHandle, valuetype [mscorlib]System.RuntimeTypeHandle)
+ ret
+ } // end of method FieldGetter`1::GetGenT_Field1
+
+ .method public hidebysig newslot virtual final
+ instance class [mscorlib]System.Reflection.FieldInfo
+ GetGenT_Field2() cil managed
+ {
+ ldtoken field string class Gen`1<!0>::m_Field2
+ ldtoken class Gen`1<!0>
+ call class [mscorlib]System.Reflection.FieldInfo [mscorlib]System.Reflection.FieldInfo::GetFieldFromHandle(valuetype [mscorlib]System.RuntimeFieldHandle, valuetype [mscorlib]System.RuntimeTypeHandle)
+ ret
+ } // end of method FieldGetter`1::GetGenT_Field2
+
+ .method public hidebysig newslot virtual final
+ instance class [mscorlib]System.Reflection.FieldInfo
+ GetGenT_Field3() cil managed
+ {
+ ldtoken field !0 class Gen`1<!0>::m_Field3
+ ldtoken class Gen`1<!0>
+ call class [mscorlib]System.Reflection.FieldInfo [mscorlib]System.Reflection.FieldInfo::GetFieldFromHandle(valuetype [mscorlib]System.RuntimeFieldHandle, valuetype [mscorlib]System.RuntimeTypeHandle)
+ ret
+ } // end of method FieldGetter`1::GetGenT_Field3
+
+ .method public hidebysig newslot virtual final
+ instance class [mscorlib]System.Reflection.FieldInfo
+ GetGenT_Field4() cil managed
+ {
+ ldtoken field class [mscorlib]System.Collections.Generic.List`1<!0> class Gen`1<!0>::m_Field4
+ ldtoken class Gen`1<!0>
+ call class [mscorlib]System.Reflection.FieldInfo [mscorlib]System.Reflection.FieldInfo::GetFieldFromHandle(valuetype [mscorlib]System.RuntimeFieldHandle, valuetype [mscorlib]System.RuntimeTypeHandle)
+ ret
+ } // end of method FieldGetter`1::GetGenT_Field4
+
+ .method public hidebysig newslot virtual final
+ instance class [mscorlib]System.Reflection.FieldInfo
+ GetGenT_Field5() cil managed
+ {
+ ldtoken field valuetype [mscorlib]System.Collections.Generic.KeyValuePair`2<!0,int32> class Gen`1<!0>::m_Field5
+ ldtoken class Gen`1<!0>
+ call class [mscorlib]System.Reflection.FieldInfo [mscorlib]System.Reflection.FieldInfo::GetFieldFromHandle(valuetype [mscorlib]System.RuntimeFieldHandle, valuetype [mscorlib]System.RuntimeTypeHandle)
+ ret
+ } // end of method FieldGetter`1::GetGenT_Field5
+
+
+
+
+
+ .method public hidebysig newslot virtual final
+ instance class [mscorlib]System.Reflection.FieldInfo
+ GetGenDllT_Field1() cil managed
+ {
+ ldtoken field string class [test]MyGeneric`2<!0,!0>::m_Field1
+ ldtoken class [test]MyGeneric`2<!0,!0>
+ call class [mscorlib]System.Reflection.FieldInfo [mscorlib]System.Reflection.FieldInfo::GetFieldFromHandle(valuetype [mscorlib]System.RuntimeFieldHandle, valuetype [mscorlib]System.RuntimeTypeHandle)
+ ret
+ } // end of method FieldGetter`1::GetGenDllT_Field1
+
+ .method public hidebysig newslot virtual final
+ instance class [mscorlib]System.Reflection.FieldInfo
+ GetGenDllT_Field2() cil managed
+ {
+ ldtoken field !0 class [test]MyGeneric`2<!0,!0>::m_Field2
+ ldtoken class [test]MyGeneric`2<!0,!0>
+ call class [mscorlib]System.Reflection.FieldInfo [mscorlib]System.Reflection.FieldInfo::GetFieldFromHandle(valuetype [mscorlib]System.RuntimeFieldHandle, valuetype [mscorlib]System.RuntimeTypeHandle)
+ ret
+ } // end of method FieldGetter`1::GetGenDllT_Field2
+
+ .method public hidebysig newslot virtual final
+ instance class [mscorlib]System.Reflection.FieldInfo
+ GetGenDllT_Field3() cil managed
+ {
+ ldtoken field class [mscorlib]System.Collections.Generic.List`1<!0> class [test]MyGeneric`2<!0,!0>::m_Field3
+ ldtoken class [test]MyGeneric`2<!0,!0>
+ call class [mscorlib]System.Reflection.FieldInfo [mscorlib]System.Reflection.FieldInfo::GetFieldFromHandle(valuetype [mscorlib]System.RuntimeFieldHandle, valuetype [mscorlib]System.RuntimeTypeHandle)
+ ret
+ } // end of method FieldGetter`1::GetGenDllT_Field3
+
+ .method public hidebysig newslot virtual final
+ instance class [mscorlib]System.Reflection.FieldInfo
+ GetGenDllT_Field4() cil managed
+ {
+ ldtoken field valuetype [mscorlib]System.Collections.Generic.KeyValuePair`2<!0,int32> class [test]MyGeneric`2<!0,!0>::m_Field4
+ ldtoken class [test]MyGeneric`2<!0,!0>
+ call class [mscorlib]System.Reflection.FieldInfo [mscorlib]System.Reflection.FieldInfo::GetFieldFromHandle(valuetype [mscorlib]System.RuntimeFieldHandle, valuetype [mscorlib]System.RuntimeTypeHandle)
+ ret
+ } // end of method FieldGetter`1::GetGenDllT_Field4
+
+ .method public hidebysig newslot virtual final
+ instance class [mscorlib]System.Reflection.FieldInfo
+ GetGenDllT_Field5() cil managed
+ {
+ ldtoken field int32 class [test]MyGeneric`2<!0,!0>::m_Field5
+ ldtoken class [test]MyGeneric`2<!0,!0>
+ call class [mscorlib]System.Reflection.FieldInfo [mscorlib]System.Reflection.FieldInfo::GetFieldFromHandle(valuetype [mscorlib]System.RuntimeFieldHandle, valuetype [mscorlib]System.RuntimeTypeHandle)
+ ret
+ } // end of method FieldGetter`1::GetGenDllT_Field5
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method FieldGetter`1::.ctor
+
+} // end of class FieldGetter`1
+
diff --git a/tests/src/readytorun/tests/fieldgetter.ilproj b/tests/src/readytorun/tests/fieldgetter.ilproj
new file mode 100644
index 0000000000..b3f2aa9e13
--- /dev/null
+++ b/tests/src/readytorun/tests/fieldgetter.ilproj
@@ -0,0 +1,30 @@
+<?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>
+ <AssemblyName>fieldgetter</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <OutputType>Library</OutputType>
+ <CLRTestKind>SharedLibrary</CLRTestKind>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="fieldgetter.il" />
+ </ItemGroup>
+
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/readytorun/tests/generics.cs b/tests/src/readytorun/tests/generics.cs
new file mode 100644
index 0000000000..4c41756305
--- /dev/null
+++ b/tests/src/readytorun/tests/generics.cs
@@ -0,0 +1,650 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading;
+
+class Program
+{
+ static int Main()
+ {
+ // Run all tests 3x times to exercise both slow and fast paths work
+ for (int i = 0; i < 3; i++)
+ RunAllTests();
+
+ Console.WriteLine(Assert.HasAssertFired ? "FAILED" : "PASSED");
+ return Assert.HasAssertFired ? 1 : 100;
+ }
+
+ static void RunAllTests()
+ {
+ RunTest1();
+ RunTest2();
+ RunTest3();
+ RunTest4();
+ RunTest5();
+ RunTest6();
+ RunTest7();
+ }
+
+ static void RunTest1()
+ {
+ var originalCultureInfo = CultureInfo.CurrentCulture;
+
+ try
+ {
+ CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
+
+ DateTime dt = new DateTime(1776, 7, 4);
+ string dtString = dt.ToString();
+ Assert.AreEqual(new GenClass1c<DateTime>(dt).ToStringEx(7), dtString + " 7");
+ Assert.AreEqual(new GenClass1c<int>(1).ToStringEx(7), "1 7");
+ Assert.AreEqual(new GenClass1c<long>(2).ToStringEx(7), "2 7");
+ Assert.AreEqual(new GenClass1c<float>(3.14f).ToStringEx(7), "3.14 7");
+ Assert.AreEqual(new GenClass1c<double>(4.13).ToStringEx(7), "4.13 7");
+ Assert.AreEqual(new GenClass1c<int?>(9).ToString(), "9");
+
+ Assert.AreEqual(new GenClass2<DateTime, double>(dt, 3.1416).ToString(), dtString + " 3.1416");
+ Assert.AreEqual(new GenClass2<DateTime, double>(dt, 3.1416).ToStringEx(7, 8), dtString + " 3.1416 7 8");
+ Assert.AreEqual(new GenClass2<object, string>(new object(), "3.1416").ToString(), "System.Object 3.1416");
+ Assert.AreEqual(new GenClass2<object, string>(new object(), "3.1416").ToStringEx(7L, 8L), "System.Object 3.1416 7 8");
+ Assert.AreEqual(GetString(7.0, 8.0), "7 8");
+
+ var gen1a = new GenClass1a<object>();
+ Assert.AreEqual(gen1a.CreateGenClass1b(), "GenClass1b`1[System.Object]");
+ Assert.AreEqual(gen1a.CreateGenClass1bArray(), "GenClass1b`1[System.Object][]");
+
+ var gen1aInt = new GenClass1a<int>();
+ var gen1bInt = new GenClass1b<int>();
+ var gen1bLong = new GenClass1b<long>();
+ Assert.AreEqual(gen1bInt.IsGenClass1a(gen1aInt).ToString(), "True");
+ Assert.AreEqual(gen1bLong.IsGenClass1a(gen1aInt).ToString(), "False");
+ Assert.AreEqual(gen1bInt.AsGenClass1a(gen1aInt)?.ToString() ?? "null", gen1aInt.ToString());
+ Assert.AreEqual(gen1bLong.AsGenClass1a(gen1aInt)?.ToString() ?? "null", "null");
+
+ var gen1aString = new GenClass1a<string>();
+ var gen1b = new GenClass1b<string>();
+ Assert.AreEqual(gen1b.IsGenClass1a(gen1aString).ToString(), "True");
+ Assert.AreEqual(gen1b.AsGenClass1a(gen1aString)?.ToString() ?? "null", gen1aString.ToString());
+ Assert.AreEqual(GenClass1a<string>.CallVirtual(gen1b), "GenClass1b`1[System.String].VirtualMethod");
+ Assert.AreEqual(GenClass1a<string>.CallInterface(gen1b), "GenClass1b`1[System.String].InterfaceMethod1");
+ Assert.AreEqual(GenClass1a<string>.CallInterface(gen1b, "Test").ToString(), "GenClass1b`1[System.String]");
+
+ NormalClass n = new NormalClass();
+ Assert.AreEqual(CallGenVirtMethod<int>(n).ToString(), "GenClass1a`1[System.Int32]");
+ Assert.AreEqual(CallGenVirtMethod<int>(n, 42).ToString(), "System.Int32[]");
+ Assert.AreEqual(CallGenVirtMethod<string>(n).ToString(), "GenClass1a`1[System.String]");
+ Assert.AreEqual(CallGenVirtMethod<string>(n, "forty-two").ToString(), "System.String[]");
+ }
+ finally
+ {
+ CultureInfo.CurrentCulture = originalCultureInfo;
+ }
+ }
+
+ static void RunTest2()
+ {
+ var mi = new GenBase<MyClass0, int>();
+ var ol = new GenBase<object, long>();
+
+ // LDTOKEN OF TYPE PARAMETERS TEST
+ Assert.AreEqual(mi.GetT(), "MyClass0");
+ Assert.AreEqual(mi.GetU(), "System.Int32");
+ Assert.AreEqual(ol.GetT(), "System.Object");
+ Assert.AreEqual(ol.GetU(), "System.Int64");
+ Assert.AreEqual(mi.GetT(), "MyClass0");
+ Assert.AreEqual(mi.GetU(), "System.Int32");
+
+ Assert.AreEqual(mi.GetTArray(), "MyClass0[]");
+ Assert.AreEqual(ol.GetTArray(), "System.Object[]");
+ Assert.AreEqual(mi.GetTArray(), "MyClass0[]");
+ Assert.AreEqual(mi.GetTBasedInst(), "MyGenClass2`1[MyGenClass1`1[MyClass0]]");
+ Assert.AreEqual(ol.GetTBasedInst(), "MyGenClass2`1[MyGenClass1`1[System.Object]]");
+ Assert.AreEqual(mi.GetTBasedInst(), "MyGenClass2`1[MyGenClass1`1[MyClass0]]");
+ }
+
+ static void RunTest3()
+ {
+ var mi = new GenBase<MyClass0, int>();
+ var ol = new GenBase<object, long>();
+
+ // GENERIC INTERFACE CALL AND CASTING TEST
+ Assert.AreEqual(mi.IFaceCallTest(mi), "IFaceCallTest = IFooFunc - GenBase`2[MyClass0,System.Int32]");
+ Assert.AreEqual(ol.IFaceCallTest(ol), "IFaceCallTest = IFooFunc - GenBase`2[System.Object,System.Int64]");
+ Assert.AreEqual(mi.IFaceCallTest(mi), "IFaceCallTest = IFooFunc - GenBase`2[MyClass0,System.Int32]");
+
+ // LDTOKEN TEST
+ Assert.AreEqual(mi.LdTokenTest(), "LdTokenTest - System.Collections.Generic.Dictionary`2[MyClass0,System.Int32]");
+ Assert.AreEqual(ol.LdTokenTest(), "LdTokenTest - System.Collections.Generic.Dictionary`2[System.Object,System.Int64]");
+ Assert.AreEqual(mi.LdTokenTest(), "LdTokenTest - System.Collections.Generic.Dictionary`2[MyClass0,System.Int32]");
+
+ // DICTIONARY ACCESS FROM STATIC METHOD
+ Assert.AreEqual(GenBase<MyClass0, int>.StaticNonGenMethod(), "StaticNonGenMethod - System.Collections.Generic.List`1[MyClass0]");
+ Assert.AreEqual(GenBase<object, long>.StaticNonGenMethod(), "StaticNonGenMethod - System.Collections.Generic.List`1[System.Object]");
+ Assert.AreEqual(GenBase<MyClass0, int>.StaticNonGenMethod(), "StaticNonGenMethod - System.Collections.Generic.List`1[MyClass0]");
+ Assert.AreEqual(GenBase<MyClass0, int>.StaticGenMethod<Type>(), "StaticGenMethod - System.Collections.Generic.Dictionary`2[System.Type,MyClass0]");
+ Assert.AreEqual(GenBase<object, long>.StaticGenMethod<Type>(), "StaticGenMethod - System.Collections.Generic.Dictionary`2[System.Type,System.Object]");
+ Assert.AreEqual(GenBase<MyClass0, int>.StaticGenMethod<Type>(), "StaticGenMethod - System.Collections.Generic.Dictionary`2[System.Type,MyClass0]");
+
+ // NEW TEST
+ Assert.AreEqual(mi.NewTest(), "NewTest - MyClass0 - MyGenClass1`1[MyClass0] - MyClass0[] - MyClass0[,] - MyGenClass3`1[MyClass0][] - MyGenClass3`1[MyClass0][,]");
+ Assert.AreEqual(ol.NewTest(), "NewTest - System.Object - MyGenClass1`1[System.Object] - System.Object[] - System.Object[,] - MyGenClass3`1[System.Object][] - MyGenClass3`1[System.Object][,]");
+ Assert.AreEqual(mi.NewTest(), "NewTest - MyClass0 - MyGenClass1`1[MyClass0] - MyClass0[] - MyClass0[,] - MyGenClass3`1[MyClass0][] - MyGenClass3`1[MyClass0][,]");
+ }
+
+ static void RunTest4()
+ {
+ // FIELDS TEST
+ var fobj1 = new GenBase<MyIdClass0, int>();
+ var fobj2 = new GenBase<MyIdClass1, int>();
+ GenBase<MyIdClass0, int>.SetFieldsTest(fobj1, new MyIdClass0("1"), new MyIdClass0("2"), new MyIdClass0("3"), 1, 2, 3);
+ GenBase<MyIdClass1, int>.SetFieldsTest(fobj2, new MyIdClass1("1"), new MyIdClass1("2"), new MyIdClass1("3"), 1, 2, 3);
+
+ GenBase<MyIdClass0, int>.GetFieldsTest(fobj1, "MyIdClass0=1", "MyIdClass0=2", "MyIdClass0=3", 1, 2, 3);
+ GenBase<MyIdClass1, int>.GetFieldsTest(fobj2, "MyIdClass1=1", "MyIdClass1=2", "MyIdClass1=3", 1, 2, 3);
+
+ Thread t = new Thread(new ThreadStart(() =>
+ {
+ GenBase<MyIdClass0, int>.SetFieldsTest(fobj1, new MyIdClass0("11"), new MyIdClass0("22"), new MyIdClass0("33"), 11, 22, 33);
+ GenBase<MyIdClass1, int>.SetFieldsTest(fobj2, new MyIdClass1("11"), new MyIdClass1("22"), new MyIdClass1("33"), 11, 22, 33);
+
+ GenBase<MyIdClass0, int>.GetFieldsTest(fobj1, "MyIdClass0=11", "MyIdClass0=22", "MyIdClass0=33", 11, 22, 33);
+ GenBase<MyIdClass1, int>.GetFieldsTest(fobj2, "MyIdClass1=11", "MyIdClass1=22", "MyIdClass1=33", 11, 22, 33);
+ }));
+ t.Start();
+ t.Join();
+
+ GenBase<MyIdClass0, int>.GetFieldsTest(fobj1, "MyIdClass0=11", "MyIdClass0=22", "MyIdClass0=3", 11, 22, 3);
+ GenBase<MyIdClass1, int>.GetFieldsTest(fobj2, "MyIdClass1=11", "MyIdClass1=22", "MyIdClass1=3", 11, 22, 3);
+ }
+
+ static void RunTest5()
+ {
+ // DELEGATES TEST
+ var fobj1 = new GenBase<MyIdClass0, int>();
+ var fobj2 = new GenBase<MyIdClass1, int>();
+
+ Func<MyIdClass0, int, string>[] del1 = fobj1.GetDelegateTest();
+ Func<MyIdClass1, int, string>[] del2 = fobj2.GetDelegateTest();
+ Assert.AreEqual(del1[0](new MyIdClass0("1"), 1), "InstanceDelMethod(GenBase`2[MyIdClass0,System.Int32] - MyIdClass0=1 - 1)");
+ Assert.AreEqual(del1[1](new MyIdClass0("2"), 2), "StaticDelMethod(MyIdClass0=2 - 2)");
+ Assert.AreEqual(del2[0](new MyIdClass1("3"), 3), "InstanceDelMethod(GenBase`2[MyIdClass1,System.Int32] - MyIdClass1=3 - 3)");
+ Assert.AreEqual(del2[1](new MyIdClass1("4"), 4), "StaticDelMethod(MyIdClass1=4 - 4)");
+ Assert.AreEqual(del1[0](new MyIdClass0("5"), 5), "InstanceDelMethod(GenBase`2[MyIdClass0,System.Int32] - MyIdClass0=5 - 5)");
+ Assert.AreEqual(del1[1](new MyIdClass0("6"), 6), "StaticDelMethod(MyIdClass0=6 - 6)");
+ }
+
+ static void RunTest6()
+ {
+ // BOXING AND NULLABLE TEST
+ var mi = new GenBase<MyClass0, int>();
+ var ol = new GenBase<object, long>();
+
+ Assert.AreEqual(mi.BoxingAndNullableTest(
+ new MyGenClass1<KeyValuePair<MyClass0, int>>(),
+ new MyGenStruct1<Dictionary<MyClass0, int>>(),
+ new MyGenStruct1<Dictionary<MyClass0, int>>()),
+ "BoxingAndNullableTest - GenBase`2[MyClass0,System.Int32]::(MyGenClass1`1[System.Collections.Generic.KeyValuePair`2[MyClass0,System.Int32]] - MyGenStruct1`1[System.Collections.Generic.Dictionary`2[MyClass0,System.Int32]] - MyGenStruct1`1[System.Collections.Generic.Dictionary`2[MyClass0,System.Int32]])");
+ Assert.AreEqual(ol.BoxingAndNullableTest(
+ new MyGenClass1<KeyValuePair<object, long>>(),
+ new MyGenStruct1<Dictionary<object, long>>(),
+ new MyGenStruct1<Dictionary<object, long>>()),
+ "BoxingAndNullableTest - GenBase`2[System.Object,System.Int64]::(MyGenClass1`1[System.Collections.Generic.KeyValuePair`2[System.Object,System.Int64]] - MyGenStruct1`1[System.Collections.Generic.Dictionary`2[System.Object,System.Int64]] - MyGenStruct1`1[System.Collections.Generic.Dictionary`2[System.Object,System.Int64]])");
+ }
+
+ static void RunTest7()
+ {
+ // GENERIC METHOD TEST
+
+ Base b = new Base();
+ var obj1 = new GenBase<MyClass1, int>();
+ var obj2 = new GenBase<MyClass2, long>();
+
+ // LDTOKEN OF TYPE PARAMETERS TEST
+ Assert.AreEqual(b.GetT<string>().ToString(), "System.String");
+ Assert.AreEqual(b.GetT<object>().ToString(), "System.Object");
+ Assert.AreEqual(b.GetTArray<string>().ToString(), "System.String[]");
+ Assert.AreEqual(b.GetTArray<object>().ToString(), "System.Object[]");
+ Assert.AreEqual(b.GetTBasedInst<string>().ToString(), "MyGenClass2`1[MyGenClass1`1[System.String]]");
+ Assert.AreEqual(b.GetTBasedInst<object>().ToString(), "MyGenClass2`1[MyGenClass1`1[System.Object]]");
+
+ Assert.AreEqual(b.GetT<MyClass1, int>(), "MyClass1");
+ Assert.AreEqual(b.GetU<MyClass1, int>(), "System.Int32");
+ Assert.AreEqual(b.GetT<MyClass2, long>(), "MyClass2");
+ Assert.AreEqual(b.GetU<MyClass2, long>(), "System.Int64");
+
+ // GENERIC INTERFACE CALL AND CASTING TEST
+ Assert.AreEqual(b.IFaceCallTest<MyClass1, int>(obj1), "IFaceCallTest = IFooFunc - GenBase`2[MyClass1,System.Int32]");
+ Assert.AreEqual(b.IFaceCallTest<MyClass2, long>(obj2), "IFaceCallTest = IFooFunc - GenBase`2[MyClass2,System.Int64]");
+
+ // LDTOKEN TEST
+ Assert.AreEqual(b.LdTokenTest<MyClass1, int>(), "System.Collections.Generic.Dictionary`2[MyClass1,System.Int32]");
+ Assert.AreEqual(b.LdTokenTest<MyClass2, long>(), "System.Collections.Generic.Dictionary`2[MyClass2,System.Int64]");
+
+ // DICTIONARY ACCESS FROM STATIC METHOD
+ Assert.AreEqual(Base.StaticGenMethod<float, MyClass1>(), "StaticGenMethod - System.Collections.Generic.Dictionary`2[MyClass1,System.Single]");
+ Assert.AreEqual(Base.StaticGenMethod<float, MyClass2>(), "StaticGenMethod - System.Collections.Generic.Dictionary`2[MyClass2,System.Single]");
+
+ // NEW TEST
+ Assert.AreEqual(b.NewTest<MyClass1, MyClass2>(),
+ "NewTest - MyClass1 - MyGenClass1`1[MyClass1] - MyClass1[] - MyClass1[,] - MyGenClass2`1[MyClass1][] - MyGenClass2`1[MyClass1][,]");
+ Assert.AreEqual(b.NewTest<MyClass2, MyClass1>(),
+ "NewTest - MyClass2 - MyGenClass1`1[MyClass2] - MyClass2[] - MyClass2[,] - MyGenClass2`1[MyClass2][] - MyGenClass2`1[MyClass2][,]");
+
+ // BOXING AND NULLABLE TEST
+ Assert.AreEqual(b.BoxingAndNullableTest<MyClass0, int>(
+ new MyGenClass1<KeyValuePair<MyClass0, int>>(),
+ new MyGenStruct1<Dictionary<MyClass0, int>>(),
+ new MyGenStruct1<Dictionary<MyClass0, int>>()),
+ "BoxingAndNullableTest - Base::(MyGenClass1`1[System.Collections.Generic.KeyValuePair`2[MyClass0,System.Int32]] - MyGenStruct1`1[System.Collections.Generic.Dictionary`2[MyClass0,System.Int32]] - MyGenStruct1`1[System.Collections.Generic.Dictionary`2[MyClass0,System.Int32]])");
+ Assert.AreEqual(b.BoxingAndNullableTest<object, int>(
+ new MyGenClass1<KeyValuePair<object, int>>(),
+ new MyGenStruct1<Dictionary<object, int>>(),
+ new MyGenStruct1<Dictionary<object, int>>()),
+ "BoxingAndNullableTest - Base::(MyGenClass1`1[System.Collections.Generic.KeyValuePair`2[System.Object,System.Int32]] - MyGenStruct1`1[System.Collections.Generic.Dictionary`2[System.Object,System.Int32]] - MyGenStruct1`1[System.Collections.Generic.Dictionary`2[System.Object,System.Int32]])");
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static string GetString<X, Y>(X x, Y y)
+ {
+ return string.Join(" ", x, y);
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static GenClass1a<T> CallGenVirtMethod<T>(NormalClass n)
+ {
+ return n.GetGenClass1a<T>();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static IEnumerable<T> CallGenVirtMethod<T>(NormalClass n, object o)
+ {
+ return n.GetEnumerable<T>(o);
+ }
+}
+
+interface IGenInterface<T>
+{
+ string InterfaceMethod1();
+ IGenInterface<T> InterfaceMethod2<U>(U u);
+}
+
+class GenClass1a<T>
+{
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public string CreateGenClass1b()
+ {
+ var x = new GenClass1b<T>();
+ return x.ToString();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public string CreateGenClass1bArray()
+ {
+ var x = new GenClass1b<T>[3];
+ return x.ToString();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static string CallVirtual(GenClass1b<T> x)
+ {
+ return x.VirtualMethod();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static string CallInterface(IGenInterface<T> x)
+ {
+ return x.InterfaceMethod1();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static IGenInterface<U> CallInterface<U, V>(IGenInterface<U> x, V v)
+ {
+ return x.InterfaceMethod2(v);
+ }
+}
+
+class GenClass1b<T> : IGenInterface<T>
+{
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public virtual string VirtualMethod()
+ {
+ return ToString() + ".VirtualMethod";
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public virtual string InterfaceMethod1()
+ {
+ return ToString() + ".InterfaceMethod1";
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public virtual IGenInterface<T> InterfaceMethod2<U>(U u)
+ {
+ return this;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public bool IsGenClass1a(object o)
+ {
+ return o is GenClass1a<T>;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public GenClass1a<T> AsGenClass1a(object o)
+ {
+ return o as GenClass1a<T>;
+ }
+}
+
+class GenClass1c<T> where T : new()
+{
+ public T t;
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public GenClass1c()
+ {
+ t = new T();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public GenClass1c(T _t)
+ {
+ t = _t;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public void SetT(object x)
+ {
+ t = (T)x;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public override string ToString()
+ {
+ return t.ToString();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public string ToStringEx<X>(X x)
+ {
+ return string.Join(" ", t, x);
+ }
+}
+
+class GenClass2<T, U>
+{
+ T t;
+ U u;
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public GenClass2(T t, U u)
+ {
+ this.t = t;
+ this.u = u;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public override string ToString()
+ {
+ return t.ToString() + " " + u.ToString();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public string ToStringEx<X, Y>(X x, Y y)
+ {
+ return string.Join(" ", t, u, x, y);
+ }
+}
+
+class NormalClass
+{
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public virtual GenClass1a<T> GetGenClass1a<T>()
+ {
+ return new GenClass1a<T>();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public virtual IEnumerable<T> GetEnumerable<T>(object o)
+ {
+ T[] array = new T[1];
+ array[0] = (T)o;
+ return array;
+ }
+}
+
+public interface IFoo<T> { string IFooFunc(); }
+public class MyClass0 { }
+public class MyClass1 { }
+public class MyClass2 { }
+public class MyGenClass1<T> { public override string ToString() { return this.GetType().ToString(); } }
+public class MyGenClass2<T> { public override string ToString() { return this.GetType().ToString(); } }
+public class MyGenClass3<T> { public override string ToString() { return this.GetType().ToString(); } }
+public struct MyGenStruct1<T> { public override string ToString() { return this.GetType().ToString(); } }
+public class MyIdClass0 { string _id; public MyIdClass0() { } public MyIdClass0(string id) { _id = id; } public override string ToString() { return "MyIdClass0=" + _id; } }
+public class MyIdClass1 { string _id; public MyIdClass1() { } public MyIdClass1(string id) { _id = id; } public override string ToString() { return "MyIdClass1=" + _id; } }
+
+public class GenBase<T, U> : IFoo<T> where T : new()
+{
+ public T m_fieldT;
+ public U m_fieldU;
+ public static T s_fieldT;
+ public static U s_fieldU;
+ [ThreadStatic]
+ public static T st_fieldT;
+ [ThreadStatic]
+ public static U st_fieldU;
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void SetFieldsTest(GenBase<T, U> obj, T t1, T t2, T t3, U u1, U u2, U u3)
+ {
+ obj.m_fieldT = t1;
+ GenBase<T, U>.s_fieldT = t2;
+ GenBase<T, U>.st_fieldT = t3;
+
+ obj.m_fieldU = u1;
+ GenBase<T, U>.s_fieldU = u2;
+ GenBase<T, U>.st_fieldU = u3;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void GetFieldsTest(GenBase<T, U> obj, string s1, string s2, string s3, U u1, U u2, U u3)
+ {
+ Assert.AreEqual(obj.m_fieldT.ToString(), s1);
+ Assert.AreEqual(GenBase<T, U>.s_fieldT.ToString(), s2);
+ Assert.AreEqual(GenBase<T, U>.st_fieldT.ToString(), s3);
+
+ Assert.AreEqual(obj.m_fieldU, u1);
+ Assert.AreEqual(GenBase<T, U>.s_fieldU, u2);
+ Assert.AreEqual(GenBase<T, U>.st_fieldU, u3);
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ // BUG BUG BUG: bad codegen when method is private
+ public string InstanceDelMethod(T t, U u)
+ {
+ return "InstanceDelMethod(" + this + " - " + t + " - " + u + ")";
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ // BUG BUG BUG: bad codegen when method is private
+ public static string StaticDelMethod(T t, U u)
+ {
+ return "StaticDelMethod(" + t + " - " + u + ")";
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public Func<T, U, string>[] GetDelegateTest()
+ {
+ Func<T, U, string> del1 = this.InstanceDelMethod;
+ Func<T, U, string> del2 = StaticDelMethod;
+ return new Func<T, U, string>[] { del1, del2 };
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public string IFooFunc()
+ {
+ return "IFooFunc - " + this.ToString();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public string IFaceCallTest(object ifoo)
+ {
+ IFoo<T> i = (IFoo<T>)ifoo;
+ return "IFaceCallTest = " + i.IFooFunc();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public string GetT()
+ {
+ return typeof(T).ToString();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public string GetU()
+ {
+ return typeof(U).ToString();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public string GetTArray()
+ {
+ return typeof(T[]).ToString();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public string GetTBasedInst()
+ {
+ return typeof(MyGenClass2<MyGenClass1<T>>).ToString();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public string LdTokenTest()
+ {
+ return "LdTokenTest - " + typeof(Dictionary<T, U>).ToString();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static string StaticNonGenMethod()
+ {
+ return "StaticNonGenMethod - " + typeof(List<T>).ToString();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static string StaticGenMethod<V>()
+ {
+ return "StaticGenMethod - " + typeof(Dictionary<V, T>).ToString();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public string NewTest()
+ {
+ var a = new T();
+ var b = new MyGenClass1<T>();
+ var c = new T[10];
+ var d = new T[30,30];
+ var e = new MyGenClass3<T>[5];
+ var f = new MyGenClass3<T>[5,13];
+ return "NewTest - " + a + " - " + b + " - " + c + " - " + d + " - " + e + " - " + f;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public string BoxingAndNullableTest(MyGenClass1<KeyValuePair<T,U>> t, MyGenStruct1<Dictionary<T,U>> u, MyGenStruct1<Dictionary<T,U>>? u2)
+ {
+ return "BoxingAndNullableTest - " + this + "::(" + t + " - " + u + " - " + u2 + ")";
+ }
+}
+
+public class Base
+{
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public string GetT<T>()
+ {
+ return typeof(T).ToString();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public string GetT<T, U>()
+ {
+ return typeof(T).ToString();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public string GetU<T, U>()
+ {
+ return typeof(U).ToString();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public string GetTArray<T>()
+ {
+ return typeof(T[]).ToString();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public string GetTBasedInst<T>()
+ {
+ return typeof(MyGenClass2<MyGenClass1<T>>).ToString();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public string IFaceCallTest<T, U>(object ifoo)
+ {
+ IFoo<T> i = (IFoo<T>)ifoo;
+ return "IFaceCallTest = " + i.IFooFunc();
+ }
+
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public string LdTokenTest<T, U>()
+ {
+ return typeof(Dictionary<T, U>).ToString();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static string StaticGenMethod<T, U>()
+ {
+ return "StaticGenMethod - " + typeof(Dictionary<U, T>).ToString();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public string NewTest<T, U>() where T : new()
+ {
+ var a = new T();
+ var b = new MyGenClass1<T>();
+ var c = new T[10];
+ var d = new T[30, 30];
+ var e = new MyGenClass2<T>[5];
+ var f = new MyGenClass2<T>[5, 13];
+ return "NewTest - " + a + " - " + b + " - " + c + " - " + d + " - " + e + " - " + f;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public string BoxingAndNullableTest<T, U>(MyGenClass1<KeyValuePair<T, U>> t, MyGenStruct1<Dictionary<T, U>> u, MyGenStruct1<Dictionary<T, U>>? u2)
+ {
+ return "BoxingAndNullableTest - " + this + "::(" + t + " - " + u + " - " + u2 + ")";
+ }
+}
+
+public static class Assert
+{
+ public static bool HasAssertFired;
+
+ public static void AreEqual(Object actual, Object expected)
+ {
+ if (!(actual == null && expected == null) && !actual.Equals(expected))
+ {
+ Console.WriteLine("Not equal!");
+ Console.WriteLine("actual = " + actual.ToString());
+ Console.WriteLine("expected = " + expected.ToString());
+ HasAssertFired = true;
+ }
+ }
+}
diff --git a/tests/src/readytorun/tests/generics.csproj b/tests/src/readytorun/tests/generics.csproj
new file mode 100644
index 0000000000..4ea64b30d6
--- /dev/null
+++ b/tests/src/readytorun/tests/generics.csproj
@@ -0,0 +1,32 @@
+<?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>
+ <AssemblyName>generics</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="generics.cs" />
+ </ItemGroup>
+
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/readytorun/tests/genericsload/callgenericctor.cs b/tests/src/readytorun/tests/genericsload/callgenericctor.cs
new file mode 100644
index 0000000000..05e16afb3b
--- /dev/null
+++ b/tests/src/readytorun/tests/genericsload/callgenericctor.cs
@@ -0,0 +1,35 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//
+
+using System;
+using System.Runtime.CompilerServices;
+
+class Foo<T>
+{
+ [MethodImplAttribute(MethodImplOptions.NoInlining)]
+ internal void M()
+ {
+ new GenClass<T>();
+ }
+}
+
+class Program
+{
+ static int Main()
+ {
+ try
+ {
+ new Foo<string>().M();
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("FAIL");
+ return 101;
+ }
+
+ Console.WriteLine("PASS");
+ return 100;
+ }
+}
diff --git a/tests/src/readytorun/tests/genericsload/callgenericctor.csproj b/tests/src/readytorun/tests/genericsload/callgenericctor.csproj
new file mode 100644
index 0000000000..0f73092f43
--- /dev/null
+++ b/tests/src/readytorun/tests/genericsload/callgenericctor.csproj
@@ -0,0 +1,50 @@
+<?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>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{7DECC55A-B584-4456-83BA-6C42A5B3B3CB}</ProjectGuid>
+ <OutputType>exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <DefineConstants>$(DefineConstants);STATIC;CORECLR</DefineConstants>
+ <ZapRequire>1</ZapRequire>
+ </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>
+ <ProjectReference Include="genericslib.ilproj">
+ <Project>{F74F55A1-DFCF-4C7C-B462-E96E1D0BB667}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="callgenericctor.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <PropertyGroup>
+ <CLRTestBatchPreCommands><![CDATA[
+$(CLRTestBatchPreCommands)
+%Core_Root%\crossgen /readytorun /platform_assemblies_paths %Core_Root%%3B%25CD% /out genericslib.ni.dll genericslib.dll
+%Core_Root%\crossgen /readytorun /platform_assemblies_paths %Core_Root%%3B%25CD% /out callgenericctor.ni.exe callgenericctor.exe
+]]></CLRTestBatchPreCommands>
+ <BashCLRTestPreCommands><![CDATA[
+$(BashCLRTestPreCommands)
+$CORE_ROOT/crossgen -readytorun -platform_assemblies_paths $CORE_ROOT:`pwd` -out genericslib.ni.dll genericslib.dll
+$CORE_ROOT/crossgen -readytorun -platform_assemblies_paths $CORE_ROOT:`pwd` -out callgenericctor.ni.exe callgenericctor.exe
+]]></BashCLRTestPreCommands>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/readytorun/tests/genericsload/genericslib.il b/tests/src/readytorun/tests/genericsload/genericslib.il
new file mode 100644
index 0000000000..fdc2f408a3
--- /dev/null
+++ b/tests/src/readytorun/tests/genericsload/genericslib.il
@@ -0,0 +1,58 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//
+
+.assembly genericslib { }
+.module genericslib.dll
+
+.assembly extern mscorlib { }
+
+// A module constructor that sets GenClass`1<string>::StaticField to true.
+.method assembly specialname rtspecialname static
+ void .cctor() cil managed
+{
+ ldc.i4.1
+ stsfld bool class GenClass`1<string>::StaticField
+ ret
+}
+
+.class public auto ansi beforefieldinit GenClass`1<T>
+ extends [mscorlib]System.Object
+{
+ .field static public bool StaticField
+
+ /*
+ public GenClass()
+ {
+ if (!StaticField)
+ throw new System.Exception();
+ }
+ */
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ ldarg.0
+ call instance void [mscorlib]System.Object::.ctor()
+
+ ldsfld bool class GenClass`1<!T>::StaticField
+ brtrue.s OK
+
+ newobj instance void [mscorlib]System.Exception::.ctor()
+ throw
+
+ OK: ret
+ }
+
+ /*
+ public static bool StaticMethod()
+ {
+ return StaticField;
+ }
+ */
+ .method public hidebysig static bool StaticMethod() cil managed
+ {
+ ldsfld bool class GenClass`1<!T>::StaticField
+ ret
+ }
+}
diff --git a/tests/src/readytorun/tests/genericsload/genericslib.ilproj b/tests/src/readytorun/tests/genericsload/genericslib.ilproj
new file mode 100644
index 0000000000..04548543af
--- /dev/null
+++ b/tests/src/readytorun/tests/genericsload/genericslib.ilproj
@@ -0,0 +1,37 @@
+<?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>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>library</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <CLRTestKind>SharedLibrary</CLRTestKind>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="genericslib.il" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/readytorun/tests/genericsload/usegenericfield.cs b/tests/src/readytorun/tests/genericsload/usegenericfield.cs
new file mode 100644
index 0000000000..770334c6cf
--- /dev/null
+++ b/tests/src/readytorun/tests/genericsload/usegenericfield.cs
@@ -0,0 +1,39 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//
+
+using System;
+using System.Runtime.CompilerServices;
+
+class Foo<T>
+{
+ [MethodImplAttribute(MethodImplOptions.NoInlining)]
+ internal bool M()
+ {
+ return GenClass<T>.StaticField;
+ }
+}
+
+class Program
+{
+ static int Main()
+ {
+ try
+ {
+ if (!new Foo<string>().M())
+ {
+ Console.WriteLine("FAIL - bad result");
+ return 102;
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("FAIL - exception caught");
+ return 101;
+ }
+
+ Console.WriteLine("PASS");
+ return 100;
+ }
+}
diff --git a/tests/src/readytorun/tests/genericsload/usegenericfield.csproj b/tests/src/readytorun/tests/genericsload/usegenericfield.csproj
new file mode 100644
index 0000000000..6b9e15a733
--- /dev/null
+++ b/tests/src/readytorun/tests/genericsload/usegenericfield.csproj
@@ -0,0 +1,50 @@
+<?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>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{7DECC55A-B584-4456-83BA-6C42A5B3B3CB}</ProjectGuid>
+ <OutputType>exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <DefineConstants>$(DefineConstants);STATIC;CORECLR</DefineConstants>
+ <ZapRequire>1</ZapRequire>
+ </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>
+ <ProjectReference Include="genericslib.ilproj">
+ <Project>{F74F55A1-DFCF-4C7C-B462-E96E1D0BB667}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="usegenericfield.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <PropertyGroup>
+ <CLRTestBatchPreCommands><![CDATA[
+$(CLRTestBatchPreCommands)
+%Core_Root%\crossgen /readytorun /platform_assemblies_paths %Core_Root%%3B%25CD% /out genericslib.ni.dll genericslib.dll
+%Core_Root%\crossgen /readytorun /platform_assemblies_paths %Core_Root%%3B%25CD% /out usegenericfield.ni.exe usegenericfield.exe
+]]></CLRTestBatchPreCommands>
+ <BashCLRTestPreCommands><![CDATA[
+$(BashCLRTestPreCommands)
+$CORE_ROOT/crossgen -readytorun -platform_assemblies_paths $CORE_ROOT:`pwd` -out genericslib.ni.dll genericslib.dll
+$CORE_ROOT/crossgen -readytorun -platform_assemblies_paths $CORE_ROOT:`pwd` -out usegenericfield.ni.exe usegenericfield.exe
+]]></BashCLRTestPreCommands>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/readytorun/tests/main.cs b/tests/src/readytorun/tests/main.cs
new file mode 100644
index 0000000000..783c1fd3cb
--- /dev/null
+++ b/tests/src/readytorun/tests/main.cs
@@ -0,0 +1,494 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+#if CORECLR
+using System.Runtime.Loader;
+#endif
+using System.Reflection;
+using System.IO;
+
+class InstanceFieldTest : MyClass
+{
+ public int Value;
+}
+
+class InstanceFieldTest2 : InstanceFieldTest
+{
+ public int Value2;
+}
+
+[StructLayout(LayoutKind.Sequential)]
+class InstanceFieldTestWithLayout : MyClassWithLayout
+{
+ public int Value;
+}
+
+class GrowingBase
+{
+ MyGrowingStruct s;
+}
+
+class InheritingFromGrowingBase : GrowingBase
+{
+ public int x;
+}
+
+
+static class OpenClosedDelegateExtension
+{
+ public static string OpenClosedDelegateTarget(this string x, string foo)
+ {
+ return x + ", " + foo;
+ }
+}
+
+class Program
+{
+ static void TestVirtualMethodCalls()
+ {
+ var o = new MyClass();
+ Assert.AreEqual(o.VirtualMethod(), "Virtual method result");
+
+ var iface = (IMyInterface)o;
+ Assert.AreEqual(iface.InterfaceMethod(" "), "Interface result");
+ Assert.AreEqual(MyClass.TestInterfaceMethod(iface, "+"), "Interface+result");
+ }
+
+ static void TestMovedVirtualMethods()
+ {
+ var o = new MyChildClass();
+
+ Assert.AreEqual(o.MovedToBaseClass(), "MovedToBaseClass");
+ Assert.AreEqual(o.ChangedToVirtual(), "ChangedToVirtual");
+
+ if (!LLILCJitEnabled)
+ {
+ o = null;
+
+ try
+ {
+ o.MovedToBaseClass();
+ }
+ catch (NullReferenceException)
+ {
+ try
+ {
+ o.ChangedToVirtual();
+ }
+ catch (NullReferenceException)
+ {
+ return;
+ }
+ }
+
+ Assert.AreEqual("NullReferenceException", "thrown");
+ }
+ }
+
+
+ static void TestConstrainedMethodCalls()
+ {
+ using (MyStruct s = new MyStruct())
+ {
+ ((Object)s).ToString();
+ }
+
+ // Enum.GetHashCode optimization requires special treatment
+ // in native signature encoding
+ MyEnum e = MyEnum.Apple;
+ e.GetHashCode();
+ }
+
+ static void TestConstrainedMethodCalls_Unsupported()
+ {
+ MyStruct s = new MyStruct();
+ s.ToString();
+ }
+
+ static void TestInterop()
+ {
+ // Verify both intra-module and inter-module PInvoke interop
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ MyClass.GetTickCount();
+ }
+ else
+ {
+ MyClass.GetCurrentThreadId();
+ }
+
+ MyClass.TestInterop();
+ }
+
+ static void TestStaticFields()
+ {
+ MyClass.StaticObjectField = 894;
+ MyClass.StaticLongField = 4392854;
+ MyClass.StaticNullableGuidField = new Guid("0D7E505F-E767-4FEF-AEEC-3243A3005673");
+ MyClass.ThreadStaticStringField = "Hello";
+ MyClass.ThreadStaticIntField = 735;
+ MyClass.ThreadStaticDateTimeField = new DateTime(2011, 1, 1);
+
+ MyClass.TestStaticFields();
+
+#if false // TODO: Enable once LDFTN is supported
+ Task.Run(() => {
+ MyClass.ThreadStaticStringField = "Garbage";
+ MyClass.ThreadStaticIntField = 0xBAAD;
+ MyClass.ThreadStaticDateTimeField = DateTime.Now;
+ }).Wait();
+#endif
+
+ Assert.AreEqual(MyClass.StaticObjectField, 894 + 12345678 /* + 1234 */);
+ Assert.AreEqual(MyClass.StaticLongField, (long)(4392854 * 456 /* * 45 */));
+ Assert.AreEqual(MyClass.StaticNullableGuidField, null);
+ Assert.AreEqual(MyClass.ThreadStaticStringField, "HelloWorld");
+ Assert.AreEqual(MyClass.ThreadStaticIntField, 735/78);
+ Assert.AreEqual(MyClass.ThreadStaticDateTimeField, new DateTime(2011, 1, 1) + new TimeSpan(123));
+ }
+
+ static void TestPreInitializedArray()
+ {
+ var a = new int[] { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 };
+
+ int sum = 0;
+ foreach (var e in a) sum += e;
+ Assert.AreEqual(sum, 1023);
+ }
+
+ static void TestMultiDimmArray()
+ {
+ var a = new int[2,3,4];
+ a[0,1,2] = a[0,0,0] + a[1,1,1];
+ a.ToString();
+ }
+
+ static void TestGenericVirtualMethod()
+ {
+ var o = new MyGeneric<String, Object>();
+ Assert.AreEqual(o.GenericVirtualMethod<Program, IEnumerable<String>>(),
+ "System.StringSystem.ObjectProgramSystem.Collections.Generic.IEnumerable`1[System.String]");
+ }
+
+ static void TestMovedGenericVirtualMethod()
+ {
+ var o = new MyChildGeneric<Object>();
+
+ Assert.AreEqual(o.MovedToBaseClass<WeakReference>(), typeof(List<WeakReference>).ToString());
+ Assert.AreEqual(o.ChangedToVirtual<WeakReference>(), typeof(List<WeakReference>).ToString());
+
+ if (!LLILCJitEnabled)
+ {
+ o = null;
+
+ try
+ {
+ o.MovedToBaseClass<WeakReference>();
+ }
+ catch (NullReferenceException)
+ {
+ try
+ {
+ o.ChangedToVirtual<WeakReference>();
+ }
+ catch (NullReferenceException)
+ {
+ return;
+ }
+ }
+
+ Assert.AreEqual("NullReferenceException", "thrown");
+ }
+ }
+
+ [MethodImplAttribute(MethodImplOptions.NoInlining)]
+ static void TestGenericNonVirtualMethod()
+ {
+ var c = new MyChildGeneric<string>();
+ Assert.AreEqual(CallGeneric(c), "MyGeneric.NonVirtualMethod");
+ }
+
+ [MethodImplAttribute(MethodImplOptions.NoInlining)]
+ static string CallGeneric<T>(MyGeneric<T, T> g)
+ {
+ return g.NonVirtualMethod();
+ }
+
+ static void TestGenericOverStruct()
+ {
+ var o1 = new MyGeneric<String, MyGrowingStruct>();
+ Assert.AreEqual(o1.GenericVirtualMethod < MyChangingStruct, IEnumerable<Program>>(),
+ "System.StringMyGrowingStructMyChangingStructSystem.Collections.Generic.IEnumerable`1[Program]");
+
+ var o2 = new MyChildGeneric<MyChangingStruct>();
+ Assert.AreEqual(o2.MovedToBaseClass<MyGrowingStruct>(), typeof(List<MyGrowingStruct>).ToString());
+ Assert.AreEqual(o2.ChangedToVirtual<MyGrowingStruct>(), typeof(List<MyGrowingStruct>).ToString());
+ }
+
+ static void TestInstanceFields()
+ {
+ var t = new InstanceFieldTest2();
+ t.Value = 123;
+ t.Value2 = 234;
+ t.InstanceField = 345;
+
+ Assert.AreEqual(typeof(InstanceFieldTest).GetRuntimeField("Value").GetValue(t), 123);
+ Assert.AreEqual(typeof(InstanceFieldTest2).GetRuntimeField("Value2").GetValue(t), 234);
+ Assert.AreEqual(typeof(MyClass).GetRuntimeField("InstanceField").GetValue(t), 345);
+ }
+
+ static void TestInstanceFieldsWithLayout()
+ {
+ var t = new InstanceFieldTestWithLayout();
+ t.Value = 123;
+
+ Assert.AreEqual(typeof(InstanceFieldTestWithLayout).GetRuntimeField("Value").GetValue(t), 123);
+ }
+
+ static void TestInheritingFromGrowingBase()
+ {
+ var o = new InheritingFromGrowingBase();
+ o.x = 6780;
+ Assert.AreEqual(typeof(InheritingFromGrowingBase).GetRuntimeField("x").GetValue(o), 6780);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.NoInlining)]
+ static void TestGrowingStruct()
+ {
+ MyGrowingStruct s = MyGrowingStruct.Construct();
+ MyGrowingStruct.Check(ref s);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.NoInlining)]
+ static void TestChangingStruct()
+ {
+ MyChangingStruct s = MyChangingStruct.Construct();
+ s.x++;
+ MyChangingStruct.Check(ref s);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.NoInlining)]
+ static void TestChangingHFAStruct()
+ {
+ MyChangingHFAStruct s = MyChangingHFAStruct.Construct();
+ MyChangingHFAStruct.Check(s);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.NoInlining)]
+ static void TestGetType()
+ {
+ new MyClass().GetType().ToString();
+ }
+
+ [MethodImplAttribute(MethodImplOptions.NoInlining)]
+ static void TestStaticBaseCSE()
+ {
+ // There should be just one call to CORINFO_HELP_READYTORUN_STATIC_BASE
+ // in the generated code.
+ s++;
+ s++;
+ Assert.AreEqual(s, 2);
+ s = 0;
+ }
+
+ [MethodImplAttribute(MethodImplOptions.NoInlining)]
+ static void TestIsInstCSE()
+ {
+ // There should be just one call to CORINFO_HELP_READYTORUN_ISINSTANCEOF
+ // in the generated code.
+ object o1 = (s < 1) ? (object)"foo" : (object)1;
+ Assert.AreEqual(o1 is string, true);
+ Assert.AreEqual(o1 is string, true);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.NoInlining)]
+ static void TestCastClassCSE()
+ {
+ // There should be just one call to CORINFO_HELP_READYTORUN_CHKCAST
+ // in the generated code.
+ object o1 = (s < 1) ? (object)"foo" : (object)1;
+ string str1 = (string)o1;
+ string str2 = (string)o1;
+ Assert.AreEqual(str1, str2);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.NoInlining)]
+ static void TestRangeCheckElimination()
+ {
+ // Range checks for array accesses should be eliminated by the compiler.
+ int[] array = new int[5];
+ array[2] = 2;
+ Assert.AreEqual(array[2], 2);
+ }
+
+#if CORECLR
+ class MyLoadContext : AssemblyLoadContext
+ {
+ public MyLoadContext()
+ {
+ }
+
+ public void TestMultipleLoads()
+ {
+ Assembly a = LoadFromAssemblyPath(Path.Combine(Directory.GetCurrentDirectory(), "test.ni.dll"));
+ Assert.AreEqual(AssemblyLoadContext.GetLoadContext(a), this);
+ }
+
+ protected override Assembly Load(AssemblyName an)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ static void TestMultipleLoads()
+ {
+ if (!LLILCJitEnabled) {
+ // Runtime should be able to load the same R2R image in another load context,
+ // even though it will be treated as an IL-only image.
+ new MyLoadContext().TestMultipleLoads();
+ }
+ }
+#endif
+
+ static void TestFieldLayoutNGenMixAndMatch()
+ {
+ // This test is verifying consistent field layout when ReadyToRun images are combined with NGen images
+ // "ngen install /nodependencies main.exe" to exercise the interesting case
+ var o = new ByteChildClass(67);
+ Assert.AreEqual(o.ChildByte, (byte)67);
+ }
+
+ static void TestOpenClosedDelegate()
+ {
+ // This test is verifying the the fixups for open vs. closed delegate created against the same target
+ // method are encoded correctly.
+
+ Func<string, string, object> idOpen = OpenClosedDelegateExtension.OpenClosedDelegateTarget;
+ Assert.AreEqual(idOpen("World", "foo"), "World, foo");
+
+ Func<string, object> idClosed = "World".OpenClosedDelegateTarget;
+ Assert.AreEqual(idClosed("hey"), "World, hey");
+ }
+
+ static void GenericLdtokenFieldsTest()
+ {
+ Func<FieldInfo, string> FieldFullName = (fi) => fi.FieldType + " " + fi.DeclaringType.ToString() + "::" + fi.Name;
+
+ IFieldGetter getter1 = new FieldGetter<string>();
+ IFieldGetter getter2 = new FieldGetter<object>();
+ IFieldGetter getter3 = new FieldGetter<int>();
+
+ foreach (var instArg in new Type[]{typeof(String), typeof(object), typeof(int)})
+ {
+ IFieldGetter getter = (IFieldGetter)Activator.CreateInstance(typeof(FieldGetter<>).MakeGenericType(instArg));
+
+ string expectedField1 = "System.Int32 Gen`1[???]::m_Field1".Replace("???", instArg.ToString());
+ string expectedField2 = "System.String Gen`1[???]::m_Field2".Replace("???", instArg.ToString());
+ string expectedField3 = "??? Gen`1[???]::m_Field3".Replace("???", instArg.ToString());
+ string expectedField4 = "System.Collections.Generic.List`1[???] Gen`1[???]::m_Field4".Replace("???", instArg.ToString());
+ string expectedField5 = "System.Collections.Generic.KeyValuePair`2[???,System.Int32] Gen`1[???]::m_Field5".Replace("???", instArg.ToString());
+
+ string expectedDllField1 = "System.String MyGeneric`2[???,???]::m_Field1".Replace("???", instArg.ToString());
+ string expectedDllField2 = "??? MyGeneric`2[???,???]::m_Field2".Replace("???", instArg.ToString());
+ string expectedDllField3 = "System.Collections.Generic.List`1[???] MyGeneric`2[???,???]::m_Field3".Replace("???", instArg.ToString());
+ string expectedDllField4 = "System.Collections.Generic.KeyValuePair`2[???,System.Int32] MyGeneric`2[???,???]::m_Field4".Replace("???", instArg.ToString());
+ string expectedDllField5 = "System.Int32 MyGeneric`2[???,???]::m_Field5".Replace("???", instArg.ToString());
+
+ Assert.AreEqual(expectedField1, FieldFullName(getter.GetGenT_Field1()));
+ Assert.AreEqual(expectedField2, FieldFullName(getter.GetGenT_Field2()));
+ Assert.AreEqual(expectedField3, FieldFullName(getter.GetGenT_Field3()));
+ Assert.AreEqual(expectedField4, FieldFullName(getter.GetGenT_Field4()));
+ Assert.AreEqual(expectedField5, FieldFullName(getter.GetGenT_Field5()));
+
+ Assert.AreEqual(expectedDllField1, FieldFullName(getter.GetGenDllT_Field1()));
+ Assert.AreEqual(expectedDllField2, FieldFullName(getter.GetGenDllT_Field2()));
+ Assert.AreEqual(expectedDllField3, FieldFullName(getter.GetGenDllT_Field3()));
+ Assert.AreEqual(expectedDllField4, FieldFullName(getter.GetGenDllT_Field4()));
+ Assert.AreEqual(expectedDllField5, FieldFullName(getter.GetGenDllT_Field5()));
+ }
+ }
+
+ static void RunAllTests()
+ {
+ TestVirtualMethodCalls();
+ TestMovedVirtualMethods();
+
+ TestConstrainedMethodCalls();
+
+ TestConstrainedMethodCalls_Unsupported();
+
+ TestInterop();
+
+ TestStaticFields();
+
+ TestPreInitializedArray();
+
+ TestMultiDimmArray();
+
+ TestGenericVirtualMethod();
+ TestMovedGenericVirtualMethod();
+ TestGenericNonVirtualMethod();
+
+ TestGenericOverStruct();
+
+ TestInstanceFields();
+
+ TestInstanceFieldsWithLayout();
+
+ TestInheritingFromGrowingBase();
+
+ TestGrowingStruct();
+ TestChangingStruct();
+ TestChangingHFAStruct();
+
+ TestGetType();
+
+#if CORECLR
+ TestMultipleLoads();
+#endif
+
+ TestFieldLayoutNGenMixAndMatch();
+
+ TestStaticBaseCSE();
+
+ TestIsInstCSE();
+
+ TestCastClassCSE();
+
+ TestRangeCheckElimination();
+
+ TestOpenClosedDelegate();
+
+ GenericLdtokenFieldsTest();
+ }
+
+ static int Main()
+ {
+ // Code compiled by LLILC jit can't catch exceptions yet so the tests
+ // don't throw them if LLILC jit is enabled. This should be removed once
+ // exception catching is supported by LLILC jit.
+ string AltJitName = System.Environment.GetEnvironmentVariable("complus_altjitname");
+ LLILCJitEnabled =
+ ((AltJitName != null) && AltJitName.ToLower().StartsWith("llilcjit") &&
+ ((System.Environment.GetEnvironmentVariable("complus_altjit") != null) ||
+ (System.Environment.GetEnvironmentVariable("complus_altjitngen") != null)));
+
+ // Run all tests 3x times to exercise both slow and fast paths work
+ for (int i = 0; i < 3; i++)
+ RunAllTests();
+
+ Console.WriteLine("PASSED");
+ return Assert.HasAssertFired ? 1 : 100;
+ }
+
+ static bool LLILCJitEnabled;
+
+ static int s;
+}
diff --git a/tests/src/readytorun/tests/mainv1.csproj b/tests/src/readytorun/tests/mainv1.csproj
new file mode 100644
index 0000000000..cca0b4106b
--- /dev/null
+++ b/tests/src/readytorun/tests/mainv1.csproj
@@ -0,0 +1,56 @@
+<?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>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{7DECC55A-B584-4456-83BA-6C42A5B3B3CB}</ProjectGuid>
+ <OutputType>exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <DefineConstants>$(DefineConstants);STATIC;CORECLR</DefineConstants>
+ </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>
+ <ProjectReference Include="fieldgetter.ilproj" />
+ <ProjectReference Include="testv1\test.csproj">
+ <Project>{F74F55A1-DFCF-4C7C-B462-E96E1D0BB667}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="main.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <PropertyGroup>
+ <CLRTestBatchPreCommands><![CDATA[
+$(CLRTestBatchPreCommands)
+DEL test.dll
+COPY /Y ..\testv1\test\test.dll test.dll
+%Core_Root%\crossgen /readytorun /platform_assemblies_paths %Core_Root%%3B%25CD% /out test.ni.dll test.dll
+%Core_Root%\crossgen /readytorun /platform_assemblies_paths %Core_Root%%3B%25CD% /out fieldgetter.ni.dll fieldgetter.dll
+%Core_Root%\crossgen /readytorun /platform_assemblies_paths %Core_Root%%3B%25CD% /out mainv1.ni.exe mainv1.exe
+]]></CLRTestBatchPreCommands>
+ <BashCLRTestPreCommands><![CDATA[
+$(BashCLRTestPreCommands)
+rm -f test.dll
+cp ../testv1/test/test.dll test.dll
+$CORE_ROOT/crossgen -readytorun -platform_assemblies_paths $CORE_ROOT:`pwd` -out test.ni.dll test.dll
+$CORE_ROOT/crossgen -readytorun -platform_assemblies_paths $CORE_ROOT:`pwd` -out fieldgetter.ni.dll fieldgetter.dll
+$CORE_ROOT/crossgen -readytorun -platform_assemblies_paths $CORE_ROOT:`pwd` -out mainv1.ni.exe mainv1.exe
+]]></BashCLRTestPreCommands>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/readytorun/tests/mainv2.csproj b/tests/src/readytorun/tests/mainv2.csproj
new file mode 100644
index 0000000000..acf898e7f9
--- /dev/null
+++ b/tests/src/readytorun/tests/mainv2.csproj
@@ -0,0 +1,59 @@
+<?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>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{840300BB-0DD2-4BD3-A3C1-51C92DD4ADAD}</ProjectGuid>
+ <OutputType>exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <DefineConstants>$(DefineConstants);STATIC;CORECLR</DefineConstants>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ </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>
+ <ProjectReference Include="fieldgetter.ilproj" />
+ <ProjectReference Include="testv1\test.csproj" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="main.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <PropertyGroup>
+ <CLRTestBatchPreCommands><![CDATA[
+$(CLRTestBatchPreCommands)
+DEL test.dll
+COPY /Y ..\testv1\test\test.dll test.dll
+%Core_Root%\crossgen /readytorun /platform_assemblies_paths %Core_Root%%3B%25CD% /out mainv2.ni.exe mainv2.exe
+%Core_Root%\crossgen /readytorun /platform_assemblies_paths %Core_Root%%3B%25CD% /out fieldgetter.ni.dll fieldgetter.dll
+DEL test.dll
+COPY /Y ..\testv2\test\test.dll test.dll
+%Core_Root%\crossgen /readytorun /platform_assemblies_paths %Core_Root%%3B%25CD% /out test.ni.dll test.dll
+]]></CLRTestBatchPreCommands>
+ <BashCLRTestPreCommands><![CDATA[
+$(BashCLRTestPreCommands)
+rm -f test.dll
+cp ../testv1/test/test.dll test.dll
+$CORE_ROOT/crossgen -readytorun -platform_assemblies_paths $CORE_ROOT:`pwd` -out mainv2.ni.exe mainv2.exe
+$CORE_ROOT/crossgen -readytorun -platform_assemblies_paths $CORE_ROOT:`pwd` -out fieldgetter.ni.dll fieldgetter.dll
+rm -f test.dll
+cp ../testv2/test/test.dll test.dll
+$CORE_ROOT/crossgen -readytorun -platform_assemblies_paths $CORE_ROOT:`pwd` -out test.ni.dll test.dll
+
+]]></BashCLRTestPreCommands>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/readytorun/tests/test.cs b/tests/src/readytorun/tests/test.cs
new file mode 100644
index 0000000000..8a6beaea15
--- /dev/null
+++ b/tests/src/readytorun/tests/test.cs
@@ -0,0 +1,412 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//
+
+using System;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+
+public static class Assert
+{
+ public static bool HasAssertFired;
+
+ public static void AreEqual(Object actual, Object expected)
+ {
+ if (!(actual == null && expected == null) && !actual.Equals(expected))
+ {
+ Console.WriteLine("Not equal!");
+ Console.WriteLine("actual = " + actual.ToString());
+ Console.WriteLine("expected = " + expected.ToString());
+ HasAssertFired = true;
+ }
+ }
+}
+
+public interface IMyInterface
+{
+#if V2
+ // Adding new methods to interfaces is incompatible change, but we will make sure that it works anyway
+ void NewInterfaceMethod();
+#endif
+
+ string InterfaceMethod(string s);
+}
+
+public class MyClass : IMyInterface
+{
+#if V2
+ public int _field1;
+ public int _field2;
+ public int _field3;
+#endif
+ public int InstanceField;
+
+#if V2
+ public static Object StaticObjectField2;
+
+ [ThreadStatic] public static String ThreadStaticStringField2;
+
+ [ThreadStatic] public static int ThreadStaticIntField;
+
+ public static Nullable<Guid> StaticNullableGuidField;
+
+ public static Object StaticObjectField;
+
+ [ThreadStatic] public static int ThreadStaticIntField2;
+
+ public static long StaticLongField;
+
+ [ThreadStatic] public static DateTime ThreadStaticDateTimeField2;
+
+ public static long StaticLongField2;
+
+ [ThreadStatic] public static DateTime ThreadStaticDateTimeField;
+
+ public static Nullable<Guid> StaticNullableGuidField2;
+
+ [ThreadStatic] public static String ThreadStaticStringField;
+#else
+ public static Object StaticObjectField;
+
+ public static long StaticLongField;
+
+ public static Nullable<Guid> StaticNullableGuidField;
+
+ [ThreadStatic] public static String ThreadStaticStringField;
+
+ [ThreadStatic] public static int ThreadStaticIntField;
+
+ [ThreadStatic] public static DateTime ThreadStaticDateTimeField;
+#endif
+
+ public MyClass()
+ {
+ }
+
+#if V2
+ public virtual void NewVirtualMethod()
+ {
+ }
+
+ public virtual void NewInterfaceMethod()
+ {
+ throw new Exception();
+ }
+#endif
+
+ public virtual string VirtualMethod()
+ {
+ return "Virtual method result";
+ }
+
+ public virtual string InterfaceMethod(string s)
+ {
+ return "Interface" + s + "result";
+ }
+
+ public static string TestInterfaceMethod(IMyInterface i, string s)
+ {
+ return i.InterfaceMethod(s);
+ }
+
+ public static void TestStaticFields()
+ {
+ StaticObjectField = (int)StaticObjectField + 12345678;
+
+ StaticLongField *= 456;
+
+ Assert.AreEqual(StaticNullableGuidField, new Guid("0D7E505F-E767-4FEF-AEEC-3243A3005673"));
+ StaticNullableGuidField = null;
+
+ ThreadStaticStringField += "World";
+
+ ThreadStaticIntField /= 78;
+
+ ThreadStaticDateTimeField = ThreadStaticDateTimeField + new TimeSpan(123);
+
+ MyGeneric<int,int>.ThreadStatic = new Object();
+
+#if false // TODO: Enable once LDFTN is supported
+ // Do some operations on static fields on a different thread to verify that we are not mixing thread-static and non-static
+ Task.Run(() => {
+
+ StaticObjectField = (int)StaticObjectField + 1234;
+
+ StaticLongField *= 45;
+
+ ThreadStaticStringField = "Garbage";
+
+ ThreadStaticIntField = 0xBAAD;
+
+ ThreadStaticDateTimeField = DateTime.Now;
+
+ }).Wait();
+#endif
+ }
+
+ [DllImport("api-ms-win-core-sysinfo-l1-1-0.dll")]
+ public extern static int GetTickCount();
+
+ [DllImport("libcoreclr")]
+ public extern static int GetCurrentThreadId();
+
+ static public void TestInterop()
+ {
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ GetTickCount();
+ }
+ else
+ {
+ GetCurrentThreadId();
+ }
+ }
+
+#if V2
+ public string MovedToBaseClass()
+ {
+ return "MovedToBaseClass";
+ }
+#endif
+
+#if V2
+ public virtual string ChangedToVirtual()
+ {
+ return null;
+ }
+#else
+ public string ChangedToVirtual()
+ {
+ return "ChangedToVirtual";
+ }
+#endif
+
+}
+
+public class MyChildClass : MyClass
+{
+ public MyChildClass()
+ {
+ }
+
+#if !V2
+ public string MovedToBaseClass()
+ {
+ return "MovedToBaseClass";
+ }
+#endif
+
+#if V2
+ public override string ChangedToVirtual()
+ {
+ return "ChangedToVirtual";
+ }
+#endif
+}
+
+
+public struct MyStruct : IDisposable
+{
+ int x;
+
+#if V2
+ void IDisposable.Dispose()
+ {
+ }
+#else
+ public void Dispose()
+ {
+ }
+#endif
+}
+
+public class MyGeneric<T,U>
+{
+#if V2
+ public object m_unused1;
+ public string m_Field1;
+
+ public object m_unused2;
+ public T m_Field2;
+
+ public object m_unused3;
+ public List<T> m_Field3;
+
+ static public object m_unused4;
+ static public KeyValuePair<T, int> m_Field4;
+
+ static public object m_unused5;
+ static public int m_Field5;
+
+ public object m_unused6;
+ static public object m_unused7;
+#else
+ public string m_Field1;
+ public T m_Field2;
+ public List<T> m_Field3;
+ static public KeyValuePair<T, int> m_Field4;
+ static public int m_Field5;
+#endif
+
+ [ThreadStatic] public static Object ThreadStatic;
+
+ public MyGeneric()
+ {
+ }
+
+ public virtual string GenericVirtualMethod<V,W>()
+ {
+ return typeof(T).ToString() + typeof(U).ToString() + typeof(V).ToString() + typeof(W).ToString();
+ }
+
+#if V2
+ public string MovedToBaseClass<W>()
+ {
+ typeof(Dictionary<W,W>).ToString();
+ return typeof(List<W>).ToString();
+ }
+#endif
+
+#if V2
+ public virtual string ChangedToVirtual<W>()
+ {
+ return null;
+ }
+#else
+ public string ChangedToVirtual<W>()
+ {
+ return typeof(List<W>).ToString();
+ }
+#endif
+
+ public string NonVirtualMethod()
+ {
+ return "MyGeneric.NonVirtualMethod";
+ }
+}
+
+public class MyChildGeneric<T> : MyGeneric<T,T>
+{
+ public MyChildGeneric()
+ {
+ }
+
+#if !V2
+ public string MovedToBaseClass<W>()
+ {
+ return typeof(List<W>).ToString();
+ }
+#endif
+
+#if V2
+ public override string ChangedToVirtual<W>()
+ {
+ typeof(Dictionary<Int32, W>).ToString();
+ return typeof(List<W>).ToString();
+ }
+#endif
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public class MyClassWithLayout
+{
+#if V2
+ public int _field1;
+ public int _field2;
+ public int _field3;
+#endif
+}
+
+public struct MyGrowingStruct
+{
+ int x;
+ int y;
+#if V2
+ Object o1;
+ Object o2;
+#endif
+
+ static public MyGrowingStruct Construct()
+ {
+ return new MyGrowingStruct() { x = 111, y = 222 };
+ }
+
+ public static void Check(ref MyGrowingStruct s)
+ {
+ Assert.AreEqual(s.x, 111);
+ Assert.AreEqual(s.y, 222);
+ }
+}
+
+public struct MyChangingStruct
+{
+#if V2
+ public int y;
+ public int x;
+#else
+ public int x;
+ public int y;
+#endif
+
+ static public MyChangingStruct Construct()
+ {
+ return new MyChangingStruct() { x = 111, y = 222 };
+ }
+
+ public static void Check(ref MyChangingStruct s)
+ {
+ Assert.AreEqual(s.x, 112);
+ Assert.AreEqual(s.y, 222);
+ }
+}
+
+public struct MyChangingHFAStruct
+{
+#if V2
+ float x;
+ float y;
+#else
+ int x;
+ int y;
+#endif
+ static public MyChangingHFAStruct Construct()
+ {
+ return new MyChangingHFAStruct() { x = 12, y = 23 };
+ }
+
+ public static void Check(MyChangingHFAStruct s)
+ {
+#if V2
+ Assert.AreEqual(s.x, 12.0f);
+ Assert.AreEqual(s.y, 23.0f);
+#else
+ Assert.AreEqual(s.x, 12);
+ Assert.AreEqual(s.y, 23);
+#endif
+ }
+}
+
+public class ByteBaseClass : List<byte>
+{
+ public byte BaseByte;
+}
+public class ByteChildClass : ByteBaseClass
+{
+ public byte ChildByte;
+
+ [MethodImplAttribute(MethodImplOptions.NoInlining)]
+ public ByteChildClass(byte value)
+ {
+ ChildByte = 67;
+ }
+}
+
+public enum MyEnum
+{
+ Apple = 1,
+ Banana = 2,
+ Orange = 3
+}
diff --git a/tests/src/readytorun/tests/testv1/test.csproj b/tests/src/readytorun/tests/testv1/test.csproj
new file mode 100644
index 0000000000..c56c53cad9
--- /dev/null
+++ b/tests/src/readytorun/tests/testv1/test.csproj
@@ -0,0 +1,32 @@
+<?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>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{F74F55A1-DFCF-4C7C-B462-E96E1D0BB667}</ProjectGuid>
+ <OutputType>library</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\..\</SolutionDir>
+ <DefineConstants>$(DefineConstants);STATIC;CORECLR</DefineConstants>
+ <CLRTestKind>SharedLibrary</CLRTestKind>
+ </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="..\test.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project> \ No newline at end of file
diff --git a/tests/src/readytorun/tests/testv2/test.csproj b/tests/src/readytorun/tests/testv2/test.csproj
new file mode 100644
index 0000000000..058a0d6346
--- /dev/null
+++ b/tests/src/readytorun/tests/testv2/test.csproj
@@ -0,0 +1,32 @@
+<?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>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>library</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\..\</SolutionDir>
+ <DefineConstants>$(DefineConstants);STATIC;CORECLR;V2</DefineConstants>
+ <CLRTestKind>SharedLibrary</CLRTestKind>
+ </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="..\test.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>