예제 #1
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());
            }
        }
        protected override bool EmitInternal(BinaryExpression node, EmittingContext context, GroboIL.Label returnDefaultValueLabel, ResultType whatReturn, bool extend, out Type resultType)
        {
            if (node.Conversion != null)
            {
                throw new NotSupportedException("Coalesce with conversion is not supported");
            }
            // note ich: баг решарпера
            // ReSharper disable HeuristicUnreachableCode
            var     left  = node.Left;
            var     right = node.Right;
            GroboIL il    = context.Il;

            GroboIL.Label valueIsNullLabel = il.DefineLabel("valueIsNull");
            Type          leftType;
            bool          labelUsed = ExpressionEmittersCollection.Emit(left, context, valueIsNullLabel, out leftType);

            if (left.Type.IsValueType)
            {
                using (var temp = context.DeclareLocal(left.Type))
                {
                    il.Stloc(temp);
                    il.Ldloca(temp);
                }
            }
            labelUsed |= context.EmitNullChecking(left.Type, valueIsNullLabel);
            if (left.Type.IsValueType)
            {
                if (!left.Type.IsNullable())
                {
                    throw new InvalidOperationException("Type '" + left.Type + "' cannot be null");
                }
                if (node.Type != left.Type)
                {
                    context.EmitValueAccess(left.Type);
                }
                else
                {
                    il.Ldobj(left.Type);
                }
            }
            var valueIsNotNullLabel = il.DefineLabel("valueIsNotNull");

            il.Br(valueIsNotNullLabel);
            if (labelUsed)
            {
                context.MarkLabelAndSurroundWithSP(valueIsNullLabel);
                il.Pop();
            }
            Type rightType;
            var  result = ExpressionEmittersCollection.Emit(right, context, returnDefaultValueLabel, out rightType);

            context.MarkLabelAndSurroundWithSP(valueIsNotNullLabel);
            resultType = node.Type;
            return(result);
            // ReSharper restore HeuristicUnreachableCode
        }
예제 #3
0
        public void BuildSizeCounter(SizeCounterBuilderContext sizeCounterBuilderContext)
        {
            var method = new DynamicMethod("Count_" + Type.Name + "_" + Guid.NewGuid(), typeof(int), new[] { Type, typeof(bool), typeof(WriterContext) }, sizeCounterBuilderContext.Module, true);

            sizeCounterBuilderContext.SetSizeCounterMethod(Type, method);
            using (var il = new GroboIL(method))
            {
                var context = new SizeCounterMethodBuilderContext(sizeCounterBuilderContext, il);

                var notEmptyLabel = il.DefineLabel("notEmpty");
                if (CheckEmpty(context, notEmptyLabel)) // Check if obj is empty
                {
                    context.ReturnForNull();            // return for null
                }
                il.MarkLabel(notEmptyLabel);            // Now we know that obj is not empty

                if (!Type.IsValueType && IsReference && sizeCounterBuilderContext.GroBufWriter.Options.HasFlag(GroBufOptions.PackReferences))
                {
                    // Pack reference
                    var index = il.DeclareLocal(typeof(int));
                    context.LoadContext();                                                                                // stack: [context]
                    il.Dup();                                                                                             // stack: [context, context]
                    il.Ldfld(WriterContext.IndexField);                                                                   // stack: [context, context.index]
                    il.Stloc(index);                                                                                      // index = context.index; stack: [context]
                    il.Ldfld(WriterContext.ObjectsField);                                                                 // stack: [context.objects]
                    context.LoadObj();                                                                                    // stack: [context.objects, obj]
                    il.Call(HackHelpers.GetMethodDefinition <Dictionary <object, int> >(dict => dict.ContainsKey(null))); // stack: [context.object.ContainsKey(obj)]
                    var storeLocationLabel = il.DefineLabel("storeLocation");
                    il.Brfalse(storeLocationLabel);                                                                       // if(!context.objects.ContainsKey(obj)) goto storeLocation; stack: []
                    context.LoadContext();                                                                                // stack: [context]
                    il.Dup();                                                                                             // stack: [context, context]
                    il.Ldfld(WriterContext.ReferencesField);                                                              // stack: [context, context.references]
                    il.Ldc_I4(1);                                                                                         // stack: [context, context.references, 1]
                    il.Add();                                                                                             // stack: [context, context.references + 1]
                    il.Stfld(WriterContext.ReferencesField);                                                              // context.references += 1; stack: []
                    il.Ldc_I4(5);                                                                                         // stack: [5]
                    il.Ret();                                                                                             // return 5
                    il.MarkLabel(storeLocationLabel);
                    context.LoadContext();                                                                                // stack: [context]
                    il.Ldfld(typeof(WriterContext).GetField("objects", BindingFlags.Public | BindingFlags.Instance));     // stack: [context.objects]
                    context.LoadObj();                                                                                    // stack: [context.objects, obj]
                    il.Ldloc(index);                                                                                      // stack: [context.objects, obj, index]
                    il.Call(HackHelpers.GetMethodDefinition <Dictionary <object, int> >(dict => dict.Add(null, 0)));      // context.objects.Add(obj, index);
                }

                CountSizeNotEmpty(context); // Count size
                il.Ret();
            }
            var @delegate = method.CreateDelegate(typeof(SizeCounterDelegate <>).MakeGenericType(Type));
            var pointer   = GroBufHelpers.ExtractDynamicMethodPointer(method);

            sizeCounterBuilderContext.SetSizeCounterPointer(Type, pointer, @delegate);
        }
