예제 #1
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);
        }
예제 #2
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);
        }
예제 #3
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))));
        }
예제 #4
0
        public void TestStarg2()
        {
            var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(void), new[] { typeof(int), typeof(int) }, typeof(TestArgumentOutOfRange));
            var il     = new GroboIL(method);

            il.Ldc_I4(0);
            il.Starg(0);
            il.Ldc_I4(0);
            il.Starg(1);
            il.Ldc_I4(0);
            Assert.Throws <ArgumentOutOfRangeException>(() => il.Starg(2));
        }
예제 #5
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);
        }
예제 #6
0
 public static void WriteOffsetAppend(GroboIL il, GroboIL.Local offset, int len)
 {
     il.Ldloc(offset);
     il.Ldc_I4(len);
     il.Add();
     il.Stloc(offset);
 }
예제 #7
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));
        }
예제 #8
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));
        }
예제 #9
0
 private void LoadValue(BitsValue value)
 {
     Generator.Ldc_I8((long)value.Number);
     Generator.Conv <ulong>();
     Generator.Ldc_I4(value.Length);
     NumberToBitsValue(true);
 }
예제 #10
0
        private object BuildDelegate <T>(MetadataForModel metadata)
        {
            var dynamicMethod = GetDynamicMethod <T>();

            using (var il = new GroboIL(dynamicMethod))
            {
                il.Ldarg(0);
                il.Callnonvirt(GetStartRowMethod());

                foreach (var emitInfo in metadata.EmitInfos)
                {
                    il.Ldarg(0);
                    il.Ldarg(1);
                    il.Callnonvirt(emitInfo.Getter);
                    if (emitInfo.PostgresType != null)
                    {
                        il.Ldc_I4((int)emitInfo.PostgresType.Value);
                    }
                    il.Callnonvirt(emitInfo.WriteMethod);
                }

                il.Ret();
            }

            return(dynamicMethod.CreateDelegate(typeof(Action <NpgsqlBinaryImporter, T>)));
        }
예제 #11
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));
        }
예제 #12
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);
 }
예제 #13
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);
 }
예제 #14
0
        public void TestLabelHasBeenMarkedTwice()
        {
            var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(void), Type.EmptyTypes, typeof(string), true);
            var il     = new GroboIL(method);
            var label  = il.DefineLabel("L");

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

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

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

            context.EmitLoadArgument(operand, false, out resultType);
            if (resultType == typeof(bool))
            {
                il.Ldc_I4(1);
                il.Xor();
            }
            else if (resultType == typeof(bool?))
            {
                using (var value = context.DeclareLocal(typeof(bool?)))
                {
                    il.Stloc(value);
                    il.Ldloca(value);
                    context.EmitHasValueAccess(typeof(bool?));
                    var returnLabel = il.DefineLabel("return");
                    il.Brfalse(returnLabel);
                    il.Ldloca(value);
                    context.EmitValueAccess(typeof(bool?));
                    il.Ldc_I4(1);
                    il.Xor();
                    il.Newobj(nullableBoolConstructor);
                    il.Stloc(value);
                    context.MarkLabelAndSurroundWithSP(returnLabel);
                    il.Ldloc(value);
                }
            }
            else
            {
                throw new InvalidOperationException("Cannot perform '" + node.NodeType + "' operator on type '" + resultType + "'");
            }
            return(false);
        }
예제 #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(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);
            }
        }
예제 #17
0
 public static void WriteSizeChecker(GroboIL il, GroboIL.Local buffer, GroboIL.Local offset, int len)
 {
     //il.Ldloca(buffer);
     //il.Ldloc(offset);
     //il.Ldc_I4(len);
     //il.Call(resizeMethod);
     il.Ldc_I4(len);
     Resize(il, buffer, offset);
 }
