예제 #1
0
        private Func <TestClassA, int> Build1()
        {
            var typeBuilder = Module.DefineType(Guid.NewGuid().ToString(), TypeAttributes.Class | TypeAttributes.Public);
            var method      = typeBuilder.DefineMethod("zzz", MethodAttributes.Public | MethodAttributes.Static, typeof(int), new[] { typeof(TestClassA) });

            using (var il = new GroboIL(method))
            {
                il.Ldarg(0);
                il.Ldfld(typeof(TestClassA).GetField("Y"));
                var y = il.DeclareLocal(typeof(int));
                il.Stloc(y);
                il.Ldarg(0);
                il.Ldfld(typeof(TestClassA).GetField("Z"));
                var z = il.DeclareLocal(typeof(int));
                il.Stloc(z);
                il.Ldloc(y);
                il.Ldloc(z);
                il.Add();
                il.Ret();
            }
            var type          = typeBuilder.CreateType();
            var dynamicMethod = new DynamicMethod(Guid.NewGuid().ToString(), MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, typeof(Func <TestClassA, int>), Type.EmptyTypes, Module, true);

            using (var il = new GroboIL(dynamicMethod))
            {
                il.Ldnull();
                il.Ldftn(type.GetMethod("zzz"));
                il.Newobj(typeof(Func <TestClassA, int>).GetConstructor(new[] { typeof(object), typeof(IntPtr) }));
                il.Ret();
            }
            return(((Func <Func <TestClassA, int> >)dynamicMethod.CreateDelegate(typeof(Func <Func <TestClassA, int> >)))());
        }
예제 #2
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>)));
        }
예제 #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
 public static void WriteOffsetAppend(GroboIL il, GroboIL.Local offset, GroboIL.Local typeSize)
 {
     il.Ldloc(offset);
     il.Ldloc(typeSize);
     il.Add();
     il.Stloc(offset);
 }
예제 #5
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 r = il.DeclareLocal(typeof(sbyte));

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

            il.Ldelem(typeof(byte));
            if (listValue)
            {
                il.Stloc(result);
            }
            else
            {
                il.Stloc(r);
            }

            BinaryStruct.WriteOffsetAppend(il, offset, 1);
            if (!listValue)
            {
                il.Ldloc(result);
                il.Ldloc(r);
                il.Call(prop.Setter, isVirtual: true);
            }
        }
예제 #6
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 r = il.DeclareLocal(typeof(TimeSpan));
            var v = il.DeclareLocal(typeof(double));

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


            il.Ldloc(v);
            il.Call(timeSpanConstructor);

            if (listValue)
            {
                il.Stloc(result);
            }
            else
            {
                il.Stloc(r);
            }

            BinaryStruct.WriteOffsetAppend(il, offset, 8);
            if (!listValue)
            {
                il.Ldloc(result);
                il.Ldloc(r);
                il.Call(prop.Setter, isVirtual: true);
            }
        }
예제 #7
0
 public static void ReadObjectNull(GroboIL il, GroboIL.Label finishMethod, GroboIL.Local buffer, GroboIL.Local offset, GroboIL.Local typeSize)
 {
     il.Ldloc(buffer);
     il.Ldloc(offset);
     il.Ldelem(typeof(byte));
     WriteOffsetAppend(il, offset, 1);
     il.Brtrue(finishMethod);
 }
