Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
Freekjan opened this issue Jan 9, 2023 · 2 comments
Assignees
Labels
bug Something isn't working

Comments

@Freekjan
Copy link

Freekjan commented Jan 9, 2023

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
}
@vermorel
Copy link
Member

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.

@OlegRa
Copy link
Collaborator

OlegRa commented Apr 25, 2023

@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 OlegRa added the bug Something isn't working label Apr 25, 2023
@OlegRa OlegRa self-assigned this Apr 25, 2023
OlegRa added a commit to OlegRa/ILPack that referenced this issue May 1, 2023
…handle equals to body handle (default interface method case).
VictorNicollet pushed a commit that referenced this issue Jun 14, 2023
…e equals to body handle (default interface method case).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants