private int callConstructorInternal(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; } if (!translator.interpreter.ManagedObjectSecurityPolicy.PermitObjectConstruction(klass.UnderlyingSystemType)) { LuaLib.lua_pushnil(luaState); return(1); } 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); }
/* * __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) { 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); }
/* * Checks if the method matches the arguments in the Lua stack, getting * the arguments if it does. */ internal bool MatchParameters(LuaState luaState, MethodBase method, MethodCache methodCache, int skipParam) { return(metaFunctions.MatchParameters(luaState, method, methodCache, skipParam)); }
/* * Checks if the method matches the arguments in the Lua stack, getting * the arguments if it does. */ internal bool MatchParameters(LuaState luaState, MethodBase method, ref MethodCache methodCache) { return(metaFunctions.MatchParameters(luaState, method, ref methodCache)); }
/* * 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(LuaCore.lua_State luaState, MethodBase method, ref MethodCache methodCache) { ExtractValue extractValue; bool isMethod = true; var paramInfo = method.GetParameters(); int currentLuaParam = 1; int nLuaParams = LuaLib.lua_gettop(luaState); var paramList = new List <object> (); var outList = new List <int> (); var argTypes = new List <MethodArgs> (); foreach (var currentNetParam in paramInfo) { #if !SILVERLIGHT if (!currentNetParam.IsIn && currentNetParam.IsOut) // Skips out params #else if (currentNetParam.IsOut) // Skips out params #endif { paramList.Add(null); outList.Add(paramList.LastIndexOf(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 { 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)) { object luaParamValue = extractValue(luaState, currentLuaParam); var paramArrayType = currentNetParam.ParameterType.GetElementType(); Array paramArray = TableToArray(luaParamValue, paramArrayType); 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); 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); }
/* * 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(LuaCore.lua_State luaState, MethodBase method, ref MethodCache methodCache) { ExtractValue extractValue; bool isMethod = true; var paramInfo = method.GetParameters(); int currentLuaParam = 1; int nLuaParams = LuaLib.lua_gettop(luaState); var paramList = new ArrayList(); var outList = new List <int> (); var argTypes = new List <MethodArgs> (); foreach (var 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)); 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)) { object luaParamValue = extractValue(luaState, currentLuaParam); var paramArrayType = currentNetParam.ParameterType.GetElementType(); Array paramArray; if (luaParamValue is LuaTable) { var table = (LuaTable)luaParamValue; var 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); var 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); }
/* * 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)); }