예제 #8
0
        public void GetWriteILCode(PropertyData prop, BinaryStruct currentStruct, GroboIL il, GroboIL.Local binaryStruct, GroboIL.Local value, GroboIL.Local typeSize, GroboIL.Local buffer, GroboIL.Local offset, bool listValue)
        {
            BinaryStruct.WriteSizeChecker(il, buffer, offset, 8);
            var arr = il.DeclareLocal(typeof(byte[]));
            var v   = il.DeclareLocal(typeof(DateTime));
            var t   = il.DeclareLocal(typeof(TimeSpan));

            if (!listValue)
            {
                il.Ldloc(value);
                var v1 = il.DeclareLocal(typeof(DateTime));
                il.Call(prop.Getter);
                il.Stloc(v1);
                il.Ldloca(v1);
            }
            else
            {
                il.Ldloca(value);
            }

            il.Ldloca(v);
            il.Ldc_I4(1970);
            il.Ldc_I4(1);
            il.Ldc_I4(1);
            il.Ldc_I4(0);
            il.Ldc_I4(0);
            il.Ldc_I4(0);
            il.Ldc_I4(0);
            il.Call(datetimeConstructor);


            il.Ldloc(v);
            il.Call(substractMethod);
            il.Stloc(t);
            il.Ldloca(t);
            il.Call(propertyGetter);

            il.Call(writeBitConverterMethodInfo);
            il.Stloc(arr);

            il.Ldloc(buffer);
            il.Ldloc(offset);
            il.Ldloc(arr);
            il.Ldc_I4(0);
            il.Ldelem(typeof(byte));
            il.Stelem(typeof(byte));

            for (int i = 1; i < 8; i++)
            {
                il.Ldloc(buffer);
                il.Ldloc(offset);
                il.Ldc_I4(i);
                il.Add();
                il.Ldloc(arr);
                il.Ldc_I4(i);
                il.Ldelem(typeof(byte));
                il.Stelem(typeof(byte));
            }
            BinaryStruct.WriteOffsetAppend(il, offset, 8);
        }
        protected override bool EmitInternal(NewExpression node, EmittingContext context, GroboIL.Label returnDefaultValueLabel, ResultType whatReturn, bool extend, out Type resultType)
        {
            context.EmitLoadArguments(node.Arguments.ToArray());
            // note ich: баг решарпера
            // ReSharper disable ConditionIsAlwaysTrueOrFalse
            // ReSharper disable HeuristicUnreachableCode
            GroboIL il = context.Il;

            if (node.Constructor != null)
            {
                il.Newobj(node.Constructor);
            }
            else
            {
                if (node.Type.IsValueType)
                {
                    using (var temp = context.DeclareLocal(node.Type))
                    {
                        il.Ldloca(temp);
                        il.Initobj(node.Type);
                        il.Ldloc(temp);
                    }
                }
                else
                {
                    throw new InvalidOperationException("Missing constructor for type '" + node.Type + "'");
                }
            }
            resultType = node.Type;
            // ReSharper restore ConditionIsAlwaysTrueOrFalse
            // ReSharper restore HeuristicUnreachableCode
            return(false);
        }
예제 #10
0
        private static KeyValuePair <Delegate, IntPtr> GetReader(ReaderMethodBuilderContext context, Type type)
        {
            var method = new DynamicMethod("Read_" + type.Name + "_AndCastToObject_" + Guid.NewGuid(), typeof(void),
                                           new[]
            {
                typeof(IntPtr), typeof(int).MakeByRefType(), typeof(object).MakeByRefType(), typeof(ReaderContext)
            }, context.Context.Module, true);

            using (var il = new GroboIL(method))
            {
                il.Ldarg(2);      // stack: [ref result]
                il.Ldarg(0);      // stack: [ref result, data]
                il.Ldarg(1);      // stack: [ref result, data, ref index]
                var value = il.DeclareLocal(type);
                il.Ldloca(value); // stack: [ref result, data, ref index, ref value]
                il.Ldarg(3);      // stack: [ref result, data, ref index, ref value, context]

                ReaderMethodBuilderContext.CallReader(il, type, context.Context);

                il.Ldloc(value); // stack: [ref result, value]
                if (type.IsValueType)
                {
                    il.Box(type); // stack: [ref result, (object)value]
                }
                else
                {
                    il.Castclass(type);
                }
                il.Stind(typeof(object)); // result = (object)value
                il.Ret();
            }
            var @delegate = method.CreateDelegate(typeof(ReaderDelegate));

            return(new KeyValuePair <Delegate, IntPtr>(@delegate, GroBufHelpers.ExtractDynamicMethodPointer(method)));
        }
예제 #11
0
 public static void WriteOffsetAppend(GroboIL il, GroboIL.Local offset, int len)
 {
     il.Ldloc(offset);
     il.Ldc_I4(len);
     il.Add();
     il.Stloc(offset);
 }
        protected override bool EmitInternal(MemberInitExpression node, EmittingContext context, GroboIL.Label returnDefaultValueLabel, ResultType whatReturn, bool extend, out Type resultType)
        {
            ExpressionEmittersCollection.Emit(node.NewExpression, context, out resultType); // stack: [new obj(args)]
            GroboIL il = context.Il;

            if (!node.Type.IsValueType)
            {
                foreach (MemberAssignment assignment in node.Bindings)
                {
                    il.Dup();
                    context.EmitLoadArguments(assignment.Expression);
                    context.EmitMemberAssign(node.Type, assignment.Member);
                }
            }
            else
            {
                using (var temp = context.DeclareLocal(node.Type))
                {
                    il.Stloc(temp);
                    il.Ldloca(temp);
                    foreach (MemberAssignment assignment in node.Bindings)
                    {
                        il.Dup();
                        context.EmitLoadArguments(assignment.Expression);
                        context.EmitMemberAssign(node.Type, assignment.Member);
                    }
                    // todo или il.Ldobj()?
                    il.Pop();
                    il.Ldloc(temp);
                }
            }
            return(false);
        }
