/*
  * Matches a method against its arguments in the Lua stack. Returns
  * if the match was succesful. It it was also returns the information
  * necessary to invoke the method.
  */
 internal bool matchParameters(IntPtr luaState,MethodBase method,ref MethodCache methodCache)
 {
     ExtractValue extractValue;
     bool isMethod=true;
     ParameterInfo[] paramInfo=method.GetParameters();
     int currentLuaParam=1;
     int nLuaParams=LuaDLL.lua_gettop(luaState);
     ArrayList paramList=new ArrayList();
     ArrayList outList=new ArrayList();
     ArrayList argTypes=new ArrayList();
     foreach(ParameterInfo currentNetParam in paramInfo)
     {
         if(!currentNetParam.IsIn && currentNetParam.IsOut)  // Skips out params
         {
             outList.Add(paramList.Add(null));
         }
         else if(currentLuaParam>nLuaParams) // Adds optional parameters
         {
             if(currentNetParam.IsOptional)
             {
                 paramList.Add(currentNetParam.DefaultValue);
             }
             else
             {
                 isMethod=false;
                 break;
             }
         }
         else if((extractValue=translator.typeChecker.checkType(luaState,currentLuaParam,currentNetParam.ParameterType))!=null)  // Type checking
         {
             int index=paramList.Add(extractValue(luaState,currentLuaParam));
             MethodArgs methodArg=new MethodArgs();
             methodArg.index=index;
             methodArg.extractValue=extractValue;
             argTypes.Add(methodArg);
             if(currentNetParam.ParameterType.IsByRef)
                 outList.Add(index);
             currentLuaParam++;
         }  // Type does not match, ignore if the parameter is optional
         else if(currentNetParam.IsOptional)
         {
             paramList.Add(currentNetParam.DefaultValue);
         }
         else  // No match
         {
             isMethod=false;
             break;
         }
     }
     if(currentLuaParam!=nLuaParams+1) // Number of parameters does not match
         isMethod=false;
     if(isMethod)
     {
         methodCache.args=paramList.ToArray();
         methodCache.cachedMethod=method;
         methodCache.outList=(int[])outList.ToArray(typeof(int));
         methodCache.argTypes=(MethodArgs[])argTypes.ToArray(typeof(MethodArgs));
     }
     return isMethod;
 }
Example #2
0
        /// <summary>
        /// __call metafunction of type references.
        /// Searches for and calls a constructor for the type.
        /// Returns nil if the constructor is not found or if the arguments are invalid.
        /// Throws an error if the constructor generates an exception.
        /// </summary>
        int classCall(lua.State L)
        {
            using (luanet.entercfunction(L, interpreter))
            {
                var klass            = _checktyperef(L);
                var validConstructor = new MethodCache();
                lua.remove(L, 1);
                var constructors = klass.UnderlyingSystemType.GetConstructors();

                foreach (ConstructorInfo constructor in constructors)
                {
                    if (translator.matchParameters(L, constructor, ref validConstructor))
                    {
                        if (!translator.memberIsAllowed(constructor))
                        {
                            if (constructors.Length == 1)
                            {
                                return(luaL.error(L, "constructor call failed (access denied)"));
                            }
                            continue;
                        }
                        object result;
                        try { result = constructor.Invoke(validConstructor.args); }
                        catch (TargetInvocationException ex) { return(translator.throwError(L, luaclr.verifyex(ex.InnerException))); }
                        catch (Exception ex) { return(luaL.error(L, "constructor call failed (" + ex.Message + ")")); }
                        translator.push(L, result);
                        return(1);
                    }
                }
                return(luaL.error(L, "constructor arguments do not match (" + klass.UnderlyingSystemType + ")"));
            }
        }
 public LuaMethodWrapper(ObjectTranslator translator, IReflect targetType, string methodName, BindingFlags bindingType)
 {
     this._LastCalledMethod = new MethodCache();
     this._Translator = translator;
     this._MethodName = methodName;
     this._TargetType = targetType;
     if (targetType != null)
     {
         this._ExtractTarget = translator.typeChecker.getExtractor(targetType);
     }
     this._BindingType = bindingType;
     this._Members = targetType.UnderlyingSystemType.GetMember(methodName, MemberTypes.Method, (bindingType | BindingFlags.Public) | BindingFlags.IgnoreCase);
 }
Example #4
0
        /*
         * __call metafunction of type references. Searches for and calls
         * a constructor for the type. Returns nil if the constructor is not
         * found or if the arguments are invalid. Throws an error if the constructor
         * generates an exception.
         */
        private int callConstructor(LuaCore.lua_State luaState)
        {
            var      validConstructor = new MethodCache();
            IReflect klass;
            object   obj = translator.getRawNetObject(luaState, 1);

            if (obj.IsNull() || !(obj is IReflect))
            {
                translator.throwError(luaState, "trying to call constructor on an invalid type reference");
                LuaLib.lua_pushnil(luaState);
                return(1);
            }
            else
            {
                klass = (IReflect)obj;
            }

            LuaLib.lua_remove(luaState, 1);
            var constructors = klass.UnderlyingSystemType.GetConstructors();

            foreach (var constructor in constructors)
            {
                bool isConstructor = matchParameters(luaState, constructor, ref validConstructor);

                if (isConstructor)
                {
                    try
                    {
                        translator.push(luaState, constructor.Invoke(validConstructor.args));
                    }
                    catch (TargetInvocationException e)
                    {
                        ThrowError(luaState, e);
                        LuaLib.lua_pushnil(luaState);
                    }
                    catch
                    {
                        LuaLib.lua_pushnil(luaState);
                    }

                    return(1);
                }
            }

            string constructorName = (constructors.Length == 0) ? "unknown" : constructors[0].Name;

            translator.throwError(luaState, String.Format("{0} does not contain constructor({1}) argument match",
                                                          klass.UnderlyingSystemType, constructorName));
            LuaLib.lua_pushnil(luaState);
            return(1);
        }
