示例#1
0
        public void TestEmitString()
        {
            Func <string> tst      = () => "hello";
            Func <int>    tstToken = () =>
            {
                var tstMethod   = tst.Method;
                var methodBytes = tstMethod.GetMethodBody().GetILAsByteArray();
                var ilStream    = ILInstructionReader.FromByteCode(tstMethod.GetMethodBody().GetILAsByteArray());
                return((int)ilStream[0].Arg);
            };
            int stringToken = tstToken();

            var expected = tst();
            var builder  = new ILInstructionBuilder();

            builder.Write(OpCodes.Ldstr, stringToken);
            builder.Write(OpCodes.Ret);
            var ilMethod = new ILMethod(MethodBase.GetCurrentMethod().Name, expected.GetType());

            ilMethod.AddInstructions(builder.Instructions.ToArray());
            ilMethod.Module = this.GetType().Module;
            var method = ilMethod.Compile();
            var actual = method.Invoke(null, Type.EmptyTypes);

            Assert.IsTrue((string)actual == expected, $"Actual: {actual}\r\nExpected:{expected}");
        }
示例#2
0
        public void TestEmitMethod()
        {
            var c        = new ILEngineUnitTestModel(1);
            var cType    = c.GetType();
            var cMethod  = cType.GetMethod(nameof(c.GetValue));
            var expected = c.Value;

            var builder = new ILInstructionBuilder();

            builder.Write(OpCodes.Ldarg_0);
            builder.Write(OpCodes.Call, cMethod.MetadataToken);
            builder.Write(OpCodes.Ret);

            var frame = ILStackFrameBuilder.Build(builder.Instructions);

            frame.SetResolver(this.GetType());
            frame.Args = new object[] { c };
            frame.Execute();


            var ilMethod = new ILMethod(MethodBase.GetCurrentMethod().Name, expected.GetType());

            ilMethod.AddParameters(new[] { cType });
            ilMethod.AddInstructions(builder.Instructions.ToArray());
            ilMethod.Module = this.GetType().Module;
            var method = ilMethod.Compile();
            var actual = method.Invoke(null, new object[] { c });

            Assert.IsTrue((int)actual == expected, $"Actual: {actual}\r\nExpected:{expected}");
        }
示例#3
0
        public void TestEmitConstructorInfo()
        {
            var c       = new ILEngineUnitTestModel(0);
            var cType   = c.GetType();
            var cMethod = cType.GetConstructor(Type.EmptyTypes);
            var cResult = cMethod.Invoke(null);

            Assert.IsNotNull(cMethod);
            var expected = c;

            var builder = new ILInstructionBuilder();

            builder.Write(OpCodes.Newobj, cMethod);
            builder.Write(OpCodes.Ret);


            var ilMethod = new ILMethod(MethodBase.GetCurrentMethod().Name, expected.GetType());

            ilMethod.AddInstructions(builder.Instructions.ToArray());
            ilMethod.Module = cType.GetType().Module;
            var method = ilMethod.Compile();
            var actual = method.Invoke(null, null);

            Assert.IsTrue((ILEngineUnitTestModel)actual == expected, $"Actual: {actual}\r\nExpected:{expected}");
        }
        //protected void AssertEmptyStackResult<TResult>(TStackFrame frame, object expected, Func<object, TResult> converter)
        //{
        //    AssertExceptionIsNull(frame);
        //    AssertEmptyStack(frame);
        //    AssertFrameResult(frame, expected, converter);
        //}


        protected TStackFrame Build(params ILOpCodeValues[] instructions)
        {
            var builder = new ILInstructionBuilder();

            builder.Write(instructions);
            var frame = BuildTestFrame(builder.Instructions);

            return(frame);
        }
 public void TestExceptionHandling()
 {
     var builder = new ILInstructionBuilder();
     builder.Write(ILOpCodeValues.Ldobj, "test");
     builder.Write(ILOpCodeValues.Conv_I4);
     var frame = new ILStackFrameWithDiagnostics();
     frame.Stream = builder.Instructions;
     frame.Execute(100);
     Assert.IsInstanceOfType(frame.Exception, typeof(FormatException));
 }
        public void WriteOpCodeTest()
        {
            var opCode1 = OpCodes.Nop;
            var builder = new ILInstructionBuilder();

            builder.Write(opCode1);
            Assert.IsTrue(builder.Instructions.Count == 1);
            Assert.IsTrue(builder.Instructions[0].OpCode == opCode1);
            Assert.IsNull(builder.Instructions[0].Arg);
        }
        public void WriteSingleILOpCodeValues()
        {
            var opCode1 = OpCodes.Ret;
            var builder = new ILInstructionBuilder();

            builder.Write(ILOpCodeValues.Ret);
            Assert.IsTrue(builder.Instructions.Count == 1);
            Assert.IsTrue(builder.Instructions[0].OpCode == opCode1);
            Assert.IsNull(builder.Instructions[0].Arg);
        }
        public void ClearTest()
        {
            var builder = new ILInstructionBuilder();

            Assert.IsTrue(builder.Instructions.Count == 0);
            builder.Write(OpCodes.Ret);
            Assert.IsTrue(builder.Instructions.Count == 1);
            Assert.IsTrue(builder.Instructions[0].OpCode == OpCodes.Ret);
            builder.Clear();
            Assert.IsTrue(builder.Instructions.Count == 0);
        }
        public void WriteILInstructionTest()
        {
            var opCode      = OpCodes.Nop;
            var instruction = ILInstruction.Create(opCode);
            var builder     = new ILInstructionBuilder();

            builder.Write(instruction);
            Assert.IsTrue(builder.Instructions.Count == 1);
            Assert.IsTrue(builder.Instructions[0].OpCode == opCode);
            Assert.IsNull(builder.Instructions[0].Arg);
        }
        public void WriteOpCodeWithArgTest()
        {
            var opCode1    = OpCodes.Ldarga_S;
            var opCode1Arg = 1;
            var builder    = new ILInstructionBuilder();

            builder.Write(opCode1, opCode1Arg);
            Assert.IsTrue(builder.Instructions.Count == 1);
            Assert.IsTrue(builder.Instructions[0].OpCode == opCode1);
            Assert.IsNotNull(builder.Instructions[0].Arg);
            Assert.IsTrue((int)builder.Instructions[0].Arg == opCode1Arg);
        }
        public void WriteILOpCodeValues()
        {
            var opCode1 = OpCodes.Nop;
            var opCode2 = OpCodes.Ret;
            var builder = new ILInstructionBuilder();

            builder.Write(opCode1, opCode2);
            Assert.IsTrue(builder.Instructions.Count == 2);
            Assert.IsTrue(builder.Instructions[0].OpCode == opCode1);
            Assert.IsNull(builder.Instructions[0].Arg);
            Assert.IsTrue(builder.Instructions[1].OpCode == opCode2);
            Assert.IsNull(builder.Instructions[1].Arg);
        }
        public void WriteILInstructionsTest()
        {
            var opCode1      = OpCodes.Nop;
            var opCode2      = OpCodes.Ret;
            var instruction1 = ILInstruction.Create(opCode1);
            var instruction2 = ILInstruction.Create(opCode2);
            var builder      = new ILInstructionBuilder();

            builder.Write(instruction1, instruction2);
            Assert.IsTrue(builder.Instructions.Count == 2);
            Assert.IsTrue(builder.Instructions[0].OpCode == opCode1);
            Assert.IsNull(builder.Instructions[0].Arg);
            Assert.IsTrue(builder.Instructions[1].OpCode == opCode2);
            Assert.IsNull(builder.Instructions[1].Arg);
        }