예제 #4
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 }));
        }
예제 #5
0
        private static Func <MethodBase, DynamicMethod> EmitTryCastToDynamicMethod()
        {
            var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(DynamicMethod), new[] { typeof(MethodBase) }, typeof(string), true);

            using (var il = new GroboIL(method))
            {
                var RTDynamicMethod_t = typeof(DynamicMethod).GetNestedType("RTDynamicMethod", BindingFlags.NonPublic);
                if (RTDynamicMethod_t == null)
                {
                    throw new InvalidOperationException("Missing type 'System.Reflection.Emit.DynamicMethod.RTDynamicMethod'");
                }
                il.Ldarg(0);                  // stack: [method]
                il.Isinst(RTDynamicMethod_t); // stack: [method as RTDynamicMethod]
                il.Dup();                     // stack: [method as RTDynamicMethod, method as RTDynamicMethod]
                var retLabel = il.DefineLabel("ret");
                il.Brfalse(retLabel);         // if(!(method is RTDynamicMethod)] goto ret; stack: [method as RTDynamicMethod]
                var m_owner_f = RTDynamicMethod_t.GetField("m_owner", BindingFlags.Instance | BindingFlags.NonPublic);
                if (m_owner_f == null)
                {
                    throw new InvalidOperationException("Missing field 'System.Reflection.Emit.DynamicMethod.RTDynamicMethod.m_owner'");
                }
                il.Ldfld(m_owner_f); // stack: [((RTDynamicMethod)method).m_owner]
                il.MarkLabel(retLabel);
                il.Ret();
            }
            return((Func <MethodBase, DynamicMethod>)method.CreateDelegate(typeof(Func <MethodBase, DynamicMethod>)));
        }
예제 #6
0
        public void WithExceptions()
        {
            var dynamicMethod = new DynamicMethod(Guid.NewGuid().ToString(), typeof(int), new[] { typeof(int), typeof(int) }, typeof(string), true);

            using (var il = new GroboIL(dynamicMethod, false))
            {
                var endLabel    = il.DefineLabel("end");
                var resultLocal = il.DeclareLocal(typeof(int), "result");
                il.BeginExceptionBlock();
                il.Ldarg(0);
                il.Ldarg(1);
                il.Div(false);
                il.Stloc(resultLocal);
                il.BeginCatchBlock(typeof(DivideByZeroException));
                il.Pop();
                il.WriteLine("Division by zero caught");
                il.Ldc_I4(0);
                il.Stloc(resultLocal);
                il.BeginFinallyBlock();
                il.WriteLine("It is finally");
                il.EndExceptionBlock();
                il.MarkLabel(endLabel);
                il.Ldloc(resultLocal);
                il.Ret();
            }

            DynamicMethodTracingInstaller.InstallTracing(dynamicMethod);

            var func = (Func <int, int, int>)dynamicMethod.CreateDelegate(typeof(Func <int, int, int>));

            Console.WriteLine(func(12, 5));
            Console.WriteLine(func(5, 0));
        }