Example #5
0
        public static int callConstructor(IntPtr luaState)
        {
            ObjectTranslator translator       = ObjectTranslator.FromState(luaState);
            MethodCache      validConstructor = new MethodCache();
            IReflect         klass;
            object           obj = translator.getRawNetObject(luaState, 1);

            if (obj == null || !(obj is IReflect))
            {
                translator.throwError(luaState, "trying to call constructor on an invalid type reference");
                LuaDLL.lua_pushnil(luaState);
                return(1);
            }
            else
            {
                klass = (IReflect)obj;
            }
            LuaDLL.lua_remove(luaState, 1);
            ConstructorInfo[] constructors = klass.UnderlyingSystemType.GetConstructors();
            foreach (ConstructorInfo constructor in constructors)
            {
                bool isConstructor = translator.metaFunctions.matchParameters(luaState, constructor, ref validConstructor);
                if (isConstructor)
                {
                    try
                    {
                        translator.push(luaState, constructor.Invoke(validConstructor.args));
                    }
                    catch (TargetInvocationException e)
                    {
                        translator.metaFunctions.ThrowError(luaState, e);
                        LuaDLL.lua_pushnil(luaState);
                    }
                    catch
                    {
                        LuaDLL.lua_pushnil(luaState);
                    }
                    return(1);
                }
            }

            string constructorName = (constructors.Length == 0) ? "unknown" : constructors[0].Name;

            translator.throwError(luaState, String.Format("{0} does not contain constructor({1}) argument match",
                                                          klass.UnderlyingSystemType,
                                                          constructorName));
            LuaDLL.lua_pushnil(luaState);
            return(1);
        }
Example #6
0
        public static int callConstructor(IntPtr luaState)
        {
            ObjectTranslator objectTranslator = ObjectTranslator.FromState(luaState);
            MethodCache      methodCache      = default(MethodCache);
            object           rawNetObject     = objectTranslator.getRawNetObject(luaState, 1);

            if (rawNetObject == null || !(rawNetObject is IReflect))
            {
                LuaDLL.luaL_error(luaState, "trying to call constructor on an invalid type reference");
                LuaDLL.lua_pushnil(luaState);
                return(1);
            }
            IReflect reflect = (IReflect)rawNetObject;

            LuaDLL.lua_remove(luaState, 1);
            ConstructorInfo[] constructors = reflect.UnderlyingSystemType.GetConstructors();
            ConstructorInfo[] array        = constructors;
            for (int i = 0; i < array.Length; i++)
            {
                ConstructorInfo constructorInfo = array[i];
                bool            flag            = objectTranslator.metaFunctions.matchParameters(luaState, constructorInfo, ref methodCache);
                if (flag)
                {
                    try
                    {
                        objectTranslator.push(luaState, constructorInfo.Invoke(methodCache.args));
                    }
                    catch (TargetInvocationException e)
                    {
                        objectTranslator.metaFunctions.ThrowError(luaState, e);
                        LuaDLL.lua_pushnil(luaState);
                    }
                    catch
                    {
                        LuaDLL.lua_pushnil(luaState);
                    }
                    return(1);
                }
            }
            string arg = (constructors.Length != 0) ? constructors[0].Name : "unknown";

            LuaDLL.luaL_error(luaState, string.Format("{0} does not contain constructor({1}) argument match", reflect.UnderlyingSystemType, arg));
            LuaDLL.lua_pushnil(luaState);
            return(1);
        }
Example #7
0
        public static int callConstructor(IntPtr luaState)
        {
            ObjectTranslator translator = ObjectTranslator.FromState(luaState);
            MethodCache validConstructor = new MethodCache();
            IReflect klass;
            object obj = translator.getRawNetObject(luaState, 1);
            if (obj == null || !(obj is IReflect))
            {
                translator.throwError(luaState, "trying to call constructor on an invalid type reference");
                LuaDLL.lua_pushnil(luaState);
                return 1;
            }
            else klass = (IReflect)obj;
            LuaDLL.lua_remove(luaState, 1);
            ConstructorInfo[] constructors = klass.UnderlyingSystemType.GetConstructors();
            foreach (ConstructorInfo constructor in constructors)
            {
                bool isConstructor = translator.metaFunctions.matchParameters(luaState, constructor, ref validConstructor);
                if (isConstructor)
                {
                    try
                    {
                        translator.push(luaState, constructor.Invoke(validConstructor.args));
                    }
                    catch (TargetInvocationException e)
                    {
                        translator.metaFunctions.ThrowError(luaState, e);
                        LuaDLL.lua_pushnil(luaState);
                    }
                    catch
                    {
                        LuaDLL.lua_pushnil(luaState);
                    }
                    return 1;
                }
            }

            string constructorName = (constructors.Length == 0) ? "unknown" : constructors[0].Name;

            translator.throwError(luaState, String.Format("{0} does not contain constructor({1}) argument match",
                                                          klass.UnderlyingSystemType,
                                                          constructorName));
            LuaDLL.lua_pushnil(luaState);
            return 1;
        }
Example #8
0
        /*
         * __call metafunction of type references. Searches for and calls
         * a constructor for the type. Returns nil if the constructor is not
         * found or if the arguments are invalid. Throws an error if the constructor
         * generates an exception.
         */
        private int callConstructor(IntPtr luaState)
        {
            MethodCache validConstructor = new MethodCache();
            IReflect    klass;
            object      obj = translator.getRawNetObject(luaState, 1);

            if (obj == null || !(obj is IReflect))
            {
                translator.throwError(luaState, "trying to call constructor on an invalid type reference");
                LuaDLL.lua_pushnil(luaState);
                return(1);
            }
            else
            {
                klass = (IReflect)obj;
            }
            LuaDLL.lua_remove(luaState, 1);
            ConstructorInfo[] constructors = klass.UnderlyingSystemType.GetConstructors();
            foreach (ConstructorInfo constructor in constructors)
            {
                bool isConstructor = matchParameters(luaState, constructor, ref validConstructor);
                if (isConstructor)
                {
                    try
                    {
                        translator.push(luaState, constructor.Invoke(validConstructor.args));
                    }
                    catch (TargetInvocationException e)
                    {
                        translator.throwError(luaState, e.InnerException);
                        LuaDLL.lua_pushnil(luaState);
                    }
                    catch
                    {
                        LuaDLL.lua_pushnil(luaState);
                    }
                    return(1);
                }
            }

            translator.throwError(luaState, "can't find constructor to match arguments");
            LuaDLL.lua_pushnil(luaState);
            return(1);
        }
Example #9
0
        /// <summary>
        /// __call metafunction of type references.
        /// Searches for and calls a constructor for the type.
        /// Returns nil if the constructor is not found or if the arguments are invalid.
        /// Throws an error if the constructor generates an exception.
        /// </summary>
        int classCall(lua.State L)
        {
            Debug.Assert(translator.interpreter.IsSameLua(L) && luanet.infunction(L));
            var validConstructor = new MethodCache();
            var klass            = _checktyperef(L);

            lua.remove(L, 1);
            var constructors = klass.UnderlyingSystemType.GetConstructors();

            foreach (ConstructorInfo constructor in constructors)
            {
                if (translator.matchParameters(L, constructor, ref validConstructor))
                {
                    try { translator.push(L, constructor.Invoke(validConstructor.args)); }
                    catch (TargetInvocationException e) { return(translator.throwError(L, e.InnerException)); }
                    catch { lua.pushnil(L); }
                    return(1);
                }
            }
            return(luaL.error(L, klass.UnderlyingSystemType + " constructor arguments do not match"));
        }
 public LuaMethodWrapper(ObjectTranslator translator, object target, IReflect targetType, MethodBase method)
 {
     this._LastCalledMethod = new MethodCache();
     this._Translator = translator;
     this._Target = target;
     this._TargetType = targetType;
     if (targetType != null)
     {
         this._ExtractTarget = translator.typeChecker.getExtractor(targetType);
     }
     this._Method = method;
     this._MethodName = method.Name;
     if (method.IsStatic)
     {
         this._BindingType = BindingFlags.Static;
     }
     else
     {
         this._BindingType = BindingFlags.Instance;
     }
 }