示例#13
0
        public void TestEmitInlineNone()
        {
            var expected = 1;
            var builder  = new ILInstructionBuilder();

            builder.Write(OpCodes.Ldc_I4_1);
            builder.Write(OpCodes.Ret);
            var ilMethod = new ILMethod(System.Reflection.MethodBase.GetCurrentMethod().Name, expected.GetType());

            ilMethod.AddInstructions(builder.Instructions.ToArray());
            ilMethod.Module = this.GetType().Module;
            var method = ilMethod.Compile();
            var actual = method.Invoke(null, Type.EmptyTypes);

            Assert.IsTrue((int)actual == expected, $"Actual: {actual}\r\nExpected:{expected}");
        }
示例#14
0
        public void TestEmitShortInlineVar()
        {
            var expected = 1;
            var builder  = new ILInstructionBuilder();

            builder.Write(OpCodes.Ldarg_S, 0);
            builder.Write(OpCodes.Ret);
            var ilMethod = new ILMethod(MethodBase.GetCurrentMethod().Name, expected.GetType());

            ilMethod.AddInstructions(builder.Instructions.ToArray());
            ilMethod.AddParameters(new[] { typeof(int) });
            ilMethod.Module = this.GetType().Module;
            var method = ilMethod.Compile();
            var actual = method.Invoke(null, new object[] { expected });

            Assert.IsTrue((int)actual == expected, $"Actual: {actual}\r\nExpected:{expected}");
        }
        public void TestReadInlineBrTarget()
        {
            var builder = new ILInstructionBuilder();

            builder.Write(ILInstruction.Create(ILOpCodeValues.Br, 0));
            builder.Write(ILOpCodeValues.Ldc_I8, 1L);
            builder.Write(ILOpCodeValues.Ret);
            var ilMethod = new Models.ILMethod(MethodBase.GetCurrentMethod().Name, typeof(long));

            ilMethod.AddInstructions(builder.Instructions.ToArray());
            var method = ilMethod.Compile();

            var expected     = method.Invoke(null, Type.EmptyTypes);
            var instructions = ILInstructionReader.FromMethod(method);

            ExecuteAndAssertResult(instructions, expected, OperandType.InlineBrTarget);
        }
