private object ResolveArgumentValue(MetadataCAArgumentStruct* argument, Type type)
        {
            TypeCode typeCode = (TypeCode)(argument->ArgumentType->Attributes >> 24);
            var valuePtr = MetadataCAArgumentStruct.GetArgumentAddress(argument);

            // If its an enum type
            if (argument->ArgumentType->ParentType == EnumTypePtr)
            {
                typeCode = (TypeCode)(argument->ArgumentType->ElementType->Attributes >> 24);
            }

            switch (typeCode)
            {
                // 1 byte
                case TypeCode.Boolean:
                    return ((bool*)valuePtr)[0];

                case TypeCode.U1:
                    return ((byte*)valuePtr)[0];

                case TypeCode.I1:
                    return ((sbyte*)valuePtr)[0];

                // 2 bytes
                case TypeCode.Char:
                    return ((char*)valuePtr)[0];

                case TypeCode.U2:
                    return ((ushort*)valuePtr)[0];

                case TypeCode.I2:
                    return ((short*)valuePtr)[0];

                // 4 bytes
                case TypeCode.U4:
                    return ((uint*)valuePtr)[0];

                case TypeCode.I4:
                    return ((int*)valuePtr)[0];

                case TypeCode.R4:
                    return ((float*)valuePtr)[0];

                // 8 bytes
                case TypeCode.U8:
                    return ((ulong*)valuePtr)[0];

                case TypeCode.I8:
                    return ((long*)valuePtr)[0];

                case TypeCode.R8:
                    return ((double*)valuePtr)[0];

                // SZArray
                case TypeCode.SZArray:
                    return ResolveArrayValue(argument, type);

                // String
                case TypeCode.String:
                    return x86Runtime.InitializeMetadataString(valuePtr);

                default:
                    if (type.FullName == "System.Type")
                    {
                        // Get the argument type
                        RuntimeTypeHandle argTypeHandle = new RuntimeTypeHandle();
                        ((uint**)&argTypeHandle)[0] = (uint*)argument->ArgumentType;
                        return Type.GetTypeFromHandle(argTypeHandle);
                    }
                    throw new ArgumentException();
            }

            //return null;
        }
        private object ResolveArrayValue(MetadataCAArgumentStruct* argument, Type type)
        {
            TypeCode typeCode = (TypeCode)(argument->ArgumentType->ElementType->Attributes >> 24);
            var valuePtr = MetadataCAArgumentStruct.GetArgumentAddress(argument);
            var size = valuePtr[0];
            valuePtr++;

            switch (typeCode)
            {
                // 1 byte
                case TypeCode.Boolean:
                    {
                        bool[] array = new bool[size];
                        for (int i = 0; i < size; i++)
                            array[i] = ((bool*)valuePtr)[i];
                        return array;
                    }

                case TypeCode.U1:
                    {
                        byte[] array = new byte[size];
                        for (int i = 0; i < size; i++)
                            array[i] = ((byte*)valuePtr)[i];
                        return array;
                    }

                case TypeCode.I1:
                    {
                        sbyte[] array = new sbyte[size];
                        for (int i = 0; i < size; i++)
                            array[i] = ((sbyte*)valuePtr)[i];
                        return array;
                    }

                // 2 bytes
                case TypeCode.Char:
                    {
                        char[] array = new char[size];
                        for (int i = 0; i < size; i++)
                            array[i] = ((char*)valuePtr)[i];
                        return array;
                    }

                case TypeCode.U2:
                    {
                        ushort[] array = new ushort[size];
                        for (int i = 0; i < size; i++)
                            array[i] = ((ushort*)valuePtr)[i];
                        return array;
                    }

                case TypeCode.I2:
                    {
                        short[] array = new short[size];
                        for (int i = 0; i < size; i++)
                            array[i] = ((short*)valuePtr)[i];
                        return array;
                    }

                // 4 bytes
                case TypeCode.U4:
                    {
                        uint[] array = new uint[size];
                        for (int i = 0; i < size; i++)
                            array[i] = ((uint*)valuePtr)[i];
                        return array;
                    }

                case TypeCode.I4:
                    {
                        int[] array = new int[size];
                        for (int i = 0; i < size; i++)
                            array[i] = ((int*)valuePtr)[i];
                        return array;
                    }

                case TypeCode.R4:
                    {
                        float[] array = new float[size];
                        for (int i = 0; i < size; i++)
                            array[i] = ((float*)valuePtr)[i];
                        return array;
                    }

                // 8 bytes
                case TypeCode.U8:
                    {
                        ulong[] array = new ulong[size];
                        for (int i = 0; i < size; i++)
                            array[i] = ((ulong*)valuePtr)[i];
                        return array;
                    }

                case TypeCode.I8:
                    {
                        long[] array = new long[size];
                        for (int i = 0; i < size; i++)
                            array[i] = ((long*)valuePtr)[i];
                        return array;
                    }

                case TypeCode.R8:
                    {
                        double[] array = new double[size];
                        for (int i = 0; i < size; i++)
                            array[i] = ((double*)valuePtr)[i];
                        return array;
                    }

                default:
                    // TODO: Enums
                    // What kind of array is this!?
                    throw new NotSupportedException();
            }
        }
 public static uint* GetArgumentAddress(MetadataCAArgumentStruct* data)
 {
     return (uint*)((uint*)data + MetadataCAArgumentStruct.ArgumentOffset);
 }