예제 #13
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));
        }
예제 #14
0
        private static TryParseDelegate EmitTryParseDelegate()
        {
            var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(bool),
                                           new[] { typeof(string), typeof(DateTimeTypeCode), typeof(object).MakeByRefType() }, typeof(string), true);
            var xsdDateTimeType = typeof(XmlReader).Assembly.GetTypes().FirstOrDefault(type => type.Name == "XsdDateTime");

            if (xsdDateTimeType == null)
            {
                throw new InvalidOperationException("The type 'XsdDateTime' is not found");
            }
            var tryParseMethod = xsdDateTimeType.GetMethod("TryParse", BindingFlags.Static | BindingFlags.NonPublic);

            if (tryParseMethod == null)
            {
                throw new InvalidOperationException("The method 'XsdDateTime.TryParse' is not found");
            }
            using (var il = new GroboIL(method))
            {
                il.Ldarg(0); // stack: [value]
                il.Ldarg(1); // stack: [value, typeCode]
                var strongBoxType = typeof(StrongBox <>).MakeGenericType(xsdDateTimeType);
                var strongBox     = il.DeclareLocal(strongBoxType);
                il.Ldarg(2);                                                                             // stack: [value, typeCode, ref result]
                il.Newobj(strongBoxType.GetConstructor(Type.EmptyTypes));                                // stack: [value, typeCode, ref result, new StrongBox<XsdDateTime>()]
                il.Dup();
                il.Stloc(strongBox);                                                                     // strongBox = new StrongBox<XsdDateTime>(); stack: [value, typeCode, ref result, strongBox]
                il.Stind(typeof(object));                                                                // result = strongBox; stack: [value, typeCode]
                il.Ldloc(strongBox);                                                                     // stack: [value, typeCode, strongBox]
                il.Ldflda(strongBoxType.GetField("Value", BindingFlags.Instance | BindingFlags.Public)); // stack: [value, typeCode, ref strongBox.Value]
                il.Call(tryParseMethod);                                                                 // stack: [XsdDateTime.TryParse(value, typeCode, ref strongBox.Value]
                il.Ret();
            }
            return((TryParseDelegate)method.CreateDelegate(typeof(TryParseDelegate)));
        }
예제 #15
0
 private static void EmitMinusMinusX(this GroboIL il, GroboIL.Local intLocal)
 {
     il.Ldloc(intLocal);
     il.Ldc_I4(1);
     il.Sub();
     il.Dup();
     il.Stloc(intLocal);
 }
예제 #16
0
 private static void EmitXPlusPlus(this GroboIL il, GroboIL.Local intLocal)
 {
     il.Ldloc(intLocal);
     il.Dup();
     il.Ldc_I4(1);
     il.Add();
     il.Stloc(intLocal);
 }
예제 #17
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);
        }
예제 #18
0
        public void GetWriteILCode(PropertyData prop, BinaryStruct currentStruct, GroboIL il, GroboIL.Local binaryStruct, GroboIL.Local value, GroboIL.Local typeSize, GroboIL.Local buffer, GroboIL.Local offset, bool listValue)
        {
            BinaryStruct.WriteSizeChecker(il, buffer, offset, 1);

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

            il.Ldloc(value);
            if (!listValue)
            {
                il.Call(prop.Getter);
            }

            il.Stelem(typeof(byte));

            BinaryStruct.WriteOffsetAppend(il, offset, 1);
        }
