예제 #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());
            }
        }
예제 #2
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);
            }
        }
예제 #3
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);
        }
예제 #4
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);
        }
예제 #5
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 }));
        }
예제 #6
0
 private static void EmitBne(GroboIL il, MethodInfo getMethod, GroboIL.Label returnFalse)
 {
     // a.Property == b.Property
     il.Ldarg(0);
     il.Call(getMethod);
     il.Ldarg(1);
     il.Call(getMethod);
     il.Bne_Un(returnFalse);
 }
예제 #7
0
 private static void EmitStatic(GroboIL il, MethodInfo getMethod, MethodInfo staticMethod, GroboIL.Label returnFalse)
 {
     // Equals(a.Property, b.Property)
     il.Ldarg(0);
     il.Call(getMethod);
     il.Ldarg(1);
     il.Call(getMethod);
     il.Call(staticMethod);
     il.Brfalse(returnFalse);
 }
예제 #8
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);
        }
예제 #9
0
 private void ProcessFuncParameter(ParameterInfo parameterInfo, GroboIL il, Type parameterType)
 {
     if (parameterInfo.Name.StartsWith("get", StringComparison.InvariantCultureIgnoreCase))
     {
         il.Call(funcHelper.GetBuildGetFuncMethodInfo(parameterType));
     }
     else if (parameterInfo.Name.StartsWith("create", StringComparison.InvariantCultureIgnoreCase))
     {
         il.Call(funcHelper.GetBuildCreateFuncMethodInfo(parameterInfo.ParameterType));
     }
     else
     {
         throw new NotSupportedException($"Failed to resolve func parameter {parameterInfo.Name} of type {parameterType}. Func parameter names should have 'get' or 'create' prefix.");
     }
 }
예제 #10
0
        private static void EmitInstance(GroboIL il, MethodInfo getMethod, MethodInfo instanceMethod, GroboIL.Label returnFalse)
        {
            // a.Property.Equals(b.Property)
            var type  = getMethod.ReturnType;
            var local = il.DeclareLocal(type);

            il.Ldarg(0);
            il.Call(getMethod);
            il.Stloc(local);
            il.Ldloca(local);
            il.Ldarg(1);
            il.Call(getMethod);
            il.Call(instanceMethod, type);
            il.Brfalse(returnFalse);
        }
예제 #11
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);
            }
        }
예제 #12
0
        public static TryGetValueDelegate <T> Build <T>(string[] keys, T[] values)
        {
            var trie   = BuildTrie(keys);
            var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(bool), new[] { typeof(T[]), typeof(string), typeof(T).MakeByRefType() },
                                           typeof(string), true);

            using (var il = new GroboIL(method))
            {
                il.Ldarg(2);                 // stack: [ref value]
                il.Initobj(typeof(T));       // value = default(value); stack: []
                var index = il.DeclareLocal(typeof(int), "index");
                il.Ldc_I4(0);                // stack: [0]
                il.Stloc(index);             // index = 0; stack: []
                var length = il.DeclareLocal(typeof(int), "length");
                il.Ldarg(1);                 // stack: [key]
                il.Call(stringLengthGetter); // stack: [key.Length]
                il.Stloc(length);            // length = key.Length; stack: []
                var context = new EmittingContext
                {
                    Il      = il,
                    Index   = index,
                    Length  = length,
                    CurChar = il.DeclareLocal(typeof(char))
                };
                InlineTrie <T>(trie, context);
            }
            return((TryGetValueDelegate <T>)method.CreateDelegate(typeof(TryGetValueDelegate <T>), values));
        }
예제 #13
0
        private static Delegate BuildInvoker(MethodInfo method)
        {
            var parameterTypes = new List <Type>();

            if (!method.IsStatic)
            {
                parameterTypes.Add(method.ReflectedType);
            }
            parameterTypes.AddRange(method.GetParameters().Select(p => p.ParameterType));
            var prefix = "MethodInvoker";

            if (method.IsStatic)
            {
                prefix += "$" + Formatter.Format(method.DeclaringType);
            }
            var dynamicMethod = new DynamicMethod(prefix + "$" + method.Name + "$" + Guid.NewGuid(), method.ReturnType, parameterTypes.ToArray(), typeof(MethodInvokerBuilder), true);

            using (var il = new GroboIL(dynamicMethod))
            {
                for (var i = 0; i < parameterTypes.Count; ++i)
                {
                    il.Ldarg(i);
                }
                il.Call(method);
                il.Ret();
            }
            return(dynamicMethod.CreateDelegate(Extensions.GetDelegateType(parameterTypes.ToArray(), method.ReturnType)));
        }