Example #11
0
 private int callConstructor(IntPtr luaState)
 {
     MethodCache methodCache = new MethodCache();
     object obj2 = this.translator.getRawNetObject(luaState, 1);
     if ((obj2 == null) || !(obj2 is IReflect))
     {
         this.translator.throwError(luaState, "trying to call constructor on an invalid type reference");
         LuaDLL.lua_pushnil(luaState);
         return 1;
     }
     IReflect reflect = (IReflect) obj2;
     LuaDLL.lua_remove(luaState, 1);
     ConstructorInfo[] constructors = reflect.UnderlyingSystemType.GetConstructors();
     foreach (ConstructorInfo info in constructors)
     {
         if (this.matchParameters(luaState, info, ref methodCache))
         {
             try
             {
                 this.translator.push(luaState, info.Invoke(methodCache.args));
             }
             catch (TargetInvocationException exception)
             {
                 this.ThrowError(luaState, exception);
                 LuaDLL.lua_pushnil(luaState);
             }
             catch
             {
                 LuaDLL.lua_pushnil(luaState);
             }
             return 1;
         }
     }
     string str = (constructors.Length == 0) ? "unknown" : constructors[0].Name;
     this.translator.throwError(luaState, string.Format("{0} does not contain constructor({1}) argument match", reflect.UnderlyingSystemType, str));
     LuaDLL.lua_pushnil(luaState);
     return 1;
 }
Example #12
0
        /*
         * Matches a method against its arguments in the Lua stack. Returns
         * if the match was succesful. It it was also returns the information
         * necessary to invoke the method.
         */
        internal bool matchParameters(IntPtr luaState, MethodBase method, ref MethodCache methodCache)
        {
            ExtractValue extractValue;
            bool isMethod = true;
            var paramInfo = method.GetParameters ();
            int currentLuaParam = 1;
            int nLuaParams = LuaDLL.lua_gettop(luaState);
            var paramList = new List<object> ();
            var outList = new List<int> ();
            var argTypes = new List<MethodArgs> ();

            foreach (var currentNetParam in paramInfo) {
                if (!currentNetParam.IsIn && currentNetParam.IsOut)  // Skips out params 
                {
                    paramList.Add (null);
                    outList.Add (paramList.LastIndexOf (null));
                }  else if (currentLuaParam <= nLuaParams && _IsTypeCorrect (luaState, currentLuaParam, currentNetParam, out extractValue)) {  // Type checking
                    var value = extractValue (luaState, currentLuaParam);
                    paramList.Add (value);
                    int index = paramList.LastIndexOf (value);
                    var methodArg = new MethodArgs ();
                    methodArg.index = index;
                    methodArg.extractValue = extractValue;
                    argTypes.Add (methodArg);

                    if (currentNetParam.ParameterType.IsByRef)
                        outList.Add (index);

                    currentLuaParam++;
                }  // Type does not match, ignore if the parameter is optional
                else if (_IsParamsArray (luaState, currentLuaParam, currentNetParam, out extractValue)) {

                    var paramArrayType = currentNetParam.ParameterType.GetElementType ();

                    Func<int, object> extractDelegate = (currentParam) => {
                        currentLuaParam ++;
                        return extractValue (luaState, currentParam);
                    };
                    int count = (nLuaParams - currentLuaParam) + 1;
                    Array paramArray = TableToArray (extractDelegate, paramArrayType, currentLuaParam, count);

                    paramList.Add (paramArray);
                    int index = paramList.LastIndexOf (paramArray);
                    var methodArg = new MethodArgs ();
                    methodArg.index = index;
                    methodArg.extractValue = extractValue;
                    methodArg.isParamsArray = true;
                    methodArg.paramsArrayType = paramArrayType;
                    argTypes.Add (methodArg);

                } else if (currentLuaParam > nLuaParams) { // Adds optional parameters
                    if (currentNetParam.IsOptional)
                        paramList.Add (currentNetParam.DefaultValue);
                    else {
                        isMethod = false;
                        break;
                    }
                } else if (currentNetParam.IsOptional)
                    paramList.Add (currentNetParam.DefaultValue);
                else {  // No match
                    isMethod = false;
                    break;
                }
            }

            if (currentLuaParam != nLuaParams + 1) // Number of parameters does not match
                isMethod = false;
            if (isMethod) {
                methodCache.args = paramList.ToArray ();
                methodCache.cachedMethod = method;
                methodCache.outList = outList.ToArray ();
                methodCache.argTypes = argTypes.ToArray ();
            }

            return isMethod;
        }