예제 #18
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)));
        }
        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);
        }
        private static void MakeShift(Type elementType, GroboIL il)
        {
            var typeCode = GroBufTypeCodeMap.GetTypeCode(elementType);

            switch (typeCode)
            {
            case GroBufTypeCode.Int8:
            case GroBufTypeCode.UInt8:
            case GroBufTypeCode.Boolean:
                break;

            case GroBufTypeCode.Int16:
            case GroBufTypeCode.UInt16:
                il.Ldc_I4(1);
                il.Shl();
                break;

            case GroBufTypeCode.Int32:
            case GroBufTypeCode.UInt32:
                il.Ldc_I4(2);
                il.Shl();
                break;

            case GroBufTypeCode.Int64:
            case GroBufTypeCode.UInt64:
                il.Ldc_I4(3);
                il.Shl();
                break;

            case GroBufTypeCode.Single:
                il.Ldc_I4(2);
                il.Shl();
                break;

            case GroBufTypeCode.Double:
                il.Ldc_I4(3);
                il.Shl();
                break;

            default:
                throw new NotSupportedException("Type '" + elementType + "' is not supported");
            }
        }
예제 #21
0
파일: Test.cs 프로젝트: qinfengzhu/gremit
 private static void BuildIlWithNativeCallingConvention(MethodBuilder methodBuilder)
 {
     using (var il = new GroboIL(methodBuilder))
     {
         il.Ldc_I4(10);
         il.Ldarg(0);
         il.Calli(CallingConvention.StdCall, typeof(int), new[] { typeof(int) });
         il.Ret();
     }
 }
예제 #22
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));
        }
        private static Tuple <Delegate, IntPtr> EmitListResizer <T>()
        {
            var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(void), new[] { typeof(List <T>), typeof(int) }, typeof(string), true);

            using (var il = new GroboIL(method))
            {
                il.Ldarg(0);                                                                                           // stack: [list]
                il.Ldarg(1);                                                                                           // stack: [list, arrayIndex]
                il.Ldc_I4(1);                                                                                          // stack: [list, arrayIndex, 1]
                il.Add();                                                                                              // stack: [list, arrayIndex + 1]
                il.Call(typeof(List <T>).GetMethod("EnsureCapacity", BindingFlags.Instance | BindingFlags.NonPublic)); // list.EnsureCapacity(arrayIndex + 1); stack: []
                il.Ldarg(0);                                                                                           // stack: [list]
                il.Ldarg(1);                                                                                           // stack: [list, arrayIndex]
                il.Ldc_I4(1);                                                                                          // stack: [list, arrayIndex, 1]
                il.Add();                                                                                              // stack: [list, arrayIndex + 1]
                il.Stfld(typeof(List <T>).GetField("_size", BindingFlags.Instance | BindingFlags.NonPublic));          // list.Count = arrayIndex + 1; stack: []
                il.Ret();
            }
            return(new Tuple <Delegate, IntPtr>((Action <List <T>, int>)method.CreateDelegate(typeof(Action <List <T>, int>)), DynamicMethodInvokerBuilder.DynamicMethodPointerExtractor(method)));
        }
예제 #24
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());
            }
        }
예제 #25
0
        private static void BuildConstructor(TypeBuilder typeBuilder, int n, Context context)
        {
            var constructor = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, new[] { typeof(int[]), typeof(MethodCallNode[]) });

            using (var il = new GroboIL(constructor))
            {
                for (int i = 0; i < n; ++i)
                {
                    il.Ldarg(0);                       // stack: [this]
                    il.Ldarg(1);                       // stack: [this, keys]
                    il.Ldc_I4(i);                      // stack: [this, keys, i]
                    il.Ldelem(typeof(int));            // stack: [this, keys[i]]
                    il.Stfld(context.keys[i]);         // this.key_{i} = keys[i]; stack: []
                    il.Ldarg(0);                       // stack: [this]
                    il.Ldarg(2);                       // stack: [this, values]
                    il.Ldc_I4(i);                      // stack: [this, values, i]
                    il.Ldelem(typeof(MethodCallNode)); // stack: [this, values[i]]
                    il.Stfld(context.values[i]);       // this.value_{i} = values[i]; stack: []
                }
                il.Ret();
            }
        }