예제 #14
0
        private static Func <object, object, int> EmitCompareDelegate()
        {
            var method          = new DynamicMethod(Guid.NewGuid().ToString(), typeof(int), new[] { typeof(object), typeof(object) }, 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 compareMethod = xsdDateTimeType.GetMethod("Compare", BindingFlags.Static | BindingFlags.Public);

            if (compareMethod == null)
            {
                throw new InvalidOperationException("The method 'XsdDateTime.Compare' is not found");
            }
            using (var il = new GroboIL(method))
            {
                var strongBoxType = typeof(StrongBox <>).MakeGenericType(xsdDateTimeType);
                var valueField    = strongBoxType.GetField("Value", BindingFlags.Instance | BindingFlags.Public);
                il.Ldarg(0);                 // stack: [arg0]
                il.Castclass(strongBoxType); // stack: [(StrongBox<XsdDateTime>)arg0]
                il.Ldfld(valueField);        // stack: [((StrongBox<XsdDateTime>)arg0).Value]
                il.Ldarg(1);                 // stack: [((StrongBox<XsdDateTime>)arg0).Value, arg1]
                il.Castclass(strongBoxType); // stack: [((StrongBox<XsdDateTime>)arg0).Value, (StrongBox<XsdDateTime>)arg1]
                il.Ldfld(valueField);        // stack: [((StrongBox<XsdDateTime>)arg0).Value, ((StrongBox<XsdDateTime>)arg1).Value]
                il.Call(compareMethod);      // stack: [XsdDateTime.CompareTo(((StrongBox<XsdDateTime>)arg0).Value, ((StrongBox<XsdDateTime>)arg1).Value)]
                il.Ret();
            }
            return((Func <object, object, int>)method.CreateDelegate(typeof(Func <object, object, int>)));
        }
예제 #15
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)));
        }
예제 #16
0
        private ITest BuildDelegate()
        {
            var action      = Build();
            var typeBuilder = Module.DefineType(Guid.NewGuid().ToString(), TypeAttributes.Class | TypeAttributes.Public);
            var actionField = typeBuilder.DefineField("action", typeof(Action), FieldAttributes.Private | FieldAttributes.InitOnly);
            var constructor = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, new[] { typeof(Action) });

            using (var il = new GroboIL(constructor))
            {
                il.Ldarg(0);
                il.Ldarg(1);
                il.Stfld(actionField);
                il.Ret();
            }
            var method = typeBuilder.DefineMethod("DoNothing", MethodAttributes.Public | MethodAttributes.Virtual, typeof(void), Type.EmptyTypes);

            using (var il = new GroboIL(method))
            {
                il.Ldarg(0);
                il.Ldfld(actionField);
                il.Call(typeof(Action).GetMethod("Invoke", Type.EmptyTypes), typeof(Action));
                il.Ret();
            }
            typeBuilder.DefineMethodOverride(method, typeof(ITest).GetMethod("DoNothing"));
            typeBuilder.AddInterfaceImplementation(typeof(ITest));
            var type = typeBuilder.CreateType();

            return((ITest)Activator.CreateInstance(type, new object[] { action.Item1 }));
        }
예제 #17
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>)));
        }
예제 #18
0
        private static void EmitNullableEquals(GroboIL il, MethodInfo getMethod, GroboIL.Label returnFalse)
        {
            // a.Equals(b)
            var type  = getMethod.ReturnType;
            var local = il.DeclareLocal(type);

            il.Ldarg(0);
            il.Call(getMethod);
            il.Stloc(local);
            il.Ldloca(local);
            il.Ldarg(1);
            il.Call(getMethod);
            il.Box(type);
            il.Call(ObjectEquals, type);
            il.Brfalse(returnFalse);
        }
예제 #19
0
        private ITest BuildCall()
        {
            var typeBuilder     = Module.DefineType(Guid.NewGuid().ToString(), TypeAttributes.Class | TypeAttributes.Public);
            var doNothingMethod = typeBuilder.DefineMethod("DoNothingImpl", MethodAttributes.Public, typeof(void), Type.EmptyTypes);

            using (var il = new GroboIL(doNothingMethod))
            {
                il.Ldfld(xField);
                il.Ldc_I4(1);
                il.Add();
                il.Stfld(xField);
                il.Ret();
            }
            var method = typeBuilder.DefineMethod("DoNothing", MethodAttributes.Public | MethodAttributes.Virtual, typeof(void), Type.EmptyTypes);

            using (var il = new GroboIL(method))
            {
                il.Ldarg(0);
                il.Call(doNothingMethod);
                il.Ret();
            }
            typeBuilder.DefineMethodOverride(method, typeof(ITest).GetMethod("DoNothing"));
            typeBuilder.AddInterfaceImplementation(typeof(ITest));
            var type = typeBuilder.CreateType();

            return((ITest)Activator.CreateInstance(type));
        }
