예제 #1
0
        public static CaseDelegate CompileCases(ErrorSink errors, Case[] cases, string name)
        {
            var ab = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(name), AssemblyBuilderAccess.RunAndCollect);
            var mb = ab.DefineDynamicModule("MainModule");
            var cb = mb.DefineType("Cases");

            var methods = new List <MethodInfo>();

            for (int i = 0; i < cases.Length; i++)
            {
                var method = cb.DefineMethod($"Case{i}", MethodAttributes.Private | MethodAttributes.Static, typeof(void), new[] { typeof(IMachine) });

                using (var il = new GroboIL(method))
                {
                    var visitor = new CompilerVisitor(il, errors);
                    visitor.Visit(cases[i]);

                    il.Ret();

                    Console.WriteLine(il.GetILCode());
                }

                methods.Add(method);
            }

            CreateRunAllMethod(cb, methods);

            var type = cb.CreateType();

            return((CaseDelegate)type.GetMethod("RunAll").CreateDelegate(typeof(CaseDelegate)));
        }
예제 #2
0
        public void TestDifferentPathsGeneric()
        {
            var assembly          = AppDomain.CurrentDomain.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());
            }
        }
예제 #3
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(byte));

            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);
            }
        }
예제 #4
0
        protected void SaveOrCheck(GroboIL il, EvaluationStack stack, GroboIL.Label label)
        {
            ESType[] labelStack;
            if (!il.labelStacks.TryGetValue(label, out labelStack))
            {
                il.labelStacks.Add(label, stack.Reverse().ToArray());
                Propogate(il, il.ilCode.GetLabelLineNumber(label), stack);
            }
            else
            {
                ESType[] merged;
                var      comparisonResult = CompareStacks(stack.Reverse().ToArray(), labelStack, out merged);
                switch (comparisonResult)
                {
                case StacksComparisonResult.Equal:
                    return;

                case StacksComparisonResult.Inconsistent:
                    ThrowError(il, string.Format("Inconsistent stack for the label '{0}'{1}Stack #1: {2}{1}Stack #2: {3}", label.Name, Environment.NewLine, stack, new EvaluationStack(labelStack)));
                    break;

                case StacksComparisonResult.Equivalent:
                    il.labelStacks[label] = merged;
                    Propogate(il, il.ilCode.GetLabelLineNumber(label), new EvaluationStack(merged));
                    break;
                }
            }
        }
예제 #5
0
 protected static void CheckNotEmpty(GroboIL il, EvaluationStack stack, Func <string> message)
 {
     if (stack.Count == 0)
     {
         ThrowError(il, message());
     }
 }
예제 #6
0
 protected static void CheckCanBeAssigned(GroboIL il, Type to, Type from)
 {
     if (!CanBeAssigned(to, from))
     {
         ThrowError(il, string.Format("Unable to set a value of type '{0}' to an instance of type '{1}'", Formatter.Format(from), Formatter.Format(to)));
     }
 }
예제 #7
0
        private SizeCounterDelegate BuildCounter(Type type, bool ignoreCustomSerialization)
        {
            IntPtr counter = GetCounter(type, ignoreCustomSerialization);

            var dynamicMethod = new DynamicMethod(Guid.NewGuid().ToString(), typeof(int), new[] { typeof(object), typeof(bool), typeof(WriterContext) }, GetType(), true);

            using (var il = new GroboIL(dynamicMethod))
            {
                il.Ldarg(0); // stack: [obj]
                if (type.IsValueType)
                {
                    il.Unbox_Any(type); // stack: [(type)obj]
                }
                else
                {
                    il.Castclass(type);                                                                                  // stack: [(type)obj]
                }
                il.Ldarg(1);                                                                                             // stack: [(type)obj, writeEmpty]
                il.Ldarg(2);                                                                                             // stack: [(type)obj, writeEmpty, context]
                il.Ldc_IntPtr(counter);                                                                                  // stack: [(type)obj, writeEmpty, context, counter]
                il.Calli(CallingConventions.Standard, typeof(int), new[] { type, typeof(bool), typeof(WriterContext) }); // counter((type)obj, writeEmpty, context); stack: []
                il.Ret();
            }

            return((SizeCounterDelegate)dynamicMethod.CreateDelegate(typeof(SizeCounterDelegate)));
        }
예제 #8
0
 protected static void CheckNotStruct(GroboIL il, ESType type)
 {
     if (ToCLIType(type) == CLIType.Struct)
     {
         ThrowError(il, string.Format("Struct of type '{0}' is not valid at this point", type));
     }
 }
