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);
        }
        protected override bool EmitInternal(InvocationExpression node, EmittingContext context, GroboIL.Label returnDefaultValueLabel, ResultType whatReturn, bool extend, out Type resultType)
        {
            bool result;

            if (node.Expression.NodeType != ExpressionType.Lambda)
            {
                Type delegateType;
                result = ExpressionEmittersCollection.Emit(node.Expression, context, returnDefaultValueLabel, ResultType.Value, extend, out delegateType);
                context.EmitLoadArguments(node.Arguments.ToArray());
                var invokeMethod = delegateType.GetMethod("Invoke", node.Arguments.Select(argument => argument.Type).ToArray());
                context.Il.Call(invokeMethod, delegateType);
            }
            else
            {
                result = false;
                var    lambda = (LambdaExpression)node.Expression;
                Type[] constantTypes;
                var    compiledLambda = LambdaExpressionEmitter.CompileAndLoadConstants(lambda, context, out constantTypes);
                context.EmitLoadArguments(node.Arguments.ToArray());
                context.LoadCompiledLambdaPointer(compiledLambda);
                context.Il.Calli(CallingConventions.Standard, lambda.ReturnType, constantTypes.Concat(lambda.Parameters.Select(parameter => parameter.Type)).ToArray());
            }
            resultType = node.Type;
            return(result);
        }