示例#16
0
        public void InlineTypeToken()
        {
            var expected = 4;
            var builder  = new ILInstructionBuilder();
            var intType  = typeof(int);

            builder.Write(OpCodes.Sizeof, intType.MetadataToken);
            builder.Write(OpCodes.Ret);
            var ilMethod = new ILMethod(MethodBase.GetCurrentMethod().Name, expected.GetType());

            ilMethod.AddInstructions(builder.Instructions.ToArray());
            ilMethod.AddParameters(new[] { typeof(int) });
            ilMethod.Module = intType.Module;
            var method = ilMethod.Compile();
            var actual = method.Invoke(null, new object[] { expected });

            Assert.IsTrue((int)actual == expected, $"Actual: {actual}\r\nExpected:{expected}");
        }
        public void ResetTest()
        {
            var builder = new ILInstructionBuilder();
            builder.Write(ILOpCodeValues.Ldc_I4_0);
            builder.Write(ILOpCodeValues.Ldc_I4_1);
            builder.Write(ILOpCodeValues.Ret);

            var frame = new ILStackFrameWithDiagnostics();
            frame.Stream = builder.Instructions;
            frame.Execute();

            Assert.IsTrue(frame.ReturnResult == 1);
            Assert.IsTrue(frame.Stack.Count == 1);
            frame.Reset();

            Assert.IsNull(frame.ReturnResult);
            Assert.IsTrue(frame.Stack.Count == 0);
        }
        public void TestConvNoOverflowCheck()
        {
            var frame = new ILStackFrameWithDiagnostics();

            var stream = new ILInstructionBuilder();

            frame.Stream = stream.Instructions;

            stream.Clear();
            frame.Args = new object[] { uint.MaxValue };
            stream.Write(OpCodes.Ldarg_0);
            stream.Write(OpCodes.Conv_I);
            stream.Write(OpCodes.Ret);
            frame.Execute();

            int expected = unchecked((int)Convert.ToInt64(uint.MaxValue));
            Assert.IsNull(frame.Exception, $"Frame returned exception: {frame.Exception?.Message}");
            Assert.IsTrue(frame.ReturnResult == expected, $"Conv_I uint.MaxValue failed\r\nExpected: {expected}\r\nActual:{frame.ReturnResult ?? "null"}");
        }
示例#19
0
        public void TestEmitField()
        {
            var c        = new FieldTest(1);
            var cType    = c.GetType();
            var cMethod  = cType.GetField(nameof(c.Value));
            var expected = c.Value;
            var builder  = new ILInstructionBuilder();

            builder.Write(OpCodes.Ldarg_0);
            builder.Write(OpCodes.Ldfld, cMethod.MetadataToken);
            builder.Write(OpCodes.Ret);
            var ilMethod = new ILMethod(MethodBase.GetCurrentMethod().Name, expected.GetType());

            ilMethod.AddParameters(new[] { cType });
            ilMethod.AddInstructions(builder.Instructions.ToArray());
            ilMethod.Module = this.GetType().Module;
            var method = ilMethod.Compile();
            var actual = method.Invoke(null, new[] { c });

            Assert.IsTrue((int)actual == expected, $"Actual: {actual}\r\nExpected:{expected}");
        }
