Beispiel #1
0
        public Signature(IKVM.Reflection.Universe universe, Reader reader, uint typeIndex)
        {
            this.TypeIndex = typeIndex;

            reader.ReadVarInt7(); //Function Type

            var parameters     = this.ParameterTypes = new System.Type[reader.ReadVarUInt32()];
            var ikvmParameters = this.IKVMParameterTypes = new IKVM.Reflection.Type[parameters.Length];
            var rawParameters  = this.RawParameterTypes = new ValueType[parameters.Length];

            for (var i = 0; i < parameters.Length; i++)
            {
                parameters[i]     = (rawParameters[i] = (ValueType)reader.ReadVarInt7()).ToSystemType();
                ikvmParameters[i] = universe.Import(parameters[i]);
            }

            var returns     = this.ReturnTypes = new System.Type[reader.ReadVarUInt1()];
            var ikvmReturns = this.IKVMReturnTypes = new IKVM.Reflection.Type[returns.Length];
            var rawReturns  = this.RawReturnTypes = new ValueType[returns.Length];

            if (returns.Length > 1)
            {
                throw new ModuleLoadException("Multiple returns are not supported.", reader.Offset - 1);
            }

            for (var i = 0; i < returns.Length; i++)
            {
                returns[i]     = (rawReturns[i] = (ValueType)reader.ReadVarInt7()).ToSystemType();
                ikvmReturns[i] = universe.Import(returns[i]);
            }
        }
Beispiel #2
0
        private IKVM.Reflection.Emit.MethodBuilder IKVMCreateStoreMethod(HelperMethod helper, IKVMCompilationContext context, IKVM.Reflection.Universe universe)
        {
            var builder = context.ExportsBuilder.DefineMethod(
                $"☣ {helper}",
                IKVMCompilationContext.HelperMethodAttributes,
                universe.Import(typeof(void)),
                new[]
            {
                universe.Import(typeof(uint)),             //Address
                universe.Import(this.Type.ToSystemType()), //Value
                universe.Import(typeof(uint)),             //Offset
                context.ExportsBuilder.AsType(),
            }
                );
            var il = builder.GetILGenerator();

            il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_2);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Add_Ovf_Un);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_3);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Call, IKVMCreateRangeCheck(this.RangeCheckHelper, context, universe));
            il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_3);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Ldfld, context.Memory);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Call, Runtime.UnmanagedMemory.IKVMStartGetter(universe));
            il.Emit(IKVM.Reflection.Emit.OpCodes.Add);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_1);
            il.Emit(this.IKVMEmittedOpCode);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Ret);

            return(builder);
        }
        internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe)
        {
            var stack = context.Stack;

            if (stack.Count < 2)
            {
                throw new StackTooSmallException(OpCode.Int64RotateLeft, 2, stack.Count);
            }

            var typeB = stack.Pop();
            var typeA = stack.Peek(); //Assuming validation passes, the remaining type will be this.

            if (typeA != ValueType.Int64)
            {
                throw new StackTypeInvalidException(OpCode.Int64RotateLeft, ValueType.Int64, typeA);
            }

            if (typeA != typeB)
            {
                throw new StackParameterMismatchException(OpCode.Int64RotateLeft, typeA, typeB);
            }

            context.Emit(IKVM.Reflection.Emit.OpCodes.Call, context[HelperMethod.Int64RotateLeft, (helper, c) =>
                                                                    {
                                                                        var builder = c.ExportsBuilder.DefineMethod(
                                                                            "☣ Int64RotateLeft",
                                                                            IKVMCompilationContext.HelperMethodAttributes,
                                                                            universe.Import(typeof(ulong)),
                                                                            new[]
                {
                    universe.Import(typeof(ulong)),
                    universe.Import(typeof(long)),
                }
                                                                            );

                                                                        var il = builder.GetILGenerator();
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_1);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Conv_I4);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4_S, 63);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.And);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Shl);

                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4_S, 64);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_1);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Conv_I4);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Sub);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4_S, 63);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.And);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Shr_Un);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Or);

                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ret);
                                                                        return(builder);
                                                                    }
                         ]);
        }