예제 #26
0
        private static void BuildCount(TypeBuilder typeBuilder, int n)
        {
            var property = typeBuilder.DefineProperty("Count", PropertyAttributes.None, typeof(int), Type.EmptyTypes);
            var getter   = typeBuilder.DefineMethod("get_Count", MethodAttributes.Public | MethodAttributes.Virtual, CallingConventions.HasThis, typeof(int), Type.EmptyTypes);

            using (var il = new GroboIL(getter))
            {
                il.Ldc_I4(n);
                il.Ret();
            }
            property.SetGetMethod(getter);
            typeBuilder.DefineMethodOverride(getter, typeof(MethodCallNodeEdges).GetProperty(property.Name, BindingFlags.Public | BindingFlags.Instance).GetGetMethod());
        }
예제 #27
0
        public void TestLabelHasNotBeenMarked_Switch()
        {
            var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(void), Type.EmptyTypes, typeof(string), true);
            var il     = new GroboIL(method);
            var label  = il.DefineLabel("L");

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

            Assert.AreEqual("The label 'L_0' has not been marked", e.Message);
        }
예제 #28
0
        public static TryGetValueDelegate <T> Build <T>(string[] keys, T[] values)
        {
            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))
            {
                for (int i = 0; i < keys.Length; ++i)
                {
                    il.Ldarg(1);                     // stack: [key]
                    il.Ldstr(keys[i]);               // stack: [key, keys[i]]
                    var nextKeyLabel = il.DefineLabel("nextKey");
                    il.Call(stringEqualityOperator); // stack: [key == keys[i]]
                    il.Brfalse(nextKeyLabel);        // if(key != keys[i]) goto nextKey; stack: []
                    il.Ldarg(2);                     // stack: [ref value]
                    il.Ldarg(0);                     // stack: [ref value, values]
                    il.Ldc_I4(i);                    // stack: [ref value, values, i]
                    il.Ldelem(typeof(T));            // stack: [ref value, values[i]]
                    il.Stind(typeof(T));             // value = values[i]; stack: []
                    il.Ldc_I4(1);                    // stack: [true]
                    il.Ret();
                    il.MarkLabel(nextKeyLabel);
                }
                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();
            }
            return((TryGetValueDelegate <T>)method.CreateDelegate(typeof(TryGetValueDelegate <T>), values));
        }
예제 #29
0
        private static void BuildChildren(TypeBuilder typeBuilder, int n, Context context)
        {
            var property = typeBuilder.DefineProperty("Children", PropertyAttributes.None, typeof(IEnumerable <MethodCallNode>), Type.EmptyTypes);
            var getter   = typeBuilder.DefineMethod("get_Children", MethodAttributes.Public | MethodAttributes.Virtual, CallingConventions.HasThis, typeof(IEnumerable <MethodCallNode>), Type.EmptyTypes);

            using (var il = new GroboIL(getter))
            {
                il.Ldc_I4(n);                      // stack: [n]
                il.Newarr(typeof(MethodCallNode)); // stack: [new int[n] -> values]
                for (int i = 0; i < n; ++i)
                {
                    il.Dup();                          // stack: [values, values]
                    il.Ldc_I4(i);                      // stack: [values, values, i]
                    il.Ldarg(0);                       // stack: [values, values, i, this]
                    il.Ldfld(context.values[i]);       // stack: [values, values, i, this.values_{i}]
                    il.Stelem(typeof(MethodCallNode)); // values[i] = this.values_{i}; stack: [values]
                }
                il.Castclass(typeof(IEnumerable <MethodCallNode>));
                il.Ret();
            }
            property.SetGetMethod(getter);
            typeBuilder.DefineMethodOverride(getter, typeof(MethodCallNodeEdges).GetProperty(property.Name, BindingFlags.Public | BindingFlags.Instance).GetGetMethod());
        }
        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();
            }
        }
예제 #31
0
        private Tuple <Action, MethodInfo> Build()
        {
            var dynamicMethod = new DynamicMethod(Guid.NewGuid().ToString(), MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, typeof(void), Type.EmptyTypes, Module, true);

            using (var il = new GroboIL(dynamicMethod))
            {
                il.Ldfld(xField);
                il.Ldc_I4(1);
                il.Add();
                il.Stfld(xField);
                il.Ret();
            }
            return(new Tuple <Action, MethodInfo>((Action)dynamicMethod.CreateDelegate(typeof(Action)), dynamicMethod));
        }