예제 #7
0
        private static Func <IntPtr, long, long> EmitRelJmpHooker()
        {
            var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(long), new[] { typeof(IntPtr), typeof(long) }, typeof(string), true);

            using (var il = new GroboIL(method))
            {
                il.VerificationKind = TypesAssignabilityVerificationKind.LowLevelOnly;
                var cycleLabel = il.DefineLabel("cycle");
                il.MarkLabel(cycleLabel);
                il.Ldarg(0);            // stack: [ptr]
                il.Dup();               // stack: [ptr, ptr]
                var x = il.DeclareLocal(typeof(long));
                il.Ldind(typeof(long)); // stack: [ptr, *ptr]
                il.Dup();
                il.Stloc(x);            // x = *ptr; stack: [ptr, newCode]
                il.Ldc_I8(unchecked ((long)0xFFFFFF0000000000));
                il.And();               // stack: [ptr, x & 0xFFFFFF0000000000]
                il.Ldarg(1);            // stack: [ptr, x & 0xFFFFFF0000000000, code]
                il.Or();                // stack: [ptr, (x & 0xFFFFFF0000000000) | code]
                il.Ldloc(x);            // stack: [ptr, (x & 0xFFFFFF0000000000) | code, newCode]
                var methodInfo = typeof(Interlocked).GetMethod("CompareExchange", BindingFlags.Static | BindingFlags.Public, null, new[] { typeof(long).MakeByRefType(), typeof(long), typeof(long) }, null);
                il.Call(methodInfo);    // stack: [Interlocked.CompareExchange(ptr, (x & 0xFFFFFF0000000000) | code, newCode)]
                il.Ldloc(x);            // stack: [Interlocked.CompareExchange(ptr, (x & 0xFFFFFF0000000000) | code, newCode), newCode]
                il.Bne_Un(cycleLabel);  // if(Interlocked.CompareExchange(ptr, (x & 0xFFFFFF0000000000) | code, newCode) != newCode) goto cycle; stack: []
                il.Ldloc(x);
                il.Ret();
            }
            return((Func <IntPtr, long, long>)method.CreateDelegate(typeof(Func <IntPtr, long, long>)));
        }
예제 #8
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))));
        }
예제 #9
0
파일: Test.cs 프로젝트: qinfengzhu/gremit
        public void TestDifferentStructs()
        {
            var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(void), new[] { typeof(int) }, typeof(Test));
            var il     = new GroboIL(method);
            var loc1   = il.DeclareLocal(typeof(int?));
            var loc2   = il.DeclareLocal(typeof(Qxx?));
            var label1 = il.DefineLabel("zzz");

            il.Ldarg(0);
            il.Brfalse(label1);
            il.Ldloc(loc1);
            var label2 = il.DefineLabel("qxx");

            il.Br(label2);
            il.MarkLabel(label1);
            il.Ldloc(loc2);
            Assert.Throws <InvalidOperationException>(() => il.MarkLabel(label2));
        }
        protected override bool EmitInternal(TypeBinaryExpression node, EmittingContext context, GroboIL.Label returnDefaultValueLabel, ResultType whatReturn, bool extend, out Type resultType)
        {
            bool    result;
            GroboIL il = context.Il;

            if (!node.Expression.Type.IsAssignableFrom(node.TypeOperand))
            {
                il.Ldc_I4(0);
                result = false;
            }
            else if (node.Expression.Type == node.TypeOperand && node.TypeOperand.IsValueType)
            {
                il.Ldc_I4(1);
                result = false;
            }
            else
            {
                Type operandType;
                result = ExpressionEmittersCollection.Emit(node.Expression, context, returnDefaultValueLabel, ResultType.Value, extend, out operandType);
                if (operandType.IsValueType)
                {
                    using (var temp = context.DeclareLocal(operandType))
                    {
                        il.Stloc(temp);
                        il.Ldloca(temp);
                    }
                }
                var returnFalseLabel = il.DefineLabel("returnFalse");
                il.Dup();
                il.Brfalse(returnFalseLabel);
                il.Call(typeof(object).GetMethod("GetType"), operandType);
                il.Ldtoken(node.TypeOperand);
                il.Call(typeof(Type).GetMethod("GetTypeFromHandle"));
                il.Ceq();
                var doneLabel = il.DefineLabel("done");
                il.Br(doneLabel);
                context.MarkLabelAndSurroundWithSP(returnFalseLabel);
                il.Pop();
                il.Ldc_I4(0);
                context.MarkLabelAndSurroundWithSP(doneLabel);
            }
            resultType = typeof(bool);
            return(result);
        }
