private FunctionIdentifier(string methodName, FunctionMethod method, AbstractInstruction instruction)
 {
     Code        = FunctionCode.__NULL__;
     ArgBuilder  = instruction.ArgBuilder;
     flag        = instruction.Flag;
     Method      = method;
     Name        = methodName;
     Instruction = instruction;
 }
Exemple #2
0
 public static void Register(FunctionKey functionKey, FunctionMethod functionMethod)
 {
     if (Hooks.ContainsKey(functionKey))
     {
         Hooks[functionKey] = functionMethod;
     }
     else
     {
         Hooks.Add(functionKey, functionMethod);
     }
 }
Exemple #3
0
 public static void Register(FunctionKey functionKey, FunctionMethod functionMethod)
 {
     if (Hooks.ContainsKey(functionKey))
     {
         Hooks[functionKey] = functionMethod;
     }
     else
     {
         Hooks.Add(functionKey, functionMethod);
     }
 }
Exemple #4
0
        // REF: https://github.com/OData/WebApi/blob/master/src/Microsoft.AspNet.OData.Shared/Routing/Conventions/ActionRoutingConvention.cs
        // REF: https://github.com/OData/WebApi/blob/master/src/Microsoft.AspNet.OData.Shared/Routing/Conventions/FunctionRoutingConvention.cs
        // REF: https://github.com/OData/WebApi/blob/master/src/Microsoft.AspNet.OData.Shared/Routing/Conventions/EntitySetRoutingConvention.cs
        // REF: https://github.com/OData/WebApi/blob/master/src/Microsoft.AspNet.OData.Shared/Routing/Conventions/EntityRoutingConvention.cs
        // REF: https://github.com/OData/WebApi/blob/master/src/Microsoft.AspNet.OData.Shared/Routing/Conventions/SingletonRoutingConvention.cs
        static bool IsActionOrFunction(IEdmEntitySet?entitySet, IEdmSingleton?singleton, string actionName, IEnumerable <string> methods)
        {
            using var iterator = methods.GetEnumerator();

            if (!iterator.MoveNext())
            {
                return(false);
            }

            var method = iterator.Current;

            if (iterator.MoveNext())
            {
                return(false);
            }

            if (entitySet == null && singleton == null)
            {
                return(true);
            }

            const string ActionMethod      = "Post";
            const string AddNavigationLink = ActionMethod + "To";
            const string FunctionMethod    = "Get";

            if (ActionMethod.Equals(method, OrdinalIgnoreCase) && actionName != ActionMethod)
            {
                if (actionName.StartsWith("CreateRef", Ordinal) ||
                    (entitySet != null && actionName == (ActionMethod + entitySet.Name)))
                {
                    return(false);
                }

                return(!IsNavigationPropertyLink(entitySet, singleton, actionName, ActionMethod, AddNavigationLink));
            }
            else if (FunctionMethod.Equals(method, OrdinalIgnoreCase) && actionName != FunctionMethod)
            {
                if (actionName.StartsWith("GetRef", Ordinal) ||
                    (entitySet != null && actionName == (FunctionMethod + entitySet.Name)))
                {
                    return(false);
                }

                return(!IsNavigationPropertyLink(entitySet, singleton, actionName, FunctionMethod));
            }

            return(false);
        }
        public UserdataMethod MakeGenericMethod(Type[] parameters)
        {
            List <MethodInfo> methods = new List <MethodInfo>();

            for (int i = 0; i < m_Count; ++i)
            {
                FunctionMethod method = m_Methods[i] as FunctionMethod;
                if (method != null)
                {
                    if (method.Method.IsGenericMethod)
                    {
                        Type[] types = method.Method.GetGenericArguments();
                        if (types.Length == parameters.Length)
                        {
                            bool accord = true;
                            int  length = types.Length;
                            for (int j = 0; j < length; ++j)
                            {
#if UWP
                                if (!types[j].GetTypeInfo().BaseType.IsAssignableFrom(parameters[j]))
                                {
                                    accord = false;
                                    break;
                                }
#else
                                if (!types[j].BaseType.IsAssignableFrom(parameters[j]))
                                {
                                    accord = false;
                                    break;
                                }
#endif
                            }
                            if (accord)
                            {
                                methods.Add(method.Method.MakeGenericMethod(parameters));
                                break;
                            }
                        }
                    }
                }
            }
            if (methods.Count > 0)
            {
                return(new UserdataMethod(m_Script, m_Type, MethodName, methods));
            }
            throw new ExecutionException(m_Script, "没有找到合适的泛型函数 " + MethodName);
        }
 public UserdataMethod MakeGenericMethod(Type[] parameters)
 {
     if ((this.m_GenericCount > 0) && (this.m_GenericMethods != null))
     {
         List <MethodInfo> methods = new List <MethodInfo>();
         for (int i = 0; i < this.m_GenericCount; i++)
         {
             FunctionMethod method = this.m_GenericMethods[i] as FunctionMethod;
             if (method != null)
             {
                 Type[] genericArguments = method.Method.GetGenericArguments();
                 if (genericArguments.Length == parameters.Length)
                 {
                     bool flag   = true;
                     int  length = genericArguments.Length;
                     for (int j = 0; j < length; j++)
                     {
                         if (!genericArguments[j].GetTypeInfo().BaseType.GetTypeInfo().IsAssignableFrom(parameters[j]))
                         {
                             flag = false;
                             break;
                         }
                     }
                     if (flag)
                     {
                         methods.Add(method.Method.MakeGenericMethod(parameters));
                         break;
                     }
                 }
             }
         }
         if (methods.Count > 0)
         {
             return(new UserdataMethod(this.m_Script, this.m_Type, this.MethodName, methods));
         }
     }
     throw new ExecutionException(this.m_Script, "没有找到合适的泛型函数 " + this.MethodName);
 }