Example #13
0
        internal bool matchParameters(IntPtr luaState, MethodBase method, ref MethodCache methodCache)
        {
            bool flag = true;

            ParameterInfo[]   parameters = method.GetParameters();
            int               num        = 1;
            int               num2       = LuaDLL.lua_gettop(luaState);
            ArrayList         arrayList  = new ArrayList();
            List <int>        list       = new List <int>();
            List <MethodArgs> list2      = new List <MethodArgs>();

            ParameterInfo[] array = parameters;
            for (int i = 0; i < array.Length; i++)
            {
                ParameterInfo parameterInfo = array[i];
                ExtractValue  extractValue;
                if (!parameterInfo.IsIn && parameterInfo.IsOut)
                {
                    list.Add(arrayList.Add(null));
                }
                else if (num > num2)
                {
                    if (!parameterInfo.IsOptional)
                    {
                        flag = false;
                        break;
                    }
                    arrayList.Add(parameterInfo.DefaultValue);
                }
                else if (this._IsTypeCorrect(luaState, num, parameterInfo, out extractValue))
                {
                    int num3 = arrayList.Add(extractValue(luaState, num));
                    list2.Add(new MethodArgs
                    {
                        index        = num3,
                        extractValue = extractValue
                    });
                    if (parameterInfo.ParameterType.IsByRef)
                    {
                        list.Add(num3);
                    }
                    num++;
                }
                else if (this._IsParamsArray(luaState, num, parameterInfo, out extractValue))
                {
                    object luaParamValue = extractValue(luaState, num);
                    Type   elementType   = parameterInfo.ParameterType.GetElementType();
                    Array  value         = this.TableToArray(luaParamValue, elementType);
                    int    index         = arrayList.Add(value);
                    list2.Add(new MethodArgs
                    {
                        index           = index,
                        extractValue    = extractValue,
                        isParamsArray   = true,
                        paramsArrayType = elementType
                    });
                    num++;
                }
                else
                {
                    if (!parameterInfo.IsOptional)
                    {
                        flag = false;
                        break;
                    }
                    arrayList.Add(parameterInfo.DefaultValue);
                }
            }
            if (num != num2 + 1)
            {
                flag = false;
            }
            if (flag)
            {
                methodCache.args         = arrayList.ToArray();
                methodCache.cachedMethod = method;
                methodCache.outList      = list.ToArray();
                methodCache.argTypes     = list2.ToArray();
            }
            return(flag);
        }
 /*
  * Checks if the method matches the arguments in the Lua stack, getting
  * the arguments if it does.
  */
 internal bool matchParameters(IntPtr luaState,MethodBase method,ref MethodCache methodCache)
 {
     return metaFunctions.matchParameters(luaState,method,ref methodCache);
 }
 /*
  * Checks if the method matches the arguments in the Lua stack, getting
  * the arguments if it does.
  */
 internal bool matchParameters(KopiLua.Lua.lua_State luaState, MethodBase method, ref MethodCache methodCache)
 {
     return(metaFunctions.matchParameters(luaState, method, ref methodCache));
 }
 /*
  * __call metafunction of type references. Searches for and calls
  * a constructor for the type. Returns nil if the constructor is not
  * found or if the arguments are invalid. Throws an error if the constructor
  * generates an exception.
  */
 private int callConstructor(IntPtr luaState)
 {
     MethodCache validConstructor=new MethodCache();
     Type klass;
     object obj=translator.getRawNetObject(luaState,1);
     if(obj==null || !(obj is Type))
     {
         translator.throwError(luaState,"trying to call constructor on an invalid type reference");
         LuaDLL.lua_pushnil(luaState);
         return 1;
     }
     else klass=(Type)obj;
     ArrayList paramList=new ArrayList();
     ArrayList outList=new ArrayList();
     LuaDLL.lua_remove(luaState,1);
     ConstructorInfo[] constructors=klass.GetConstructors();
     foreach(ConstructorInfo constructor in constructors)
     {
         bool isConstructor=matchParameters(luaState,constructor,ref validConstructor);
         if(isConstructor)
         {
             object[] args=paramList.ToArray();
             try
             {
                 translator.push(luaState,constructor.Invoke(validConstructor.args));
             }
             catch(TargetInvocationException e)
             {
                 translator.throwError(luaState,e.InnerException);
                 LuaDLL.lua_pushnil(luaState);
             }
             catch
             {
                 LuaDLL.lua_pushnil(luaState);
             }
             return 1;
         }
     }
     LuaDLL.lua_pushnil(luaState);
     return 1;
 }
Example #17
0
        /*
         * Matches a method against its arguments in the Lua stack. Returns
         * if the match was succesful. It it was also returns the information
         * necessary to invoke the method.
         */
        internal bool matchParameters(IntPtr luaState, MethodBase method, ref MethodCache methodCache)
        {
            ExtractValue extractValue;
            bool isMethod = true;
            ParameterInfo[] paramInfo = method.GetParameters();
            int currentLuaParam = 1;
            int nLuaParams = LuaDLL.lua_gettop(luaState);
            ArrayList paramList = new ArrayList();
            List<int> outList = new List<int>();
            List<MethodArgs> argTypes = new List<MethodArgs>();
            foreach (ParameterInfo currentNetParam in paramInfo)
            {
                if (!currentNetParam.IsIn && currentNetParam.IsOut)  // Skips out params
                {
                    outList.Add(paramList.Add(null));
                }
                else if (currentLuaParam > nLuaParams) // Adds optional parameters
                {
                    if (currentNetParam.IsOptional)
                    {
                        paramList.Add(currentNetParam.DefaultValue);
                    }
                    else
                    {
                        isMethod = false;
                        break;
                    }
                }
                else if (_IsTypeCorrect(luaState, currentLuaParam, currentNetParam, out extractValue))  // Type checking
                {
                    int index = paramList.Add(extractValue(luaState, currentLuaParam));

                    MethodArgs methodArg = new MethodArgs();
                    methodArg.index = index;
                    methodArg.extractValue = extractValue;
                    argTypes.Add(methodArg);

                    if (currentNetParam.ParameterType.IsByRef)
                        outList.Add(index);
                    currentLuaParam++;
                }  // Type does not match, ignore if the parameter is optional
                else if (_IsParamsArray(luaState, currentLuaParam, currentNetParam, out extractValue))
                {
                    object luaParamValue = extractValue(luaState, currentLuaParam);

                    Type paramArrayType = currentNetParam.ParameterType.GetElementType();

                    Array paramArray;

                    if (luaParamValue is LuaTable)
                    {
                        LuaTable table = (LuaTable)luaParamValue;
                        IDictionaryEnumerator tableEnumerator = table.GetEnumerator();

                        paramArray = Array.CreateInstance(paramArrayType, table.Values.Count);

                        tableEnumerator.Reset();

                        int paramArrayIndex = 0;

                        while(tableEnumerator.MoveNext())
                        {
                            paramArray.SetValue(Convert.ChangeType(tableEnumerator.Value, currentNetParam.ParameterType.GetElementType()), paramArrayIndex);
                            paramArrayIndex++;
                        }
                    }
                    else
                    {
                        paramArray = Array.CreateInstance(paramArrayType, 1);
                        paramArray.SetValue(luaParamValue, 0);
                    }

                    int index = paramList.Add(paramArray);

                    MethodArgs methodArg = new MethodArgs();
                    methodArg.index = index;
                    methodArg.extractValue = extractValue;
                    methodArg.isParamsArray = true;
                    methodArg.paramsArrayType = paramArrayType;
                    argTypes.Add(methodArg);

                    currentLuaParam++;
                }
                else if (currentNetParam.IsOptional)
                {
                    paramList.Add(currentNetParam.DefaultValue);
                }
                else  // No match
                {
                    isMethod = false;
                    break;
                }
            }
            // HACK: If a CSFunction is used as the generator in a for loop
            // Then the for loop calls the CSFunction with two null parameters
            // I assume some Lua functions use these parameters to speed up the loop
            //
            // As a side effect of this hack you can pass any number of null/nil parameters
            // to a CSFunction that normaly takes no parameters
             if (currentLuaParam != nLuaParams + 1) // Number of parameters does not match
            {
                isMethod = false;
                if(currentLuaParam == 1){
                    while(LuaDLL.lua_gettop(luaState) != 0){
                        //FIXME: LuaDLL.lua_isnil doesn't seem to detect LuaTypes.LUA_TNIL as nil
                        if(LuaDLL.lua_isnil(luaState, LuaDLL.lua_gettop(luaState)) || LuaDLL.lua_type(luaState, 1) == LuaTypes.LUA_TNIL)
                        {
                            LuaDLL.lua_pop(luaState, 1);
                            isMethod = true;
                        }else{
                            isMethod = false;
                            break;
                        }
                    }
                }
            }
            if (isMethod)
            {
                methodCache.args = paramList.ToArray();
                methodCache.cachedMethod = method;
                methodCache.outList = outList.ToArray();
                methodCache.argTypes = argTypes.ToArray();
            }
            return isMethod;
        }
 /*
  * Checks if the method matches the arguments in the Lua stack, getting
  * the arguments if it does.
  */
 internal bool matchParameters(KopiLua.Lua.lua_State luaState, MethodBase method, ref MethodCache methodCache)
 {
     return metaFunctions.matchParameters(luaState,method,ref methodCache);
 }