示例#20
0
        public void TestEmitLdtokenType()
        {
            var intType = typeof(int);


            var expected = intType.TypeHandle;

            var builder = new ILInstructionBuilder();

            builder.Write(ILOpCodeValues.Ldtoken, intType.MetadataToken);
            builder.Write(OpCodes.Ret);


            var ilMethod = new ILMethod(MethodBase.GetCurrentMethod().Name, expected.GetType());

            ilMethod.AddInstructions(builder.Instructions.ToArray());
            ilMethod.Module = intType.Module;
            var method = ilMethod.Compile();
            var actual = method.Invoke(null, null);

            Assert.IsTrue(actual == expected, $"Actual: {actual}\r\nExpected:{expected}");
        }
        public void TestConvUnsigned()
        {
            var frame = new TStackFrame();

            var stream = new ILInstructionBuilder();

            frame.Stream = stream.Instructions;



            stream.Clear();
            frame.Args = new object[] { byte.MinValue };
            stream.Write(OpCodes.Ldarg_0);
            stream.Write(OpCodes.Conv_U);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsNull(frame.Exception, $"Frame returned exception: {frame.Exception?.Message}");
            Assert.IsTrue(frame.ReturnResult == (uint)byte.MinValue, $"Conv_U byte.MinValue return result = {frame.ReturnResult ?? "null"}");

            stream.Clear();
            frame.Args = new object[] { byte.MaxValue };
            stream.Write(OpCodes.Ldarg_0);
            stream.Write(OpCodes.Conv_U);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsNull(frame.Exception, $"Frame returned exception: {frame.Exception?.Message}");
            Assert.IsTrue(frame.ReturnResult == (uint)byte.MaxValue, $"Conv_U byte.MaxValue return result = {frame.ReturnResult ?? "null"}");


            stream.Clear();
            frame.Args = new object[] { byte.MinValue };
            stream.Write(OpCodes.Ldarg_0);
            stream.Write(OpCodes.Conv_U1);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsNull(frame.Exception, $"Frame returned exception: {frame.Exception?.Message}");
            Assert.IsTrue(frame.ReturnResult == (uint)byte.MinValue, $"Conv_U1 byte.MinValue return result = {frame.ReturnResult ?? "null"}");

            stream.Clear();
            frame.Args = new object[] { byte.MaxValue };
            stream.Write(OpCodes.Ldarg_0);
            stream.Write(OpCodes.Conv_U1);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsNull(frame.Exception, $"Frame returned exception: {frame.Exception?.Message}");
            Assert.IsTrue(frame.ReturnResult == (uint)byte.MaxValue, $"Conv_U1 byte.MaxValue  return result = {frame.ReturnResult ?? "null"}");



            stream.Clear();
            frame.Args = new object[] { ushort.MinValue };
            stream.Write(OpCodes.Ldarg_0);
            stream.Write(OpCodes.Conv_U2);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsNull(frame.Exception, $"Frame returned exception: {frame.Exception?.Message}");
            Assert.IsTrue(frame.ReturnResult == (uint)ushort.MinValue, $"Conv_U2 ushort.MinValue return result = {frame.ReturnResult ?? "null"}");

            stream.Clear();
            frame.Args = new object[] { ushort.MaxValue };
            stream.Write(OpCodes.Ldarg_0);
            stream.Write(OpCodes.Conv_U2);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsNull(frame.Exception, $"Frame returned exception: {frame.Exception?.Message}");
            Assert.IsTrue(frame.ReturnResult == (uint)ushort.MaxValue, $"Conv_U2 ushort.MaxValue  return result = {frame.ReturnResult ?? "null"}");



            stream.Clear();
            frame.Args = new object[] { uint.MinValue };
            stream.Write(OpCodes.Ldarg_0);
            stream.Write(OpCodes.Conv_U4);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsNull(frame.Exception, $"Frame returned exception: {frame.Exception?.Message}");
            Assert.IsTrue(frame.ReturnResult == (uint)uint.MinValue, $"Conv_U4 uint.MinValue return result = {frame.ReturnResult ?? "null"}");

            stream.Clear();
            frame.Args = new object[] { uint.MaxValue };
            stream.Write(OpCodes.Ldarg_0);
            stream.Write(OpCodes.Conv_U4);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsNull(frame.Exception, $"Frame returned exception: {frame.Exception?.Message}");
            Assert.IsTrue(frame.ReturnResult == (uint)uint.MaxValue, $"Conv_U4 uint.MaxValue  return result = {frame.ReturnResult ?? "null"}");



            stream.Clear();
            frame.Args = new object[] { ulong.MinValue };
            stream.Write(OpCodes.Ldarg_0);
            stream.Write(OpCodes.Conv_U8);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsNull(frame.Exception, $"Frame returned exception: {frame.Exception?.Message}");
            Assert.IsTrue(frame.ReturnResult == ulong.MinValue, $"ConvU_U8 ulong.MinValue return result = {frame.ReturnResult ?? "null"}");

            stream.Clear();
            frame.Args = new object[] { ulong.MaxValue };
            stream.Write(OpCodes.Ldarg_0);
            stream.Write(OpCodes.Conv_U8);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsNull(frame.Exception, $"Frame returned exception: {frame.Exception?.Message}");
            Assert.IsTrue(frame.ReturnResult == ulong.MaxValue, $"Conv_U8 ulong.MaxValue  return result = {frame.ReturnResult ?? "null"}");
        }
        public void TesCheckInfinity()
        {
            var frame = new TStackFrame();

            var stream = new ILInstructionBuilder();

            frame.Stream = stream.Instructions;



            stream.Clear();
            stream.Write(ILOpCodeValues.Ldc_R4, float.NegativeInfinity);
            stream.Write(OpCodes.Ckfinite);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == true, $"Ckfinite float.NegativeInfinity, return result = {frame.ReturnResult ?? "null"}");

            stream.Clear();
            stream.Write(OpCodes.Ldc_R4, float.PositiveInfinity);
            stream.Write(OpCodes.Ckfinite);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == true, $"Ckfinite float.PositiveInfinity, return result = {frame.ReturnResult ?? "null"}");

            stream.Clear();
            stream.Write(OpCodes.Ldc_R4, 1.0f);
            stream.Write(OpCodes.Ckfinite);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == false, $"Ckfinite float.PositiveInfinity, return result = {frame.ReturnResult ?? "null"}");

            stream.Clear();
            stream.Write(OpCodes.Ldc_R4, 1);
            stream.Write(OpCodes.Ckfinite);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == false, $"Ckfinite float.PositiveInfinity, return result = {frame.ReturnResult ?? "null"}");



            stream.Clear();
            stream.Write(OpCodes.Ldc_R8, double.NegativeInfinity);
            stream.Write(OpCodes.Ckfinite);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == true, $"Ckfinite double.NegativeInfinityd, return result = {frame.ReturnResult ?? "null"}");

            stream.Clear();
            stream.Write(OpCodes.Ldc_R8, double.PositiveInfinity);
            stream.Write(OpCodes.Ckfinite);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == true, $"Ckfinite double.PositiveInfinity, return result = {frame.ReturnResult ?? "null"}");

            stream.Clear();
            stream.Write(OpCodes.Ldc_R8, 1.0);
            stream.Write(OpCodes.Ckfinite);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == false, $"Ckfinite 1.0, return result = {frame.ReturnResult ?? "null"}");

            stream.Clear();
            stream.Write(OpCodes.Ldc_R8, 1);
            stream.Write(OpCodes.Ckfinite);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == false, $"Ckfinite 1, return result = {frame.ReturnResult ?? "null"}");
        }
        public void TestConvSigned()
        {
            var frame = new TStackFrame();

            var stream = new ILInstructionBuilder();

            frame.Stream = stream.Instructions;



            stream.Clear();
            frame.Args = new object[] { sbyte.MinValue };
            stream.Write(OpCodes.Ldarg_0);
            stream.Write(OpCodes.Conv_I);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsNull(frame.Exception, $"Frame returned exception: {frame.Exception?.Message}");
            Assert.IsTrue(frame.ReturnResult == (int)sbyte.MinValue, $"Conv_I sbyte.MinValue return result = {frame.ReturnResult ?? "null"}");



            stream.Clear();
            frame.Args = new object[] { byte.MinValue };
            stream.Write(OpCodes.Ldarg_0);
            stream.Write(OpCodes.Conv_I);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsNull(frame.Exception, $"Frame returned exception: {frame.Exception?.Message}");
            Assert.IsTrue(frame.ReturnResult == (int)byte.MinValue, $"Conv_I byte.MinValue return result = {frame.ReturnResult ?? "null"}");

            stream.Clear();
            frame.Args = new object[] { byte.MaxValue };
            stream.Write(OpCodes.Ldarg_0);
            stream.Write(OpCodes.Conv_I);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsNull(frame.Exception, $"Frame returned exception: {frame.Exception?.Message}");
            Assert.IsTrue(frame.ReturnResult == (int)byte.MaxValue, $"Conv_I byte.MaxValue return result = {frame.ReturnResult ?? "null"}");


            stream.Clear();
            frame.Args = new object[] { sbyte.MinValue };
            stream.Write(OpCodes.Ldarg_0);
            stream.Write(OpCodes.Conv_I1);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsNull(frame.Exception, $"Frame returned exception: {frame.Exception?.Message}");
            Assert.IsTrue(frame.ReturnResult == (int)sbyte.MinValue, $"Conv_I1 sbyte.MinValue return result = {frame.ReturnResult ?? "null"}");

            stream.Clear();
            frame.Args = new object[] { sbyte.MaxValue };
            stream.Write(OpCodes.Ldarg_0);
            stream.Write(OpCodes.Conv_I1);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsNull(frame.Exception, $"Frame returned exception: {frame.Exception?.Message}");
            Assert.IsTrue(frame.ReturnResult == (int)sbyte.MaxValue, $"Conv_I1 sbyte.MaxValue  return result = {frame.ReturnResult ?? "null"}");



            stream.Clear();
            frame.Args = new object[] { short.MinValue };
            stream.Write(OpCodes.Ldarg_0);
            stream.Write(OpCodes.Conv_I2);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsNull(frame.Exception, $"Frame returned exception: {frame.Exception?.Message}");
            Assert.IsTrue(frame.ReturnResult == (int)short.MinValue, $"Conv_I1 short.MinValue return result = {frame.ReturnResult ?? "null"}");

            stream.Clear();
            frame.Args = new object[] { short.MaxValue };
            stream.Write(OpCodes.Ldarg_0);
            stream.Write(OpCodes.Conv_I2);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsNull(frame.Exception, $"Frame returned exception: {frame.Exception?.Message}");
            Assert.IsTrue(frame.ReturnResult == (int)short.MaxValue, $"Conv_I2 short.MaxValue  return result = {frame.ReturnResult ?? "null"}");



            stream.Clear();
            frame.Args = new object[] { int.MinValue };
            stream.Write(OpCodes.Ldarg_0);
            stream.Write(OpCodes.Conv_I4);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsNull(frame.Exception, $"Frame returned exception: {frame.Exception?.Message}");
            Assert.IsTrue(frame.ReturnResult == (int)int.MinValue, $"Conv_I4 int.MinValue return result = {frame.ReturnResult ?? "null"}");

            stream.Clear();
            frame.Args = new object[] { int.MaxValue };
            stream.Write(OpCodes.Ldarg_0);
            stream.Write(OpCodes.Conv_I4);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsNull(frame.Exception, $"Frame returned exception: {frame.Exception?.Message}");
            Assert.IsTrue(frame.ReturnResult == (int)int.MaxValue, $"Conv_I4 int.MaxValue  return result = {frame.ReturnResult ?? "null"}");



            stream.Clear();
            frame.Args = new object[] { long.MinValue };
            stream.Write(OpCodes.Ldarg_0);
            stream.Write(OpCodes.Conv_I8);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsNull(frame.Exception, $"Frame returned exception: {frame.Exception?.Message}");
            Assert.IsTrue(frame.ReturnResult == long.MinValue, $"Conv_I8 long.MinValue return result = {frame.ReturnResult ?? "null"}");

            stream.Clear();
            frame.Args = new object[] { long.MaxValue };
            stream.Write(OpCodes.Ldarg_0);
            stream.Write(OpCodes.Conv_I8);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsNull(frame.Exception, $"Frame returned exception: {frame.Exception?.Message}");
            Assert.IsTrue(frame.ReturnResult == long.MaxValue, $"Conv_I8 long.MaxValue  return result = {frame.ReturnResult ?? "null"}");
        }
        public void TestLoadConstants()
        {
            var frame = new TStackFrame();

            var stream = new ILInstructionBuilder();

            frame.Stream = stream.Instructions;



            stream.Clear();
            stream.Write(OpCodes.Ldc_I4_0);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == 0, $"Ldc_I4_0 failed, return result = {frame.ReturnResult ?? "null"}");

            stream.Clear();
            stream.Write(OpCodes.Ldc_I4_1);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == 1, $"Ldc_I4_1 failed, return result = {frame.ReturnResult ?? "null"}");

            stream.Clear();
            stream.Write(OpCodes.Ldc_I4_2);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == 2, $"Ldc_I4_2 failed, return result = {frame.ReturnResult ?? "null"}");

            stream.Clear();
            stream.Write(OpCodes.Ldc_I4_3);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == 3, $"Ldc_I4_3 failed, return result = {frame.ReturnResult ?? "null"}");

            stream.Clear();
            stream.Write(OpCodes.Ldc_I4_4);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == 4, $"Ldc_I4_4 failed, return result = {frame.ReturnResult ?? "null"}");

            stream.Clear();
            stream.Write(OpCodes.Ldc_I4_5);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == 5, $"Ldc_I4_5 failed, return result = {frame.ReturnResult ?? "null"}");


            stream.Clear();
            stream.Write(OpCodes.Ldc_I4_6);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == 6, $"Ldc_I4_6 failed, return result = {frame.ReturnResult ?? "null"}");

            stream.Clear();
            stream.Write(OpCodes.Ldc_I4_7);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == 7, $"Ldc_I4_7 failed, return result = {frame.ReturnResult ?? "null"}");

            stream.Clear();
            stream.Write(OpCodes.Ldc_I4_8);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == 8, $"Ldc_I4_8 failed, return result = {frame.ReturnResult ?? "null"}");

            stream.Clear();
            stream.Write(OpCodes.Ldc_I4_M1);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == -1, $"Ldc_I4_M1 failed, return result = {frame.ReturnResult ?? "null"}");


            stream.Clear();
            stream.Write(OpCodes.Ldc_I4, 1);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == 1, $"Ldc_I4(1) failed, return result = {frame.ReturnResult ?? "null"}");


            stream.Clear();
            stream.Write(OpCodes.Ldc_I4_S, byte.MaxValue);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == byte.MaxValue, $"Ldc_I4_s(255) failed, return result = {frame.ReturnResult ?? "null"}");


            stream.Clear();
            stream.Write(OpCodes.Ldc_I8, long.MaxValue);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == long.MaxValue, $"Ldc_I8(long.MaxValue) failed, return result = {frame.ReturnResult ?? "null"}");



            stream.Clear();
            stream.Write(OpCodes.Ldc_R4, 0);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == 0, $"Ldc_R4(float.MaxValue) failed, return result = {frame.ReturnResult ?? "null"}");

            stream.Clear();
            stream.Write(OpCodes.Ldc_R4, float.MaxValue);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == float.MaxValue, $"Ldc_R4(float.MaxValue) failed, return result = {frame.ReturnResult ?? "null"}");

            stream.Clear();
            stream.Write(OpCodes.Ldc_R4, float.MinValue);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == float.MinValue, $"Ldc_R4(float.MinValue) failed, return result = {frame.ReturnResult ?? "null"}");



            stream.Clear();
            stream.Write(OpCodes.Ldc_R8, 0);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == 0, $"Ldc_R8(float.MaxValue) failed, return result = {frame.ReturnResult ?? "null"}");

            stream.Clear();
            stream.Write(OpCodes.Ldc_R8, double.MaxValue);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == double.MaxValue, $"Ldc_R8(double.MaxValue) failed, return result = {frame.ReturnResult ?? "null"}");

            stream.Clear();
            stream.Write(OpCodes.Ldc_R8, double.MinValue);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == double.MinValue, $"Ldc_R8(double.MinValue) failed, return result = {frame.ReturnResult ?? "null"}");
        }
        public void TestLoadAndStoreArgs()
        {
            var frame = new TStackFrame();

            var intType = typeof(int);
            var rng     = Enumerable.Range(0, 8);

            frame.Args = rng
                         .Select(idx => (object)idx).ToArray();
            var stream = new ILInstructionBuilder();

            frame.Stream = stream.Instructions;



            stream.Write(OpCodes.Ldarg_0);
            stream.Write(OpCodes.Starg, 0);
            stream.Write(OpCodes.Ldarg_0);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == (int)frame.Args[0], $"Args 0 failed, return result = {frame.ReturnResult ?? "null"}");

            stream.Clear();
            stream.Write(OpCodes.Ldarg_1);
            stream.Write(OpCodes.Starg_S, 1);
            stream.Write(OpCodes.Ldarg_1);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == (int)frame.Args[1], $"Args 1 failed, return result = {frame.ReturnResult ?? "null"}");


            stream.Clear();
            stream.Write(OpCodes.Ldarg_2);
            stream.Write(OpCodes.Starg, 2);
            stream.Write(OpCodes.Ldarg_2);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == (int)frame.Args[2], $"Args 2 failed, return result = {frame.ReturnResult ?? "null"}");;

            stream.Clear();
            stream.Write(OpCodes.Ldarg_3);
            stream.Write(OpCodes.Starg, 3);
            stream.Write(OpCodes.Ldarg_3);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == (int)frame.Args[3], $"Args 3 failed, return result = {frame.ReturnResult ?? "null"}");


            stream.Clear();
            stream.Write(OpCodes.Ldarg, 4);
            stream.Write(OpCodes.Starg, 4);
            stream.Write(OpCodes.Ldarg, 4);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == (int)frame.Args[4], $"Args(arg=4) failed, return result = {frame.ReturnResult ?? "null"}");


            stream.Clear();
            stream.Write(OpCodes.Ldarg_S, 5);
            stream.Write(OpCodes.Starg_S, 5);
            stream.Write(OpCodes.Ldarg_S, 5);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == (int)frame.Args[5], $"Args(arg=5) failed, return result = {frame.ReturnResult ?? "null"}");


            stream.Clear();
            stream.Write(OpCodes.Ldarga, 6);
            stream.Write(OpCodes.Starg_S, 6);
            stream.Write(OpCodes.Ldarga, 6);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == (int)frame.Args[6], $"Ldarga(arg=6) failed, return result = {frame.ReturnResult ?? "null"}");


            stream.Clear();
            stream.Write(OpCodes.Ldarga_S, 7);
            stream.Write(OpCodes.Starg_S, 7);
            stream.Write(OpCodes.Ldarga_S, 7);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == (int)frame.Args[7], $"Ldarga_S(arg=6) failed, return result = {frame.ReturnResult ?? "null"}");
        }
        public void TestLoadAndStoreLocals()
        {
            var frame = new TStackFrame();

            var intType = typeof(int);
            var rng     = Enumerable.Range(0, 8);

            frame.Locals = rng
                           .Select(idx => new ILVariable {
                Index = idx, Type = intType, Value = idx
            }).ToArray();
            var stream = new ILInstructionBuilder();

            frame.Stream = stream.Instructions;



            stream.Write(OpCodes.Ldloc_0);
            stream.Write(OpCodes.Stloc_0);
            stream.Write(OpCodes.Ldloc_0);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == (int)frame.Locals[0].Value, $"Locals 0 failed, return result = {frame.ReturnResult ?? "null"}");

            stream.Clear();
            stream.Write(OpCodes.Ldloc_1);
            stream.Write(OpCodes.Stloc_1);
            stream.Write(OpCodes.Ldloc_1);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == (int)frame.Locals[1].Value, $"Locals 1 failed, return result = {frame.ReturnResult ?? "null"}");


            stream.Clear();
            stream.Write(OpCodes.Ldloc_2);
            stream.Write(OpCodes.Stloc_2);
            stream.Write(OpCodes.Ldloc_2);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == (int)frame.Locals[2].Value, $"Locals 2 failed, return result = {frame.ReturnResult ?? "null"}");;

            stream.Clear();
            stream.Write(OpCodes.Ldloc_3);
            stream.Write(OpCodes.Stloc_3);
            stream.Write(OpCodes.Ldloc_3);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == (int)frame.Locals[3].Value, $"Locals 3 failed, return result = {frame.ReturnResult ?? "null"}");


            stream.Clear();
            stream.Write(OpCodes.Ldloc, 4);
            stream.Write(OpCodes.Stloc, 4);
            stream.Write(OpCodes.Ldloc, 4);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == (int)frame.Locals[4].Value, $"Ldloc(arg=4) failed, return result = {frame.ReturnResult ?? "null"}");


            stream.Clear();
            stream.Write(OpCodes.Ldloc_S, 5);
            stream.Write(OpCodes.Stloc_S, 5);
            stream.Write(OpCodes.Ldloc_S, 5);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == (int)frame.Locals[5].Value, $"Ldloc_S(arg=5) failed, return result = {frame.ReturnResult ?? "null"}");


            stream.Clear();
            stream.Write(OpCodes.Ldloca, 6);
            stream.Write(OpCodes.Stloc_S, 6);
            stream.Write(OpCodes.Ldloca, 6);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == (int)frame.Locals[6].Value, $"Ldloca(arg=6) failed, return result = {frame.ReturnResult ?? "null"}");


            stream.Clear();
            stream.Write(OpCodes.Ldloca_S, 7);
            stream.Write(OpCodes.Stloc_S, 7);
            stream.Write(OpCodes.Ldloca_S, 7);
            stream.Write(OpCodes.Ret);
            frame.Execute();
            Assert.IsTrue(frame.ReturnResult == (int)frame.Locals[7].Value, $"Ldloca_S(arg=6) failed, return result = {frame.ReturnResult ?? "null"}");
        }