Exemple #7
0
        private void Initialize_impl(Type type, string methodName, List <MethodBase> methods)
        {
            m_Type       = type;
            m_IsClass    = type.IsClass;
            m_MethodName = methodName;
            List <FunctionBase> functionMethod = new List <FunctionBase>();
            List <FunctionBase> genericMethods = new List <FunctionBase>();
            bool Params    = false;                                 //是否是不定参函数
            Type ParamType = null;                                  //不定参类型

            ParameterInfo[] Parameters;                             //所有参数
            List <Type>     parameterTypes   = new List <Type>();   //参数类型
            List <object>   defaultParameter = new List <object>(); //默认参数
            int             length           = methods.Count;       //总数量
            MethodBase      method           = null;
            FunctionBase    functionBase;

            for (int i = 0; i < length; ++i)
            {
                method    = methods[i];
                Params    = false;
                ParamType = null;
                parameterTypes.Clear();
                defaultParameter.Clear();
                Parameters = method.GetParameters();
                if (Util.IsExtensionMethod(method))
                {
                    for (int j = 1; j < Parameters.Length; ++j)
                    {
                        var par = Parameters[j];
                        parameterTypes.Add(par.ParameterType);
                        if (par.DefaultValue != DBNull.Value)
                        {
                            defaultParameter.Add(par.DefaultValue);
                        }
                        Params = Util.IsParamArray(par);
                        if (Params)
                        {
                            ParamType = par.ParameterType.GetElementType();
                        }
                    }
                    functionBase = new ExtensionMethod(method as MethodInfo, parameterTypes.ToArray(), defaultParameter.ToArray(), ParamType, Params, "");
                }
                else
                {
                    foreach (ParameterInfo par in Parameters)
                    {
                        parameterTypes.Add(par.ParameterType);
                        if (par.DefaultValue != DBNull.Value)
                        {
                            defaultParameter.Add(par.DefaultValue);
                        }
                        Params = Util.IsParamArray(par);
                        if (Params)
                        {
                            ParamType = par.ParameterType.GetElementType();
                        }
                    }
                    if (method is MethodInfo)
                    {
                        functionBase = new FunctionMethod(method as MethodInfo, parameterTypes.ToArray(), defaultParameter.ToArray(), ParamType, Params, "");
                    }
                    else
                    {
                        functionBase = new FunctionConstructor(method as ConstructorInfo, parameterTypes.ToArray(), defaultParameter.ToArray(), ParamType, Params, "");
                    }
                }
                if (functionBase.IsGeneric)
                {
                    genericMethods.Add(functionBase);
                }
                else
                {
                    functionMethod.Add(functionBase);
                }
            }
            m_Methods        = functionMethod.ToArray();
            m_Count          = m_Methods.Length;
            m_GenericMethods = genericMethods.ToArray();
            m_GenericCount   = m_GenericMethods.Length;
        }
