/* ****************************************************************************
 *
 * Copyright (c) Microsoft Corporation.
 *
 * This source code is subject to terms and conditions of the Apache License, Version 2.0. A
 * copy of the license can be found in the License.html file at the root of this distribution. If
 * you cannot locate the  Apache License, Version 2.0, please send an email to
 * ironpy@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
 * by the terms of the Apache License, Version 2.0.
 *
 * You must not remove this notice, or any other, from this software.
 *
 *
 * ***************************************************************************/
#if !CLR2
using System.Linq.Expressions;
#else
using Microsoft.Scripting.Ast;
#endif

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Threading;

using System.Dynamic;

namespace System.Management.Automation.Interpreter {
    #region Generated Reflected Caller

    // *** BEGIN GENERATED CODE ***
    // generated by function: gen_all from: generate_reflected_calls.py

    internal partial class CallInstruction {
        private const int MaxHelpers = 10;
        private const int MaxArgs = 3;

        public virtual object InvokeInstance(object instance, params object[] args) {
            switch(args.Length) {
                case 0: return Invoke(instance);
                case 1: return Invoke(instance, args[0]);
                case 2: return Invoke(instance, args[0], args[1]);
                case 3: return Invoke(instance, args[0], args[1], args[2]);
                case 4: return Invoke(instance, args[0], args[1], args[2], args[3]);
                case 5: return Invoke(instance, args[0], args[1], args[2], args[3], args[4]);
                case 6: return Invoke(instance, args[0], args[1], args[2], args[3], args[4], args[5]);
                case 7: return Invoke(instance, args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
                case 8: return Invoke(instance, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
                default: throw new InvalidOperationException();
            }
        }

        public virtual object Invoke(params object[] args) {
            switch(args.Length) {
                case 0: return Invoke();
                case 1: return Invoke(args[0]);
                case 2: return Invoke(args[0], args[1]);
                case 3: return Invoke(args[0], args[1], args[2]);
                case 4: return Invoke(args[0], args[1], args[2], args[3]);
                case 5: return Invoke(args[0], args[1], args[2], args[3], args[4]);
                case 6: return Invoke(args[0], args[1], args[2], args[3], args[4], args[5]);
                case 7: return Invoke(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
                case 8: return Invoke(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
                case 9: return Invoke(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]);
                default: throw new InvalidOperationException();
            }
        }

        public virtual object Invoke() { throw new InvalidOperationException(); }
        public virtual object Invoke(object arg0) { throw new InvalidOperationException(); }
        public virtual object Invoke(object arg0, object arg1) { throw new InvalidOperationException(); }
        public virtual object Invoke(object arg0, object arg1, object arg2) { throw new InvalidOperationException(); }
        public virtual object Invoke(object arg0, object arg1, object arg2, object arg3) { throw new InvalidOperationException(); }
        public virtual object Invoke(object arg0, object arg1, object arg2, object arg3, object arg4) { throw new InvalidOperationException(); }
        public virtual object Invoke(object arg0, object arg1, object arg2, object arg3, object arg4, object arg5) { throw new InvalidOperationException(); }
        public virtual object Invoke(object arg0, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6) { throw new InvalidOperationException(); }
        public virtual object Invoke(object arg0, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7) { throw new InvalidOperationException(); }
        public virtual object Invoke(object arg0, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8) { throw new InvalidOperationException(); }

        /// <summary>
        /// Fast creation works if we have a known primitive types for the entire
        /// method signature.  If we have any non-primitive types then FastCreate
        /// falls back to SlowCreate which works for all types.
        ///
        /// Fast creation is fast because it avoids using reflection (MakeGenericType
        /// and Activator.CreateInstance) to create the types.  It does this through
        /// calling a series of generic methods picking up each strong type of the
        /// signature along the way.  When it runs out of types it news up the
        /// appropriate CallInstruction with the strong-types that have been built up.
        ///
        /// One relaxation is that for return types which are non-primitive types
        /// we can fallback to object due to relaxed delegates.
        /// </summary>
        private static CallInstruction FastCreate(MethodInfo target, ParameterInfo[] pi) {
            Type t = TryGetParameterOrReturnType(target, pi, 0);
            if (t == null) {
                return new ActionCallInstruction(target);
            }

            var typeInfo = t.GetTypeInfo();
            if (typeInfo.IsEnum) return SlowCreate(target, pi);
            switch (t.GetTypeCode()) {
                case TypeCode.Object: {
                    if (t != typeof(object) && (IndexIsNotReturnType(0, target, pi) || typeInfo.IsValueType)) {
                        // if we're on the return type relaxed delegates makes it ok to use object
                        goto default;
                    }
                    return FastCreate<Object>(target, pi);
                }
                case TypeCode.Int16: return FastCreate<Int16>(target, pi);
                case TypeCode.Int32: return FastCreate<Int32>(target, pi);
                case TypeCode.Int64: return FastCreate<Int64>(target, pi);
                case TypeCode.Boolean: return FastCreate<Boolean>(target, pi);
                case TypeCode.Char: return FastCreate<Char>(target, pi);
                case TypeCode.Byte: return FastCreate<Byte>(target, pi);
                case TypeCode.Decimal: return FastCreate<Decimal>(target, pi);
                case TypeCode.DateTime: return FastCreate<DateTime>(target, pi);
                case TypeCode.Double: return FastCreate<Double>(target, pi);
                case TypeCode.Single: return FastCreate<Single>(target, pi);
                case TypeCode.UInt16: return FastCreate<UInt16>(target, pi);
                case TypeCode.UInt32: return FastCreate<UInt32>(target, pi);
                case TypeCode.UInt64: return FastCreate<UInt64>(target, pi);
                case TypeCode.String: return FastCreate<String>(target, pi);
                case TypeCode.SByte: return FastCreate<SByte>(target, pi);
                default: return SlowCreate(target, pi);
            }
        }

        private static CallInstruction FastCreate<T0>(MethodInfo target, ParameterInfo[] pi) {
            Type t = TryGetParameterOrReturnType(target, pi, 1);
            if (t == null) {
                if (target.ReturnType == typeof(void)) {
                    return new ActionCallInstruction<T0>(target);
                }
                return new FuncCallInstruction<T0>(target);
            }

            var typeInfo = t.GetTypeInfo();
            if (typeInfo.IsEnum) return SlowCreate(target, pi);
            switch (t.GetTypeCode()) {
                case TypeCode.Object: {
                    if (t != typeof(object) && (IndexIsNotReturnType(1, target, pi) || typeInfo.IsValueType)) {
                        // if we're on the return type relaxed delegates makes it ok to use object
                        goto default;
                    }
                    return FastCreate<T0, Object>(target, pi);
                }
                case TypeCode.Int16: return FastCreate<T0, Int16>(target, pi);
                case TypeCode.Int32: return FastCreate<T0, Int32>(target, pi);
                case TypeCode.Int64: return FastCreate<T0, Int64>(target, pi);
                case TypeCode.Boolean: return FastCreate<T0, Boolean>(target, pi);
                case TypeCode.Char: return FastCreate<T0, Char>(target, pi);
                case TypeCode.Byte: return FastCreate<T0, Byte>(target, pi);
                case TypeCode.Decimal: return FastCreate<T0, Decimal>(target, pi);
                case TypeCode.DateTime: return FastCreate<T0, DateTime>(target, pi);
                case TypeCode.Double: return FastCreate<T0, Double>(target, pi);
                case TypeCode.Single: return FastCreate<T0, Single>(target, pi);
                case TypeCode.UInt16: return FastCreate<T0, UInt16>(target, pi);
                case TypeCode.UInt32: return FastCreate<T0, UInt32>(target, pi);
                case TypeCode.UInt64: return FastCreate<T0, UInt64>(target, pi);
                case TypeCode.String: return FastCreate<T0, String>(target, pi);
                case TypeCode.SByte: return FastCreate<T0, SByte>(target, pi);
                default: return SlowCreate(target, pi);
            }
        }

        private static CallInstruction FastCreate<T0, T1>(MethodInfo target, ParameterInfo[] pi) {
            Type t = TryGetParameterOrReturnType(target, pi, 2);
            if (t == null) {
                if (target.ReturnType == typeof(void)) {
                    return new ActionCallInstruction<T0, T1>(target);
                }
                return new FuncCallInstruction<T0, T1>(target);
            }

            var typeInfo = t.GetTypeInfo();
            if (typeInfo.IsEnum) return SlowCreate(target, pi);
            switch (t.GetTypeCode()) {
                case TypeCode.Object: {
                    Debug.Assert(pi.Length == 2);
                    if (typeInfo.IsValueType) goto default;

                    return new FuncCallInstruction<T0, T1, Object>(target);
                }
                case TypeCode.Int16: return new FuncCallInstruction<T0, T1, Int16>(target);
                case TypeCode.Int32: return new FuncCallInstruction<T0, T1, Int32>(target);
                case TypeCode.Int64: return new FuncCallInstruction<T0, T1, Int64>(target);
                case TypeCode.Boolean: return new FuncCallInstruction<T0, T1, Boolean>(target);
                case TypeCode.Char: return new FuncCallInstruction<T0, T1, Char>(target);
                case TypeCode.Byte: return new FuncCallInstruction<T0, T1, Byte>(target);
                case TypeCode.Decimal: return new FuncCallInstruction<T0, T1, Decimal>(target);
                case TypeCode.DateTime: return new FuncCallInstruction<T0, T1, DateTime>(target);
                case TypeCode.Double: return new FuncCallInstruction<T0, T1, Double>(target);
                case TypeCode.Single: return new FuncCallInstruction<T0, T1, Single>(target);
                case TypeCode.UInt16: return new FuncCallInstruction<T0, T1, UInt16>(target);
                case TypeCode.UInt32: return new FuncCallInstruction<T0, T1, UInt32>(target);
                case TypeCode.UInt64: return new FuncCallInstruction<T0, T1, UInt64>(target);
                case TypeCode.String: return new FuncCallInstruction<T0, T1, String>(target);
                case TypeCode.SByte: return new FuncCallInstruction<T0, T1, SByte>(target);
                default: return SlowCreate(target, pi);
            }
        }

        private static Type GetHelperType(MethodInfo info, Type[] arrTypes) {
            Type t;
            if (info.ReturnType == typeof(void)) {
                switch (arrTypes.Length) {
                    case 0: t = typeof(ActionCallInstruction); break;
                    case 1: t = typeof(ActionCallInstruction<>).MakeGenericType(arrTypes); break;
                    case 2: t = typeof(ActionCallInstruction<,>).MakeGenericType(arrTypes); break;
                    case 3: t = typeof(ActionCallInstruction<,,>).MakeGenericType(arrTypes); break;
                    case 4: t = typeof(ActionCallInstruction<,,,>).MakeGenericType(arrTypes); break;
                    case 5: t = typeof(ActionCallInstruction<,,,,>).MakeGenericType(arrTypes); break;
                    case 6: t = typeof(ActionCallInstruction<,,,,,>).MakeGenericType(arrTypes); break;
                    case 7: t = typeof(ActionCallInstruction<,,,,,,>).MakeGenericType(arrTypes); break;
                    case 8: t = typeof(ActionCallInstruction<,,,,,,,>).MakeGenericType(arrTypes); break;
                    case 9: t = typeof(ActionCallInstruction<,,,,,,,,>).MakeGenericType(arrTypes); break;
                    default: throw new InvalidOperationException();
                }
            } else {
                switch (arrTypes.Length) {
                    case 1: t = typeof(FuncCallInstruction<>).MakeGenericType(arrTypes); break;
                    case 2: t = typeof(FuncCallInstruction<,>).MakeGenericType(arrTypes); break;
                    case 3: t = typeof(FuncCallInstruction<,,>).MakeGenericType(arrTypes); break;
                    case 4: t = typeof(FuncCallInstruction<,,,>).MakeGenericType(arrTypes); break;
                    case 5: t = typeof(FuncCallInstruction<,,,,>).MakeGenericType(arrTypes); break;
                    case 6: t = typeof(FuncCallInstruction<,,,,,>).MakeGenericType(arrTypes); break;
                    case 7: t = typeof(FuncCallInstruction<,,,,,,>).MakeGenericType(arrTypes); break;
                    case 8: t = typeof(FuncCallInstruction<,,,,,,,>).MakeGenericType(arrTypes); break;
                    case 9: t = typeof(FuncCallInstruction<,,,,,,,,>).MakeGenericType(arrTypes); break;
                    case 10: t = typeof(FuncCallInstruction<,,,,,,,,,>).MakeGenericType(arrTypes); break;
                    default: throw new InvalidOperationException();
                }
            }
            return t;
        }
        public static MethodInfo CacheFunc<TRet>(Func<TRet> method) {
            var info = method.GetMethodInfo();
            lock (s_cache) {
                s_cache[info] = new FuncCallInstruction<TRet>(method);
            }
            return info;
        }

        public static MethodInfo CacheFunc<T0, TRet>(Func<T0, TRet> method) {
            var info = method.GetMethodInfo();
            lock (s_cache) {
                s_cache[info] = new FuncCallInstruction<T0, TRet>(method);
            }
            return info;
        }

        public static MethodInfo CacheFunc<T0, T1, TRet>(Func<T0, T1, TRet> method) {
            var info = method.GetMethodInfo();
            lock (s_cache) {
                s_cache[info] = new FuncCallInstruction<T0, T1, TRet>(method);
            }
            return info;
        }

        public static MethodInfo CacheFunc<T0, T1, T2, TRet>(Func<T0, T1, T2, TRet> method) {
            var info = method.GetMethodInfo();
            lock (s_cache) {
                s_cache[info] = new FuncCallInstruction<T0, T1, T2, TRet>(method);
            }
            return info;
        }

        public static MethodInfo CacheFunc<T0, T1, T2, T3, TRet>(Func<T0, T1, T2, T3, TRet> method) {
            var info = method.GetMethodInfo();
            lock (s_cache) {
                s_cache[info] = new FuncCallInstruction<T0, T1, T2, T3, TRet>(method);
            }
            return info;
        }

        public static MethodInfo CacheFunc<T0, T1, T2, T3, T4, TRet>(Func<T0, T1, T2, T3, T4, TRet> method) {
            var info = method.GetMethodInfo();
            lock (s_cache) {
                s_cache[info] = new FuncCallInstruction<T0, T1, T2, T3, T4, TRet>(method);
            }
            return info;
        }

        public static MethodInfo CacheFunc<T0, T1, T2, T3, T4, T5, TRet>(Func<T0, T1, T2, T3, T4, T5, TRet> method) {
            var info = method.GetMethodInfo();
            lock (s_cache) {
                s_cache[info] = new FuncCallInstruction<T0, T1, T2, T3, T4, T5, TRet>(method);
            }
            return info;
        }

        public static MethodInfo CacheFunc<T0, T1, T2, T3, T4, T5, T6, TRet>(Func<T0, T1, T2, T3, T4, T5, T6, TRet> method) {
            var info = method.GetMethodInfo();
            lock (s_cache) {
                s_cache[info] = new FuncCallInstruction<T0, T1, T2, T3, T4, T5, T6, TRet>(method);
            }
            return info;
        }

        public static MethodInfo CacheFunc<T0, T1, T2, T3, T4, T5, T6, T7, TRet>(Func<T0, T1, T2, T3, T4, T5, T6, T7, TRet> method) {
            var info = method.GetMethodInfo();
            lock (s_cache) {
                s_cache[info] = new FuncCallInstruction<T0, T1, T2, T3, T4, T5, T6, T7, TRet>(method);
            }
            return info;
        }

        public static MethodInfo CacheFunc<T0, T1, T2, T3, T4, T5, T6, T7, T8, TRet>(Func<T0, T1, T2, T3, T4, T5, T6, T7, T8, TRet> method) {
            var info = method.GetMethodInfo();
            lock (s_cache) {
                s_cache[info] = new FuncCallInstruction<T0, T1, T2, T3, T4, T5, T6, T7, T8, TRet>(method);
            }
            return info;
        }

        public static MethodInfo CacheAction(Action method) {
            var info = method.GetMethodInfo();
            lock (s_cache) {
                s_cache[info] = new ActionCallInstruction(method);
            }
            return info;
        }

        public static MethodInfo CacheAction<T0>(Action<T0> method) {
            var info = method.GetMethodInfo();
            lock (s_cache) {
                s_cache[info] = new ActionCallInstruction<T0>(method);
            }
            return info;
        }

        public static MethodInfo CacheAction<T0, T1>(Action<T0, T1> method) {
            var info = method.GetMethodInfo();
            lock (s_cache) {
                s_cache[info] = new ActionCallInstruction<T0, T1>(method);
            }
            return info;
        }

        public static MethodInfo CacheAction<T0, T1, T2>(Action<T0, T1, T2> method) {
            var info = method.GetMethodInfo();
            lock (s_cache) {
                s_cache[info] = new ActionCallInstruction<T0, T1, T2>(method);
            }
            return info;
        }

        public static MethodInfo CacheAction<T0, T1, T2, T3>(Action<T0, T1, T2, T3> method) {
            var info = method.GetMethodInfo();
            lock (s_cache) {
                s_cache[info] = new ActionCallInstruction<T0, T1, T2, T3>(method);
            }
            return info;
        }

        public static MethodInfo CacheAction<T0, T1, T2, T3, T4>(Action<T0, T1, T2, T3, T4> method) {
            var info = method.GetMethodInfo();
            lock (s_cache) {
                s_cache[info] = new ActionCallInstruction<T0, T1, T2, T3, T4>(method);
            }
            return info;
        }

        public static MethodInfo CacheAction<T0, T1, T2, T3, T4, T5>(Action<T0, T1, T2, T3, T4, T5> method) {
            var info = method.GetMethodInfo();
            lock (s_cache) {
                s_cache[info] = new ActionCallInstruction<T0, T1, T2, T3, T4, T5>(method);
            }
            return info;
        }

        public static MethodInfo CacheAction<T0, T1, T2, T3, T4, T5, T6>(Action<T0, T1, T2, T3, T4, T5, T6> method) {
            var info = method.GetMethodInfo();
            lock (s_cache) {
                s_cache[info] = new ActionCallInstruction<T0, T1, T2, T3, T4, T5, T6>(method);
            }
            return info;
        }

        public static MethodInfo CacheAction<T0, T1, T2, T3, T4, T5, T6, T7>(Action<T0, T1, T2, T3, T4, T5, T6, T7> method) {
            var info = method.GetMethodInfo();
            lock (s_cache) {
                s_cache[info] = new ActionCallInstruction<T0, T1, T2, T3, T4, T5, T6, T7>(method);
            }
            return info;
        }

        public static MethodInfo CacheAction<T0, T1, T2, T3, T4, T5, T6, T7, T8>(Action<T0, T1, T2, T3, T4, T5, T6, T7, T8> method) {
            var info = method.GetMethodInfo();
            lock (s_cache) {
                s_cache[info] = new ActionCallInstruction<T0, T1, T2, T3, T4, T5, T6, T7, T8>(method);
            }
            return info;
        }

    }

    internal sealed class ActionCallInstruction : CallInstruction {
        private readonly Action _target;
        public override MethodInfo Info { get { return _target.GetMethodInfo(); } }
        public override int ArgumentCount { get { return 0; } }

        public ActionCallInstruction(Action target) {
            _target = target;
        }

        public ActionCallInstruction(MethodInfo target) {
            _target = (Action)target.CreateDelegate(typeof(Action));
        }

        public override object Invoke() {
            _target();
            return null;
        }

        public override int Run(InterpretedFrame frame) {
            _target();
            frame.StackIndex -= 0;
            return 1;
        }
    }

    internal sealed class ActionCallInstruction<T0> : CallInstruction {
        private readonly Action<T0> _target;
        public override MethodInfo Info { get { return _target.GetMethodInfo(); } }
        public override int ArgumentCount { get { return 1; } }

        public ActionCallInstruction(Action<T0> target) {
            _target = target;
        }

        public ActionCallInstruction(MethodInfo target) {
            _target = (Action<T0>)target.CreateDelegate(typeof(Action<T0>));
        }

        public override object Invoke(object arg0) {
            _target(arg0 != null ? (T0)arg0 : default(T0));
            return null;
        }

        public override int Run(InterpretedFrame frame) {
            _target((T0)frame.Data[frame.StackIndex - 1]);
            frame.StackIndex -= 1;
            return 1;
        }
    }

    internal sealed class ActionCallInstruction<T0, T1> : CallInstruction {
        private readonly Action<T0, T1> _target;
        public override MethodInfo Info { get { return _target.GetMethodInfo(); } }
        public override int ArgumentCount { get { return 2; } }

        public ActionCallInstruction(Action<T0, T1> target) {
            _target = target;
        }

        public ActionCallInstruction(MethodInfo target) {
            _target = (Action<T0, T1>)target.CreateDelegate(typeof(Action<T0, T1>));
        }

        public override object Invoke(object arg0, object arg1) {
            _target(arg0 != null ? (T0)arg0 : default(T0), arg1 != null ? (T1)arg1 : default(T1));
            return null;
        }

        public override int Run(InterpretedFrame frame) {
            _target((T0)frame.Data[frame.StackIndex - 2], (T1)frame.Data[frame.StackIndex - 1]);
            frame.StackIndex -= 2;
            return 1;
        }
    }

    internal sealed class ActionCallInstruction<T0, T1, T2> : CallInstruction {
        private readonly Action<T0, T1, T2> _target;
        public override MethodInfo Info { get { return _target.GetMethodInfo(); } }
        public override int ArgumentCount { get { return 3; } }

        public ActionCallInstruction(Action<T0, T1, T2> target) {
            _target = target;
        }

        public ActionCallInstruction(MethodInfo target) {
            _target = (Action<T0, T1, T2>)target.CreateDelegate(typeof(Action<T0, T1, T2>));
        }

        public override object Invoke(object arg0, object arg1, object arg2) {
            _target(arg0 != null ? (T0)arg0 : default(T0), arg1 != null ? (T1)arg1 : default(T1), arg2 != null ? (T2)arg2 : default(T2));
            return null;
        }

        public override int Run(InterpretedFrame frame) {
            _target((T0)frame.Data[frame.StackIndex - 3], (T1)frame.Data[frame.StackIndex - 2], (T2)frame.Data[frame.StackIndex - 1]);
            frame.StackIndex -= 3;
            return 1;
        }
    }

    internal sealed class ActionCallInstruction<T0, T1, T2, T3> : CallInstruction {
        private readonly Action<T0, T1, T2, T3> _target;
        public override MethodInfo Info { get { return _target.GetMethodInfo(); } }
        public override int ArgumentCount { get { return 4; } }

        public ActionCallInstruction(Action<T0, T1, T2, T3> target) {
            _target = target;
        }

        public ActionCallInstruction(MethodInfo target) {
            _target = (Action<T0, T1, T2, T3>)target.CreateDelegate(typeof(Action<T0, T1, T2, T3>));
        }

        public override object Invoke(object arg0, object arg1, object arg2, object arg3) {
            _target(arg0 != null ? (T0)arg0 : default(T0), arg1 != null ? (T1)arg1 : default(T1), arg2 != null ? (T2)arg2 : default(T2), arg3 != null ? (T3)arg3 : default(T3));
            return null;
        }

        public override int Run(InterpretedFrame frame) {
            _target((T0)frame.Data[frame.StackIndex - 4], (T1)frame.Data[frame.StackIndex - 3], (T2)frame.Data[frame.StackIndex - 2], (T3)frame.Data[frame.StackIndex - 1]);
            frame.StackIndex -= 4;
            return 1;
        }
    }

    internal sealed class ActionCallInstruction<T0, T1, T2, T3, T4> : CallInstruction {
        private readonly Action<T0, T1, T2, T3, T4> _target;
        public override MethodInfo Info { get { return _target.GetMethodInfo(); } }
        public override int ArgumentCount { get { return 5; } }

        public ActionCallInstruction(Action<T0, T1, T2, T3, T4> target) {
            _target = target;
        }

        public ActionCallInstruction(MethodInfo target) {
            _target = (Action<T0, T1, T2, T3, T4>)target.CreateDelegate(typeof(Action<T0, T1, T2, T3, T4>));
        }

        public override object Invoke(object arg0, object arg1, object arg2, object arg3, object arg4) {
            _target(arg0 != null ? (T0)arg0 : default(T0), arg1 != null ? (T1)arg1 : default(T1), arg2 != null ? (T2)arg2 : default(T2), arg3 != null ? (T3)arg3 : default(T3), arg4 != null ? (T4)arg4 : default(T4));
            return null;
        }

        public override int Run(InterpretedFrame frame) {
            _target((T0)frame.Data[frame.StackIndex - 5], (T1)frame.Data[frame.StackIndex - 4], (T2)frame.Data[frame.StackIndex - 3], (T3)frame.Data[frame.StackIndex - 2], (T4)frame.Data[frame.StackIndex - 1]);
            frame.StackIndex -= 5;
            return 1;
        }
    }

    internal sealed class ActionCallInstruction<T0, T1, T2, T3, T4, T5> : CallInstruction {
        private readonly Action<T0, T1, T2, T3, T4, T5> _target;
        public override MethodInfo Info { get { return _target.GetMethodInfo(); } }
        public override int ArgumentCount { get { return 6; } }

        public ActionCallInstruction(Action<T0, T1, T2, T3, T4, T5> target) {
            _target = target;
        }

        public ActionCallInstruction(MethodInfo target) {
            _target = (Action<T0, T1, T2, T3, T4, T5>)target.CreateDelegate(typeof(Action<T0, T1, T2, T3, T4, T5>));
        }

        public override object Invoke(object arg0, object arg1, object arg2, object arg3, object arg4, object arg5) {
            _target(arg0 != null ? (T0)arg0 : default(T0), arg1 != null ? (T1)arg1 : default(T1), arg2 != null ? (T2)arg2 : default(T2), arg3 != null ? (T3)arg3 : default(T3), arg4 != null ? (T4)arg4 : default(T4), arg5 != null ? (T5)arg5 : default(T5));
            return null;
        }

        public override int Run(InterpretedFrame frame) {
            _target((T0)frame.Data[frame.StackIndex - 6], (T1)frame.Data[frame.StackIndex - 5], (T2)frame.Data[frame.StackIndex - 4], (T3)frame.Data[frame.StackIndex - 3], (T4)frame.Data[frame.StackIndex - 2], (T5)frame.Data[frame.StackIndex - 1]);
            frame.StackIndex -= 6;
            return 1;
        }
    }

    internal sealed class ActionCallInstruction<T0, T1, T2, T3, T4, T5, T6> : CallInstruction {
        private readonly Action<T0, T1, T2, T3, T4, T5, T6> _target;
        public override MethodInfo Info { get { return _target.GetMethodInfo(); } }
        public override int ArgumentCount { get { return 7; } }

        public ActionCallInstruction(Action<T0, T1, T2, T3, T4, T5, T6> target) {
            _target = target;
        }

        public ActionCallInstruction(MethodInfo target) {
            _target = (Action<T0, T1, T2, T3, T4, T5, T6>)target.CreateDelegate(typeof(Action<T0, T1, T2, T3, T4, T5, T6>));
        }

        public override object Invoke(object arg0, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6) {
            _target(arg0 != null ? (T0)arg0 : default(T0), arg1 != null ? (T1)arg1 : default(T1), arg2 != null ? (T2)arg2 : default(T2), arg3 != null ? (T3)arg3 : default(T3), arg4 != null ? (T4)arg4 : default(T4), arg5 != null ? (T5)arg5 : default(T5), arg6 != null ? (T6)arg6 : default(T6));
            return null;
        }

        public override int Run(InterpretedFrame frame) {
            _target((T0)frame.Data[frame.StackIndex - 7], (T1)frame.Data[frame.StackIndex - 6], (T2)frame.Data[frame.StackIndex - 5], (T3)frame.Data[frame.StackIndex - 4], (T4)frame.Data[frame.StackIndex - 3], (T5)frame.Data[frame.StackIndex - 2], (T6)frame.Data[frame.StackIndex - 1]);
            frame.StackIndex -= 7;
            return 1;
        }
    }

    internal sealed class ActionCallInstruction<T0, T1, T2, T3, T4, T5, T6, T7> : CallInstruction {
        private readonly Action<T0, T1, T2, T3, T4, T5, T6, T7> _target;
        public override MethodInfo Info { get { return _target.GetMethodInfo(); } }
        public override int ArgumentCount { get { return 8; } }

        public ActionCallInstruction(Action<T0, T1, T2, T3, T4, T5, T6, T7> target) {
            _target = target;
        }

        public ActionCallInstruction(MethodInfo target) {
            _target = (Action<T0, T1, T2, T3, T4, T5, T6, T7>)target.CreateDelegate(typeof(Action<T0, T1, T2, T3, T4, T5, T6, T7>));
        }

        public override object Invoke(object arg0, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7) {
            _target(arg0 != null ? (T0)arg0 : default(T0), arg1 != null ? (T1)arg1 : default(T1), arg2 != null ? (T2)arg2 : default(T2), arg3 != null ? (T3)arg3 : default(T3), arg4 != null ? (T4)arg4 : default(T4), arg5 != null ? (T5)arg5 : default(T5), arg6 != null ? (T6)arg6 : default(T6), arg7 != null ? (T7)arg7 : default(T7));
            return null;
        }

        public override int Run(InterpretedFrame frame) {
            _target((T0)frame.Data[frame.StackIndex - 8], (T1)frame.Data[frame.StackIndex - 7], (T2)frame.Data[frame.StackIndex - 6], (T3)frame.Data[frame.StackIndex - 5], (T4)frame.Data[frame.StackIndex - 4], (T5)frame.Data[frame.StackIndex - 3], (T6)frame.Data[frame.StackIndex - 2], (T7)frame.Data[frame.StackIndex - 1]);
            frame.StackIndex -= 8;
            return 1;
        }
    }

    internal sealed class ActionCallInstruction<T0, T1, T2, T3, T4, T5, T6, T7, T8> : CallInstruction {
        private readonly Action<T0, T1, T2, T3, T4, T5, T6, T7, T8> _target;
        public override MethodInfo Info { get { return _target.GetMethodInfo(); } }
        public override int ArgumentCount { get { return 9; } }

        public ActionCallInstruction(Action<T0, T1, T2, T3, T4, T5, T6, T7, T8> target) {
            _target = target;
        }

        public ActionCallInstruction(MethodInfo target) {
            _target = (Action<T0, T1, T2, T3, T4, T5, T6, T7, T8>)target.CreateDelegate(typeof(Action<T0, T1, T2, T3, T4, T5, T6, T7, T8>));
        }

        public override object Invoke(object arg0, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8) {
            _target(arg0 != null ? (T0)arg0 : default(T0), arg1 != null ? (T1)arg1 : default(T1), arg2 != null ? (T2)arg2 : default(T2), arg3 != null ? (T3)arg3 : default(T3), arg4 != null ? (T4)arg4 : default(T4), arg5 != null ? (T5)arg5 : default(T5), arg6 != null ? (T6)arg6 : default(T6), arg7 != null ? (T7)arg7 : default(T7), arg8 != null ? (T8)arg8 : default(T8));
            return null;
        }

        public override int Run(InterpretedFrame frame) {
            _target((T0)frame.Data[frame.StackIndex - 9], (T1)frame.Data[frame.StackIndex - 8], (T2)frame.Data[frame.StackIndex - 7], (T3)frame.Data[frame.StackIndex - 6], (T4)frame.Data[frame.StackIndex - 5], (T5)frame.Data[frame.StackIndex - 4], (T6)frame.Data[frame.StackIndex - 3], (T7)frame.Data[frame.StackIndex - 2], (T8)frame.Data[frame.StackIndex - 1]);
            frame.StackIndex -= 9;
            return 1;
        }
    }

    internal sealed class FuncCallInstruction<TRet> : CallInstruction {
        private readonly Func<TRet> _target;
        public override MethodInfo Info { get { return _target.GetMethodInfo(); } }
        public override int ArgumentCount { get { return 0; } }

        public FuncCallInstruction(Func<TRet> target) {
            _target = target;
        }

        public FuncCallInstruction(MethodInfo target) {
            _target = (Func<TRet>)target.CreateDelegate(typeof(Func<TRet>));
        }

        public override object Invoke() {
            return _target();
        }

        public override int Run(InterpretedFrame frame) {
            frame.Data[frame.StackIndex - 0] = _target();
            frame.StackIndex -= -1;
            return 1;
        }
    }

    internal sealed class FuncCallInstruction<T0, TRet> : CallInstruction {
        private readonly Func<T0, TRet> _target;
        public override MethodInfo Info { get { return _target.GetMethodInfo(); } }
        public override int ArgumentCount { get { return 1; } }

        public FuncCallInstruction(Func<T0, TRet> target) {
            _target = target;
        }

        public FuncCallInstruction(MethodInfo target) {
            _target = (Func<T0, TRet>)target.CreateDelegate(typeof(Func<T0, TRet>));
        }

        public override object Invoke(object arg0) {
            return _target(arg0 != null ? (T0)arg0 : default(T0));
        }

        public override int Run(InterpretedFrame frame) {
            frame.Data[frame.StackIndex - 1] = _target((T0)frame.Data[frame.StackIndex - 1]);
            frame.StackIndex -= 0;
            return 1;
        }
    }

    internal sealed class FuncCallInstruction<T0, T1, TRet> : CallInstruction {
        private readonly Func<T0, T1, TRet> _target;
        public override MethodInfo Info { get { return _target.GetMethodInfo(); } }
        public override int ArgumentCount { get { return 2; } }

        public FuncCallInstruction(Func<T0, T1, TRet> target) {
            _target = target;
        }

        public FuncCallInstruction(MethodInfo target) {
            _target = (Func<T0, T1, TRet>)target.CreateDelegate(typeof(Func<T0, T1, TRet>));
        }

        public override object Invoke(object arg0, object arg1) {
            return _target(arg0 != null ? (T0)arg0 : default(T0), arg1 != null ? (T1)arg1 : default(T1));
        }

        public override int Run(InterpretedFrame frame) {
            frame.Data[frame.StackIndex - 2] = _target((T0)frame.Data[frame.StackIndex - 2], (T1)frame.Data[frame.StackIndex - 1]);
            frame.StackIndex -= 1;
            return 1;
        }
    }

    internal sealed class FuncCallInstruction<T0, T1, T2, TRet> : CallInstruction {
        private readonly Func<T0, T1, T2, TRet> _target;
        public override MethodInfo Info { get { return _target.GetMethodInfo(); } }
        public override int ArgumentCount { get { return 3; } }

        public FuncCallInstruction(Func<T0, T1, T2, TRet> target) {
            _target = target;
        }

        public FuncCallInstruction(MethodInfo target) {
            _target = (Func<T0, T1, T2, TRet>)target.CreateDelegate(typeof(Func<T0, T1, T2, TRet>));
        }

        public override object Invoke(object arg0, object arg1, object arg2) {
            return _target(arg0 != null ? (T0)arg0 : default(T0), arg1 != null ? (T1)arg1 : default(T1), arg2 != null ? (T2)arg2 : default(T2));
        }

        public override int Run(InterpretedFrame frame) {
            frame.Data[frame.StackIndex - 3] = _target((T0)frame.Data[frame.StackIndex - 3], (T1)frame.Data[frame.StackIndex - 2], (T2)frame.Data[frame.StackIndex - 1]);
            frame.StackIndex -= 2;
            return 1;
        }
    }

    internal sealed class FuncCallInstruction<T0, T1, T2, T3, TRet> : CallInstruction {
        private readonly Func<T0, T1, T2, T3, TRet> _target;
        public override MethodInfo Info { get { return _target.GetMethodInfo(); } }
        public override int ArgumentCount { get { return 4; } }

        public FuncCallInstruction(Func<T0, T1, T2, T3, TRet> target) {
            _target = target;
        }

        public FuncCallInstruction(MethodInfo target) {
            _target = (Func<T0, T1, T2, T3, TRet>)target.CreateDelegate(typeof(Func<T0, T1, T2, T3, TRet>));
        }

        public override object Invoke(object arg0, object arg1, object arg2, object arg3) {
            return _target(arg0 != null ? (T0)arg0 : default(T0), arg1 != null ? (T1)arg1 : default(T1), arg2 != null ? (T2)arg2 : default(T2), arg3 != null ? (T3)arg3 : default(T3));
        }

        public override int Run(InterpretedFrame frame) {
            frame.Data[frame.StackIndex - 4] = _target((T0)frame.Data[frame.StackIndex - 4], (T1)frame.Data[frame.StackIndex - 3], (T2)frame.Data[frame.StackIndex - 2], (T3)frame.Data[frame.StackIndex - 1]);
            frame.StackIndex -= 3;
            return 1;
        }
    }

    internal sealed class FuncCallInstruction<T0, T1, T2, T3, T4, TRet> : CallInstruction {
        private readonly Func<T0, T1, T2, T3, T4, TRet> _target;
        public override MethodInfo Info { get { return _target.GetMethodInfo(); } }
        public override int ArgumentCount { get { return 5; } }

        public FuncCallInstruction(Func<T0, T1, T2, T3, T4, TRet> target) {
            _target = target;
        }

        public FuncCallInstruction(MethodInfo target) {
            _target = (Func<T0, T1, T2, T3, T4, TRet>)target.CreateDelegate(typeof(Func<T0, T1, T2, T3, T4, TRet>));
        }

        public override object Invoke(object arg0, object arg1, object arg2, object arg3, object arg4) {
            return _target(arg0 != null ? (T0)arg0 : default(T0), arg1 != null ? (T1)arg1 : default(T1), arg2 != null ? (T2)arg2 : default(T2), arg3 != null ? (T3)arg3 : default(T3), arg4 != null ? (T4)arg4 : default(T4));
        }

        public override int Run(InterpretedFrame frame) {
            frame.Data[frame.StackIndex - 5] = _target((T0)frame.Data[frame.StackIndex - 5], (T1)frame.Data[frame.StackIndex - 4], (T2)frame.Data[frame.StackIndex - 3], (T3)frame.Data[frame.StackIndex - 2], (T4)frame.Data[frame.StackIndex - 1]);
            frame.StackIndex -= 4;
            return 1;
        }
    }

    internal sealed class FuncCallInstruction<T0, T1, T2, T3, T4, T5, TRet> : CallInstruction {
        private readonly Func<T0, T1, T2, T3, T4, T5, TRet> _target;
        public override MethodInfo Info { get { return _target.GetMethodInfo(); } }
        public override int ArgumentCount { get { return 6; } }

        public FuncCallInstruction(Func<T0, T1, T2, T3, T4, T5, TRet> target) {
            _target = target;
        }

        public FuncCallInstruction(MethodInfo target) {
            _target = (Func<T0, T1, T2, T3, T4, T5, TRet>)target.CreateDelegate(typeof(Func<T0, T1, T2, T3, T4, T5, TRet>));
        }

        public override object Invoke(object arg0, object arg1, object arg2, object arg3, object arg4, object arg5) {
            return _target(arg0 != null ? (T0)arg0 : default(T0), arg1 != null ? (T1)arg1 : default(T1), arg2 != null ? (T2)arg2 : default(T2), arg3 != null ? (T3)arg3 : default(T3), arg4 != null ? (T4)arg4 : default(T4), arg5 != null ? (T5)arg5 : default(T5));
        }

        public override int Run(InterpretedFrame frame) {
            frame.Data[frame.StackIndex - 6] = _target((T0)frame.Data[frame.StackIndex - 6], (T1)frame.Data[frame.StackIndex - 5], (T2)frame.Data[frame.StackIndex - 4], (T3)frame.Data[frame.StackIndex - 3], (T4)frame.Data[frame.StackIndex - 2], (T5)frame.Data[frame.StackIndex - 1]);
            frame.StackIndex -= 5;
            return 1;
        }
    }

    internal sealed class FuncCallInstruction<T0, T1, T2, T3, T4, T5, T6, TRet> : CallInstruction {
        private readonly Func<T0, T1, T2, T3, T4, T5, T6, TRet> _target;
        public override MethodInfo Info { get { return _target.GetMethodInfo(); } }
        public override int ArgumentCount { get { return 7; } }

        public FuncCallInstruction(Func<T0, T1, T2, T3, T4, T5, T6, TRet> target) {
            _target = target;
        }

        public FuncCallInstruction(MethodInfo target) {
            _target = (Func<T0, T1, T2, T3, T4, T5, T6, TRet>)target.CreateDelegate(typeof(Func<T0, T1, T2, T3, T4, T5, T6, TRet>));
        }

        public override object Invoke(object arg0, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6) {
            return _target(arg0 != null ? (T0)arg0 : default(T0), arg1 != null ? (T1)arg1 : default(T1), arg2 != null ? (T2)arg2 : default(T2), arg3 != null ? (T3)arg3 : default(T3), arg4 != null ? (T4)arg4 : default(T4), arg5 != null ? (T5)arg5 : default(T5), arg6 != null ? (T6)arg6 : default(T6));
        }

        public override int Run(InterpretedFrame frame) {
            frame.Data[frame.StackIndex - 7] = _target((T0)frame.Data[frame.StackIndex - 7], (T1)frame.Data[frame.StackIndex - 6], (T2)frame.Data[frame.StackIndex - 5], (T3)frame.Data[frame.StackIndex - 4], (T4)frame.Data[frame.StackIndex - 3], (T5)frame.Data[frame.StackIndex - 2], (T6)frame.Data[frame.StackIndex - 1]);
            frame.StackIndex -= 6;
            return 1;
        }
    }

    internal sealed class FuncCallInstruction<T0, T1, T2, T3, T4, T5, T6, T7, TRet> : CallInstruction {
        private readonly Func<T0, T1, T2, T3, T4, T5, T6, T7, TRet> _target;
        public override MethodInfo Info { get { return _target.GetMethodInfo(); } }
        public override int ArgumentCount { get { return 8; } }

        public FuncCallInstruction(Func<T0, T1, T2, T3, T4, T5, T6, T7, TRet> target) {
            _target = target;
        }

        public FuncCallInstruction(MethodInfo target) {
            _target = (Func<T0, T1, T2, T3, T4, T5, T6, T7, TRet>)target.CreateDelegate(typeof(Func<T0, T1, T2, T3, T4, T5, T6, T7, TRet>));
        }

        public override object Invoke(object arg0, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7) {
            return _target(arg0 != null ? (T0)arg0 : default(T0), arg1 != null ? (T1)arg1 : default(T1), arg2 != null ? (T2)arg2 : default(T2), arg3 != null ? (T3)arg3 : default(T3), arg4 != null ? (T4)arg4 : default(T4), arg5 != null ? (T5)arg5 : default(T5), arg6 != null ? (T6)arg6 : default(T6), arg7 != null ? (T7)arg7 : default(T7));
        }

        public override int Run(InterpretedFrame frame) {
            frame.Data[frame.StackIndex - 8] = _target((T0)frame.Data[frame.StackIndex - 8], (T1)frame.Data[frame.StackIndex - 7], (T2)frame.Data[frame.StackIndex - 6], (T3)frame.Data[frame.StackIndex - 5], (T4)frame.Data[frame.StackIndex - 4], (T5)frame.Data[frame.StackIndex - 3], (T6)frame.Data[frame.StackIndex - 2], (T7)frame.Data[frame.StackIndex - 1]);
            frame.StackIndex -= 7;
            return 1;
        }
    }

    internal sealed class FuncCallInstruction<T0, T1, T2, T3, T4, T5, T6, T7, T8, TRet> : CallInstruction {
        private readonly Func<T0, T1, T2, T3, T4, T5, T6, T7, T8, TRet> _target;
        public override MethodInfo Info { get { return _target.GetMethodInfo(); } }
        public override int ArgumentCount { get { return 9; } }

        public FuncCallInstruction(Func<T0, T1, T2, T3, T4, T5, T6, T7, T8, TRet> target) {
            _target = target;
        }

        public FuncCallInstruction(MethodInfo target) {
            _target = (Func<T0, T1, T2, T3, T4, T5, T6, T7, T8, TRet>)target.CreateDelegate(typeof(Func<T0, T1, T2, T3, T4, T5, T6, T7, T8, TRet>));
        }

        public override object Invoke(object arg0, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8) {
            return _target(arg0 != null ? (T0)arg0 : default(T0), arg1 != null ? (T1)arg1 : default(T1), arg2 != null ? (T2)arg2 : default(T2), arg3 != null ? (T3)arg3 : default(T3), arg4 != null ? (T4)arg4 : default(T4), arg5 != null ? (T5)arg5 : default(T5), arg6 != null ? (T6)arg6 : default(T6), arg7 != null ? (T7)arg7 : default(T7), arg8 != null ? (T8)arg8 : default(T8));
        }

        public override int Run(InterpretedFrame frame) {
            frame.Data[frame.StackIndex - 9] = _target((T0)frame.Data[frame.StackIndex - 9], (T1)frame.Data[frame.StackIndex - 8], (T2)frame.Data[frame.StackIndex - 7], (T3)frame.Data[frame.StackIndex - 6], (T4)frame.Data[frame.StackIndex - 5], (T5)frame.Data[frame.StackIndex - 4], (T6)frame.Data[frame.StackIndex - 3], (T7)frame.Data[frame.StackIndex - 2], (T8)frame.Data[frame.StackIndex - 1]);
            frame.StackIndex -= 8;
            return 1;
        }
    }

    internal sealed partial class MethodInfoCallInstruction : CallInstruction {
        public override object Invoke() {
            return InvokeWorker();
        }
        public override object Invoke(object arg0) {
            return InvokeWorker(arg0);
        }
        public override object Invoke(object arg0, object arg1) {
            return InvokeWorker(arg0, arg1);
        }
    }

    // *** END GENERATED CODE ***

    #endregion
}