예제 #11
0
        public void TestLabelHasNotBeenUsed()
        {
            var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(void), Type.EmptyTypes, typeof(string), true);

            using (var il = new GroboIL(method))
            {
                il.DefineLabel("L");
                il.Ret();
            }
        }
예제 #12
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());
            }
        }
예제 #13
0
        private Func <string, string> BuildSwitch4()
        {
            Init(new[] { "0", "2", "5", "1000001", "7", "1000000" });
            var dynamicMethod = new DynamicMethod(Guid.NewGuid().ToString(), MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, typeof(string), new[] { typeof(string) }, Module, true);

            using (var il = new GroboIL(dynamicMethod))
            {
                var zzzLabel = il.DefineLabel("zzz");
                var qxxLabel = il.DefineLabel("qxx");
                var qzzLabel = il.DefineLabel("qzz");
                var xxxLabel = il.DefineLabel("xxx");
                var index    = il.DeclareLocal(typeof(uint));
                il.Ldfld(typeof(TestPerformance).GetField("testValues2"));
                il.Ldarg(0);
                il.Call(typeof(object).GetMethod("GetHashCode"), typeof(string));
                il.Ldc_I4(testValues2.Length);
                il.Rem(true);
                il.Stloc(index);
                il.Ldloc(index);
                il.Ldelem(typeof(string));
                il.Ldarg(0);
                il.Call(typeof(object).GetMethod("Equals", new[] { typeof(object) }), typeof(string));
                il.Brfalse(xxxLabel);
                il.Ldfld(typeof(TestPerformance).GetField("indexes2"));
                il.Ldloc(index);
                il.Ldelem(typeof(int));
                il.Switch(zzzLabel, zzzLabel, qxxLabel, qxxLabel, qzzLabel, qzzLabel);
                il.Br(xxxLabel);
                il.MarkLabel(zzzLabel);
                il.Ldstr("zzz");
                il.Ret();
                il.MarkLabel(qxxLabel);
                il.Ldstr("qxx");
                il.Ret();
                il.MarkLabel(qzzLabel);
                il.Ldstr("qzz");
                il.Ret();
                il.MarkLabel(xxxLabel);
                il.Ldstr("xxx");
                il.Ret();
            }
            return((Func <string, string>)dynamicMethod.CreateDelegate(typeof(Func <string, string>)));
        }
예제 #14
0
        public static TryGetValueDelegate <T> Build <T>(string[] keys, T[] values, Func <string, int> hashCodeEvaluator)
        {
            var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(bool),
                                           new[] { typeof(Closure <T>), typeof(string), typeof(T).MakeByRefType() }, typeof(string), true);
            var hashCodes = keys.Select(hashCodeEvaluator).ToArray();
            int n         = keys.Length;
            var indexes   = new int[n];

            for (int i = 0; i < n; ++i)
            {
                indexes[i] = i;
            }
            Array.Sort(indexes, (lhs, rhs) => hashCodes[lhs].CompareTo(hashCodes[rhs]));
            using (var il = new GroboIL(method))
            {
                var retFalseLabel = il.DefineLabel("retFalse");
                var hashCode      = il.DeclareLocal(typeof(int), "hashCode");
                il.Ldarg(0);                                                                                          // stack: [closure]
                il.Ldfld(HackHelpers.GetField <Closure <T> >(x => x.hashCodeEvaluator));                              // stack: [closure.hashCodeEvaluator]
                il.Ldarg(1);                                                                                          // stack: [closure.hashCodeEvaluator, key]
                il.Call(typeof(Func <string, int>).GetMethod("Invoke", BindingFlags.Instance | BindingFlags.Public)); // stack: [closure.hashCodeEvaluator(key)]
                il.Stloc(hashCode);                                                                                   // hashCode = closure.hashCodeEvaluator(key); stack: []

                var context = new EmittingContext
                {
                    Il            = il,
                    Keys          = keys,
                    HashCodes     = hashCodes,
                    Indexes       = indexes,
                    HashCode      = hashCode,
                    RetFalseLabel = retFalseLabel
                };
                DoBinarySearch <T>(context, 0, n - 1);
                il.MarkLabel(retFalseLabel);
                il.Ldarg(2); // stack: [ref value]
                if (typeof(T).IsValueType)
                {
                    il.Initobj(typeof(T)); // value = default(T); stack: []
                }
                else
                {
                    il.Ldnull();         // stack: [ref value, null]
                    il.Stind(typeof(T)); // value = null; stack: []
                }
                il.Ldc_I4(0);            // stack: [false]
                il.Ret();
            }
            var closure = new Closure <T>
            {
                hashCodeEvaluator = hashCodeEvaluator,
                values            = values
            };

            return((TryGetValueDelegate <T>)method.CreateDelegate(typeof(TryGetValueDelegate <T>), closure));
        }