Exemple #8
0
        public IOperandTerm GetFunctionMethod(LabelDictionary labelDic, string codeStr, IOperandTerm[] arguments, bool userDefinedOnly)
        {
            if (Config.ICFunction)
            {
                codeStr = codeStr.ToUpper();
            }
            if (arguments == null)            //引数なし、名前のみの探索
            {
                if (refmethodDic.ContainsKey(codeStr))
                {
                    return(new UserDefinedRefMethodNoArgTerm(refmethodDic[codeStr]));
                }
                return(null);
            }
            if ((labelDic != null) && (labelDic.Initialized))
            {
                if (refmethodDic.ContainsKey(codeStr))
                {
                    return(new UserDefinedRefMethodTerm(refmethodDic[codeStr], arguments));
                }
                FunctionLabelLine func = labelDic.GetNonEventLabel(codeStr);
                if (func != null)
                {
                    if (userDefinedOnly && !func.IsMethod)
                    {
                        throw new CodeEE("#FUNCTIONが指定されていない関数\"@" + func.LabelName + "\"をCALLF系命令で呼び出そうとしました");
                    }
                    if (func.IsMethod)
                    {
                        string       errMes;
                        IOperandTerm ret = UserDefinedMethodTerm.Create(func, arguments, out errMes);
                        if (ret == null)
                        {
                            throw new CodeEE(errMes);
                        }
                        return(ret);
                    }
                    //1.721 #FUNCTIONが定義されていない関数は組み込み関数を上書きしない方向に。 PANCTION.ERBのRANDとか。
                    if (!methodDic.ContainsKey(codeStr))
                    {
                        throw new CodeEE("#FUNCTIONが定義されていない関数(" + func.Position.Filename + ":" + func.Position.LineNo + "行目)を式中で呼び出そうとしました");
                    }
                }
            }
            if (userDefinedOnly)
            {
                return(null);
            }
            FunctionMethod method = null;

            if (!methodDic.TryGetValue(codeStr, out method))
            {
                return(null);
            }
            string errmes = method.CheckArgumentType(codeStr, arguments);

            if (errmes != null)
            {
                throw new CodeEE(errmes);
            }
            return(new FunctionMethodTerm(method, arguments));
        }
        /// <summary>
        ///     1803beta005 予め引数の数を合わせて規定値を代入しておく
        ///     1806+v6.99 式中関数の引数に無効な#DIM変数を与えている場合に例外になるのを修正
        ///     1808beta009 REF型に対応
        /// </summary>
        public UserDefinedFunctionArgument ConvertArg(IOperandTerm[] srcArgs, out string errMes)
        {
            errMes = null;
            if (TopLabel.IsError)
            {
                errMes = TopLabel.ErrMes;
                return(null);
            }
            var func         = TopLabel;
            var convertedArg = new IOperandTerm[func.Arg.Length];

            if (convertedArg.Length < srcArgs.Length)
            {
                errMes = "引数の数が関数\"@" + func.LabelName + "\"に設定された数を超えています";
                return(null);
            }
            IOperandTerm term     = null;
            VariableTerm destArg  = null;
            var          isString = false;

            for (var i = 0; i < func.Arg.Length; i++)
            {
                term     = i < srcArgs.Length ? srcArgs[i] : null;
                destArg  = func.Arg[i];
                isString = destArg.IsString;
                if (destArg.Identifier.IsReference) //参照渡しの場合
                {
                    if (term == null)
                    {
                        errMes = "\"@" + func.LabelName + "\"の" + (i + 1) + "番目の引数は参照渡しのため省略できません";
                        return(null);
                    }
                    var vTerm = term as VariableTerm;
                    if (vTerm == null || vTerm.Identifier.Dimension == 0)
                    {
                        errMes = "\"@" + func.LabelName + "\"の" + (i + 1) + "番目の引数は参照渡しのための配列変数でなければなりません";
                        return(null);
                    }
                    //TODO 1810alpha007 キャラ型を認めるかどうかはっきりしたい 今のところ認めない方向
                    //型チェック
                    if (!((ReferenceToken)destArg.Identifier).MatchType(vTerm.Identifier, false, out errMes))
                    {
                        errMes = "\"@" + func.LabelName + "\"の" + (i + 1) + "番目の引数:" + errMes;
                        return(null);
                    }
                }
                else if (term == null)  //引数が省略されたとき
                {
                    term = func.Def[i]; //デフォルト値を代入
                    //1808beta001 デフォルト値がない場合はエラーにする
                    //一応逃がす
                    if (term == null && !Config.CompatiFuncArgOptional)
                    {
                        errMes = "\"@" + func.LabelName + "\"の" + (i + 1) + "番目の引数は省略できません(この警告は互換性オプション「" +
                                 Config.GetConfigName(ConfigCode.CompatiFuncArgOptional) + "」により無視できます)";
                        return(null);
                    }
                }
                else if (term.GetOperandType() != destArg.GetOperandType())
                {
                    if (term.GetOperandType() == typeof(string))
                    {
                        errMes = "\"@" + func.LabelName + "\"の" + (i + 1) + "番目の引数を文字列型から整数型に変換できません";
                        return(null);
                    }
                    if (!Config.CompatiFuncArgAutoConvert)
                    {
                        errMes = "\"@" + func.LabelName + "\"の" + (i + 1) + "番目の引数を整数型から文字列型に変換できません(この警告は互換性オプション「" +
                                 Config.GetConfigName(ConfigCode.CompatiFuncArgAutoConvert) + "」により無視できます)";
                        return(null);
                    }
                    if (tostrMethod == null)
                    {
                        tostrMethod = FunctionMethodCreator.GetMethodList()["TOSTR"];
                    }
                    term = new FunctionMethodTerm(tostrMethod, new[] { term });
                }
                convertedArg[i] = term;
            }
            return(new UserDefinedFunctionArgument(convertedArg, func.Arg));
        }
 private void Initialize_impl(Type type, string methodName, List<MethodBase> methods)
 {
     m_Type = type;
     m_MethodName = methodName;
     List<FunctionBase> functionMethod = new List<FunctionBase>();
     List<FunctionBase> genericMethods = new List<FunctionBase>();
     bool Params = false;                                    //是否是不定参函数
     Type ParamType = null;                                  //不定参类型
     ParameterInfo[] Parameters;                             //所有参数
     List<Type> parameterTypes = new List<Type>();           //参数类型
     List<object> defaultParameter = new List<object>();     //默认参数
     int length = methods.Count;                             //总数量
     MethodBase method = null;
     FunctionBase functionBase;
     for (int i = 0; i < length; ++i) {
         method = methods[i];
         Params = false;
         ParamType = null;
         parameterTypes.Clear();
         defaultParameter.Clear();
         Parameters = method.GetParameters();
         if (Util.IsExtensionMethod(method)) {
             for (int j = 1; j < Parameters.Length; ++j) {
                 var par = Parameters[j];
                 parameterTypes.Add(par.ParameterType);
                 if (par.DefaultValue != DBNull.Value) { defaultParameter.Add(par.DefaultValue); }
                 Params = Util.IsParamArray(par);
                 if (Params) ParamType = par.ParameterType.GetElementType();
             }
             functionBase = new ExtensionMethod(method as MethodInfo, parameterTypes.ToArray(), defaultParameter.ToArray(), ParamType, Params, "");
         } else {
             foreach (ParameterInfo par in Parameters) {
                 parameterTypes.Add(par.ParameterType);
                 if (par.DefaultValue != DBNull.Value) { defaultParameter.Add(par.DefaultValue); }
                 Params = Util.IsParamArray(par);
                 if (Params) ParamType = par.ParameterType.GetElementType();
             }
             if (method is MethodInfo)
                 functionBase = new FunctionMethod(method as MethodInfo, parameterTypes.ToArray(), defaultParameter.ToArray(), ParamType, Params, "");
             else
                 functionBase = new FunctionConstructor(method as ConstructorInfo, parameterTypes.ToArray(), defaultParameter.ToArray(), ParamType, Params, "");
         }
         if (functionBase.IsGeneric)
             genericMethods.Add(functionBase);
         else
             functionMethod.Add(functionBase);
     }
     m_Methods = functionMethod.ToArray();
     m_Count = m_Methods.Length;
     m_GenericMethods = genericMethods.ToArray();
     m_GenericCount = m_GenericMethods.Length;
 }