示例#27
0
        public void TestEmitCompiledSwitch()
        {
            var compiledType   = BuildSwitchTestType();
            var compiledMethod = compiledType.GetMethod("SwitchTest");

            Assert.IsNotNull(compiledMethod);


            var compiledInstructions = ILInstructionReader.FromMethod(compiledMethod).ToArray();

            //TODO: auto label read instructions.

            //mark default case jump target
            compiledInstructions[7].Label = 0;
            //set default case jump target
            compiledInstructions[2].Arg = compiledInstructions[7];
            // set break target;
            compiledInstructions[8].Label = 1;

            //set jump targets for switch breaks statements
            compiledInstructions[4].Arg = compiledInstructions[6].Arg = compiledInstructions[8];

            //mark switch jump targets;

            compiledInstructions[3].Label = 2;
            compiledInstructions[5].Label = 3;

            //set switch jump targets =
            compiledInstructions[1].Arg = new[] { compiledInstructions[3], compiledInstructions[5] };


            var builder = new ILInstructionBuilder();

            builder.Write(compiledInstructions.ToArray());

            //TODO: implement auto fixup of instuctions.

            var frame = ILStackFrameBuilder.Build(builder.Instructions);

            frame.Args = new object[] { 1 };
            frame.Reset();
            int Position  = -1;
            var jumpTable = frame.Stream.ToDictionary(x => (int)x.ByteIndex, x => ++ Position);

            frame.Execute();
            var expected = 1;

            Assert.IsNull(frame.Exception, $"Executing switch: add throw an exception {frame?.Exception}");
            Assert.IsTrue(frame.Stack.Count == 0, "Stack was not cleared executing switch: add");
            Assert.IsTrue((int)frame.ReturnResult == expected, $"Actual: {frame.ReturnResult}\r\nExpected: {expected}");

            frame.Args = new object[] { 0 };
            frame.Execute();
            expected = 0;
            Assert.IsNull(frame.Exception, $"Executing switch: add throw an exception {frame?.Exception}");
            Assert.IsTrue(frame.Stack.Count == 0, "Stack was not cleared executing switch: add");
            Assert.IsTrue((int)frame.ReturnResult == expected, $"Actual: {frame.ReturnResult}\r\nExpected: {expected}");

            frame.Args = new object[] { 2 };
            frame.Execute();
            expected = 2;
            Assert.IsNull(frame.Exception, $"Executing switch: add throw an exception {frame?.Exception}");
            Assert.IsTrue(frame.Stack.Count == 0, "Stack was not cleared executing switch: add");
            Assert.IsTrue((int)frame.ReturnResult == expected, $"Actual: {frame.ReturnResult}\r\nExpected: {expected}");
        }
