Washi1337 / OldRod

An automated KoiVM disassembler and devirtualisation utility
GNU General Public License v3.0
350 stars 80 forks source link

Interfaces are cast to objects for no apparent reason. #48

Closed ElektroKill closed 2 years ago

ElektroKill commented 2 years ago

Describe the bug OldRod's type analyzer doesn't treat interfaces to be objects. This causes weird casts to System.Object like in the example below. These casts often occur to null checking code.

image image

This code works exactly the same and is cleaner when decompiled if the castclass to System.Object is removed from the method.

To Reproduce Devirtualize the sample provided for issue #47.

Potential solution https://github.com/Washi1337/OldRod/blob/6773f8dcc780efae20722fe3242d7afc6144d564/src/OldRod.Core/Recompiler/Transform/TypeHelper.cs#L134-L136 The code above could be replaced with something along the lines of:

if (typeDef.IsEnum)
    typeSig = typeDef.GetEnumUnderlyingType();
else if (typeDef.IsInterface && typeDef.BaseType is null)
    typeSig = _objectType.ToTypeSignature();
else
    typeSig = typeDef.BaseType?.ToTypeSignature().InstantiateGenericTypes(genericContext);

This seems to resolve the problem. However, I am not sure if this would have some side effects which didn't come up in my very limited testing. Would this be ok? If yes then I can make a PR :)

Washi1337 commented 2 years ago

This should be an acceptable change. Every interface instance that is not explicitly typed must be at least an instance of System.Object (either as a class instance, or a boxed structure instance).

PR is welcome.