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}"); }
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}"); }
public static MethodInfo Compile_LdNull() { var method = new ILMethod(nameof(ILOpCodeValues.Ldnull)); method.AddInstructions(ILInstruction.Create(OpCodes.Ldnull), ILInstruction.Ret); return(method.Compile()); }
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}"); }
public static MethodInfo Compile_Add_Ovf(Type returnType, params Type[] parameters) { var method = new ILMethod(nameof(ILOpCodeValues.Add_Ovf), returnType); method.AddParameters(parameters); method.AddInstructions(ILOpCodeValues.Ldarg_0, ILOpCodeValues.Ldarg_1, ILOpCodeValues.Add_Ovf, ILOpCodeValues.Ret); return(method.Compile()); }
public static MethodInfo Compile_Ldloc_0() { var method = new ILMethod(nameof(ILOpCodeValues.Ldloc_0), typeof(int)); method.AddLocals(typeof(int)); method.AddInstructions( ILInstruction.Create(OpCodes.Ldc_I4_1), ILInstruction.Create(OpCodes.Stloc_0), ILInstruction.Create(OpCodes.Ldloc_0), ILInstruction.Ret); return(method.Compile()); }
public static MethodInfo CompileBinary(ILOpCodeValues opCodeValue, Type returnType, params Type[] parameters) { var methodName = $"{opCodeValue}"; var method = new ILMethod(methodName, returnType); method.AddParameters(parameters); method.AddInstructions(ILOpCodeValues.Ldarg_0, ILOpCodeValues.Ldarg_1, opCodeValue, ILOpCodeValues.Ret); return(method.Compile()); }
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}"); }
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 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 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}"); }
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 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); }