private void TestSuccess(Type type1, Type type2) { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(void), new[] { type1, type2, }.Where(type => type != null).ToArray(), typeof(string), true); using (var il = new GroboIL(method)) { var index = 0; if (type1 != null) { il.Ldarg(index++); } else { il.Ldnull(); } if (type2 != null) { il.Ldarg(index++); } else { il.Ldnull(); } il.Xor(); il.Pop(); il.Ret(); Console.WriteLine(il.GetILCode()); } }
public static CaseDelegate CompileCases(ErrorSink errors, Case[] cases, string name) { var ab = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(name), AssemblyBuilderAccess.RunAndCollect); var mb = ab.DefineDynamicModule("MainModule"); var cb = mb.DefineType("Cases"); var methods = new List <MethodInfo>(); for (int i = 0; i < cases.Length; i++) { var method = cb.DefineMethod($"Case{i}", MethodAttributes.Private | MethodAttributes.Static, typeof(void), new[] { typeof(IMachine) }); using (var il = new GroboIL(method)) { var visitor = new CompilerVisitor(il, errors); visitor.Visit(cases[i]); il.Ret(); Console.WriteLine(il.GetILCode()); } methods.Add(method); } CreateRunAllMethod(cb, methods); var type = cb.CreateType(); return((CaseDelegate)type.GetMethod("RunAll").CreateDelegate(typeof(CaseDelegate))); }
public static Func <Dictionary <string, object>, object> GenerateMethod(Type type) { var da = AppDomain.CurrentDomain.DefineDynamicAssembly( new AssemblyName("dyn"), // call it whatever you want AssemblyBuilderAccess.RunAndSave); var dm = da.DefineDynamicModule("dyn_mod", "dyn.dll"); var dt = dm.DefineType("dyn_type"); var emiter = Emit <Func <int> > .NewDynamicMethod("MyMethod"); var method = dt.DefineMethod( "Foo", MethodAttributes.Public | MethodAttributes.Static, typeof(object), new[] { typeof(Dictionary <string, object>) }); method.DefineParameter(1, ParameterAttributes.None, "dictionary"); using (var il = new GroboIL(method)) { var target = il.DeclareLocal(type); var value = il.DeclareLocal(typeof(object)); il.Newobj(type.GetConstructor(Type.EmptyTypes)); // [Person] il.Stloc(target); // [] foreach (var property in type.GetProperties()) { var label = il.DefineLabel("ifLabel"); il.Ldarg(0); // [Dictionary<String, Object>] il.Ldstr(property.Name); // [Dictionary<String, Object>, String] il.Ldloca(value); // [Dictionary<String, Object>, String, Object&] il.Call(typeof(Dictionary <string, object>) .GetMethod("TryGetValue")); // [Boolean] il.Brfalse(label); // [] il.Ldloc(target); // [Person] il.Ldloc(value); // [Person, Object] il.Castclass(typeof(string)); // [Dictionary<String, Object>, String] il.Call(property.GetSetMethod(true)); // [] il.MarkLabel(label); } il.Ldloc(target); il.Ret(); Console.WriteLine(il.GetILCode()); } dt.CreateType(); da.Save("dyn.dll"); return((dic) => dt.GetMethod("Foo").Invoke(null, new object[] { dic })); }
public void TestDifferentPathsGeneric() { var assembly = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(Guid.NewGuid().ToString()), AssemblyBuilderAccess.Run); var module = assembly.DefineDynamicModule(Guid.NewGuid().ToString()); var type = module.DefineType("Zzz", TypeAttributes.Class | TypeAttributes.Public); var method = type.DefineMethod("Qzz", MethodAttributes.Public | MethodAttributes.Static); var genericParameters = method.DefineGenericParameters("TZzz"); var parameter = genericParameters[0]; method.SetParameters(typeof(bool), typeof(C1 <>).MakeGenericType(parameter), typeof(C2 <>).MakeGenericType(parameter)); method.SetReturnType(typeof(void)); using (var il = new GroboIL(method)) { il.Ldarg(0); var label1 = il.DefineLabel("L1"); il.Brfalse(label1); il.Ldarg(1); var label2 = il.DefineLabel("L2"); il.Br(label2); il.MarkLabel(label1); il.Ldarg(2); il.MarkLabel(label2); il.Dup(); il.Call(HackHelpers.GetMethodDefinition <I1 <int> >(x => F1(x)).GetGenericMethodDefinition().MakeGenericMethod(parameter)); il.Call(HackHelpers.GetMethodDefinition <I2 <int> >(x => F2(x)).GetGenericMethodDefinition().MakeGenericMethod(parameter)); il.Ret(); Console.Write(il.GetILCode()); } }
public static Delegate Emit(Type type) { Console.WriteLine("EMITTING " + type); var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(bool), new[] { type, type }, type, true); using (var il = new GroboIL(method)) { var r0 = il.DefineLabel("Return_0", false); // todo: inheritance // todo: public/private // todo: fields // todo: options for public/private, field/property var props = type.GetProperties(); foreach (var propertyInfo in props) { // todo: nullable // todo: array // todo: struct (DateTime, Guid) var propertyType = propertyInfo.PropertyType; var nullableType = Nullable.GetUnderlyingType(propertyType); if (BneTypes.Contains(propertyType) || propertyType.IsEnum) { EmitBne(il, propertyInfo.GetMethod, r0); } else if (StaticEqualsTypes.ContainsKey(propertyType)) { EmitStatic(il, propertyInfo.GetMethod, StaticEqualsTypes[propertyType], r0); } else if (InstanceEqualsTypes.ContainsKey(propertyType)) { EmitInstance(il, propertyInfo.GetMethod, InstanceEqualsTypes[propertyType], r0); } else if (nullableType != null && (BneTypes.Contains(nullableType) || nullableType.IsEnum)) { EmitNullableBne(il, propertyInfo.GetMethod, r0); } else if (nullableType != null) { EmitNullableEquals(il, propertyInfo.GetMethod, r0); } else { EmitStatic(il, propertyInfo.GetMethod, EmittedEquals, r0); } } il.Ldc_I4(1); il.Ret(); il.MarkLabel(r0); il.Ldc_I4(0); il.Ret(); Console.WriteLine(il.GetILCode()); } return(method.CreateDelegate(typeof(Func <, ,>).MakeGenericType(type, type, typeof(bool)))); }
public void TestRet() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(void), Type.EmptyTypes, typeof(Test)); using (var il = new GroboIL(method)) { il.Ret(); Console.Write(il.GetILCode()); } }
public void TestConstrained() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(string), new[] { typeof(int) }, typeof(string), true); using (var il = new GroboIL(method)) { il.Ldarga(0); il.Call(typeof(object).GetMethod("ToString"), typeof(int)); il.Ret(); Console.WriteLine(il.GetILCode()); } }
public void TestAPlusB() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(int), new[] { typeof(int), typeof(int) }, typeof(Test)); using (var il = new GroboIL(method)) { il.Ldarg(0); il.Ldarg(1); il.Add(); il.Ret(); Console.Write(il.GetILCode()); } }
public void TestBrfalse() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(void), new[] { typeof(C2) }, typeof(string), true); using (var il = new GroboIL(method)) { il.Ldarg(0); il.Dup(); var label = il.DefineLabel("L"); il.Brfalse(label); il.Call(HackHelpers.GetMethodDefinition <I1>(x => x.GetI2())); il.MarkLabel(label); il.Call(HackHelpers.GetMethodDefinition <int>(x => F2(null))); il.Ret(); Console.WriteLine(il.GetILCode()); } }
public void TestLdDec() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(decimal), Type.EmptyTypes); using (var il = new GroboIL(method)) { il.LdDec(-12.3m); il.LdDec(34.5m); il.Call(typeof(decimal).GetMethod("Add", new[] { typeof(decimal), typeof(decimal) })); il.Ret(); Console.WriteLine(il.GetILCode()); } var compiledMethod = (Func <decimal>)method.CreateDelegate(typeof(Func <decimal>)); Assert.That(compiledMethod(), Is.EqualTo(22.2m)); }
private void CompileReader() { DynamicMethod dm = new DynamicMethod(Guid.NewGuid().ToString(), typeof(Tuple <int, object>), new[] { typeof(byte[]), typeof(BinaryStruct), typeof(int) }); using (var il = new GroboIL(dm)) { var offset = il.DeclareLocal(typeof(int)); var result = il.DeclareLocal(this.Type); var typeSize = il.DeclareLocal(typeof(int)); var buffer = il.DeclareLocal(typeof(byte[])); var binaryStruct = il.DeclareLocal(typeof(BinaryStruct)); il.Ldarg(1); il.Stloc(binaryStruct); var constr = GetConstructor(result.Type, null); if (constr == null) { throw new Exception($"Type {result.Type} not have constructor with not parameters"); } il.Ldarg(0); il.Stloc(buffer); il.Ldarg(2); il.Stloc(offset); il.Newobj(constr); il.Stloc(result); CompileReader(this, il, binaryStruct, buffer, offset, result, typeSize); il.Ldloc(offset); il.Ldloc(result); il.Newobj(typeof(Tuple <int, object>).GetConstructor(new Type[] { typeof(int), typeof(object) })); il.Ret(); IlReadCode = il.GetILCode(); } //ReadMethod = (ReadMethodDelegate)dm.CreateDelegate(typeof(ReadMethodDelegate)); ReadMethod = CreateReader(dm); }
public void TestMax() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(int), new[] { typeof(int), typeof(int) }, typeof(Test)); using (var il = new GroboIL(method)) { il.Ldarg(0); il.Ldarg(1); var returnSecondLabel = il.DefineLabel("returnSecond"); il.Ble(returnSecondLabel, false); il.Ldarg(0); il.Ret(); il.MarkLabel(returnSecondLabel); il.Ldarg(1); il.Ret(); Console.Write(il.GetILCode()); } }
public void TestConstructorCall() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(void), new[] { typeof(Zzz) }, typeof(Test)); using (var il = new GroboIL(method)) { il.Ldarg(0); il.Ldc_I4(8); il.Call(typeof(Zzz).GetConstructor(new[] { typeof(int) })); il.Ret(); Console.Write(il.GetILCode()); } var action = (Action <Zzz>)method.CreateDelegate(typeof(Action <Zzz>)); var zzz = new Zzz(3); action(zzz); Assert.AreEqual(8, zzz.X); }
public static Delegate Emit(Type type) { Console.WriteLine("EMITTING " + type); var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof (bool), new[] { type, type }, type, true); using (var il = new GroboIL(method)) { var r0 = il.DefineLabel("Return_0", false); // todo: inheritance // todo: public/private // todo: fields // todo: options for public/private, field/property var props = type.GetProperties(); foreach (var propertyInfo in props) { // todo: nullable // todo: array // todo: struct (DateTime, Guid) var propertyType = propertyInfo.PropertyType; var nullableType = Nullable.GetUnderlyingType(propertyType); if (BneTypes.Contains(propertyType) || propertyType.IsEnum) EmitBne(il, propertyInfo.GetMethod, r0); else if (StaticEqualsTypes.ContainsKey(propertyType)) EmitStatic(il, propertyInfo.GetMethod, StaticEqualsTypes[propertyType], r0); else if (InstanceEqualsTypes.ContainsKey(propertyType)) EmitInstance(il, propertyInfo.GetMethod, InstanceEqualsTypes[propertyType], r0); else if (nullableType != null && (BneTypes.Contains(nullableType) || nullableType.IsEnum)) EmitNullableBne(il, propertyInfo.GetMethod, r0); else if (nullableType != null) EmitNullableEquals(il, propertyInfo.GetMethod, r0); else EmitStatic(il, propertyInfo.GetMethod, EmittedEquals, r0); } il.Ldc_I4(1); il.Ret(); il.MarkLabel(r0); il.Ldc_I4(0); il.Ret(); Console.WriteLine(il.GetILCode()); } return method.CreateDelegate(typeof(Func<,,>).MakeGenericType(type, type, typeof(bool))); }
public void TestByRefGeneric() { var assembly = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(Guid.NewGuid().ToString()), AssemblyBuilderAccess.Run); var module = assembly.DefineDynamicModule(Guid.NewGuid().ToString()); var type = module.DefineType("Zzz", TypeAttributes.Class | TypeAttributes.Public); var method = type.DefineMethod("Qzz", MethodAttributes.Public | MethodAttributes.Static); var genericParameters = method.DefineGenericParameters("TZzz"); var parameter = genericParameters[0]; method.SetParameters(parameter); method.SetReturnType(typeof(void)); using (var il = new GroboIL(method)) { il.Ldarga(0); il.Call(HackHelpers.GetMethodDefinition <int>(x => F(ref x)).GetGenericMethodDefinition().MakeGenericMethod(parameter)); il.Ret(); Console.Write(il.GetILCode()); } }
public void TestZ2() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(A), new[] { typeof(bool), typeof(B), typeof(C) }, typeof(Test)); using (var il = new GroboIL(method)) { il.Ldarg(0); var label1 = il.DefineLabel("label"); il.Brfalse(label1); il.Ldarg(1); var label2 = il.DefineLabel("label"); il.Br(label2); il.MarkLabel(label1); il.Ldarg(2); il.MarkLabel(label2); il.Ret(); Console.Write(il.GetILCode()); } }
public void TestFarsh() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(int), new[] { typeof(int) }, typeof(Test)); using (var il = new GroboIL(method)) { var temp = il.DeclareLocal(typeof(int)); il.Ldarg(0); // stack: [x] var label0 = il.DefineLabel("L"); il.Br(label0); // goto L_0; stack: [x] il.Ldstr("zzz"); il.Ldobj(typeof(DateTime)); il.Mul(); il.Initobj(typeof(int)); var label1 = il.DefineLabel("L"); il.MarkLabel(label1); // stack: [x, 2] il.Stloc(temp); // temp = 2; stack: [x] var label2 = il.DefineLabel("L"); il.MarkLabel(label2); // stack: [cur] il.Ldarg(0); // stack: [cur, x] il.Mul(); // stack: [cur * x = cur] il.Ldloc(temp); // stack: [cur, temp] il.Ldc_I4(1); // stack: [cur, temp, 1] il.Sub(); // stack: [cur, temp - 1] il.Stloc(temp); // temp = temp - 1; stack: [cur] il.Ldloc(temp); // stack: [cur, temp] il.Ldc_I4(0); // stack: [cur, temp, 0] il.Bgt(label2, false); // if(temp > 0) goto L_2; stack: [cur] var label3 = il.DefineLabel("L"); il.Br(label3); // goto L_3; stack: [cur] il.MarkLabel(label0); // stack: [x] il.Ldc_I4(2); // stack: [x, 2] il.Br(label1); // goto L_1; stack: [x, 2] il.MarkLabel(label3); // stack: [cur] il.Ret(); // return cur; stack: [] Console.Write(il.GetILCode()); } }
private void CompileWriter() { DynamicMethod dm = new DynamicMethod(Guid.NewGuid().ToString(), typeof(Tuple <int, byte[]>), new[] { Type, typeof(BinaryStruct) }); using (var il = new GroboIL(dm)) { var buffer = il.DeclareLocal(typeof(byte[])); var offset = il.DeclareLocal(typeof(int)); var typeSize = il.DeclareLocal(typeof(int)); var value = il.DeclareLocal(Type); var binaryStruct = il.DeclareLocal(typeof(BinaryStruct)); il.Ldarg(1); il.Stloc(binaryStruct); il.Ldarg(0); //il.Castclass(Type); il.Stloc(value); il.Ldc_I4(InitLen); il.Newarr(typeof(byte)); il.Stloc(buffer); CompileWriter(this, il, binaryStruct, value, buffer, offset, typeSize); il.Ldloc(offset); il.Ldloc(buffer); il.Newobj(typeof(Tuple <int, byte[]>).GetConstructor(new Type[] { typeof(int), typeof(byte[]) })); il.Ret(); IlWriteCode = il.GetILCode(); } WriteMethod = CreateWriter(dm); }
public void TestEnumerable() { var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(Guid.NewGuid().ToString()), AssemblyBuilderAccess.RunAndSave); var module = assembly.DefineDynamicModule(Guid.NewGuid().ToString(), "test.cil", true); var symWriter = module.GetSymWriter(); var symbolDocumentWriter = symWriter.DefineDocument("test.cil", Guid.Empty, Guid.Empty, Guid.Empty); var typeBuilder = module.DefineType("Zzz", TypeAttributes.Class | TypeAttributes.Public); var method = typeBuilder.DefineMethod("Qzz", MethodAttributes.Public); var genericParameters = method.DefineGenericParameters("TZzz"); var parameter = genericParameters[0]; method.SetParameters(typeof(List <>).MakeGenericType(parameter), typeof(Func <,>).MakeGenericType(parameter, typeof(int))); method.DefineParameter(2, ParameterAttributes.In, "list"); method.SetReturnType(typeof(int)); using (var il = new GroboIL(method, symbolDocumentWriter)) { il.Ldarg(1); il.Dup(); var notNullLabel = il.DefineLabel("notNull"); il.Brtrue(notNullLabel); il.Pop(); il.Ldc_I4(0); il.Newarr(parameter); il.MarkLabel(notNullLabel); var temp = il.DeclareLocal(typeof(IEnumerable <>).MakeGenericType(parameter), "arr"); il.Stloc(temp); il.Ldloc(temp); il.Ldarg(2); il.Call(HackHelpers.GetMethodDefinition <int[]>(ints => ints.Sum(x => x)).GetGenericMethodDefinition().MakeGenericMethod(parameter)); il.Ret(); Console.WriteLine(il.GetILCode()); } var type = typeBuilder.CreateType(); var instance = Activator.CreateInstance(type); type.GetMethod("Qzz", BindingFlags.Instance | BindingFlags.Public).MakeGenericMethod(typeof(int)).Invoke(instance, new object[] { null, null }); }
public void TestDifferentPaths() { Console.WriteLine(Formatter.Format(typeof(Dictionary <string, int>).GetProperty("Values", BindingFlags.Public | BindingFlags.Instance).GetGetMethod())); var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(void), new[] { typeof(bool), typeof(C1), typeof(C2) }, typeof(string), true); using (var il = new GroboIL(method)) { il.Ldarg(0); var label1 = il.DefineLabel("L1"); il.Brfalse(label1); il.Ldarg(1); var label2 = il.DefineLabel("L2"); il.Br(label2); il.MarkLabel(label1); il.Ldarg(2); il.MarkLabel(label2); il.Dup(); il.Call(HackHelpers.GetMethodDefinition <I1>(x => F1(x))); il.Call(HackHelpers.GetMethodDefinition <I2>(x => F2(x))); il.Ret(); Console.Write(il.GetILCode()); } var action = method.CreateDelegate(typeof(Action <bool, C1, C2>)); }
private static void LogIlCode(GroboIL il) { File.AppendAllText("DebugIlOutput.il", il.GetILCode()); }
public void Test1() { var overflow = typeof(OverflowException); var exCtorInfo = overflow.GetConstructor(new[] { typeof(string) }); var exToStrMI = overflow.GetMethod("ToString"); var writeLineMI = typeof(Console).GetMethod("WriteLine", new[] { typeof(string), typeof(object) }); var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(int), new[] { typeof(int), typeof(int) }, typeof(TestTryCatch)); using (var il = new GroboIL(method)) { GroboIL.Local tmp1 = il.DeclareLocal(typeof(int)); GroboIL.Local tmp2 = il.DeclareLocal(overflow); // In order to successfully branch, we need to create labels // representing the offset IL instruction block to branch to. // These labels, when the MarkLabel(Label) method is invoked, // will specify the IL instruction to branch to. // GroboIL.Label failed = il.DefineLabel("failed"); GroboIL.Label endOfMthd = il.DefineLabel("end"); // Begin the try block. il.BeginExceptionBlock(); // First, load argument 0 and the integer value of "100" onto the // stack. If arg0 > 100, branch to the label "failed", which is marked // as the address of the block that throws an exception. // il.Ldarg(0); il.Ldc_I4(100); il.Bgt(failed, false); // Now, check to see if argument 1 was greater than 100. If it was, // branch to "failed." Otherwise, fall through and perform the addition, // branching unconditionally to the instruction at the label "endOfMthd". // il.Ldarg(1); il.Ldc_I4(100); il.Bgt(failed, false); il.Ldarg(0); il.Ldarg(1); il.Add_Ovf(true); // Store the result of the addition. il.Stloc(tmp1); il.Leave(endOfMthd); // If one of the arguments was greater than 100, we need to throw an // exception. We'll use "OverflowException" with a customized message. // First, we load our message onto the stack, and then create a new // exception object using the constructor overload that accepts a // string message. // il.MarkLabel(failed); il.Ldstr("Cannot accept values over 100 for add."); il.Newobj(exCtorInfo); // We're going to need to refer to that exception object later, so let's // store it in a temporary variable. Since the store function pops the // the value/reference off the stack, and we'll need it to throw the // exception, we will subsequently load it back onto the stack as well. il.Stloc(tmp2); il.Ldloc(tmp2); // Throw the exception now on the stack. il.Throw(); // Start the catch block for OverflowException. // il.BeginCatchBlock(overflow); // When we enter the catch block, the thrown exception // is on the stack. Store it, then load the format string // for WriteLine. // il.Stloc(tmp2); il.Ldstr("Caught {0}"); // Push the thrown exception back on the stack, then // call its ToString() method. Note that if this catch block // were for a more general exception type, like Exception, // it would be necessary to use the ToString for that type. // il.Ldloc(tmp2); il.Call(exToStrMI); // The format string and the return value from ToString() are // now on the stack. Call WriteLine(string, object). // il.Call(writeLineMI); // Since our function has to return an integer value, we'll load -1 onto // the stack to indicate an error, and store it in local variable tmp1. // il.Ldc_I4(-1); il.Stloc(tmp1); // End the exception handling block. il.EndExceptionBlock(); // The end of the method. If no exception was thrown, the correct value // will be saved in tmp1. If an exception was thrown, tmp1 will be equal // to -1. Either way, we'll load the value of tmp1 onto the stack and return. // il.MarkLabel(endOfMthd); il.Ldloc(tmp1); il.Ret(); Console.WriteLine(il.GetILCode()); } }
public void Test2() { AssemblyName myAssemblyName = new AssemblyName(); myAssemblyName.Name = "AdderExceptionAsm"; // Create dynamic assembly. AppDomain myAppDomain = Thread.GetDomain(); AssemblyBuilder myAssemblyBuilder = myAppDomain.DefineDynamicAssembly(myAssemblyName, AssemblyBuilderAccess.RunAndSave); // Create a dynamic module. ModuleBuilder myModuleBuilder = myAssemblyBuilder.DefineDynamicModule("AdderExceptionMod", true); var symbolDocumentWriter = myModuleBuilder.GetSymWriter().DefineDocument("AdderException.cil", Guid.Empty, Guid.Empty, Guid.Empty); TypeBuilder myTypeBuilder = myModuleBuilder.DefineType("Adder"); Type[] adderParams = { typeof(int), typeof(int) }; ConstructorInfo myConstructorInfo = typeof(OverflowException).GetConstructor(new[] { typeof(string) }); MethodInfo myExToStrMI = typeof(OverflowException).GetMethod("ToString"); MethodInfo myWriteLineMI = typeof(Console).GetMethod("WriteLine", new[] { typeof(string), typeof(object) }); // Define method to add two numbers. MethodBuilder myMethodBuilder = myTypeBuilder.DefineMethod("DoAdd", MethodAttributes.Public | MethodAttributes.Static, typeof(int), adderParams); using (var il = new GroboIL(myMethodBuilder, symbolDocumentWriter)) { // Declare local variable. GroboIL.Local myLocalBuilder1 = il.DeclareLocal(typeof(int)); GroboIL.Local myLocalBuilder2 = il.DeclareLocal(typeof(OverflowException)); // Define label. GroboIL.Label myFailedLabel = il.DefineLabel("failed"); GroboIL.Label myEndOfMethodLabel = il.DefineLabel("end"); // Begin exception block. il.BeginExceptionBlock(); il.Ldarg(0); il.Ldc_I4(10); il.Bgt(myFailedLabel, false); il.Ldarg(1); il.Ldc_I4(10); il.Bgt(myFailedLabel, false); il.Ldarg(0); il.Ldarg(1); il.Add_Ovf(true); il.Stloc(myLocalBuilder1); il.Leave(myEndOfMethodLabel); il.MarkLabel(myFailedLabel); il.Ldstr("Cannot accept values over 10 for add."); il.Newobj(myConstructorInfo); il.Stloc(myLocalBuilder2); il.Ldloc(myLocalBuilder2); // Throw the exception. il.Throw(); // Call 'BeginExceptFilterBlock'. il.BeginExceptFilterBlock(); il.WriteLine("Except filter block called."); // Call catch block. il.BeginCatchBlock(null); // Call other catch block. il.BeginCatchBlock(typeof(OverflowException)); il.Ldstr("{0}"); il.Ldloc(myLocalBuilder2); il.Call(myExToStrMI); il.Call(myWriteLineMI); il.Ldc_I4(-1); il.Stloc(myLocalBuilder1); // Call finally block. il.BeginFinallyBlock(); il.WriteLine("Finally block called."); // End the exception block. il.EndExceptionBlock(); il.MarkLabel(myEndOfMethodLabel); il.Ldloc(myLocalBuilder1); il.Ret(); Console.WriteLine(il.GetILCode()); } }
protected static void ThrowError(GroboIL il, string message) { throw new InvalidOperationException(message + Environment.NewLine + il.GetILCode()); }
public void Test3() { // Create an assembly. AssemblyName myAssemblyName = new AssemblyName(); myAssemblyName.Name = "AdderExceptionAsm"; // Create dynamic assembly. AppDomain myAppDomain = Thread.GetDomain(); AssemblyBuilder myAssemblyBuilder = myAppDomain.DefineDynamicAssembly(myAssemblyName, AssemblyBuilderAccess.Run); // Create a dynamic module. ModuleBuilder myModuleBuilder = myAssemblyBuilder.DefineDynamicModule("AdderExceptionMod", true); var symbolDocumentWriter = myModuleBuilder.GetSymWriter().DefineDocument("AdderException.cil", Guid.Empty, Guid.Empty, Guid.Empty); TypeBuilder myTypeBuilder = myModuleBuilder.DefineType("Adder"); Type[] myAdderParams = new Type[] { typeof(int), typeof(int) }; // Create constructor. ConstructorInfo myConstructorInfo = typeof(OverflowException).GetConstructor( new Type[] { typeof(string) }); MethodInfo myExToStrMI = typeof(OverflowException).GetMethod("ToString"); MethodInfo myWriteLineMI = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string), typeof(object) }); // Method to add two numbers. MethodBuilder myMethodBuilder = myTypeBuilder.DefineMethod("DoAdd", MethodAttributes.Public | MethodAttributes.Static, typeof(int), myAdderParams); using (var il = new GroboIL(myMethodBuilder, symbolDocumentWriter)) { // Declare local variable. GroboIL.Local myLocalBuilder1 = il.DeclareLocal(typeof(int)); GroboIL.Local myLocalBuilder2 = il.DeclareLocal(typeof(OverflowException)); // Define label. GroboIL.Label myFailedLabel = il.DefineLabel("failed"); GroboIL.Label myEndOfMethodLabel = il.DefineLabel("end"); // Begin exception block. il.BeginExceptionBlock(); il.Ldarg(0); il.Ldc_I4(10); il.Bgt(myFailedLabel, false); il.Ldarg(1); il.Ldc_I4(10); il.Bgt(myFailedLabel, false); il.Ldarg(0); il.Ldarg(1); il.Add_Ovf(true); il.Stloc(myLocalBuilder1); il.Br(myEndOfMethodLabel); il.MarkLabel(myFailedLabel); il.Ldstr("Cannot accept values over 10 for addition."); il.Newobj(myConstructorInfo); il.Stloc(myLocalBuilder2); il.Ldloc(myLocalBuilder2); // Call fault block. il.BeginFaultBlock(); //Throw exception. il.Newobj(typeof(NotSupportedException).GetConstructor(Type.EmptyTypes)); il.Throw(); // Call finally block. il.BeginFinallyBlock(); il.Ldstr("{0}"); il.Ldloc(myLocalBuilder2); il.Call(myExToStrMI); il.Call(myWriteLineMI); il.Ldc_I4(-1); il.Stloc(myLocalBuilder1); // End exception block. il.EndExceptionBlock(); il.MarkLabel(myEndOfMethodLabel); il.Ldloc(myLocalBuilder1); il.Ret(); Console.WriteLine(il.GetILCode()); } Type adderType = myTypeBuilder.CreateType(); object addIns = Activator.CreateInstance(adderType); object[] addParams = new object[2]; addParams[0] = 20; addParams[1] = 10; Console.WriteLine("{0} + {1} = {2}", addParams[0], addParams[1], adderType.InvokeMember("DoAdd", BindingFlags.InvokeMethod, null, addIns, addParams)); }
public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack) { if (stack.Count != 0) { throw new InvalidOperationException("The evaluation stack must be empty in order to perform the 'jmp' instruction\r\n" + il.GetILCode()); } }