Exemple #11
0
        public object Call(ScriptObject[] parameters)
        {
            if (m_Count == 0)
            {
                throw new ScriptException("找不到函数 [" + MethodName + "]");
            }
            FunctionMethod methodInfo = null;

            if (m_Count == 1)
            {
                if (parameters.Length == m_Methods[0].ParameterType.Length)
                {
                    methodInfo = m_Methods[0];
                }
            }
            else
            {
                foreach (FunctionMethod method in m_Methods)
                {
                    if (Util.CanChangeType(parameters, method.ParameterType))
                    {
                        methodInfo = method;
                        break;
                    }
                }
            }
            if (methodInfo != null)
            {
                int      length = methodInfo.ParameterType.Length;
                object[] objs   = new object[length];
                for (int i = 0; i < length; i++)
                {
                    objs[i] = Util.ChangeType(parameters[i], methodInfo.ParameterType[i]);
                }
                return(methodInfo.Invoke(m_Object, objs));
            }
            else
            {
                foreach (FunctionMethod method in m_Methods)
                {
                    int length = method.ParameterType.Length;
                    if (method.Params && parameters.Length >= length - 1)
                    {
                        bool fit = true;
                        for (int i = 0; i < parameters.Length; ++i)
                        {
                            if (!Util.CanChangeType(parameters[i], i >= length - 1 ? method.ParamType : method.ParameterType[i]))
                            {
                                fit = false;
                                break;
                            }
                        }
                        if (fit)
                        {
                            object[] objs = new object[length];
                            for (int i = 0; i < length - 1; ++i)
                            {
                                objs[i] = Util.ChangeType(parameters[i], method.ParameterType[i]);
                            }
                            List <object> param = new List <object>();
                            for (int i = length - 1; i < parameters.Length; ++i)
                            {
                                param.Add(Util.ChangeType(parameters[i], method.ParamType));
                            }
                            objs[length - 1] = param.ToArray();
                            return(method.Invoke(m_Object, objs));
                        }
                    }
                }
                throw new ScriptException("找不到合适的函数 [" + MethodName + "]");
            }
        }
        public object Call(object obj, ScriptObject[] parameters)
        {
            if (m_Count == 0)
            {
                throw new ExecutionException(m_Script, "找不到函数 [" + MethodName + "]");
            }
            FunctionMethod methodInfo = null;

            if (m_Count == 1)
            {
                methodInfo = m_Methods[0];
                if (!methodInfo.IsValid)
                {
                    throw new ExecutionException(m_Script, "Type[" + m_Type.ToString() + "] 找不到合适的函数 [" + MethodName + "]");
                }
            }
            else
            {
                foreach (FunctionMethod method in m_Methods)
                {
                    if (method.IsValid && Util.CanChangeType(parameters, method.ParameterType))
                    {
                        methodInfo = method;
                        break;
                    }
                }
            }
            try {
                if (methodInfo != null && !methodInfo.Params)
                {
                    int      length = methodInfo.ParameterType.Length;
                    object[] objs   = methodInfo.Args;
                    for (int i = 0; i < length; i++)
                    {
                        objs[i] = Util.ChangeType(m_Script, parameters[i], methodInfo.ParameterType[i]);
                    }
                    return(methodInfo.Invoke(obj, m_Type));
                }
                else
                {
                    foreach (FunctionMethod method in m_Methods)
                    {
                        int length = method.ParameterType.Length;
                        if (method.Params && parameters.Length >= length - 1)
                        {
                            bool fit = true;
                            for (int i = 0; i < parameters.Length; ++i)
                            {
                                if (!Util.CanChangeType(parameters[i], i >= length - 1 ? method.ParamType : method.ParameterType[i]))
                                {
                                    fit = false;
                                    break;
                                }
                            }
                            if (fit)
                            {
                                object[] objs = method.Args;
                                for (int i = 0; i < length - 1; ++i)
                                {
                                    objs[i] = Util.ChangeType(m_Script, parameters[i], method.ParameterType[i]);
                                }
                                Array array = Array.CreateInstance(method.ParamType, parameters.Length - length + 1);
                                for (int i = length - 1; i < parameters.Length; ++i)
                                {
                                    array.SetValue(Util.ChangeType(m_Script, parameters[i], method.ParamType), i - length + 1);
                                }
                                objs[length - 1] = array;
                                return(method.Invoke(obj, m_Type));
                            }
                        }
                    }
                }
            } catch (System.Exception e) {
                throw new ExecutionException(m_Script, "Type[" + m_Type.ToString() + "] 调用函数出错 [" + MethodName + "] : " + e.ToString());
            }
            throw new ExecutionException(m_Script, "Type[" + m_Type.ToString() + "] 找不到合适的函数 [" + MethodName + "]");
        }