Example #19
0
        /*
         * Matches a method against its arguments in the Lua stack. Returns
         * if the match was succesful. It it was also returns the information
         * necessary to invoke the method.
         */
        internal bool matchParameters(IntPtr luaState, MethodBase method, ref MethodCache methodCache)
        {
            ExtractValue extractValue;
            bool         isMethod        = true;
            var          paramInfo       = method.GetParameters();
            int          currentLuaParam = 1;
            int          nLuaParams      = LuaDLL.lua_gettop(luaState);
            var          paramList       = new List <object> ();
            var          outList         = new List <int> ();
            var          argTypes        = new List <MethodArgs> ();

            foreach (var currentNetParam in paramInfo)
            {
                if (!currentNetParam.IsIn && currentNetParam.IsOut)  // Skips out params
                {
                    paramList.Add(null);
                    outList.Add(paramList.LastIndexOf(null));
                }
                else if (currentLuaParam <= nLuaParams && _IsTypeCorrect(luaState, currentLuaParam, currentNetParam, out extractValue))        // Type checking
                {
                    var value = extractValue(luaState, currentLuaParam);
                    paramList.Add(value);
                    int index     = paramList.LastIndexOf(value);
                    var methodArg = new MethodArgs();
                    methodArg.index        = index;
                    methodArg.extractValue = extractValue;
                    argTypes.Add(methodArg);

                    if (currentNetParam.ParameterType.IsByRef)
                    {
                        outList.Add(index);
                    }

                    currentLuaParam++;
                }  // Type does not match, ignore if the parameter is optional
                else if (_IsParamsArray(luaState, currentLuaParam, currentNetParam, out extractValue))
                {
                    var paramArrayType = currentNetParam.ParameterType.GetElementType();

                    Func <int, object> extractDelegate = (currentParam) => {
                        currentLuaParam++;
                        return(extractValue(luaState, currentParam));
                    };
                    int   count      = (nLuaParams - currentLuaParam) + 1;
                    Array paramArray = TableToArray(extractDelegate, paramArrayType, currentLuaParam, count);

                    paramList.Add(paramArray);
                    int index     = paramList.LastIndexOf(paramArray);
                    var methodArg = new MethodArgs();
                    methodArg.index           = index;
                    methodArg.extractValue    = extractValue;
                    methodArg.isParamsArray   = true;
                    methodArg.paramsArrayType = paramArrayType;
                    argTypes.Add(methodArg);
                }
                else if (currentLuaParam > nLuaParams)     // Adds optional parameters
                {
                    if (currentNetParam.IsOptional)
                    {
                        paramList.Add(currentNetParam.DefaultValue);
                    }
                    else
                    {
                        isMethod = false;
                        break;
                    }
                }
                else if (currentNetParam.IsOptional)
                {
                    paramList.Add(currentNetParam.DefaultValue);
                }
                else    // No match
                {
                    isMethod = false;
                    break;
                }
            }

            if (currentLuaParam != nLuaParams + 1) // Number of parameters does not match
            {
                isMethod = false;
            }
            if (isMethod)
            {
                methodCache.args         = paramList.ToArray();
                methodCache.cachedMethod = method;
                methodCache.outList      = outList.ToArray();
                methodCache.argTypes     = argTypes.ToArray();
            }

            return(isMethod);
        }
Example #20
0
        /// <summary>
        /// Matches a method against its arguments in the Lua stack.
        /// Returns if the match was successful.
        /// It it was also returns the information necessary to invoke the method.
        /// </summary>
        internal bool matchParameters(lua.State L, MethodBase method, ref MethodCache methodCache)
        {
            Debug.Assert(interpreter.IsSameLua(L));
            bool isMethod        = true;
            int  currentLuaParam = 1;
            int  nLuaParams      = lua.gettop(L);
            var  paramList       = new ArrayList();
            var  outList         = new List <int>();
            var  argTypes        = new List <MethodArgs>();

            foreach (ParameterInfo currentNetParam in method.GetParameters())
            {
                if (!currentNetParam.IsIn && currentNetParam.IsOut)                  // Skips out params
                {
                    outList.Add(paramList.Add(null));
                    continue;
                }

                if (currentLuaParam > nLuaParams)                 // Adds optional parameters
                {
                    if (currentNetParam.IsOptional)
                    {
                        paramList.Add(currentNetParam.DefaultValue);
                        continue;
                    }
                    else
                    {
                        isMethod = false;
                        break;
                    }
                }

                // Type checking
                ExtractValue extractValue;
                try { extractValue = typeChecker.checkType(L, currentLuaParam, currentNetParam.ParameterType); }
                catch
                {
                    extractValue = null;
                    Debug.WriteLine("Type wasn't correct");
                }
                if (extractValue != null)
                {
                    int index = paramList.Add(extractValue(L, currentLuaParam));

                    argTypes.Add(new MethodArgs {
                        index = index, extractValue = extractValue
                    });

                    if (currentNetParam.ParameterType.IsByRef)
                    {
                        outList.Add(index);
                    }
                    currentLuaParam++;
                    continue;
                }

                // Type does not match, ignore if the parameter is optional
                if (_IsParamsArray(L, currentLuaParam, currentNetParam, out extractValue))
                {
                    object luaParamValue  = extractValue(L, currentLuaParam);
                    Type   paramArrayType = currentNetParam.ParameterType.GetElementType();

                    Array paramArray = TableToArray(luaParamValue, paramArrayType);
                    int   index      = paramList.Add(paramArray);

                    argTypes.Add(new MethodArgs
                    {
                        index           = index,
                        extractValue    = extractValue,
                        isParamsArray   = true,
                        paramsArrayType = paramArrayType,
                    });

                    currentLuaParam++;
                    continue;
                }

                if (currentNetParam.IsOptional)
                {
                    paramList.Add(currentNetParam.DefaultValue);
                    continue;
                }

                // No match
                isMethod = false;
                break;
            }
            if (currentLuaParam != nLuaParams + 1)             // Number of parameters does not match
            {
                isMethod = false;
            }
            if (isMethod)
            {
                methodCache.args         = paramList.ToArray();
                methodCache.cachedMethod = method;
                methodCache.outList      = outList.ToArray();
                methodCache.argTypes     = argTypes.ToArray();
            }
            return(isMethod);
        }