예제 #15
0
파일: Test.cs 프로젝트: qinfengzhu/gremit
        public void TestBrtrue()
        {
            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.Brtrue(label);
                var label2 = il.DefineLabel("L");
                il.Br(label2);
                il.MarkLabel(label);
                il.Call(HackHelpers.GetMethodDefinition <I1>(x => x.GetI2()));
                il.MarkLabel(label2);
                il.Call(HackHelpers.GetMethodDefinition <int>(x => F2(null)));
                il.Ret();
                Console.WriteLine(il.GetILCode());
            }
        }
예제 #16
0
파일: Test.cs 프로젝트: qinfengzhu/gremit
        private IQxx BuildIfs(ModuleBuilder module, string[] keys)
        {
            var numberOfCases = keys.Length;
            var typeBuilder   = module.DefineType("Ifs" + Guid.NewGuid(), TypeAttributes.Class | TypeAttributes.Public);

            typeBuilder.AddInterfaceImplementation(typeof(IQxx));
            var fields = new FieldInfo[numberOfCases];

            for (var i = 0; i < numberOfCases; ++i)
            {
                fields[i] = typeBuilder.DefineField(keys[i], typeof(int), FieldAttributes.Public);
            }
            var method = typeBuilder.DefineMethod("Set", MethodAttributes.Public | MethodAttributes.Virtual, typeof(void), new[] { typeof(string), typeof(int) });

            method.DefineParameter(1, ParameterAttributes.In, "key");
            method.DefineParameter(2, ParameterAttributes.In, "value");
            using (var il = new GroboIL(method))
            {
                var doneLabel = il.DefineLabel("done");
                for (var i = 0; i < numberOfCases; ++i)
                {
                    il.Ldarg(1);                     // stack: [key]
                    il.Ldstr(keys[i]);               // stack: [key, keys[i]]
                    il.Call(stringEqualityOperator); // stack: [key == keys[i]]
                    var nextKeyLabel = il.DefineLabel("nextKey");
                    il.Brfalse(nextKeyLabel);        // if(key != keys[i]) goto nextKey; stack: []
                    il.Ldarg(0);
                    il.Ldarg(2);
                    il.Stfld(fields[i]);
                    il.Br(doneLabel);
                    il.MarkLabel(nextKeyLabel);
                }
                il.MarkLabel(doneLabel);
                il.Ret();
            }
            typeBuilder.DefineMethodOverride(method, typeof(IQxx).GetMethod("Set"));
            var type = typeBuilder.CreateType();

            return((IQxx)Activator.CreateInstance(type));
        }
