Lokad / ILPack

Serialize .NET Core assemblies

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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

Freekjan opened this issue · 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
}

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 @Freekjan I have a fix for this issue. It works fine on my side, just need time for writing unit tests required for PR.