Washi1337 / OldRod

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

Constants of type float and double are emitted as int32 or int64 #22

Closed Washi1337 closed 4 years ago

Washi1337 commented 4 years ago

Describe the bug KoiVM does not have a dedicated instruction for pushing floating point constants. Instead, it reuses the PUSHI_DWORD or PUSHI_QWORD instructions, as they use the same amount of bits as a float or a double respectively. This is not taken into account in the recompiler. The recompiler always interprets constants pushed by these instructions as int32 or int64 values.

To Reproduce

using System;

namespace MyProgram
{
    public static class Program
    {
        public static void Main()
        {
            TestFloat(1.0F);
            TestDouble(2.0F);
        }

        public static void TestFloat(float x)
        {
            Console.WriteLine(x);
        }

        public static void TestDouble(double x)
        {
            Console.WriteLine(x);
        }
    }
}

Expected behavior Old Rod should devirtualize back to the following code:

Program.TestFloat(1.0F);
Program.TestDouble(2.0F);

but instead it produces:

Program.TestFloat((float)1065353216);
Program.TestDouble((double)4611686018427387904L);

Additional context Many Windows Forms and WPF applications depend on this, as they use floats to assign locations and/or sizes to controls.