예제 #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 Func <int, string> BuildSwitch2()
        {
            var dynamicMethod = new DynamicMethod(Guid.NewGuid().ToString(), MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, typeof(string), new[] { typeof(int) }, Module, true);

            using (var il = new GroboIL(dynamicMethod))
            {
                var zzzLabel = il.DefineLabel("zzz");
                var qxxLabel = il.DefineLabel("qxx");
                var qzzLabel = il.DefineLabel("qzz");
                var xxxLabel = il.DefineLabel("xxx");
                var index    = il.DeclareLocal(typeof(uint));
                il.Ldfld(typeof(TestPerformance).GetField("testValues"));
                il.Ldarg(0);
                il.Ldc_I4(14);
                il.Rem(true);
                il.Stloc(index);
                il.Ldloc(index);
                il.Ldelem(typeof(int));
                il.Ldarg(0);
                il.Bne_Un(xxxLabel);
                il.Ldfld(typeof(TestPerformance).GetField("indexes"));
                il.Ldloc(index);
                il.Ldelem(typeof(int));
                il.Switch(zzzLabel, zzzLabel, qxxLabel, qzzLabel, qzzLabel, qxxLabel);
                il.Br(xxxLabel);
                il.MarkLabel(zzzLabel);
                il.Ldstr("zzz");
                il.Ret();
                il.MarkLabel(qxxLabel);
                il.Ldstr("qxx");
                il.Ret();
                il.MarkLabel(qzzLabel);
                il.Ldstr("qzz");
                il.Ret();
                il.MarkLabel(xxxLabel);
                il.Ldstr("xxx");
                il.Ret();
            }
            return((Func <int, string>)dynamicMethod.CreateDelegate(typeof(Func <int, string>)));
        }
예제 #19
0
        private static void EmitCrashIfValueIsNull(GroboIL il)
        {
            var box = il.DefineLabel("box");

            il.Dup();
            il.Brtrue(box);
            var crashConstructor = typeof(ArgumentException).GetConstructor(new[] { typeof(string) });

            il.Ldstr("bad parameter");
            il.Newobj(crashConstructor);
            il.Throw();
            il.MarkLabel(box);
        }
        private static void EmitLoadIndex(Expression index, EmittingContext context, Type arrayType)
        {
            GroboIL il = context.Il;

            GroboIL.Label indexIsNullLabel = context.CanReturn ? il.DefineLabel("indexIsNull") : null;
            Type          indexType;
            bool          labelUsed = ExpressionEmittersCollection.Emit(index, context, indexIsNullLabel, out indexType); // stack: [array, index]

            if (indexType != typeof(int))
            {
                throw new InvalidOperationException("Unable to perform array index operator to type '" + arrayType + "'");
            }
            if (labelUsed && context.CanReturn)
            {
                var indexIsNotNullLabel = il.DefineLabel("indexIsNotNull");
                il.Br(indexIsNotNullLabel);
                context.MarkLabelAndSurroundWithSP(indexIsNullLabel);
                il.Pop();
                il.Ldc_I4(0);
                context.MarkLabelAndSurroundWithSP(indexIsNotNullLabel);
            }
        }
예제 #21
0
        public void TestLabelHasNotBeenMarked_Switch()
        {
            var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(void), Type.EmptyTypes, typeof(string), true);
            var il     = new GroboIL(method);
            var label  = il.DefineLabel("L");

            il.Ldc_I4(0);
            il.Switch(label);
            il.Ret();
            var e = Assert.Throws <InvalidOperationException>(il.Dispose);

            Assert.AreEqual("The label 'L_0' has not been marked", e.Message);
        }
예제 #22
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>));
        }
예제 #23
0
        private Func <int, string> BuildSwitch1()
        {
            var dynamicMethod = new DynamicMethod(Guid.NewGuid().ToString(), MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, typeof(string), new[] { typeof(int) }, Module, true);

            using (var il = new GroboIL(dynamicMethod))
            {
                il.Ldarg(0);
                var zzzLabel = il.DefineLabel("zzz");
                var qxxLabel = il.DefineLabel("qxx");
                var qzzLabel = il.DefineLabel("qzz");
                var xxxLabel = il.DefineLabel("xxx");
                il.Switch(zzzLabel, xxxLabel, zzzLabel);
                il.Ldarg(0);
                il.Ldc_I4(5);
                il.Sub();
                il.Switch(qxxLabel, xxxLabel, qzzLabel);
                il.Ldarg(0);
                il.Ldc_I4(0xf4240);
                il.Sub();
                il.Switch(qzzLabel, qxxLabel);
                il.Br(xxxLabel);
                il.MarkLabel(zzzLabel);
                il.Ldstr("zzz");
                il.Ret();
                il.MarkLabel(qxxLabel);
                il.Ldstr("qxx");
                il.Ret();
                il.MarkLabel(qzzLabel);
                il.Ldstr("qzz");
                il.Ret();
                il.MarkLabel(xxxLabel);
                il.Ldstr("xxx");
                il.Ret();
            }
            return((Func <int, string>)dynamicMethod.CreateDelegate(typeof(Func <int, string>)));
        }
