Cosmos/Users/Orvid/IL2CPU Tester/CsTests/generics.cs

943 lines
20 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
public partial class Tests
{
struct TestStruct
{
public int i;
public int j;
public TestStruct(int i, int j)
{
this.i = i;
this.j = j;
}
}
public static int test_1_nullable_unbox()
{
return Unbox<int?>(1).Value;
}
public static int test_1_nullable_unbox_null()
{
return Unbox<int?>(null).HasValue ? 0 : 1;
}
public static int test_1_nullable_box()
{
return (int)Box<int?>(1);
}
public static int test_1_nullable_box_null()
{
return Box<int?>(null) == null ? 1 : 0;
}
public static int test_1_isinst_nullable()
{
object o = 1;
return (o is int?) ? 1 : 0;
}
public static int test_1_nullable_unbox_vtype()
{
return Unbox<TestStruct?>(new TestStruct(1, 2)).Value.i;
}
public static int test_1_nullable_unbox_null_vtype()
{
return Unbox<TestStruct?>(null).HasValue ? 0 : 1;
}
public static int test_1_nullable_box_vtype()
{
return ((TestStruct)(Box<TestStruct?>(new TestStruct(1, 2)))).i;
}
public static int test_1_nullable_box_null_vtype()
{
return Box<TestStruct?>(null) == null ? 1 : 0;
}
public static int test_1_isinst_nullable_vtype()
{
object o = new TestStruct(1, 2);
return (o is TestStruct?) ? 1 : 0;
}
public static int test_0_nullable_normal_unbox()
{
int? i = 5;
object o = i;
// This uses unbox instead of unbox_any
int? j = (int?)o;
if (j != 5)
return 1;
return 0;
}
public static void stelem_any<T>(T[] arr, T elem)
{
arr[0] = elem;
}
public static T ldelem_any<T>(T[] arr)
{
return arr[0];
}
public static int test_1_ldelem_stelem_any_int()
{
int[] arr = new int[3];
stelem_any(arr, 1);
return ldelem_any(arr);
}
public static T return_ref<T>(ref T t)
{
return t;
}
public static T ldelema_any<T>(T[] arr)
{
return return_ref<T>(ref arr[0]);
}
public static int test_0_ldelema()
{
string[] arr = new string[1];
arr[0] = "Hello";
if (ldelema_any<string>(arr) == "Hello")
return 0;
else
return 1;
}
public static T[,] newarr_multi<T>()
{
return new T[1, 1];
}
public static int test_0_newarr_multi_dim()
{
return newarr_multi<string>().GetType() == typeof(string[,]) ? 0 : 1;
}
interface ITest
{
void Foo<T>();
}
public static int test_0_iface_call_null_bug_77442()
{
ITest test = null;
try
{
test.Foo<int>();
}
catch (NullReferenceException)
{
return 0;
}
return 1;
}
public static int test_18_ldobj_stobj_generics()
{
GenericClass<int> t = new GenericClass<int>();
int i = 5;
int j = 6;
return t.ldobj_stobj(ref i, ref j) + i + j;
}
public static int test_5_ldelem_stelem_generics()
{
GenericClass<TestStruct> t = new GenericClass<TestStruct>();
TestStruct s = new TestStruct(5, 5);
return t.ldelem_stelem(s).i;
}
public static int test_0_constrained_vtype_box()
{
GenericClass<TestStruct> t = new GenericClass<TestStruct>();
return t.toString(new TestStruct()) == "Tests+TestStruct" ? 0 : 1;
}
public static int test_0_constrained_vtype()
{
GenericClass<int> t = new GenericClass<int>();
return t.toString(1234) == "1234" ? 0 : 1;
}
public static int test_0_constrained_reftype()
{
GenericClass<String> t = new GenericClass<String>();
return t.toString("1234") == "1234" ? 0 : 1;
}
public static int test_0_box_brtrue_optimizations()
{
if (IsNull<int>(5))
return 1;
if (!IsNull<object>(null))
return 1;
return 0;
}
public static int test_0_generic_get_value_optimization_int()
{
int[] x = new int[] { 100, 200 };
if (GenericClass<int>.Z(x, 0) != 100)
return 2;
if (GenericClass<int>.Z(x, 1) != 200)
return 3;
return 0;
}
public static int test_0_generic_get_value_optimization_vtype()
{
TestStruct[] arr = new TestStruct[] { new TestStruct(100, 200), new TestStruct(300, 400) };
IEnumerator<TestStruct> enumerator = GenericClass<TestStruct>.Y(arr);
TestStruct s;
int sum = 0;
while (enumerator.MoveNext())
{
s = enumerator.Current;
sum += s.i + s.j;
}
if (sum != 1000)
return 1;
s = GenericClass<TestStruct>.Z(arr, 0);
if (s.i != 100 || s.j != 200)
return 2;
s = GenericClass<TestStruct>.Z(arr, 1);
if (s.i != 300 || s.j != 400)
return 3;
return 0;
}
public static int test_0_nullable_ldflda()
{
return GenericClass<string>.BIsAClazz == false ? 0 : 1;
}
public struct GenericStruct<T>
{
public T t;
public GenericStruct(T t)
{
this.t = t;
}
}
public class GenericClass<T>
{
public T t;
public GenericClass(T t)
{
this.t = t;
}
public GenericClass()
{
}
public T ldobj_stobj(ref T t1, ref T t2)
{
t1 = t2;
T t = t1;
return t;
}
public T ldelem_stelem(T t)
{
T[] arr = new T[10];
arr[0] = t;
return arr[0];
}
public String toString(T t)
{
return t.ToString();
}
public static IEnumerator<T> Y(IEnumerable<T> x)
{
return x.GetEnumerator();
}
public static T Z(IList<T> x, int index)
{
return x[index];
}
protected static T NullB = default(T);
private static Nullable<bool> _BIsA = null;
public static bool BIsAClazz
{
get
{
_BIsA = false;
return _BIsA.Value;
}
}
}
public class MRO : MarshalByRefObject
{
public GenericStruct<int> struct_field;
public GenericClass<int> class_field;
}
public static int test_0_ldfld_stfld_mro()
{
MRO m = new MRO();
GenericStruct<int> s = new GenericStruct<int>(5);
// This generates stfld
m.struct_field = s;
// This generates ldflda
if (m.struct_field.t != 5)
return 1;
// This generates ldfld
GenericStruct<int> s2 = m.struct_field;
if (s2.t != 5)
return 2;
if (m.struct_field.t != 5)
return 3;
m.class_field = new GenericClass<int>(5);
if (m.class_field.t != 5)
return 4;
return 0;
}
// FIXME:
public static int test_0_generic_virtual_call_on_vtype_unbox()
{
object o = new Object();
IFoo h = new Handler(o);
if (h.Bar<object>() != o)
return 1;
else
return 0;
}
public static int test_0_box_brtrue_opt()
{
Foo<int> f = new Foo<int>(5);
f[123] = 5;
return 0;
}
public static int test_0_box_brtrue_opt_regress_81102()
{
if (new Foo<int>(5).ToString() == "null")
return 0;
else
return 1;
}
struct GenericsS
{
public int i;
}
public static int test_0_ldloca_initobj_opt()
{
if (new Foo<GenericsS>(new GenericsS()).get_default().i != 0)
return 1;
if (new Foo<object>(null).get_default() != null)
return 2;
return 0;
}
public static int test_0_ldvirtftn_generic_method()
{
new Tests().ldvirtftn<string>();
return the_type == typeof(string) ? 0 : 1;
}
public static int test_0_throw_dead_this()
{
new Foo<string>("").throw_dead_this();
return 0;
}
struct GenericsS<T> { }
public static int test_0_inline_infinite_polymorphic_recursion()
{
f<int>(0);
return 0;
}
private static void f<T>(int i)
{
if (i == 42) f<GenericsS<T>>(i);
}
// This cannot be made to work with full-aot, since there it is impossible to
// statically determine that Foo<string>.Bar <int> is needed, the code only
// references IFoo.Bar<int>
public static int test_0_generic_virtual_on_interfaces()
{
Foo<string>.count1 = 0;
Foo<string>.count2 = 0;
Foo<string>.count3 = 0;
IFoo f = new Foo<string>("");
for (int i = 0; i < 1000; ++i)
{
f.Bar<int>();
f.Bar<string>();
f.NonGeneric();
}
if (Foo<string>.count1 != 1000)
return 1;
if (Foo<string>.count2 != 1000)
return 2;
if (Foo<string>.count3 != 1000)
return 3;
VirtualInterfaceCallFromGenericMethod<long>(f);
return 0;
}
public static int test_0_generic_virtual_on_interfaces_ref()
{
Foo<string>.count1 = 0;
Foo<string>.count2 = 0;
Foo<string>.count3 = 0;
Foo<string>.count4 = 0;
IFoo f = new Foo<string>("");
for (int i = 0; i < 1000; ++i)
{
f.Bar<string>();
f.Bar<object>();
f.NonGeneric();
}
if (Foo<string>.count2 != 1000)
return 2;
if (Foo<string>.count3 != 1000)
return 3;
if (Foo<string>.count4 != 1000)
return 4;
return 0;
}
//repro for #505375
public static int test_2_cprop_bug()
{
int idx = 0;
int a = 1;
var cmp = System.Collections.Generic.Comparer<int>.Default;
if (cmp.Compare(a, 0) > 0)
a = 0;
do { idx++; } while (cmp.Compare(idx - 1, a) == 0);
return idx;
}
enum MyEnumUlong : ulong
{
Value_2 = 2
}
public static int test_0_regress_550964_constrained_enum_long()
{
MyEnumUlong a = MyEnumUlong.Value_2;
MyEnumUlong b = MyEnumUlong.Value_2;
return Pan(a, b) ? 0 : 1;
}
static bool Pan<T>(T a, T b)
{
return a.Equals(b);
}
public class XElement
{
public string Value
{
get;
set;
}
}
public static int test_0_fullaot_linq()
{
var allWords = new XElement[] { new XElement { Value = "one" } };
var filteredWords = allWords.Where(kw => kw.Value.StartsWith("T"));
return filteredWords.Count();
}
public static int test_0_fullaot_comparer_t()
{
var l = new SortedList<TimeSpan, int>();
return l.Count;
}
public static int test_0_fullaot_comparer_t_2()
{
var l = new Dictionary<TimeSpan, int>();
return l.Count;
}
static void enumerate<T>(IEnumerable<T> arr)
{
foreach (var o in arr)
;
int c = ((ICollection<T>)arr).Count;
}
/* Test that treating arrays as generic collections works with full-aot */
public static int test_0_fullaot_array_wrappers()
{
Tests[] arr = new Tests[10];
enumerate<Tests>(arr);
return 0;
}
static int cctor_count = 0;
public abstract class Beta<TChanged>
{
static Beta()
{
cctor_count++;
}
}
public class Gamma<T> : Beta<T>
{
static Gamma()
{
}
}
// #519336
public static int test_2_generic_class_init_gshared_ctor()
{
new Gamma<object>();
new Gamma<string>();
return cctor_count;
}
static int cctor_count2 = 0;
class ServiceController<T>
{
static ServiceController()
{
cctor_count2++;
}
public ServiceController()
{
}
}
static ServiceController<T> Create<T>()
{
return new ServiceController<T>();
}
// #631409
public static int test_2_generic_class_init_gshared_ctor_from_gshared()
{
Create<object>();
Create<string>();
return cctor_count2;
}
public static Type get_type<T>()
{
return typeof(T);
}
public static int test_0_gshared_delegate_rgctx()
{
Func<Type> t = new Func<Type>(get_type<string>);
if (t() == typeof(string))
return 0;
else
return 1;
}
// Creating a delegate from a generic method from gshared code
public static int test_0_gshared_delegate_from_gshared()
{
if (gshared_delegate_from_gshared<object>() != 0)
return 1;
if (gshared_delegate_from_gshared<string>() != 0)
return 2;
return 0;
}
public static int gshared_delegate_from_gshared<T>()
{
Func<Type> t = new Func<Type>(get_type<T>);
return t() == typeof(T) ? 0 : 1;
}
public static int test_0_marshalbyref_call_from_gshared_virt_elim()
{
/* Calling a virtual method from gshared code which is changed to a nonvirt call */
Class1<object> o = new Class1<object>();
o.Do(new Class2<object>());
return 0;
}
class Pair<TKey, TValue>
{
public static KeyValuePair<TKey, TValue> make_pair(TKey key, TValue value)
{
return new KeyValuePair<TKey, TValue>(key, value);
}
public delegate TRet Transform<TRet>(TKey key, TValue value);
}
public static int test_0_bug_620864()
{
var d = new Pair<string, Type>.Transform<KeyValuePair<string, Type>>(Pair<string, Type>.make_pair);
var p = d("FOO", typeof(int));
if (p.Key != "FOO" || p.Value != typeof(int))
return 1;
return 0;
}
struct RecStruct<T>
{
public void foo(RecStruct<RecStruct<T>> baz)
{
}
}
public static int test_0_infinite_generic_recursion()
{
// Check that the AOT compile can deal with infinite generic recursion through
// parameter types
RecStruct<int> bla;
return 0;
}
struct GenericsFooStruct
{
}
bool IsNull2<T>(object value) where T : struct
{
T? item = (T?)value;
if (item.HasValue)
return false;
return true;
}
public static int test_0_full_aot_nullable_unbox_from_gshared_code()
{
if (!new Tests().IsNull2<GenericsFooStruct>(null))
return 1;
if (new Tests().IsNull2<GenericsFooStruct>(new GenericsFooStruct()))
return 2;
return 0;
}
public static int test_0_partial_sharing()
{
if (PartialShared1(new List<string>(), 1) != typeof(string))
return 1;
if (PartialShared1(new List<Tests>(), 1) != typeof(Tests))
return 2;
if (PartialShared2(new List<string>(), 1) != typeof(int))
return 3;
if (PartialShared2(new List<Tests>(), 1) != typeof(int))
return 4;
return 0;
}
public static int test_6_partial_sharing_linq()
{
var messages = new List<Message>();
messages.Add(new Message() { MessageID = 5 });
messages.Add(new Message() { MessageID = 6 });
return messages.Max(i => i.MessageID);
}
public static int test_0_partial_shared_method_in_nonshared_class()
{
var c = new Class1<double>();
return (c.Foo<string>(5).GetType() == typeof(Class1<string>)) ? 0 : 1;
}
class Message
{
public int MessageID
{
get;
set;
}
}
public static Type PartialShared1<T, K>(List<T> list, K k)
{
return typeof(T);
}
public static Type PartialShared2<T, K>(List<T> list, K k)
{
return typeof(K);
}
public class Class1<T>
{
public virtual void Do(Class2<T> t)
{
t.Foo();
}
public virtual object Foo<U>(T t)
{
return new Class1<U>();
}
}
public interface IFace1<T>
{
void Foo();
}
public class Class2<T> : MarshalByRefObject, IFace1<T>
{
public void Foo()
{
}
}
public static void VirtualInterfaceCallFromGenericMethod<T>(IFoo f)
{
f.Bar<T>();
}
public static Type the_type;
public void ldvirtftn<T>()
{
Foo<T> binding = new Foo<T>(default(T));
binding.GenericEvent += event_handler;
binding.fire();
}
public virtual void event_handler<T>(Foo<T> sender)
{
the_type = typeof(T);
}
public interface IFoo
{
void NonGeneric();
object Bar<T>();
}
public class Foo<T1> : IFoo
{
public Foo(T1 t1)
{
m_t1 = t1;
}
public override string ToString()
{
return Bar(m_t1 == null ? "null" : "null");
}
public String Bar(String s)
{
return s;
}
public int this[T1 key]
{
set
{
if (key == null)
throw new ArgumentNullException("key");
}
}
public void throw_dead_this()
{
try
{
new SomeClass().ThrowAnException();
}
catch
{
}
}
public T1 get_default()
{
return default(T1);
}
readonly T1 m_t1;
public delegate void GenericEventHandler(Foo<T1> sender);
public event GenericEventHandler GenericEvent;
public void fire()
{
GenericEvent(this);
}
public static int count1, count2, count3, count4;
public void NonGeneric()
{
count3++;
}
public object Bar<T>()
{
if (typeof(T) == typeof(int))
count1++;
else if (typeof(T) == typeof(string))
count2++;
else if (typeof(T) == typeof(object))
count4++;
return null;
}
}
public class SomeClass
{
public void ThrowAnException()
{
throw new Exception("Something went wrong");
}
}
struct Handler : IFoo
{
object o;
public Handler(object o)
{
this.o = o;
}
public void NonGeneric()
{
}
public object Bar<T>()
{
return o;
}
}
static bool IsNull<T>(T t)
{
if (t == null)
return true;
else
return false;
}
static object Box<T>(T t)
{
return t;
}
static T Unbox<T>(object o)
{
return (T)o;
}
interface IDefaultRetriever
{
T GetDefault<T>();
}
class DefaultRetriever : IDefaultRetriever
{
[MethodImpl(MethodImplOptions.Synchronized)]
public T GetDefault<T>()
{
return default(T);
}
}
public static int test_0_regress_668095_synchronized_gshared()
{
return DoSomething(new DefaultRetriever());
}
static int DoSomething(IDefaultRetriever foo)
{
int result = foo.GetDefault<int>();
return result;
}
}