Exemple #13
0
        internal FunctionEmitter(IR.Function function, MethodFactory methodFactory, FunctionLookup functionLookup)
        {
            Contract.Requires(function != null);
            Contract.Requires(methodFactory != null);
            Contract.Requires(functionLookup != null);

            this.declaration    = function;
            this.functionLookup = functionLookup;
            var signature = new FunctionSignature(function.Inputs.Select(i => i.StaticRepr), function.Outputs.Select(o => o.StaticRepr));

            // Determine the method signature
            var parameterDescriptors = new List <ParameterDescriptor>();

            foreach (var input in function.Inputs)
            {
                locals.Add(input, VariableLocation.Parameter(parameterDescriptors.Count));
                parameterDescriptors.Add(new ParameterDescriptor(input.StaticCliType, ParameterAttributes.None, input.Name));
            }

            Type returnType = typeof(void);

            if (function.Outputs.Length == 1)
            {
                returnType = function.Outputs[0].StaticCliType;                 // 1 output, use return value
            }
            else if (function.Outputs.Length >= 2)
            {
                // 2 or more outputs, use 'out' parameters
                foreach (var output in function.Outputs)
                {
                    string name = output.Name;
                    if (locals.ContainsKey(output))
                    {
                        // inout parameter, rename not to clash with input
                        name += "$out";
                    }
                    else
                    {
                        locals.Add(output, VariableLocation.Parameter(parameterDescriptors.Count));
                    }

                    var parameterType = output.StaticCliType.MakeByRefType();
                    parameterDescriptors.Add(new ParameterDescriptor(parameterType, ParameterAttributes.Out, name));
                }
            }

            // Create the method and get its IL generator
            ILGenerator ilGenerator;
            var         methodInfo = methodFactory(function.Name, parameterDescriptors, returnType, out ilGenerator);

            this.method = new FunctionMethod(methodInfo, signature);

            cil = new ILGeneratorMethodBodyWriter(ilGenerator);
            cil = new MethodBodyVerifier(new MethodBodyVerificationContext
            {
                Method         = methodInfo,
                ParameterTypes = parameterDescriptors.Select(p => p.Type).ToArray(),
                ReturnType     = returnType,
                HasInitLocals  = true,
                MaxStackSize   = ushort.MaxValue
            }, cil);

            temporaryPool = new TemporaryLocalPool(cil, "$temp");

            if (function.Outputs.Length == 1)
            {
                // Declare a local variable for the return value
                var output     = function.Outputs[0];
                var localIndex = cil.DeclareLocal(output.StaticCliType, output.Name);
                if (!function.Inputs.Contains(output))
                {
                    locals.Add(output, VariableLocation.Local(localIndex));
                }
            }
        }