예제 #20
0
        private static Func <object, MethodBase, SignatureHelper, uint> BuildGetTokenFor()
        {
            var parameterTypes = new[] { typeof(object), typeof(MethodBase), typeof(SignatureHelper) };
            var method         = new DynamicMethod(Guid.NewGuid().ToString(), typeof(uint), parameterTypes, typeof(string), true);

            using (var il = new GroboIL(method))
            {
                il.Ldarg(0);                         // stack: [scope]
                il.Castclass(dynamicScopeType);
                il.Ldarg(1);                         // stack: [scope, method]
                il.Castclass(runtimeMethodInfoType); // stack: [scope, (RuntimeMethodInfo)method]
                il.Ldarg(2);                         // stack: [scope, (RuntimeMethodInfo)method, signature]

                var constructor = varArgsMethodType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { runtimeMethodInfoType, typeof(SignatureHelper) }, null);
                if (constructor == null)
                {
                    throw new MissingMethodException("VarArgsMethod", ".ctor");
                }
                var getTokenForMethod = dynamicScopeType.GetMethod("GetTokenFor", BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { varArgsMethodType }, null);
                if (getTokenForMethod == null)
                {
                    throw new MissingMethodException("DynamicScope", "GetTokenFor");
                }

                il.Newobj(constructor);     // stack: [scope, new VarArgsMethod((RuntimeMethodInfo)method, signature)]
                il.Call(getTokenForMethod); // stack: [scope.GetTokenFor(new VarArgsMethod((RuntimeMethodInfo)method, signature))]

                il.Ret();
            }

            return((Func <object, MethodBase, SignatureHelper, uint>)method.CreateDelegate(typeof(Func <object, MethodBase, SignatureHelper, uint>)));
        }
예제 #21
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());
            }
        }
예제 #22
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(Vector3));

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

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

            il.Ldloc(buffer);
            il.Ldloc(offset);
            il.Ldc_I4(4);
            il.Add();
            il.Call(readBitConverterMethodInfo);

            il.Ldloc(buffer);
            il.Ldloc(offset);
            il.Ldc_I4(8);
            il.Add();
            il.Call(readBitConverterMethodInfo);

            il.Call(initialConstructor);

            //if (listValue)
            //    il.Stloc(result);
            //else
            //    il.Stloc(r);

            BinaryStruct.WriteOffsetAppend(il, offset, 12);

            if (!listValue)
            {
                il.Ldloc(result);
                il.Ldloc(r);
                il.Call(prop.Setter, isVirtual: true);
            }
        }
예제 #23
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);
        }
예제 #24
0
 private void ProcessFuncParameter(ParameterInfo parameterInfo, GroboIL il, Type parameterType)
 {
     if (parameterInfo.Name.StartsWith("get", StringComparison.InvariantCultureIgnoreCase))
     {
         il.Call(funcHelper.GetBuildGetFuncMethodInfo(parameterType));
     }
     else if (parameterInfo.Name.StartsWith("create", StringComparison.InvariantCultureIgnoreCase))
     {
         il.Call(funcHelper.GetBuildCreateFuncMethodInfo(parameterInfo.ParameterType));
     }
     else
     {
         throw new NotSupportedException(
                   string.Format(
                       "Невозможно разрешить параметр '{0}' типа {1}. Должен иметь имя с префиксом 'get' или 'create'",
                       parameterInfo.Name, parameterType));
     }
 }
        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);
        }
예제 #26
0
파일: Test.cs 프로젝트: qinfengzhu/gremit
        public void TestCallFormat()
        {
            var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(string), new[] { typeof(string), typeof(decimal), typeof(decimal) }, typeof(string), true);
            var il     = new GroboIL(method);

            il.Ldarg(0);
            il.Ldarg(1);
            il.Ldarg(2);
            Assert.Throws <InvalidOperationException>(() => il.Call(HackHelpers.GetMethodDefinition <string>(s => string.Format(s, "", ""))));
        }
예제 #27
0
        public void Test_StaticMethod_NonVoid_NoParameters()
        {
            var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(int), Type.EmptyTypes, typeof(string), true);

            using (var il = new GroboIL(method))
            {
                il.Call(HackHelpers.GetMethodDefinition <int>(x => NonVoidStaticMethod_NoParameters()));
                il.Ret();
            }
        }
