예제 #1
0
        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());
            }
        }
예제 #2
0
        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)));
        }
예제 #3
0
        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 }));
        }
예제 #4
0
파일: Test.cs 프로젝트: qinfengzhu/gremit
        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());
            }
        }
예제 #5
0
        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))));
        }
예제 #6
0
파일: Test.cs 프로젝트: qinfengzhu/gremit
        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());
            }
        }
예제 #7
0
파일: Test.cs 프로젝트: qinfengzhu/gremit
        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());
            }
        }
예제 #8
0
파일: Test.cs 프로젝트: qinfengzhu/gremit
        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());
            }
        }
예제 #9
0
파일: Test.cs 프로젝트: qinfengzhu/gremit
        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());
            }
        }
예제 #10
0
파일: Test.cs 프로젝트: qinfengzhu/gremit
        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));
        }
예제 #11
0
        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);
        }
예제 #12
0
파일: Test.cs 프로젝트: qinfengzhu/gremit
        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());
            }
        }
예제 #13
0
파일: Test.cs 프로젝트: qinfengzhu/gremit
        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);
        }
예제 #14
0
        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)));
        }
예제 #15
0
파일: Test.cs 프로젝트: qinfengzhu/gremit
        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());
            }
        }
예제 #16
0
파일: Test.cs 프로젝트: qinfengzhu/gremit
        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());
            }
        }
예제 #17
0
파일: Test.cs 프로젝트: qinfengzhu/gremit
        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());
            }
        }
예제 #18
0
        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);
        }
예제 #19
0
파일: Test.cs 프로젝트: qinfengzhu/gremit
        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 });
        }
예제 #20
0
파일: Test.cs 프로젝트: qinfengzhu/gremit
        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>));
        }
예제 #21
0
 private static void LogIlCode(GroboIL il)
 {
     File.AppendAllText("DebugIlOutput.il", il.GetILCode());
 }
예제 #22
0
        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());
            }
        }
예제 #23
0
        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());
            }
        }
예제 #24
0
파일: StackMutator.cs 프로젝트: ymf1/gremit
 protected static void ThrowError(GroboIL il, string message)
 {
     throw new InvalidOperationException(message + Environment.NewLine + il.GetILCode());
 }
예제 #25
0
        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));
        }
예제 #26
0
 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());
     }
 }