예제 #24
0
        public void TestLabelHasBeenMarkedTwice()
        {
            var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(void), Type.EmptyTypes, typeof(string), true);
            var il     = new GroboIL(method);
            var label  = il.DefineLabel("L");

            il.Ldc_I4(0);
            il.Brfalse(label);
            il.Ldc_I4(1);
            il.Pop();
            il.MarkLabel(label);
            il.Ldc_I4(2);
            il.Pop();
            var e = Assert.Throws <InvalidOperationException>(() => il.MarkLabel(label));

            Assert.AreEqual("The label 'L_0' has already been marked", e.Message);
        }
        protected override bool EmitInternal(UnaryExpression node, EmittingContext context, GroboIL.Label returnDefaultValueLabel, ResultType whatReturn, bool extend, out Type resultType)
        {
            if (node.Type != typeof(bool) && node.Type != typeof(bool?))
            {
                return(ExpressionEmittersCollection.Emit(Expression.OnesComplement(node.Operand, node.Method), context, returnDefaultValueLabel, whatReturn, extend, out resultType));
            }
            GroboIL il = context.Il;

            if (node.Method != null)
            {
                throw new NotSupportedException("Custom operator '" + node.NodeType + "' is not supported");
            }
            var operand = node.Operand;

            context.EmitLoadArgument(operand, false, out resultType);
            if (resultType == typeof(bool))
            {
                il.Ldc_I4(1);
                il.Xor();
            }
            else if (resultType == typeof(bool?))
            {
                using (var value = context.DeclareLocal(typeof(bool?)))
                {
                    il.Stloc(value);
                    il.Ldloca(value);
                    context.EmitHasValueAccess(typeof(bool?));
                    var returnLabel = il.DefineLabel("return");
                    il.Brfalse(returnLabel);
                    il.Ldloca(value);
                    context.EmitValueAccess(typeof(bool?));
                    il.Ldc_I4(1);
                    il.Xor();
                    il.Newobj(nullableBoolConstructor);
                    il.Stloc(value);
                    context.MarkLabelAndSurroundWithSP(returnLabel);
                    il.Ldloc(value);
                }
            }
            else
            {
                throw new InvalidOperationException("Cannot perform '" + node.NodeType + "' operator on type '" + resultType + "'");
            }
            return(false);
        }
예제 #26
0
        public void GetReadILCode(PropertyData prop, BinaryStruct currentStruct, GroboIL il, GroboIL.Local binaryStruct, GroboIL.Local buffer, GroboIL.Local result, GroboIL.Local typeSize, GroboIL.Local offset, bool listValue)
        {
            var exitLabel = il.DefineLabel("exit");

            BinaryStruct.ReadObjectNull(il, exitLabel, buffer, offset, typeSize);
            var len = il.DeclareLocal(typeof(int));

            il.Ldloc(buffer);
            il.Ldloc(offset);
            il.Call(readBitConverterMethodInfo);
            il.Stloc(len);

            BinaryStruct.WriteOffsetAppend(il, offset, 4);

            if (!listValue)
            {
                il.Ldloc(result);
                il.Ldarg(1);
            }
            else
            {
                il.Ldloc(binaryStruct);
            }
            il.Call(codingMethodInfo);

            il.Castclass(typeof(UTF8Encoding));

            il.Ldloc(buffer);
            il.Ldloc(offset);
            il.Ldloc(len);

            il.Call(currentStruct.Coding.GetType().GetMethod("GetString", new Type[] { typeof(byte[]), typeof(int), typeof(int) }), isVirtual: true);

            if (!listValue)
            {
                il.Call(prop.Setter);
            }
            else
            {
                il.Stloc(result);
            }

            BinaryStruct.WriteOffsetAppend(il, offset, len);
            il.MarkLabel(exitLabel);
        }
