Washi1337 / OldRod

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

Type inference verification of function arguments passed by-ref too strict when argument types are not inferred yet #20

Open Washi1337 opened 4 years ago

Washi1337 commented 4 years ago

Describe the bug Currently, the recompiler performs type inference of both variables and parameters for each virtualized method in one visit of the CIL AST. This introduces a problem if the CIL AST contains a call to an unexported virtualized method with a by-ref parameter. If the callee was not processed by type inference yet, then any argument expression that goes into this by-ref parameter slot will trigger an exception in the type inference stage (here). The type inference stage expects a ByReferenceTypeSignature for each ldloca expression, but the method signature is still the original System.Object from the method signature auto-generated by the code analysis stage.

To Reproduce Sample code that triggers the error:

using System;
using System.IO;

namespace MyProgram
{
    public static class Program
    {
        public static void Main()
        {
            string temp = "Hello";
            Temp(ref temp);
            Console.WriteLine(temp);
        }

        private static void Temp(ref string arg)
        {
            arg += ", world!";
        }
    }
}

Ideas Possible solution is to remove the sanity check all together, but this is undesirable. Another solution is to delay the verification, or split up parameter type inference from variable type inference. Another idea could be an additional check whether the parameter type is not finalized yet.