Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
More wip
  • Loading branch information
MichalStrehovsky committed May 14, 2024
commit f589dfa595b27fd68f9c90433d3bae217103ccf5
Original file line number Diff line number Diff line change
Expand Up @@ -501,8 +501,12 @@ public sealed override IEnumerable<CombinedDependencyListEntry> GetConditionalSt
MethodDesc defaultIntfMethod = implMethod.GetCanonMethodTarget(CanonicalFormKind.Specific);

// If the interface method is used virtually, the implementation body is used
// BUGBUG: static virtual delegates?
result.Add(new CombinedDependencyListEntry(factory.MethodEntrypoint(defaultIntfMethod), factory.VirtualMethodUse(interfaceMethod), "Interface method"));

// If the interface method is virtual delegate target, the implementation is address taken
result.Add(new CombinedDependencyListEntry(
factory.AddressTakenMethodEntrypoint(defaultIntfMethod),
factory.DelegateTargetVirtualMethod(interfaceMethod.GetCanonMethodTarget(CanonicalFormKind.Specific)), "Interface slot is delegate target"));
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,12 @@ public bool BuildSealedVTableSlots(NodeFactory factory, bool relocsOnly)

if (targetMethod.CanMethodBeInSealedVTable(factory) || implMethod.Signature.IsStatic)
{
// BUGBUG
IMethodNode node = factory.MethodEntrypoint(targetMethod.GetCanonMethodTarget(CanonicalFormKind.Specific), unboxingStub: !targetMethod.Signature.IsStatic && declType.IsValueType);
IMethodNode node;
if (factory.DelegateTargetVirtualMethod(declMethod.GetCanonMethodTarget(CanonicalFormKind.Specific)).Marked)
node = factory.AddressTakenMethodEntrypoint(targetMethod.GetCanonMethodTarget(CanonicalFormKind.Specific), unboxingStub: !targetMethod.Signature.IsStatic && declType.IsValueType);
else
node = factory.MethodEntrypoint(targetMethod.GetCanonMethodTarget(CanonicalFormKind.Specific), unboxingStub: !targetMethod.Signature.IsStatic && declType.IsValueType);

_sealedVTableEntries.Add(SealedVTableEntry.FromVirtualMethod(targetMethod, node));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ interface IStaticInterfaceTargets
static abstract object Return1Del();
static abstract object Return2Del();

static virtual object Return1DelDefaultImpl() => new object();
static virtual object Return2DelDefaultImpl() => new object();

public static void Test<T>() where T : IStaticInterfaceTargets
{
{
Expand All @@ -129,6 +132,21 @@ public static void Test<T>() where T : IStaticInterfaceTargets
if (!f1.Equals(f2))
throw new Exception();
}

{
Func<object> f1 = T.Return1DelDefaultImpl;
Func<object> f2 = T.Return2DelDefaultImpl;
if (f1.Equals(f2))
throw new Exception();
}

// Sanity check equality of delegates pointing to exact same thing
{
Func<object> f1 = T.Return1DelDefaultImpl;
Func<object> f2 = T.Return1DelDefaultImpl;
if (!f1.Equals(f2))
throw new Exception();
}
}
}

Expand All @@ -138,6 +156,13 @@ class StaticInterfaceImplementedTargetsClass : IStaticInterfaceTargets
public static object Return2Del() => new object();
}

class StaticInterfaceImplementedTargetsClass2 : IStaticInterfaceTargets
{
public static object Return1Del() => new object();
public static object Return2Del() => new object();
}


struct StaticInterfaceImplementedTargetsStruct : IStaticInterfaceTargets
{
public static object Return1Del() => new object();
Expand Down Expand Up @@ -192,6 +217,18 @@ class GvmImplementingClass : IInterfaceWithGvms
public virtual object Return2Del<T>() => new object();
}

struct UnboxingThunkStruct<T>
{
public object Return1Del() => new object();
public object Return2Del() => new object();
}

struct ReflectedUnboxingThunkStruct<T>
{
public object Return1Del() => new object();
public object Return2Del() => new object();
}

public static void Run()
{
Return1();
Expand Down Expand Up @@ -347,6 +384,11 @@ public static void Run()

IStaticInterfaceTargets.Test<StaticInterfaceImplementedTargetsClass>();
IStaticInterfaceTargets.Test<StaticInterfaceImplementedTargetsStruct>();
typeof(IStaticInterfaceTargets).GetMethod(nameof(IStaticInterfaceTargets.Test))
.MakeGenericMethod(GetStaticInterfaceImplementedTargetsClass2())
.Invoke(null, []);

static Type GetStaticInterfaceImplementedTargetsClass2() => typeof(StaticInterfaceImplementedTargetsClass2);

{
var f1 = typeof(ReflectedOnType).GetMethod(nameof(ReflectedOnType.Return1Del)).CreateDelegate<Func<object>>();
Expand Down Expand Up @@ -393,5 +435,41 @@ public static void Run()
if (!f1.Equals(f2))
throw new Exception();
}

// Instance method on struct (unshared)
{
var o = new UnboxingThunkStruct<int>();
Func<object> f1 = o.Return1Del;
Func<object> f2 = o.Return2Del;
if (f1.Equals(f2))
throw new Exception();
}

// Instance method on struct (shared)
{
var o = new UnboxingThunkStruct<object>();
Func<object> f1 = o.Return1Del;
Func<object> f2 = o.Return2Del;
if (f1.Equals(f2))
throw new Exception();
}

// Reflection-created open delegates to valuetypes (unshared)
{
var f1 = typeof(ReflectedUnboxingThunkStruct<int>).GetMethod(nameof(ReflectedUnboxingThunkStruct<int>.Return1Del)).CreateDelegate<RefParamDelegate<ReflectedUnboxingThunkStruct<int>>>();
var f2 = typeof(ReflectedUnboxingThunkStruct<int>).GetMethod(nameof(ReflectedUnboxingThunkStruct<int>.Return2Del)).CreateDelegate<RefParamDelegate<ReflectedUnboxingThunkStruct<int>>>();
if (f1.Equals(f2))
throw new Exception();
}

// Reflection-created open delegates to valuetypes (shared)
{
var f1 = typeof(ReflectedUnboxingThunkStruct<object>).GetMethod(nameof(ReflectedUnboxingThunkStruct<object>.Return1Del)).CreateDelegate<RefParamDelegate<ReflectedUnboxingThunkStruct<object>>>();
var f2 = typeof(ReflectedUnboxingThunkStruct<object>).GetMethod(nameof(ReflectedUnboxingThunkStruct<object>.Return2Del)).CreateDelegate<RefParamDelegate<ReflectedUnboxingThunkStruct<object>>>();
if (f1.Equals(f2))
throw new Exception();
}
}

delegate object RefParamDelegate<T>(ref T inst);
}