Beispiel #4
0
        internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe)
        {
            var stack = context.Stack;

            if (stack.Count < 1)
            {
                throw new StackTooSmallException(OpCode.Float32CopySign, 1, stack.Count);
            }

            var type = stack.Pop();

            if (type != ValueType.Float32)
            {
                throw new StackTypeInvalidException(OpCode.Float32CopySign, ValueType.Float32, type);
            }

            type = stack.Peek(); //Assuming validation passes, the remaining type will be this.
            if (type != ValueType.Float32)
            {
                throw new StackTypeInvalidException(OpCode.Float32CopySign, ValueType.Float32, type);
            }

            context.Emit(IKVM.Reflection.Emit.OpCodes.Call, context[HelperMethod.Float32CopySign, (helper, c) =>
                                                                    {
                                                                        var builder = c.ExportsBuilder.DefineMethod(
                                                                            "☣ Float32CopySign",
                                                                            IKVMCompilationContext.HelperMethodAttributes,
                                                                            universe.Import(typeof(float)),
                                                                            new[]
                {
                    universe.Import(typeof(float)),
                    universe.Import(typeof(float)),
                }
                                                                            );

                                                                        var il = builder.GetILGenerator();
                                                                        var value = il.DeclareLocal(universe.Import(typeof(uint)));

                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarga_S, 0);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldind_U4);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4, 0x7fffffff);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.And);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarga_S, 1);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldind_U4);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4, 0x80000000);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.And);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Or);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Stloc_0);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldloca_S, value);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldind_R4);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ret);

                                                                        return(builder);
                                                                    }
                         ]);
        }
Beispiel #5
0
        internal static IKVM.Reflection.Emit.MethodBuilder IKVMCreateHelper(HelperMethod helper, IKVMCompilationContext context, IKVM.Reflection.Universe universe)
        {
            Assert(context != null);

            var result = context.ExportsBuilder.DefineMethod(
                "☣ Int32CountOneBits",
                IKVMCompilationContext.HelperMethodAttributes,
                universe.Import(typeof(uint)),
                new[] { universe.Import(typeof(uint)) });

            //All modern CPUs have a fast instruction specifically for this process, but there's no way to use it from .NET.
            //This algorithm is from https://stackoverflow.com/questions/109023/how-to-count-the-number-of-set-bits-in-a-32-bit-integer
            var il = result.GetILGenerator();

            il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4_1);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Shr_Un);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4, 0x55555555);
            il.Emit(IKVM.Reflection.Emit.OpCodes.And);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Sub);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Starg_S, 0);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4, 0x33333333);
            il.Emit(IKVM.Reflection.Emit.OpCodes.And);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4_2);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Shr_Un);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4, 0x33333333);
            il.Emit(IKVM.Reflection.Emit.OpCodes.And);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Add);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Starg_S, 0);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4_4);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Shr_Un);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Add);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4, 0x0f0f0f0f);
            il.Emit(IKVM.Reflection.Emit.OpCodes.And);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4, 0x01010101);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Mul);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4_S, 24);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Shr_Un);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Ret);

            return(result);
        }
