Fix interface handling in CorInfoImpl.resolveVirtualMethod (#3922)

Without this fix, the CoreRT compiler generated the following code for the
test that I am adding:

call    Interfaces!_NewHelper_Interfaces_BringUpTest_SomeClass
mov     rcx,rax
call
Interfaces!Interfaces_BringUpTest_SomeAbstractBaseClass__get_SomeValue

As you can see, it ends up calling an abstract method on the base class.

With this fix, the interface call is resolved correctly:

call    Interfaces!_NewHelper_Interfaces_BringUpTest_SomeClass
mov     rcx,rax
call    Interfaces!Interfaces_BringUpTest_SomeClass__get_SomeValue
This commit is contained in:
Sergiy Kuryata 2017-06-19 14:10:44 -07:00 коммит произвёл Jan Kotas
Родитель cccbccac22
Коммит f613261b65
2 изменённых файлов: 38 добавлений и 0 удалений

Просмотреть файл

@ -849,6 +849,10 @@ namespace Internal.JitInterface
}
impl = implType.ResolveInterfaceMethodTarget(decl);
if (impl != null)
{
impl = implType.GetClosestDefType().FindVirtualFunctionTargetMethodOnObjectType(impl);
}
}
else
{

Просмотреть файл

@ -5,6 +5,7 @@
using System;
using System.Text;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
public class BringUpTest
{
@ -28,6 +29,9 @@ public class BringUpTest
if (TestSpecialArrayInterfaces() == Fail)
return Fail;
if (TestIterfaceCallOptimization() == Fail)
return Fail;
return Pass;
}
@ -359,4 +363,34 @@ public class BringUpTest
}
#endregion
#region Interface call optimization tests
public interface ISomeInterface
{
int SomeValue { get; }
}
public abstract class SomeAbstractBaseClass : ISomeInterface
{
public abstract int SomeValue { get; }
}
public class SomeClass : SomeAbstractBaseClass
{
public override int SomeValue
{
[MethodImpl(MethodImplOptions.NoInlining)]
get { return 14; }
}
}
private static int TestIterfaceCallOptimization()
{
ISomeInterface test = new SomeClass();
int v = test.SomeValue;
return (v == 14) ? Pass : Fail;
}
#endregion
}