ILPack icon indicating copy to clipboard operation
ILPack copied to clipboard

Classes that implement interfaces with defaulted methods crash the dll generator.

Open Freekjan opened this issue 3 years ago • 2 comments

If you try to emit a class that implements an interface with a default interface method, and the class does not override the defaulted method, the resulting assembly crashes the assembly generator with the following stack trace.

Unhandled exception. System.InvalidCastException: Specified cast is not valid.
   at System.Reflection.Throw.InvalidCast()
   at System.Reflection.Metadata.TypeDefinitionHandle.op_Explicit(EntityHandle handle)
   at Lokad.ILPack.AssemblyGenerator.DeclareInterfacesAndCreateInterfaceMap(Type type, TypeDefinitionHandle handle)
   at Lokad.ILPack.AssemblyGenerator.CreateType(Type type, List`1 genericParams)
   at Lokad.ILPack.AssemblyGenerator.CreateTypes(IEnumerable`1 types, List`1 genericParams)
   at Lokad.ILPack.AssemblyGenerator.CreateModules(IEnumerable`1 moduleInfo)
   at Lokad.ILPack.AssemblyGenerator.GenerateAssemblyBytes(Assembly assembly, IEnumerable`1 referencedDynamicAssembly)
   at Lokad.ILPack.AssemblyGenerator.GenerateAssembly(Assembly assembly, IEnumerable`1 referencedDynamicAssembly, String path)
   at Lokad.ILPack.AssemblyGenerator.GenerateAssembly(Assembly assembly, String path).

For completeness, the following code reproduces this bug:

using System.Reflection;
using System.Reflection.Emit;

using Lokad.ILPack;

var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("Demo"), AssemblyBuilderAccess.RunAndCollect);
var moduleBuilder = assemblyBuilder.DefineDynamicModule("ModuleName");
var typeBuilder = moduleBuilder.DefineType("Crash", TypeAttributes.Public, typeof(object), new [] {typeof(IDefaultedMethod)});
typeBuilder.DefineDefaultConstructor(MethodAttributes.Public);
typeBuilder.CreateType();
new AssemblyGenerator().GenerateAssembly(assemblyBuilder, "demo.dll");

public interface IDefaultedMethod
{
    public void Default() { } // omitting this line allows the assembly generator to emit demo.dll
}

Freekjan avatar Jan 09 '23 13:01 Freekjan

Hi @Freekjan, thanks a lot for your very precise report. I don't have resources to assign to the case at the moment, but we will try, at some point, to make another round of bugfixes on this project.

vermorel avatar Jan 16 '23 17:01 vermorel

@vermorel @Freekjan I have a fix for this issue. It works fine on my side, just need time for writing unit tests required for PR.

OlegRa avatar Apr 25 '23 18:04 OlegRa