예제 #9
0
        private WriterDelegate BuildWriter(Type type, bool ignoreCustomSerialization)
        {
            IntPtr writer = GetWriter(type, ignoreCustomSerialization);

            var dynamicMethod = new DynamicMethod(Guid.NewGuid().ToString(), typeof(void), new[] { typeof(object), typeof(bool), typeof(IntPtr), typeof(int).MakeByRefType(), typeof(WriterContext) }, module, true);

            using (var il = new GroboIL(dynamicMethod))
            {
                il.Ldarg(0); // stack: [obj]
                if (type.IsValueType)
                {
                    il.Unbox_Any(type); // stack: [(type)obj]
                }
                else
                {
                    il.Castclass(type);                                                                                                                                // stack: [(type)obj]
                }
                il.Ldarg(1);                                                                                                                                           // stack: [(type)obj, writeEmpty]
                il.Ldarg(2);                                                                                                                                           // stack: [(type)obj, writeEmpty, result]
                il.Ldarg(3);                                                                                                                                           // stack: [(type)obj, writeEmpty, result, ref index]
                il.Ldarg(4);                                                                                                                                           // stack: [(type)obj, writeEmpty, result, ref index, context]
                il.Ldc_IntPtr(writer);
                il.Calli(CallingConventions.Standard, typeof(void), new[] { type, typeof(bool), typeof(IntPtr), typeof(int).MakeByRefType(), typeof(WriterContext) }); // writer.write<T>((type)obj, writeEmpty, result, ref index, context); stack: []
                il.Ret();
            }

            return((WriterDelegate)dynamicMethod.CreateDelegate(typeof(WriterDelegate)));
        }
예제 #10
0
        private void TestSuccess(Type type1, Type type2)
        {
            var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(void), new[] { type1, type2, }.Where(type => type != null).ToArray(), typeof(string), true);

            using (var il = new GroboIL(method))
            {
                var index = 0;
                if (type1 != null)
                {
                    il.Ldarg(index++);
                }
                else
                {
                    il.Ldnull();
                }
                if (type2 != null)
                {
                    il.Ldarg(index++);
                }
                else
                {
                    il.Ldnull();
                }
                il.Sub();
                il.Pop();
                il.Ret();
                Console.WriteLine(il.GetILCode());
            }
        }
예제 #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);
 }
예제 #12
0
 public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack)
 {
     if (stack.Count != 0)
     {
         throw new InvalidOperationException("The evaluation stack must be empty in order to perform the 'jmp' instruction\r\n" + il.GetILCode());
     }
 }
예제 #13
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 }));
        }
예제 #14
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[]));

            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 < 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);
        }
예제 #15
0
 public static void WriteOffsetAppend(GroboIL il, GroboIL.Local offset, GroboIL.Local typeSize)
 {
     il.Ldloc(offset);
     il.Ldloc(typeSize);
     il.Add();
     il.Stloc(offset);
 }
예제 #16
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);
            }
        }
예제 #17
0
        public static Type GenerateClass(ClassDescription description)
        {
            var             name            = new AssemblyName("MyAssembly");
            AssemblyBuilder assemblyBuilder =
                Thread.GetDomain().DefineDynamicAssembly(
                    name, AssemblyBuilderAccess.RunAndSave);
            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(
                name.Name, name.Name + ".dll");
            TypeBuilder typeBuilder = moduleBuilder.DefineType(
                description.TypeName, TypeAttributes.Class | TypeAttributes.Public);

            foreach (var constructorDescr in description.Constructors)
            {
                var staticOrDynamicAttr =
                    constructorDescr.StaticOrDynamic == StaticOrDynamic.Static ?
                    MethodAttributes.Static : MethodAttributes.Public;
                // второй вариант по сути ничего не добавляет, но атрибута Dynamic нет

                var inTypes = constructorDescr.InputTypes
                              .Select(typeName => description.AllTypes[typeName].RealType)
                              .ToArray();

                typeBuilder.DefineConstructor(
                    MethodAttributes.Public | staticOrDynamicAttr,
                    CallingConventions.Standard,
                    inTypes);
            }


            foreach (var methodDescr in description.Methods)
            {
                var staticOrDynamicAttr =
                    methodDescr.StaticOrDynamic == StaticOrDynamic.Static ?
                    MethodAttributes.Static : MethodAttributes.Public;

                var outType = description.AllTypes[methodDescr.OutputType].RealType;
                var inTypes = methodDescr.InputTypes
                              .Select(typeName => description.AllTypes[typeName].RealType)
                              .ToArray();

                var method = typeBuilder.DefineMethod(
                    methodDescr.MethodName,
                    MethodAttributes.Public | staticOrDynamicAttr,
                    outType,
                    inTypes);


                GroboIL iLgenerator = new GroboIL(method);
                iLgenerator.Newobj(new NotImplementedException()
                                   .GetType()
                                   .GetConstructors()[0]);
                iLgenerator.Throw();
            }

            var type = typeBuilder.CreateType();

            assemblyBuilder.Save(name.Name + ".dll");
            return(type);
        }