Example #21
0
        /*
         * __call metafunction of type references. Searches for and calls
         * a constructor for the type. Returns nil if the constructor is not
         * found or if the arguments are invalid. Throws an error if the constructor
         * generates an exception.
         */
        private int callConstructor(IntPtr luaState)
        {
            MethodCache validConstructor = new MethodCache();
            IReflect klass;
            object obj = translator.getRawNetObject(luaState, 1);
            if (obj == null || !(obj is IReflect))
            {
                translator.throwError(luaState, "trying to call constructor on an invalid type reference");
                LuaDLL.lua_pushnil(luaState);
                return 1;
            }
            else klass = (IReflect)obj;
            LuaDLL.lua_remove(luaState, 1);
            ConstructorInfo[] constructors = klass.UnderlyingSystemType.GetConstructors();
            foreach (ConstructorInfo constructor in constructors)
            {
                bool isConstructor = matchParameters(luaState, constructor, ref validConstructor);
                if (isConstructor)
                {
                    try
                    {
                        translator.push(luaState, constructor.Invoke(validConstructor.args));
                    }
                    catch (TargetInvocationException e)
                    {
                        translator.throwError(luaState, e.InnerException);
                        LuaDLL.lua_pushnil(luaState);
                    }
                    catch
                    {
                        LuaDLL.lua_pushnil(luaState);
                    }
                    return 1;
                }
            }

            translator.throwError(luaState, "can't find constructor to match arguments");
            LuaDLL.lua_pushnil(luaState);
            return 1;
        }
Example #22
0
        /*
         * Matches a method against its arguments in the Lua stack. Returns
         * if the match was succesful. It it was also returns the information
         * necessary to invoke the method.
         */
        internal bool matchParameters(IntPtr luaState, MethodBase method, ref MethodCache methodCache)
        {
            ExtractValue extractValue;
            bool         isMethod = true;

            ParameterInfo[]   paramInfo       = method.GetParameters();
            int               currentLuaParam = 1;
            int               nLuaParams      = LuaDLL.lua_gettop(luaState);
            ArrayList         paramList       = new ArrayList();
            List <int>        outList         = new List <int>();
            List <MethodArgs> argTypes        = new List <MethodArgs>();

            foreach (ParameterInfo currentNetParam in paramInfo)
            {
                if (!currentNetParam.IsIn && currentNetParam.IsOut)  // Skips out params
                {
                    outList.Add(paramList.Add(null));
                }
                else if (currentLuaParam > nLuaParams) // Adds optional parameters
                {
                    if (currentNetParam.IsOptional)
                    {
                        paramList.Add(currentNetParam.DefaultValue);
                    }
                    else
                    {
                        isMethod = false;
                        break;
                    }
                }
                else if (_IsTypeCorrect(luaState, currentLuaParam, currentNetParam, out extractValue))  // Type checking
                {
                    int index = paramList.Add(extractValue(luaState, currentLuaParam));

                    MethodArgs methodArg = new MethodArgs();
                    methodArg.index        = index;
                    methodArg.extractValue = extractValue;
                    argTypes.Add(methodArg);

                    if (currentNetParam.ParameterType.IsByRef)
                    {
                        outList.Add(index);
                    }
                    currentLuaParam++;
                }  // Type does not match, ignore if the parameter is optional
                else if (_IsParamsArray(luaState, currentLuaParam, currentNetParam, out extractValue))
                {
                    object luaParamValue = extractValue(luaState, currentLuaParam);

                    Type paramArrayType = currentNetParam.ParameterType.GetElementType();

                    Array paramArray;

                    if (luaParamValue is LuaTable)
                    {
                        LuaTable table = (LuaTable)luaParamValue;
                        IDictionaryEnumerator tableEnumerator = table.GetEnumerator();

                        paramArray = Array.CreateInstance(paramArrayType, table.Values.Count);

                        tableEnumerator.Reset();

                        int paramArrayIndex = 0;

                        while (tableEnumerator.MoveNext())
                        {
                            paramArray.SetValue(Convert.ChangeType(tableEnumerator.Value, currentNetParam.ParameterType.GetElementType()), paramArrayIndex);
                            paramArrayIndex++;
                        }
                    }
                    else
                    {
                        paramArray = Array.CreateInstance(paramArrayType, 1);
                        paramArray.SetValue(luaParamValue, 0);
                    }

                    int index = paramList.Add(paramArray);

                    MethodArgs methodArg = new MethodArgs();
                    methodArg.index           = index;
                    methodArg.extractValue    = extractValue;
                    methodArg.isParamsArray   = true;
                    methodArg.paramsArrayType = paramArrayType;
                    argTypes.Add(methodArg);

                    currentLuaParam++;
                }
                else if (currentNetParam.IsOptional)
                {
                    paramList.Add(currentNetParam.DefaultValue);
                }
                else  // No match
                {
                    isMethod = false;
                    break;
                }
            }
            if (currentLuaParam != nLuaParams + 1) // Number of parameters does not match
            {
                isMethod = false;
            }
            if (isMethod)
            {
                methodCache.args         = paramList.ToArray();
                methodCache.cachedMethod = method;
                methodCache.outList      = outList.ToArray();
                methodCache.argTypes     = argTypes.ToArray();
            }
            return(isMethod);
        }