Beispiel #6
0
        internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe)
        {
            var stack = context.Stack;

            if (stack.Count < 1)
            {
                throw new StackTooSmallException(OpCode.Int64CountTrailingZeroes, 1, stack.Count);
            }

            var type = stack.Peek(); //Assuming validation passes, the remaining type will be this.

            if (type != ValueType.Int64)
            {
                throw new StackTypeInvalidException(OpCode.Int64CountTrailingZeroes, ValueType.Int64, type);
            }

            context.Emit(IKVM.Reflection.Emit.OpCodes.Call, context[HelperMethod.Int64CountTrailingZeroes, (helper, c) =>
                                                                    {
                                                                        Assert(c != null);

                                                                        var result = context.ExportsBuilder.DefineMethod(
                                                                            "☣ Int64CountTrailingZeroes",
                                                                            IKVMCompilationContext.HelperMethodAttributes,
                                                                            universe.Import(typeof(long)),
                                                                            new[] { universe.Import(typeof(ulong)) });

                                                                        //All modern CPUs have a fast instruction specifically for this process, but there's no way to use it from .NET.
                                                                        //Based on the algorithm found here: http://aggregate.org/MAGIC/#Trailing%20Zero%20Count
                                                                        var il = result.GetILGenerator();
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Neg);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.And);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4_1);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Conv_I8);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Sub);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Call, Int64CountOneBits.IKVMCreateHelper(HelperMethod.Int64CountOneBits, context, universe));
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ret);

                                                                        return(result);
                                                                    }
                         ]);
        }
Beispiel #7
0
        internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe)
        {
            Assert(context != null);

            var returns = context.Signature.RawReturnTypes;
            var stack   = context.Stack;

            Assert(stack != null);

            var returnsLength = returns.Length;

            Assert(returnsLength == 0 || returnsLength == 1); //WebAssembly doesn't currently offer multiple returns, which should be blocked earlier.

            var stackCount = stack.Count;

            if (stackCount < returnsLength)
            {
                throw new StackTooSmallException(OpCode.Return, returnsLength, 0);
            }

            if (stackCount > returnsLength)
            {
                if (returnsLength == 0)
                {
                    for (var i = 0; i < stackCount - returnsLength; i++)
                    {
                        context.Emit(IKVM.Reflection.Emit.OpCodes.Pop);
                    }
                }
                else
                {
                    var value = context.DeclareLocal(universe.Import(returns[0].ToSystemType()));
                    context.Emit(IKVM.Reflection.Emit.OpCodes.Stloc, value.LocalIndex);

                    for (var i = 0; i < stackCount - returnsLength; i++)
                    {
                        context.Emit(IKVM.Reflection.Emit.OpCodes.Pop);
                    }

                    context.Emit(IKVM.Reflection.Emit.OpCodes.Ldloc, value.LocalIndex);
                }
            }
            else if (returnsLength == 1)
            {
                var type = stack.Pop();
                if (type != returns[0])
                {
                    throw new StackTypeInvalidException(OpCode.Return, returns[0], type);
                }
            }

            context.Emit(IKVM.Reflection.Emit.OpCodes.Ret);
        }
Beispiel #8
0
        internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe)
        {
            var stack = context.Stack;

            if (stack.Count < 1)
            {
                throw new StackTooSmallException(OpCode.Float32ReinterpretInt32, 1, stack.Count);
            }

            var type = stack.Pop();

            if (type != ValueType.Int32)
            {
                throw new StackTypeInvalidException(OpCode.Float32ReinterpretInt32, ValueType.Int32, type);
            }

            stack.Push(ValueType.Float32);

            context.Emit(IKVM.Reflection.Emit.OpCodes.Call, context[HelperMethod.Float32ReinterpretInt32, (helper, c) =>
                                                                    {
                                                                        var builder = c.ExportsBuilder.DefineMethod(
                                                                            "☣ Float32ReinterpretInt32",
                                                                            IKVMCompilationContext.HelperMethodAttributes,
                                                                            universe.Import(typeof(float)),
                                                                            new[]
                {
                    universe.Import(typeof(int)),
                }
                                                                            );

                                                                        var il = builder.GetILGenerator();
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarga_S, 0);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldind_R4);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ret);
                                                                        return(builder);
                                                                    }
                         ]);
        }
