protected override bool EmitInternal(LambdaExpression node, EmittingContext context, GroboIL.Label returnDefaultValueLabel, ResultType whatReturn, bool extend, out Type resultType)
        {
            var parameterTypes = node.Parameters.Select(parameter => parameter.Type).ToArray();

            Type[] constantTypes;
            var    compiledLambda = CompileAndLoadConstants(node, context, out constantTypes);

            var  il = context.Il;
            Type rawSubLambdaType;

            if (!Extensions.IsMono)
            {
                context.LoadCompiledLambdaPointer(compiledLambda);
                rawSubLambdaType = typeof(IntPtr);
            }
            else
            {
                rawSubLambdaType = Extensions.GetDelegateType(constantTypes.Concat(parameterTypes).ToArray(), node.ReturnType);
                context.LoadCompiledLambda(compiledLambda);
                il.Castclass(rawSubLambdaType);
            }

            resultType = Extensions.GetDelegateType(parameterTypes, node.ReturnType);
            var types            = constantTypes.Concat(new[] { rawSubLambdaType }).ToArray();
            var module           = (ModuleBuilder)(context.TypeBuilder == null ? null : context.TypeBuilder.Module);
            var subLambdaInvoker = DynamicMethodInvokerBuilder.BuildDynamicMethodInvoker(module, constantTypes, node.ReturnType, parameterTypes);

            il.Newobj(subLambdaInvoker.GetConstructor(types));
            il.Ldftn(subLambdaInvoker.GetMethod("Invoke"));
            il.Newobj(resultType.GetConstructor(new[] { typeof(object), typeof(IntPtr) }));
            return(false);
        }
        public unsafe void TestWriteAssemblerCode()
        {
            var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(object), new[] { typeof(object) }, typeof(string), true);

            using (var il = new GroboIL(method, false))
            {
                il.Ldarg(0);
                il.Isinst(typeof(int?));
                il.Ret();
            }
            method.CreateDelegate(typeof(Func <object, object>));
            var pointer = DynamicMethodInvokerBuilder.DynamicMethodPointerExtractor(method);
            var b       = (byte *)pointer;
            //var zzz = Convert.FromBase64String(@"VldVU0FSTInOSItsJFhIi3wkYEGJyonRRInDRInQVQ8oBg8oZhAPKMgPKOwPKNAPKPQPKNgPKPwPWUUAD1llEA9ZTTAPWW1AD1lVYA9ZdXAPWZ2QAAAAD1m9oAAAAPIPfMHyD3zl8g980/IPfPfyD3zC8g985g9Y4A8oRiAPKMgPKNAPKNgPWUUgD1lNUA9ZlYAAAAAPWZ2wAAAA8g98wfIPfNPyD3zCD1jgD1ilwAAAAA8rJ0iBxdAAAABIg8cQ/8gPhVf///9Ig8YwXf/LD4VG////Z0ONBFJnQY0EgsHgBEiYSAHF/8kPhSn///9BWltdX17D");
            var zzz = Convert.FromBase64String(@"VldVU0FSTInOSItsJFBIi3wkWEGJyonRRInDRInQVQ8oBg8oZhAPKMgPKOwPKNAPKPQPKNgPKPwPWUUAD1llEA9ZTTAPWW1AD1lVYA9ZdXAPWZ2QAAAAD1m9oAAAAPIPfMHyD3zl8g980/IPfPfyD3zC8g985g9Y4A8oRiAPKMgPKNAPKNgPWUUgD1lNUA9ZlYAAAAAPWZ2wAAAA8g98wfIPfNPyD3zCD1jgD1ilwAAAAA8rJ0iBxdAAAABIg8cQ/8gPhVf///9Ig8YwXf/LD4VG////Z0ONBFJnQY0EgsHgBEiYSAHF/8kPhSn///9BWltdX17D");

            fixed(byte *z = &zzz[0])
            {
                b = z;
                for (int i = 0; i < 20; ++i)
                {
                    for (int j = 0; j < 10; ++j)
                    {
                        Console.Write(string.Format("{0:X2} ", *b++));
                    }
                    Console.WriteLine();
                }
            }
        }
        public unsafe void TestWriteAssemblerCode3()
        {
            var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(void), new[] { typeof(IntPtr), typeof(int) }, typeof(string), true);
            var il     = method.GetILGenerator();

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_1);
            if (IntPtr.Size == 8)
            {
                il.Emit(OpCodes.Ldc_I8, 0x123456789ABCDEF1);
            }
            else
            {
                il.Emit(OpCodes.Ldc_I4, 0x12345678);
            }
            il.EmitCalli(OpCodes.Calli, CallingConvention.StdCall, typeof(void), new[] { typeof(IntPtr), typeof(int) });
            il.Emit(OpCodes.Ret);
            method.CreateDelegate(typeof(Action <IntPtr, int>));
            var pointer = DynamicMethodInvokerBuilder.DynamicMethodPointerExtractor(method);
            var b       = (byte *)pointer;

            for (int i = 0; i < 20; ++i)
            {
                for (int j = 0; j < 10; ++j)
                {
                    Console.Write(string.Format("{0:X2} ", *b++));
                }
                Console.WriteLine();
            }
            Console.WriteLine(TestStind_i4(123456678)[1]);
        }
        public unsafe void TestWriteAssemblerCode2()
        {
            var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(IntPtr), Type.EmptyTypes, typeof(string), true);
            var il     = method.GetILGenerator();
            var ptr    = new IntPtr(0x40100C);

            if (IntPtr.Size == 4)
            {
                il.Emit(OpCodes.Ldc_I4, ptr.ToInt32());
            }
            else
            {
                il.Emit(OpCodes.Ldc_I8, ptr.ToInt64());
            }
            il.Emit(OpCodes.Conv_U);
            il.EmitCalli(OpCodes.Calli, CallingConventions.Standard, typeof(void), Type.EmptyTypes, null);
            il.Emit(OpCodes.Ldnull);

            il.Emit(OpCodes.Ret);

            method.CreateDelegate(typeof(Func <IntPtr>));
            var pointer = DynamicMethodInvokerBuilder.DynamicMethodPointerExtractor(method);
            var b       = (byte *)pointer;

            for (int i = 0; i < 20; ++i)
            {
                for (int j = 0; j < 10; ++j)
                {
                    Console.Write(string.Format("{0:X2} ", *b++));
                }
                Console.WriteLine();
            }
        }
        public unsafe void TestWriteAssemblerCode0()
        {
            var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(int), new[] { typeof(double) }, typeof(string), true);

            using (var il = new GroboIL(method))
            {
                il.Ldarg(0);
                il.Conv <int>();
                il.Ret();
            }
            var func = (Func <double, int>)method.CreateDelegate(typeof(Func <double, int>));

            Console.WriteLine(func(3000000000));
            var pointer = DynamicMethodInvokerBuilder.DynamicMethodPointerExtractor(method);
            var b       = (byte *)pointer;

            for (int i = 0; i < 20; ++i)
            {
                for (int j = 0; j < 10; ++j)
                {
                    Console.Write(string.Format("{0:X2} ", *b++));
                }
                Console.WriteLine();
            }
        }
        private ITest BuildCalli()
        {
            var action        = Build();
            var typeBuilder   = Module.DefineType(Guid.NewGuid().ToString(), TypeAttributes.Class | TypeAttributes.Public);
            var pointerField  = typeBuilder.DefineField("pointer", typeof(IntPtr), FieldAttributes.Private | FieldAttributes.InitOnly);
            var delegateField = typeBuilder.DefineField("delegate", typeof(Delegate), FieldAttributes.Private | FieldAttributes.InitOnly);
            var constructor   = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, new[] { typeof(IntPtr), typeof(Delegate) });
            var il            = new GroboIL(constructor);

            il.Ldarg(0);
            il.Ldarg(1);
            il.Stfld(pointerField);
            il.Ldarg(0);
            il.Ldarg(2);
            il.Stfld(delegateField);
            il.Ret();
            var method = typeBuilder.DefineMethod("DoNothing", MethodAttributes.Public | MethodAttributes.Virtual, typeof(void), Type.EmptyTypes);

            il = new GroboIL(method);
            il.Ldarg(0);
            il.Ldfld(pointerField);
            il.Calli(CallingConventions.Standard, typeof(void), Type.EmptyTypes);
            il.Ret();
            typeBuilder.DefineMethodOverride(method, typeof(ITest).GetMethod("DoNothing"));
            typeBuilder.AddInterfaceImplementation(typeof(ITest));
            var type = typeBuilder.CreateType();

            return((ITest)Activator.CreateInstance(type, new object[] { DynamicMethodInvokerBuilder.DynamicMethodPointerExtractor((DynamicMethod)action.Item2), action.Item1 }));
        }
        public unsafe void TestWriteAssemblerCode4()
        {
            var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(int), new[] { typeof(int), typeof(int), typeof(int), typeof(int) }, typeof(string), true);
            var il     = method.GetILGenerator();

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Ldarg_2);
            il.Emit(OpCodes.Ldarg_3);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Ldarg_2);
            il.Emit(OpCodes.Ldarg_3);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_1);
            byte[] marker;
            if (IntPtr.Size == 8)
            {
                const long addr = 0x123456789ABCDEF1;
                marker = BitConverter.GetBytes(addr);
                il.Emit(OpCodes.Ldc_I8, addr);
            }
            else
            {
                const int addr = 0x12345678;
                marker = BitConverter.GetBytes(addr);
                il.Emit(OpCodes.Ldc_I4, addr);
            }
            il.EmitCalli(OpCodes.Calli, CallingConventions.Standard, typeof(int), new[] { typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), }, null);
            il.Emit(OpCodes.Ret);
            var func    = (Func <int, int, int, int, int>)method.CreateDelegate(typeof(Func <int, int, int, int, int>));
            var pointer = DynamicMethodInvokerBuilder.DynamicMethodPointerExtractor(method);

            Console.WriteLine("{0:X}", pointer.ToInt64());

            //Replace((byte*)pointer, marker);

            var b = (byte *)pointer;

            for (int i = 0; i < 20; ++i)
            {
                for (int j = 0; j < 10; ++j)
                {
                    Console.Write(string.Format("{0:X2} ", *b++));
                }
                Console.WriteLine();
            }

            var stopwatch = Stopwatch.StartNew();

            for (int i = 0; i < 1000000001; ++i)
            {
                func(i, i, i, i);
            }
            var elapsed = stopwatch.Elapsed;

            Console.WriteLine(elapsed);
        }
 public void LoadCompiledLambdaPointer(CompiledLambda compiledLambda)
 {
     if (TypeBuilder != null)
     {
         Il.Ldftn(compiledLambda.Method);
     }
     else
     {
         var stopwatch = Stopwatch.StartNew();
         var pointer   = DynamicMethodInvokerBuilder.DynamicMethodPointerExtractor((DynamicMethod)compiledLambda.Method);
         LambdaCompiler.TotalJITCompilationTime += stopwatch.Elapsed.TotalSeconds;
         Il.Ldc_IntPtr(pointer);
     }
 }
        private static Tuple <Delegate, IntPtr> EmitFieldExtractor <T, TValue>(FieldInfo field)
        {
            var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(TValue), new[] { typeof(T) }, typeof(string), true);

            using (var il = new GroboIL(method))
            {
                il.Ldarg(0); // stack: [list]
                il.Ldfld(field);
                il.Ret();
            }
            return(new Tuple <Delegate, IntPtr>((Func <T, TValue>)method.CreateDelegate(typeof(Func <T, TValue>)), DynamicMethodInvokerBuilder.DynamicMethodPointerExtractor(method)));
        }
        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)));
        }