Example #23
0
        /*
         * Matches a method against its arguments in the Lua stack. Returns
         * if the match was succesful. It it was also returns the information
         * necessary to invoke the method.
         */
        internal bool matchParameters(IntPtr luaState, MethodBase method, ref MethodCache methodCache)
        {
            ExtractValue extractValue;
            bool isMethod = true;
            ParameterInfo[] paramInfo = method.GetParameters();
            int currentLuaParam = 1;
            int nLuaParams = LuaDLL.lua_gettop(luaState);
            ArrayList paramList = new ArrayList();
            List<int> outList = new List<int>();
            List<MethodArgs> argTypes = new List<MethodArgs>();
            foreach (ParameterInfo currentNetParam in paramInfo)
            {
                if (!currentNetParam.IsIn && currentNetParam.IsOut)  // Skips out params
                {
                    outList.Add(paramList.Add(null));
                }
                else if (currentLuaParam > nLuaParams) // Adds optional parameters
                {
                    if (currentNetParam.IsOptional)
                    {
                        paramList.Add(currentNetParam.DefaultValue);
                    }
                    else
                    {
                        isMethod = false;
                        break;
                    }
                }
                else if (_IsTypeCorrect(luaState, currentLuaParam, currentNetParam, out extractValue))  // Type checking
                {
                    int index = paramList.Add(extractValue(luaState, currentLuaParam));

                    MethodArgs methodArg = new MethodArgs();
                    methodArg.index = index;
                    methodArg.extractValue = extractValue;
                    argTypes.Add(methodArg);

                    if (currentNetParam.ParameterType.IsByRef)
                        outList.Add(index);
                    currentLuaParam++;
                }  // Type does not match, ignore if the parameter is optional
                else if (_IsParamsArray(luaState, currentLuaParam, currentNetParam, out extractValue))
                {
                    object luaParamValue = extractValue(luaState, currentLuaParam);

                    Type paramArrayType = currentNetParam.ParameterType.GetElementType();

                    Array paramArray;

                    if (luaParamValue is LuaTable)
                    {
                        LuaTable table = (LuaTable)luaParamValue;
                        IDictionaryEnumerator tableEnumerator = table.GetEnumerator();

                        paramArray = Array.CreateInstance(paramArrayType, table.Values.Count);

                        tableEnumerator.Reset();

                        int paramArrayIndex = 0;

                        while(tableEnumerator.MoveNext())
                        {
                            paramArray.SetValue(Convert.ChangeType(tableEnumerator.Value, currentNetParam.ParameterType.GetElementType()), paramArrayIndex);
                            paramArrayIndex++;
                        }
                    }
                    else
                    {
                        paramArray = Array.CreateInstance(paramArrayType, 1);
                        paramArray.SetValue(luaParamValue, 0);
                    }

                    int index = paramList.Add(paramArray);

                    MethodArgs methodArg = new MethodArgs();
                    methodArg.index = index;
                    methodArg.extractValue = extractValue;
                    methodArg.isParamsArray = true;
                    methodArg.paramsArrayType = paramArrayType;
                    argTypes.Add(methodArg);

                    currentLuaParam++;
                }
                else if (currentNetParam.IsOptional)
                {
                    paramList.Add(currentNetParam.DefaultValue);
                }
                else  // No match
                {
                    isMethod = false;
                    break;
                }
            }
            if (currentLuaParam != nLuaParams + 1) // Number of parameters does not match
                isMethod = false;
            if (isMethod)
            {
                methodCache.args = paramList.ToArray();
                methodCache.cachedMethod = method;
                methodCache.outList = outList.ToArray();
                methodCache.argTypes = argTypes.ToArray();
            }
            return isMethod;
        }
Example #24
0
        /*
         * Matches a method against its arguments in the Lua stack. Returns
         * if the match was succesful. It it was also returns the information
         * necessary to invoke the method.
         */
        internal bool matchParameters(IntPtr luaState, MethodBase method, ref MethodCache methodCache)
        {
            ExtractValue extractValue;
            bool isMethod = true;
            ParameterInfo[] paramInfo = method.GetParameters();
            int currentLuaParam = 1;
            int nLuaParams = LuaDLL.lua_gettop(luaState);
            ArrayList paramList = new ArrayList();
            List<int> outList = new List<int>();
            List<MethodArgs> argTypes = new List<MethodArgs>();
            foreach (ParameterInfo currentNetParam in paramInfo)
            {
                if (!currentNetParam.IsIn && currentNetParam.IsOut)  // Skips out params
                {
                    outList.Add(paramList.Add(null));
                }
                else if (currentLuaParam > nLuaParams) // Adds optional parameters
                {
                    if (currentNetParam.IsOptional)
                    {
                        paramList.Add(currentNetParam.DefaultValue);
                    }
                    else
                    {
                        isMethod = false;
                        break;
                    }
                }
                else if (_IsTypeCorrect(luaState, currentLuaParam, currentNetParam, out extractValue))  // Type checking
                {
                    int index = paramList.Add(extractValue(luaState, currentLuaParam));

                    MethodArgs methodArg = new MethodArgs();
                    methodArg.index = index;
                    methodArg.extractValue = extractValue;
                    argTypes.Add(methodArg);

                    if (currentNetParam.ParameterType.IsByRef)
                        outList.Add(index);
                    currentLuaParam++;
                }  // Type does not match, ignore if the parameter is optional
                else if (_IsParamsArray(luaState, currentLuaParam, currentNetParam, out extractValue))
                {
                    object luaParamValue = extractValue(luaState, currentLuaParam);
                    Type paramArrayType = currentNetParam.ParameterType.GetElementType();

                    Array paramArray = TableToArray(luaParamValue, paramArrayType);
                    int index = paramList.Add(paramArray);

                    MethodArgs methodArg = new MethodArgs();
                    methodArg.index = index;
                    methodArg.extractValue = extractValue;
                    methodArg.isParamsArray = true;
                    methodArg.paramsArrayType = paramArrayType;
                    argTypes.Add(methodArg);

                    currentLuaParam++;
                }
                else if (currentNetParam.IsOptional)
                {
                    paramList.Add(currentNetParam.DefaultValue);
                }
                else  // No match
                {
                    isMethod = false;
                    break;
                }
            }
            if (currentLuaParam != nLuaParams + 1) // Number of parameters does not match
                isMethod = false;
            if (isMethod)
            {
                methodCache.args = paramList.ToArray();
                methodCache.cachedMethod = method;
                methodCache.outList = outList.ToArray();
                methodCache.argTypes = argTypes.ToArray();
            }
            return isMethod;
        }