예제 #28
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>)));
        }
        public static TTarget WithDefaultParametersPassed <TTarget>(MethodInfo sourceMethod) where TTarget : Delegate
        {
            var targetMethod = typeof(TTarget).GetMethod("Invoke");

            if (targetMethod.ReturnType != sourceMethod.ReturnType)
            {
                throw new ArgumentException("Return must be the same for the source and the target.");
            }

            var sourceParameters = sourceMethod.GetParameters();
            var targetParameters = targetMethod.GetParameters();

            //Fast path for cases where we do not need to create a shim
            if (!sourceParameters.Any(x => x.HasDefaultValue))
            {
                return((TTarget)Delegate.CreateDelegate(typeof(TTarget), sourceMethod));
            }

            var shim = new DynamicMethod(Guid.NewGuid().ToString(), targetMethod.ReturnType, targetMethod.GetParameters().Select(x => x.ParameterType).ToArray());

            using (var il = new GroboIL(shim))
            {
                var j = 0;
                for (int i = 0; i < sourceParameters.Length; i++)
                {
                    var sourceParameter = sourceParameters[i];
                    if (sourceParameter.HasDefaultValue)
                    {
                        EmitDefaultParameterValue(il, sourceParameter);
                    }
                    else
                    {
                        if (targetParameters[j].ParameterType == sourceParameter.ParameterType)
                        {
                            il.Ldarg(j);
                            j++;
                        }
                        else
                        {
                            throw new ArgumentException($"The type of the required source parameter {sourceParameter} does not match that of the target {targetParameters[j]}.");
                        }
                    }
                }

                if (j != targetParameters.Length)
                {
                    throw new ArgumentException("The parameters of target must be exactly the required parameters of source.");
                }

                il.Call(sourceMethod);
                il.Ret();
            }

            return((TTarget)shim.CreateDelegate(typeof(TTarget)));
        }
예제 #30
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));
        }
예제 #31
0
 private static void EmitInstance(GroboIL il, MethodInfo getMethod, MethodInfo instanceMethod, GroboIL.Label returnFalse)
 {
     // a.Property.Equals(b.Property)
     var type = getMethod.ReturnType;
     var local = il.DeclareLocal(type);
     il.Ldarg(0);
     il.Call(getMethod);
     il.Stloc(local);
     il.Ldloca(local);
     il.Ldarg(1);
     il.Call(getMethod);
     il.Call(instanceMethod, type);
     il.Brfalse(returnFalse);
 }
예제 #32
0
 private static void EmitBne(GroboIL il, MethodInfo getMethod, GroboIL.Label returnFalse)
 {
     // a.Property == b.Property
     il.Ldarg(0);
     il.Call(getMethod);
     il.Ldarg(1);
     il.Call(getMethod);
     il.Bne_Un(returnFalse);
 }
예제 #33
0
 private static void EmitStatic(GroboIL il, MethodInfo getMethod, MethodInfo staticMethod, GroboIL.Label returnFalse)
 {
     // Equals(a.Property, b.Property)
     il.Ldarg(0);
     il.Call(getMethod);
     il.Ldarg(1);
     il.Call(getMethod);
     il.Call(staticMethod);
     il.Brfalse(returnFalse);
 }
예제 #34
0
        private static void EmitNullableBne(GroboIL il, MethodInfo getMethod, GroboIL.Label returnFalse)
        {
            // a.GetValueOrDefault() == b.GetValueOrDefault() && a.HasValue == b.HasValue;
            var type = getMethod.ReturnType;
            var getValueOrDefault = type.GetMethod("GetValueOrDefault", new Type[0]);
            var hasValue = type.GetMethod("get_HasValue");
            var a = il.DeclareLocal(type);
            var b = il.DeclareLocal(type);

            il.Ldarg(0);
            il.Call(getMethod);
            il.Stloc(a);
            il.Ldarg(1);
            il.Call(getMethod);
            il.Stloc(b);

            il.Ldloca(a);
            il.Call(getValueOrDefault);
            il.Ldloca(b);
            il.Call(getValueOrDefault);
            il.Bne_Un(returnFalse);

            il.Ldloca(a);
            il.Call(hasValue);
            il.Ldloca(b);
            il.Call(hasValue);
            il.Bne_Un(returnFalse);
        }
예제 #35
0
 private static void EmitNullableEquals(GroboIL il, MethodInfo getMethod, GroboIL.Label returnFalse)
 {
     // a.Equals(b)
     var type = getMethod.ReturnType;
     var local = il.DeclareLocal(type);
     il.Ldarg(0);
     il.Call(getMethod);
     il.Stloc(local);
     il.Ldloca(local);
     il.Ldarg(1);
     il.Call(getMethod);
     il.Box(type);
     il.Call(ObjectEquals, type);
     il.Brfalse(returnFalse);
 }