예제 #27
0
        public void GetReadILCode(PropertyData prop, BinaryStruct currentStruct, GroboIL il, GroboIL.Local binaryStruct, GroboIL.Local buffer, GroboIL.Local result, GroboIL.Local typeSize, GroboIL.Local offset, bool listValue)
        {
            var exitLabel = il.DefineLabel("exit");

            BinaryStruct.ReadObjectNull(il, exitLabel, buffer, offset, typeSize);

            var val = il.DeclareLocal(typeof(TType));


            (new T()).GetReadILCode(prop, currentStruct, il, binaryStruct, buffer, val, typeSize, offset, true);

            il.Ldloc(result);
            il.Ldloc(val);
            il.Newobj(Setter);
            il.Call(prop.Setter);

            il.MarkLabel(exitLabel);
        }
예제 #28
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());
            }
        }
예제 #29
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)));
        }
예제 #30
0
        public static void ProcessWrite(PropertyData item, BinaryStruct bs, GroboIL il, GroboIL.Local binaryStruct, GroboIL.Local value, GroboIL.Local buffer, GroboIL.Local offset, GroboIL.Local typeSize)
        {
            if (!string.IsNullOrEmpty(item.BinaryAttr?.ArraySizeName))
            {
                item.ArraySizeProperty = bs.PropertyList.Find(x => x.PropertyInfo.Name == item.BinaryAttr.ArraySizeName);
                if (item.ArraySizeProperty == null)
                {
                    throw new Exception($"ArraySizeProperty \"{item.BinaryAttr.ArraySizeName}\" for {item.PropertyInfo.Name} in Struct {bs.Type}:{item.PropertyInfo.DeclaringType} not found(Scheme: {bs.Scheme})");
                }
            }
            if (!string.IsNullOrEmpty(item.BinaryAttr?.TypeSizeName))
            {
                item.TypeSizeProperty = bs.PropertyList.Find(x => x.PropertyInfo.Name == item.BinaryAttr.TypeSizeName);
                if (item.TypeSizeProperty == null)
                {
                    throw new Exception($"TypeSizeProperty \"{item.BinaryAttr.TypeSizeName}\" for {item.PropertyInfo.Name} in Struct {bs.Type}:{item.PropertyInfo.DeclaringType} not found(Scheme: {bs.Scheme})");
                }
            }

            if (item.IsBaseType)
            {
                item.BinaryType.GetWriteILCode(item, bs, il, binaryStruct, value, typeSize, buffer, offset, false);
                return;
            }

            var methodBreak = il.DefineLabel("breakWriteMethod");

            var in_value = il.DeclareLocal(item.PropertyInfo.PropertyType);

            //значение вложенного класса
            il.Ldloc(value);
            il.Call(item.PropertyInfo.GetGetMethod());
            il.Stloc(in_value);

            WriteSizeChecker(il, buffer, offset, 2);

            WriteObjectNull(il, methodBreak, in_value, buffer, offset, typeSize);

            CompileWriter(item.BinaryStruct, il, binaryStruct, in_value, buffer, offset, typeSize);

            il.MarkLabel(methodBreak);
            //il.Pop();
        }
예제 #31
0
        private static void BuildJump(TypeBuilder typeBuilder, int n, Context context)
        {
            var method = typeBuilder.DefineMethod("Jump", MethodAttributes.Public | MethodAttributes.Virtual, CallingConventions.HasThis, typeof(MethodCallNode), new[] { typeof(int) });

            using (var il = new GroboIL(method))
            {
                var retNullLabel    = il.DefineLabel("retNull");
                var emittingContext = new MethodJumpEmittingContext
                {
                    context      = context,
                    il           = il,
                    retNullLabel = retNullLabel
                };
                DoBinarySearch(emittingContext, 0, n - 1);
                il.MarkLabel(retNullLabel);
                il.Ldnull();
                il.Ret();
            }
            typeBuilder.DefineMethodOverride(method, typeof(MethodCallNodeEdges).GetMethod(method.Name, BindingFlags.Public | BindingFlags.Instance));
        }