예제 #19
0
        public void GetWriteILCode(PropertyData prop, BinaryStruct currentStruct, GroboIL il, GroboIL.Local binaryStruct, GroboIL.Local value, GroboIL.Local typeSize, GroboIL.Local buffer, GroboIL.Local offset, bool listValue)
        {
            BinaryStruct.WriteSizeChecker(il, buffer, offset, 2);
            var arr = il.DeclareLocal(typeof(byte[]));

            il.Ldloc(value);
            if (!listValue)
            {
                il.Call(prop.Getter);
            }
            il.Dup();
            il.Pop();
            il.Call(writeBitConverterMethodInfo);
            il.Stloc(arr);

            il.Ldloc(buffer);
            il.Ldloc(offset);
            il.Ldloc(arr);
            il.Ldc_I4(0);
            il.Ldelem(typeof(byte));
            il.Stelem(typeof(byte));

            for (int i = 1; i < 2; i++)
            {
                il.Ldloc(buffer);
                il.Ldloc(offset);
                il.Ldc_I4(i);
                il.Add();
                il.Ldloc(arr);
                il.Ldc_I4(i);
                il.Ldelem(typeof(byte));
                il.Stelem(typeof(byte));
            }
            BinaryStruct.WriteOffsetAppend(il, offset, 2);
        }
예제 #20
0
 public static void WriteSizeChecker(GroboIL il, GroboIL.Local buffer, GroboIL.Local offset, GroboIL.Local typeSize)
 {
     //il.Ldloca(buffer);
     //il.Ldloc(offset);
     //il.Ldloc(typeSize);
     //il.Call(resizeMethod);
     il.Ldloc(typeSize);
     Resize(il, buffer, offset);
 }
예제 #21
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);
        }
예제 #22
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));
        }
예제 #23
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>)));
        }
예제 #24
0
        public static void WriteObjectNull(GroboIL il, GroboIL.Label finishMethod, GroboIL.Local buffer, GroboIL.Local offset, GroboIL.Local typeSize)
        {
            var _null = il.DeclareLocal(typeof(bool));

            il.Ldnull();
            il.Ceq();
            il.Stloc(_null);

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

            il.Ldloc(_null);

            il.Stelem(typeof(byte));

            WriteOffsetAppend(il, offset, 1);

            il.Ldloc(_null);
            il.Brtrue(finishMethod);
        }
예제 #25
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);
        }
예제 #26
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());
            }
        }
예제 #27
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>)));
        }
예제 #28
0
        public static void CompileReader(BinaryStruct bs, GroboIL il, GroboIL.Local binaryStruct, GroboIL.Local buffer, GroboIL.Local offset, GroboIL.Local result, GroboIL.Local typeSize)
        {
            if (bs.PropertyList.Count > 0)
            {
                foreach (var item in bs.PropertyList)
                {
                    if (item.IsBaseType)
                    {
                        item.BinaryType.GetReadILCode(item, bs, il, binaryStruct, buffer, result, typeSize, offset, false);
                        continue;
                    }
                    var methodBreak = il.DefineLabel("breakReadMethod");

                    ReadObjectNull(il, methodBreak, buffer, offset, typeSize);

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

                    var constr = BinaryStruct.GetConstructor(item.PropertyInfo.PropertyType, null);

                    if (constr == null)
                    {
                        throw new Exception($"Type {item.PropertyInfo.PropertyType} not have constructor with not parameters");
                    }

                    il.Newobj(constr);
                    il.Stloc(in_value);


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

                    il.Ldloc(result);
                    il.Ldloc(in_value);
                    il.Call(item.Setter, isVirtual: true);

                    il.MarkLabel(methodBreak);
                    //il.Pop();
                }
            }
        }
예제 #29
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);
        }
        private static void EmitDefaultTypeValue(GroboIL il, Type type)
        {
            switch (Type.GetTypeCode(type))
            {
            case TypeCode.Byte:
            case TypeCode.SByte:
            case TypeCode.Boolean:
            case TypeCode.Char:
            case TypeCode.Int16:
            case TypeCode.UInt16:
            case TypeCode.Int32:
            case TypeCode.UInt32:
                il.Ldc_I4(0);
                return;

            case TypeCode.Int64:
            case TypeCode.UInt64:
                il.Ldc_I8(0);
                return;

            case TypeCode.Single:
                il.Ldc_R4(0f);
                return;

            case TypeCode.Double:
                il.Ldc_R8(0d);
                return;
            }

            if (type.IsPointer || type == typeof(UIntPtr) || type == typeof(IntPtr))
            {
                il.Ldc_IntPtr(IntPtr.Zero);
                il.Conv <UIntPtr>();
            }
            else if (type.IsEnum)
            {
                EmitDefaultTypeValue(il, Enum.GetUnderlyingType(type));
            }
            else if (type.IsValueType)
            {
                var local = il.DeclareLocal(type);
                il.Ldloca(local);
                il.Initobj(type);
                il.Ldloc(local);
            }
            else
            {
                il.Ldnull();
            }
        }