Beispiel #9
0
 public Signature(ValueType returnType)
 {
     IKVM.Reflection.Universe universe = new IKVM.Reflection.Universe();
     this.TypeIndex          = uint.MaxValue;
     this.ParameterTypes     = new System.Type[0];
     this.IKVMParameterTypes = new IKVM.Reflection.Type[0];
     this.RawParameterTypes  = new ValueType[0];
     this.ReturnTypes        = new[] { returnType.ToSystemType() };
     this.IKVMReturnTypes    = new IKVM.Reflection.Type[this.ReturnTypes.Length];
     for (int i = 0; i < this.ReturnTypes.Length; i++)
     {
         this.IKVMReturnTypes[i] = universe.Import(this.ReturnTypes[i]);
     }
     this.RawReturnTypes = new[] { returnType };
 }
Beispiel #10
0
        internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe)
        {
            var signature   = context.Types[this.Type];
            var paramTypes  = signature.RawParameterTypes;
            var returnTypes = signature.RawReturnTypes;

            var stack = context.Stack;

            if (stack.Count < paramTypes.Length)
            {
                throw new StackTooSmallException(OpCode.CallIndirect, paramTypes.Length, stack.Count);
            }

            var type = stack.Pop();

            if (type != ValueType.Int32)
            {
                throw new StackTypeInvalidException(OpCode.CallIndirect, ValueType.Int32, type);
            }

            for (var i = paramTypes.Length - 1; i >= 0; i--)
            {
                type = stack.Pop();
                if (type != paramTypes[i])
                {
                    throw new StackTypeInvalidException(OpCode.CallIndirect, paramTypes[i], type);
                }
            }

            for (var i = 0; i < returnTypes.Length; i++)
            {
                stack.Push(returnTypes[i]);
            }

            Int32Constant.Emit(context, checked ((int)this.Type));
            context.Emit(IKVM.Reflection.Emit.OpCodes.Call, context[HelperMethod.GetFunctionPointer]);
            context.Emit(IKVM.Reflection.Emit.OpCodes.Stloc, context.IndirectPointerLocal.LocalIndex);
            context.EmitLoadThis();
            context.Emit(IKVM.Reflection.Emit.OpCodes.Ldloc, context.IndirectPointerLocal.LocalIndex);
            context.EmitCalli(
                signature.IKVMReturnTypes.Length == 0 ? universe.Import(typeof(void)) : signature.IKVMReturnTypes[0],
                signature.IKVMParameterTypes.Concat(new[] { context.ExportsBuilder.AsType() }).ToArray(
                    ));
        }
 internal static IKVM.Reflection.MethodInfo IKVMStartGetter(IKVM.Reflection.Universe universe)
 {
     IKVM.Reflection.MethodInfo info = new RegeneratingWeakReference <IKVM.Reflection.MethodInfo>(()
                                                                                                  => universe.Import(typeof(UnmanagedMemory)).GetTypeInfo().DeclaredProperties.Where(prop => prop.Name == nameof(Start)).First().GetMethod);
     return(info);
 }
        internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe)
        {
            var stack = context.Stack;

            if (stack.Count < 1)
            {
                throw new StackTooSmallException(OpCode.Int32CountLeadingZeroes, 1, stack.Count);
            }

            var type = stack.Peek(); //Assuming validation passes, the remaining type will be this.

            if (type != ValueType.Int32)
            {
                throw new StackTypeInvalidException(OpCode.Int32CountLeadingZeroes, ValueType.Int32, type);
            }

            context.Emit(IKVM.Reflection.Emit.OpCodes.Call, context[HelperMethod.Int32CountLeadingZeroes, (helper, c) =>
                                                                    {
                                                                        Assert(c != null);

                                                                        var result = context.ExportsBuilder.DefineMethod(
                                                                            "☣ Int32CountLeadingZeroes",
                                                                            IKVMCompilationContext.HelperMethodAttributes,
                                                                            universe.Import(typeof(uint)),
                                                                            new[] { universe.Import(typeof(uint)) });

                                                                        //All modern CPUs have a fast instruction specifically for this process, but there's no way to use it from .NET.
                                                                        //This algorithm is from https://stackoverflow.com/questions/10439242/count-leading-zeroes-in-an-int32
                                                                        var il = result.GetILGenerator();
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4_1);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Shr_Un);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Or);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Starg_S, 0);

                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4_2);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Shr_Un);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Or);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Starg_S, 0);

                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4_4);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Shr_Un);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Or);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Starg_S, 0);

                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4_8);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Shr_Un);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Or);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Starg_S, 0);

                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4_S, 16);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Shr_Un);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Or);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Starg_S, 0);

                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldc_I4_S, 32);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Call, Int32CountOneBits.IKVMCreateHelper(HelperMethod.Int32CountOneBits, context, universe));
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Sub);
                                                                        il.Emit(IKVM.Reflection.Emit.OpCodes.Ret);

                                                                        return(result);
                                                                    }
                         ]);
        }
 internal sealed override void CompileIKVM(IKVMCompilationContext context, IKVM.Reflection.Universe universe)
 {
     context.Emit(IKVM.Reflection.Emit.OpCodes.Newobj, universe.Import(typeof(UnreachableException)).GetTypeInfo().DeclaredConstructors.First(c => c.GetParameters().Length == 0));
     context.Emit(IKVM.Reflection.Emit.OpCodes.Throw);
 }