예제 #18
0
        public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack)
        {
            var type = ((TypeILInstructionParameter)parameter).Type;

            CheckNotEmpty(il, stack, () => "An object must be put onto the evaluation stack in order to perform the 'unbox_any' instruction");
            CheckCanBeAssigned(il, typeof(object), stack.Pop());
            stack.Push(type);
        }
예제 #19
0
        public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack)
        {
            var type = ((TypeILInstructionParameter)parameter).Type;

            CheckNotEmpty(il, stack, () => "In order to perform the 'newarr' instruction a length of an array must be loaded onto the evaluation stack");
            CheckCanBeAssigned(il, typeof(int), stack.Pop());
            stack.Push(type.MakeArrayType());
        }
예제 #20
0
 public ReaderMethodBuilderContext(ReaderTypeBuilderContext context, GroboIL il, bool referenceType)
 {
     Context  = context;
     Il       = il;
     TypeCode = il.DeclareLocal(typeof(int));
     Length   = il.DeclareLocal(typeof(uint));
     Index    = referenceType ? il.DeclareLocal(typeof(int)) : null;
 }
예제 #21
0
        public void Test_ldvirtftn3()
        {
            var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(void), Type.EmptyTypes, typeof(string), true);
            var il     = new GroboIL(method);

            il.Newobj(typeof(C2).GetConstructor(Type.EmptyTypes));
            Assert.Throws <InvalidOperationException>(() => il.Ldvirtftn(typeof(I1).GetMethod("Zzz")));
        }
예제 #22
0
        public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack)
        {
            var type = ((TypeILInstructionParameter)parameter).Type;

            CheckNotEmpty(il, stack, () => "In order to perform the 'isinst' instruction an instance must be put onto the evaluation stack");
            CheckCanBeAssigned(il, typeof(object), stack.Pop());
            stack.Push(type.IsValueType ? typeof(object) : type);
        }
예제 #23
0
        public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack)
        {
            var type = ((TypeILInstructionParameter)parameter).Type;

            CheckNotEmpty(il, stack, () => "To perform the 'box' instruction load a value on the evaluation stack");
            CheckCanBeAssigned(il, type, stack.Pop());
            stack.Push(type.IsEnum ? typeof(Enum) : typeof(object));
        }
예제 #24
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);
 }
예제 #25
0
        private GroboIL.Local EmitDictDeclaration(GroboIL il)
        {
            il.Newobj(typeof(Dictionary <string, object>).GetConstructor(new Type[0]));
            var dict = il.DeclareLocal(typeof(Dictionary <string, object>), "dict");

            il.Stloc(dict);
            return(dict);
        }
예제 #26
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);
 }
예제 #27
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);
 }
예제 #28
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);
 }
예제 #29
0
 public override void Mutate(GroboIL il, ILInstructionParameter parameter, ref EvaluationStack stack)
 {
     CheckNotEmpty(il, stack, () => "In order to perform the 'initblk' instruction a number of bytes to initialize must be put onto the evaluation stack");
     CheckCanBeAssigned(il, typeof(int), stack.Pop());
     CheckNotEmpty(il, stack, () => "In order to perform the 'initblk' instruction an initialization value must be put onto the evaluation stack");
     CheckCanBeAssigned(il, typeof(int), stack.Pop());
     CheckNotEmpty(il, stack, () => "In order to perform the 'initblk' instruction a starting address must be put onto the evaluation stack");
     CheckIsAPointer(il, stack.Pop());
 }
예제 #30
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);
 }
예제 #31
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))));
        }
예제 #32
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)));
        }
예제 #33
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);
        }
예제 #34
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);
 }
예제 #35
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);
 }
예제 #36
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);
 }