Example #25
0
        /*
         * Matches a method against its arguments in the Lua stack. Returns
         * if the match was succesful. It it was also returns the information
         * necessary to invoke the method.
         */
        internal bool matchParameters(KopiLua.Lua.lua_State luaState, MethodBase method, ref MethodCache methodCache)
        {
            ExtractValue extractValue;
            bool         isMethod = true;

            ParameterInfo[]   paramInfo       = method.GetParameters();
            int               currentLuaParam = 1;
            int               nLuaParams      = LuaDLL.lua_gettop(luaState);
            ArrayList         paramList       = new ArrayList();
            List <int>        outList         = new List <int>();
            List <MethodArgs> argTypes        = new List <MethodArgs>();

            foreach (ParameterInfo currentNetParam in paramInfo)
            {
                if (!currentNetParam.IsIn && currentNetParam.IsOut)  // Skips out params
                {
                    outList.Add(paramList.Add(null));
                }
                else if (currentLuaParam > nLuaParams) // Adds optional parameters
                {
                    if (currentNetParam.IsOptional)
                    {
                        paramList.Add(currentNetParam.DefaultValue);
                    }
                    else
                    {
                        isMethod = false;
                        break;
                    }
                }
                else if ((extractValue = translator.typeChecker.checkType(luaState, currentLuaParam, currentNetParam.ParameterType)) != null)  // Type checking
                {
                    int        index     = paramList.Add(extractValue(luaState, currentLuaParam));
                    MethodArgs methodArg = new MethodArgs();
                    methodArg.index        = index;
                    methodArg.extractValue = extractValue;
                    argTypes.Add(methodArg);
                    if (currentNetParam.ParameterType.IsByRef)
                    {
                        outList.Add(index);
                    }
                    currentLuaParam++;
                }  // Type does not match, ignore if the parameter is optional
                else if (currentNetParam.IsOptional)
                {
                    paramList.Add(currentNetParam.DefaultValue);
                }
                else  // No match
                {
                    isMethod = false;
                    break;
                }
            }
            if (currentLuaParam != nLuaParams + 1) // Number of parameters does not match
            {
                isMethod = false;
            }
            if (isMethod)
            {
                methodCache.args         = paramList.ToArray();
                methodCache.cachedMethod = method;
                methodCache.outList      = outList.ToArray();
                methodCache.argTypes     = argTypes.ToArray();
            }
            return(isMethod);
        }
Example #26
0
 internal bool matchParameters(IntPtr luaState, MethodBase method, ref MethodCache methodCache)
 {
     bool flag = true;
     ParameterInfo[] parameters = method.GetParameters();
     int currentLuaParam = 1;
     int num2 = LuaDLL.lua_gettop(luaState);
     ArrayList list = new ArrayList();
     List<int> list2 = new List<int>();
     List<MethodArgs> list3 = new List<MethodArgs>();
     foreach (ParameterInfo info in parameters)
     {
         if (!info.IsIn && info.IsOut)
         {
             list2.Add(list.Add(null));
         }
         else
         {
             ExtractValue value2;
             if (currentLuaParam > num2)
             {
                 if (info.IsOptional)
                 {
                     list.Add(info.DefaultValue);
                     goto Label_0105;
                 }
                 flag = false;
                 break;
             }
             if (this._IsTypeCorrect(luaState, currentLuaParam, info, out value2))
             {
                 int item = list.Add(value2(luaState, currentLuaParam));
                 MethodArgs args = new MethodArgs();
                 args.index = item;
                 args.extractValue = value2;
                 list3.Add(args);
                 if (info.ParameterType.IsByRef)
                 {
                     list2.Add(item);
                 }
                 currentLuaParam++;
             }
             else if (info.IsOptional)
             {
                 list.Add(info.DefaultValue);
             }
             else
             {
                 flag = false;
                 break;
             }
         Label_0105:;
         }
     }
     if (currentLuaParam != (num2 + 1))
     {
         flag = false;
     }
     if (flag)
     {
         methodCache.args = list.ToArray();
         methodCache.cachedMethod = method;
         methodCache.outList = list2.ToArray();
         methodCache.argTypes = list3.ToArray();
     }
     return flag;
 }
 /*
  * Checks if the method matches the arguments in the Lua stack, getting
  * the arguments if it does.
  */
 internal bool matchParameters(IntPtr luaState, MethodBase method, ref MethodCache methodCache)
 {
     return metaFunctions.matchParameters(luaState, method, ref methodCache);
 }
Example #28
0
        /*
         * Matches a method against its arguments in the Lua stack. Returns
         * if the match was succesful. It it was also returns the information
         * necessary to invoke the method.
         */
        internal bool matchParameters(IntPtr luaState, MethodBase method, ref MethodCache methodCache)
        {
            ExtractValue extractValue;
            bool         isMethod = true;

            ParameterInfo[]   paramInfo       = method.GetParameters();
            int               currentLuaParam = 1;
            int               nLuaParams      = LuaAPI.lua_gettop(luaState);
            ArrayList         paramList       = new ArrayList();
            List <int>        outList         = new List <int>();
            List <MethodArgs> argTypes        = new List <MethodArgs>();

            foreach (ParameterInfo currentNetParam in paramInfo)
            {
                if (!currentNetParam.IsIn && currentNetParam.IsOut)  // Skips out params
                {
                    outList.Add(paramList.Add(null));
                }
                else if (currentLuaParam > nLuaParams) // Adds optional parameters
                {
                    if (currentNetParam.IsOptional)
                    {
                        paramList.Add(currentNetParam.DefaultValue);
                    }
                    else
                    {
                        isMethod = false;
                        break;
                    }
                }
                else if (_IsTypeCorrect(luaState, currentLuaParam, currentNetParam, out extractValue))  // Type checking
                {
                    int index = paramList.Add(extractValue(luaState, currentLuaParam));

                    MethodArgs methodArg = new MethodArgs();
                    methodArg.index        = index;
                    methodArg.extractValue = extractValue;
                    argTypes.Add(methodArg);

                    if (currentNetParam.ParameterType.IsByRef)
                    {
                        outList.Add(index);
                    }
                    currentLuaParam++;
                }  // Type does not match, ignore if the parameter is optional
                else if (_IsParamsArray(luaState, currentLuaParam, currentNetParam, out extractValue))
                {
                    object luaParamValue  = extractValue(luaState, currentLuaParam);
                    Type   paramArrayType = currentNetParam.ParameterType.GetElementType();

                    Array paramArray = TableToArray(luaParamValue, paramArrayType);
                    int   index      = paramList.Add(paramArray);

                    MethodArgs methodArg = new MethodArgs();
                    methodArg.index           = index;
                    methodArg.extractValue    = extractValue;
                    methodArg.isParamsArray   = true;
                    methodArg.paramsArrayType = paramArrayType;
                    argTypes.Add(methodArg);

                    currentLuaParam++;
                }
                else if (currentNetParam.IsOptional)
                {
                    paramList.Add(currentNetParam.DefaultValue);
                }
                else  // No match
                {
                    isMethod = false;
                    break;
                }
            }
            if (currentLuaParam != nLuaParams + 1) // Number of parameters does not match
            {
                isMethod = false;
            }
            if (isMethod)
            {
                methodCache.args         = paramList.ToArray();
                methodCache.cachedMethod = method;
                methodCache.outList      = outList.ToArray();
                methodCache.argTypes     = argTypes.ToArray();
            }
            return(isMethod);
        }