Exemple #14
0
        public void DefineAndExecuteSimpleFunctionMethod()
        {
            FunctionMethod method = new FunctionMethod((context, receiver, arguments) => "Foo");

            Assert.AreEqual("Foo", method.Execute(null, null, null));
        }
Exemple #15
0
        private void EmitCall(ImmutableArray <Variable> targets, FunctionMethod function, ImmutableArray <Variable> arguments)
        {
            var signature = function.Signature;

            Contract.Assert(arguments.Length == signature.Inputs.Count);
            Contract.Assert(targets.Length <= signature.Outputs.Count);

            // Prepare the eventual return value store
            if (signature.HasReturnValue && targets.Length == 1)
            {
                BeginEmitStore(targets[0]);
            }

            // Push the input arguments
            for (int i = 0; i < arguments.Length; ++i)
            {
                var argument = arguments[i];
                EmitLoad(argument);
                EmitConvert(argument.StaticRepr, signature.Inputs[i]);
            }

            if (signature.OutParameterCount > 0)
            {
                // Push the pointers to the output arguments
                for (int i = 0; i < signature.Outputs.Count; ++i)
                {
                    if (i < targets.Length)
                    {
                        var target   = targets[i];
                        var location = GetLocation(target);
                        if (declaration.Outputs.Contains(target) && declaration.Outputs.Length >= 2)
                        {
                            cil.Load(location);                             // Target is a ByRef parameter, so already a (managed) pointer
                        }
                        else
                        {
                            cil.LoadAddress(location);
                        }
                    }
                    else
                    {
                        throw new NotImplementedException("Ignored outputs of a multi-output function.");
                    }
                }
            }

            // Call the function
            var method = function.Method;

            if (method is System.Reflection.Emit.MethodBuilder)
            {
                // We have to supply the parameter types ourselves since MethodBodyWriter
                // can't call MethodBuilder.GetParameters() without receiving an exception.
                cil.Call(Opcode.GetDefaultCall(method), method,
                         function.Signature.GetParameterCliTypes(), function.Signature.ReturnCliType);
            }
            else
            {
                // We're calling a builtin
                var builtinCilOpcodeAttribute = method.GetCustomAttribute <BuiltinCilOpcodeAttribute>();
                if (builtinCilOpcodeAttribute == null)
                {
                    cil.Invoke(method);
                }
                else
                {
                    // Calling the builtin is equivalent to emitting a sequence of CIL opcodes, so do that instead
                    foreach (var opcodeValue in builtinCilOpcodeAttribute.Opcodes)
                    {
                        var opcode = Opcode.FromValue((OpcodeValue)opcodeValue);
                        Contract.Assert(opcode != null);
                        cil.Instruction(opcode);
                    }
                }
            }

            // Handle the return value, if any
            if (signature.HasReturnValue)
            {
                if (targets.Length == 1)
                {
                    EmitConvert(signature.Outputs[0], targets[0].StaticRepr);
                    EndEmitStore(targets[0]);
                }
                else
                {
                    // Return value ignored.
                    Contract.Assert(targets.Length == 0);
                    cil.Pop();
                }
            }
        }
        private void Initialize_impl(Type type, string methodName, List <MethodBase> methods)
        {
            this.m_Type       = type;
            this.m_MethodName = methodName;
            List <FunctionBase> list  = new List <FunctionBase>();
            List <FunctionBase> list2 = new List <FunctionBase>();
            bool          @params     = false;
            Type          paramType   = null;
            List <Type>   list3       = new List <Type>();
            List <object> list4       = new List <object>();
            int           count       = methods.Count;
            MethodBase    method      = null;

            for (int i = 0; i < count; i++)
            {
                FunctionBase base3;
                method    = methods[i];
                @params   = false;
                paramType = null;
                list3.Clear();
                list4.Clear();
                ParameterInfo[] parameters = method.GetParameters();
                if (Util.IsExtensionMethod(method))
                {
                    for (int j = 1; j < parameters.Length; j++)
                    {
                        ParameterInfo info = parameters[j];
                        list3.Add(info.ParameterType);
                        if (info.DefaultValue != DBNull.Value)
                        {
                            list4.Add(info.DefaultValue);
                        }
                        @params = Util.IsParamArray(info);
                        if (@params)
                        {
                            paramType = info.ParameterType.GetElementType();
                        }
                    }
                    base3 = new ExtensionMethod(method as MethodInfo, list3.ToArray(), list4.ToArray(), paramType, @params, "");
                }
                else
                {
                    foreach (ParameterInfo info2 in parameters)
                    {
                        list3.Add(info2.ParameterType);
                        if (info2.DefaultValue != DBNull.Value)
                        {
                            list4.Add(info2.DefaultValue);
                        }
                        @params = Util.IsParamArray(info2);
                        if (@params)
                        {
                            paramType = info2.ParameterType.GetElementType();
                        }
                    }
                    if (method is MethodInfo)
                    {
                        base3 = new FunctionMethod(method as MethodInfo, list3.ToArray(), list4.ToArray(), paramType, @params, "");
                    }
                    else
                    {
                        base3 = new FunctionConstructor(method as ConstructorInfo, list3.ToArray(), list4.ToArray(), paramType, @params, "");
                    }
                }
                if (base3.IsGeneric)
                {
                    list2.Add(base3);
                }
                else
                {
                    list.Add(base3);
                }
            }
            this.m_Methods        = list.ToArray();
            this.m_Count          = this.m_Methods.Length;
            this.m_GenericMethods = list2.ToArray();
            this.m_GenericCount   = this.m_GenericMethods.Length;
        }