示例#28
0
        public void TestEmitSwitch()
        {
            var endSwitchInstruction = ILInstruction.Create(ILOpCodeValues.Nop);

            endSwitchInstruction.Label = 2;
            var addInstructions = new[]
            {
                ILInstruction.Create(ILOpCodeValues.Add),
                ILInstruction.Create(ILOpCodeValues.Br_S, endSwitchInstruction)
            };
            var subInstructions = new[]
            {
                ILInstruction.Create(ILOpCodeValues.Sub),
                ILInstruction.Create(ILOpCodeValues.Br_S, endSwitchInstruction)
            };

            addInstructions[0].Label = 0;
            subInstructions[0].Label = 1;

            var exceptionType      = typeof(ArgumentOutOfRangeException);
            var ctor               = exceptionType.GetConstructor(Type.EmptyTypes);
            var defaultInstuctions = new[]
            {
                ILInstruction.Create(ILOpCodeValues.Newobj, ctor.MetadataToken),
                ILInstruction.Create(ILOpCodeValues.Throw)
            };

            var switchInstuction = ILInstruction.Create(ILOpCodeValues.Switch,
                                                        new[] { addInstructions[0], subInstructions[0] });
            var builder = new ILInstructionBuilder();

            //var b= arg[b];
            builder.Write(ILOpCodeValues.Ldarg_1);
            //var a= arg[1];
            builder.Write(ILOpCodeValues.Ldarg_2);
            //switch(arg[0])
            builder.Write(ILOpCodeValues.Ldarg_0);
            builder.Write(switchInstuction);
            //case default
            builder.Write(defaultInstuctions);
            //case 0: add
            builder.Write(addInstructions);
            //case 1: sub
            builder.Write(subInstructions);
            builder.Write(endSwitchInstruction);
            builder.Write(ILOpCodeValues.Ret);



            var frame = ILStackFrameBuilder.Build(builder.Instructions);

            frame.Args = new object[] { 0, 1, 2 };
            frame.Execute();

            var expected = 3;

            Assert.IsNull(frame.Exception, $"Executing switch: add throw an exception {frame?.Exception}");
            Assert.IsTrue(frame.Stack.Count == 0, "Stack was not cleared executing switch: add");
            Assert.IsTrue((int)frame.ReturnResult == expected, $"Actual: {frame.ReturnResult}\r\nExpected: {expected}");

            expected   = -1;
            frame.Args = new object[] { 1, 1, 2 };
            frame.Execute();
            Assert.IsNull(frame.Exception, $"Executing switch: add throw an exception {frame?.Exception}");
            Assert.IsTrue(frame.Stack.Count == 0, "Stack was not cleared executing switch: add");
            Assert.IsTrue((int)frame.ReturnResult == expected, $"Actual: {frame.ReturnResult}\r\nExpected: {expected}");

            frame.Args = new object[] { 2, 1, 2 };
            frame.Execute();
            Assert.IsNotNull(frame.Exception, $"Executing switch failed to execute default case to and throw and exception.");
            Assert.IsInstanceOfType(frame.Exception, typeof(ArgumentOutOfRangeException), $"Frame failed to throw {nameof(ArgumentOutOfRangeException)}");
            Assert.IsNull(frame.ReturnResult, $"Actual: {frame.ReturnResult}\r\nExpected: [null]");


            //var type = BuildSwitchTestType();
            //var switchMethod = type.GetMethod("SwitchTest");
            //Assert.IsNotNull(switchMethod);
            //var instructions = ILInstructionReader.FromMethod(switchMethod);

            var ilMethod = new ILMethod(MethodBase.GetCurrentMethod().Name, expected.GetType());

            ilMethod.AddParameters(new[] { typeof(int), typeof(int), typeof(int) });
            ilMethod.AddInstructions(builder.Instructions.ToArray());

            ilMethod.Module = exceptionType.Module;
            var method = ilMethod.Compile();
            var actual = method.Invoke(null, new object[] { 0, 1, 2 });

            expected = 3;
            Assert.IsTrue((int)actual == expected, $"Actual: {actual}\r\nExpected:{expected}");

            actual   = method.Invoke(null, new object[] { 1, 1, 2 });
            expected = -1;
            Assert.IsTrue((int)actual == expected, $"Actual: {actual}\r\nExpected:{expected}");

            Exception exception = null;

            try
            {
                actual = method.Invoke(null, new object[] { 2, 1, 2 });
            }
            catch (TargetInvocationException ex)
            {
                exception = ex.InnerException;
            }
            Assert.IsNotNull(exception, $"Failed to catch argument exception");
            Assert.IsInstanceOfType(exception, exceptionType);
        }