Beispiel #14
0
        static IKVM.Reflection.Emit.MethodBuilder IKVMCreateSelectHelper(HelperMethod helper, IKVMCompilationContext context, IKVM.Reflection.Universe universe)
        {
            Assert(context != null);

            IKVM.Reflection.Emit.MethodBuilder builder;
            switch (helper)
            {
            default:
                Fail("Attempted to obtain an unknown helper method.");
                return(null);

            case HelperMethod.SelectInt32:
                builder = context.ExportsBuilder.DefineMethod(
                    "☣ Select Int32",
                    IKVMCompilationContext.HelperMethodAttributes,
                    universe.Import(typeof(int)),
                    new[]
                {
                    universe.Import(typeof(int)),
                    universe.Import(typeof(int)),
                    universe.Import(typeof(int)),
                }
                    );
                break;

            case HelperMethod.SelectInt64:
                builder = context.ExportsBuilder.DefineMethod(
                    "☣ Select Int64",
                    IKVMCompilationContext.HelperMethodAttributes,
                    universe.Import(typeof(long)),
                    new[]
                {
                    universe.Import(typeof(long)),
                    universe.Import(typeof(long)),
                    universe.Import(typeof(int)),
                }
                    );
                break;

            case HelperMethod.SelectFloat32:
                builder = context.ExportsBuilder.DefineMethod(
                    "☣ Select Float32",
                    IKVMCompilationContext.HelperMethodAttributes,
                    universe.Import(typeof(float)),
                    new[]
                {
                    universe.Import(typeof(float)),
                    universe.Import(typeof(float)),
                    universe.Import(typeof(int)),
                }
                    );
                break;

            case HelperMethod.SelectFloat64:
                builder = context.ExportsBuilder.DefineMethod(
                    "☣ Select Float64",
                    IKVMCompilationContext.HelperMethodAttributes,
                    universe.Import(typeof(double)),
                    new[]
                {
                    universe.Import(typeof(double)),
                    universe.Import(typeof(double)),
                    universe.Import(typeof(int)),
                }
                    );
                break;
            }

            var il = builder.GetILGenerator();

            il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_2);
            var @true = il.DefineLabel();

            il.Emit(IKVM.Reflection.Emit.OpCodes.Brtrue_S, @true);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_1);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Ret);
            il.MarkLabel(@true);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Ldarg_0);
            il.Emit(IKVM.Reflection.Emit.OpCodes.Ret);
            return(builder);
        }