public static int importType(IntPtr luaState) { ObjectTranslator translator = ObjectTranslator.FromState(luaState); string className = LuaDLL.lua_tostring(luaState, 1); Type klass = translator.FindType(className); if (klass != null) { translator.pushType(luaState, klass); } else { LuaDLL.lua_pushnil(luaState); } return(1); }
public static int registerTable(IntPtr luaState) { #if __NOGEN__ throwError(luaState,"Tables as Objects not implemnented"); #else ObjectTranslator translator = ObjectTranslator.FromState(luaState); if (LuaDLL.lua_type(luaState, 1) == LuaTypes.LUA_TTABLE) { LuaTable luaTable = translator.getTable(luaState, 1); string superclassName = LuaDLL.lua_tostring(luaState, 2); if (superclassName != null) { Type klass = translator.FindType(superclassName); if (klass != null) { // Creates and pushes the object in the stack, setting // it as the metatable of the first argument object obj = CodeGeneration.Instance.GetClassInstance(klass, luaTable); translator.pushObject(luaState, obj, "luaNet_metatable"); LuaDLL.lua_newtable(luaState); LuaDLL.lua_pushstring(luaState, "__index"); LuaDLL.lua_pushvalue(luaState, -3); LuaDLL.lua_settable(luaState, -3); LuaDLL.lua_pushstring(luaState, "__newindex"); LuaDLL.lua_pushvalue(luaState, -3); LuaDLL.lua_settable(luaState, -3); LuaDLL.lua_setmetatable(luaState, 1); // Pushes the object again, this time as the base field // of the table and with the luaNet_searchbase metatable LuaDLL.lua_pushstring(luaState, "base"); int index = translator.addObject(obj); translator.pushNewObject(luaState, obj, index, "luaNet_searchbase"); LuaDLL.lua_rawset(luaState, 1); } else translator.throwError(luaState, "register_table: can not find superclass '" + superclassName + "'"); } else translator.throwError(luaState, "register_table: superclass name can not be null"); } else translator.throwError(luaState, "register_table: first arg is not a table"); #endif return 0; }
public static int registerTable(IntPtr luaState) { ObjectTranslator objectTranslator = ObjectTranslator.FromState(luaState); if (LuaDLL.lua_type(luaState, 1) == LuaTypes.LUA_TTABLE) { LuaTable table = objectTranslator.getTable(luaState, 1); string text = LuaDLL.lua_tostring(luaState, 2); if (text != null) { Type type = objectTranslator.FindType(text); if (type != null) { object classInstance = CodeGeneration.Instance.GetClassInstance(type, table); objectTranslator.pushObject(luaState, classInstance, "luaNet_metatable"); LuaDLL.lua_newtable(luaState); LuaDLL.lua_pushstring(luaState, "__index"); LuaDLL.lua_pushvalue(luaState, -3); LuaDLL.lua_settable(luaState, -3); LuaDLL.lua_pushstring(luaState, "__newindex"); LuaDLL.lua_pushvalue(luaState, -3); LuaDLL.lua_settable(luaState, -3); LuaDLL.lua_setmetatable(luaState, 1); LuaDLL.lua_pushstring(luaState, "base"); int index = objectTranslator.addObject(classInstance); objectTranslator.pushNewObject(luaState, classInstance, index, "luaNet_searchbase"); LuaDLL.lua_rawset(luaState, 1); } else { objectTranslator.throwError(luaState, "register_table: can not find superclass '" + text + "'"); } } else { objectTranslator.throwError(luaState, "register_table: superclass name can not be null"); } } else { objectTranslator.throwError(luaState, "register_table: first arg is not a table"); } return(0); }
public static int getMethodSignature(IntPtr luaState) { ObjectTranslator translator = ObjectTranslator.FromState(luaState); IReflect klass; object target; int udata = LuaDLL.luanet_checkudata(luaState, 1, "luaNet_class"); if (udata != -1) { klass = (IReflect)translator.objects[udata]; target = null; } else { target = translator.getRawNetObject(luaState, 1); if (target == null) { translator.throwError(luaState, "get_method_bysig: first arg is not type or object reference"); LuaDLL.lua_pushnil(luaState); return(1); } klass = target.GetType(); } string methodName = LuaDLL.lua_tostring(luaState, 2); Type[] signature = new Type[LuaDLL.lua_gettop(luaState) - 2]; for (int i = 0; i < signature.Length; i++) { signature[i] = translator.FindType(LuaDLL.lua_tostring(luaState, i + 3)); } try { //CP: Added ignore case MethodInfo method = klass.GetMethod(methodName, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.IgnoreCase, null, signature, null); translator.pushFunction(luaState, new LuaCSFunction((new LuaMethodWrapper(translator, target, klass, method)).call)); } catch (Exception e) { translator.throwError(luaState, e.Message); LuaDLL.lua_pushnil(luaState); } return(1); }
public static int getMethodSignature(IntPtr luaState) { ObjectTranslator objectTranslator = ObjectTranslator.FromState(luaState); int num = LuaDLL.luanet_checkudata(luaState, 1, "luaNet_class"); IReflect reflect; object obj; if (num != -1) { reflect = (IReflect)objectTranslator.objects[num]; obj = null; } else { obj = objectTranslator.getRawNetObject(luaState, 1); if (obj == null) { objectTranslator.throwError(luaState, "get_method_bysig: first arg is not type or object reference"); LuaDLL.lua_pushnil(luaState); return(1); } reflect = obj.GetType(); } string name = LuaDLL.lua_tostring(luaState, 2); Type[] array = new Type[LuaDLL.lua_gettop(luaState) - 2]; for (int i = 0; i < array.Length; i++) { array[i] = objectTranslator.FindType(LuaDLL.lua_tostring(luaState, i + 3)); } try { MethodInfo method = reflect.GetMethod(name, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy, null, array, null); objectTranslator.pushFunction(luaState, new LuaCSFunction(new LuaMethodWrapper(objectTranslator, obj, reflect, method).call)); } catch (Exception ex) { objectTranslator.throwError(luaState, ex.Message); LuaDLL.lua_pushnil(luaState); } return(1); }
/* * Pushes the value of a member or a delegate to call it, depending on the type of * the member. Works with static or instance members. * Uses reflection to find members, and stores the reflected MemberInfo object in * a cache (indexed by the type of the object and the name of the member). */ private int getMember(KopiLua.Lua.lua_State luaState, IReflect objType, object obj, string methodName, BindingFlags bindingType) { bool implicitStatic = false; MemberInfo member = null; object cachedMember = checkMemberCache(memberCache, objType, methodName); //object cachedMember=null; if (cachedMember is KopiLua.Lua.lua_CFunction) { translator.pushFunction(luaState, (KopiLua.Lua.lua_CFunction)cachedMember); translator.push(luaState, true); return(2); } else if (cachedMember != null) { member = (MemberInfo)cachedMember; } else { MemberInfo[] members = objType.GetMember(methodName, bindingType | BindingFlags.Public | BindingFlags.NonPublic); if (members.Length > 0) { member = members[0]; } else { // If we can't find any suitable instance members, try to find them as statics - but we only want to allow implicit static // lookups for fields/properties/events -kevinh members = objType.GetMember(methodName, bindingType | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (members.Length > 0) { member = members[0]; implicitStatic = true; } } } if (member != null) { if (member.MemberType == MemberTypes.Field) { FieldInfo field = (FieldInfo)member; if (cachedMember == null) { setMemberCache(memberCache, objType, methodName, member); } try { translator.push(luaState, field.GetValue(obj)); } catch { LuaDLL.lua_pushnil(luaState); } } else if (member.MemberType == MemberTypes.Property) { PropertyInfo property = (PropertyInfo)member; if (cachedMember == null) { setMemberCache(memberCache, objType, methodName, member); } try { object val = property.GetValue(obj, null); translator.push(luaState, val); } catch (ArgumentException) { // If we can't find the getter in our class, recurse up to the base class and see // if they can help. if (objType is Type && !(((Type)objType) == typeof(object))) { return(getMember(luaState, ((Type)objType).BaseType, obj, methodName, bindingType)); } else { LuaDLL.lua_pushnil(luaState); } } catch (TargetInvocationException e) // Convert this exception into a Lua error { ThrowError(luaState, e); LuaDLL.lua_pushnil(luaState); } } else if (member.MemberType == MemberTypes.Event) { EventInfo eventInfo = (EventInfo)member; if (cachedMember == null) { setMemberCache(memberCache, objType, methodName, member); } translator.push(luaState, new RegisterEventHandler(translator.pendingEvents, obj, eventInfo)); } else if (!implicitStatic) { if (member.MemberType == MemberTypes.NestedType) { // kevinh - added support for finding nested types // cache us if (cachedMember == null) { setMemberCache(memberCache, objType, methodName, member); } // Find the name of our class string name = member.Name; Type dectype = member.DeclaringType; // Build a new long name and try to find the type by name string longname = dectype.FullName + "+" + name; Type nestedType = translator.FindType(longname); translator.pushType(luaState, nestedType); } else { // Member type must be 'method' KopiLua.Lua.lua_CFunction wrapper = new KopiLua.Lua.lua_CFunction((new LuaMethodWrapper(translator, objType, methodName, bindingType)).call); if (cachedMember == null) { setMemberCache(memberCache, objType, methodName, wrapper); } translator.pushFunction(luaState, wrapper); translator.push(luaState, true); return(2); } } else { // If we reach this point we found a static method, but can't use it in this context because the user passed in an instance translator.throwError(luaState, "can't pass instance to static method " + methodName); LuaDLL.lua_pushnil(luaState); } } else { // kevinh - we want to throw an exception because meerly returning 'nil' in this case // is not sufficient. valid data members may return nil and therefore there must be some // way to know the member just doesn't exist. translator.throwError(luaState, "unknown member name " + methodName); LuaDLL.lua_pushnil(luaState); } // push false because we are NOT returning a function (see luaIndexFunction) translator.push(luaState, false); return(2); }
/// <summary>[-0, +2, e] /// Returns to Lua the value of a member or a delegate to call it, depending on the type of the member. /// Works with static or instance members. Uses reflection to find members, /// and stores the reflected MemberInfo object in a cache (indexed by <paramref name="objType"/> and <paramref name="methodName"/>). /// </summary> /// <exception cref="ArgumentNullException"><paramref name="objType"/> and <paramref name="methodName"/> are required</exception> int getMember(lua.State L, IReflect objType, object obj, string methodName, BindingFlags bindingType) { Debug.Assert(interpreter.IsSameLua(L)); Debug.Assert(objType != null && methodName != null); Debug.Assert((obj == null) == (objType is ProxyType)); Debug.Assert((obj == null) != (objType is Type)); Debug.Assert((obj == null) == ((bindingType & BindingFlags.Static) == BindingFlags.Static)); Debug.Assert((obj == null) != ((bindingType & BindingFlags.Instance) == BindingFlags.Instance)); MemberInfo member = null; object cachedMember = checkMemberCache(objType, methodName); if (cachedMember != null) { var cachedMethod = cachedMember as lua.CFunction; if (cachedMethod != null) { luaclr.pushcfunction(L, cachedMethod); lua.pushboolean(L, true); return(2); } Debug.Assert(cachedMember is MemberInfo); member = (MemberInfo)cachedMember; } else { MemberInfo[] members = objType.GetMember(methodName, bindingType | luanet.LuaBindingFlags); if (members.Length != 0) { member = members[0]; #if DEBUG if (!(members.Length == 1 || member is MethodBase)) // todo { return(luaL.error(L, "Overloads for members other than methods are not implemented.")); } #endif } } object value = null; switch (member == null ? MemberTypes.All : member.MemberType) { default: // not found or found a constructor // kevinh - we want to throw an error because merely returning 'nil' in this case // is not sufficient. valid data members may return nil and therefore there must be some // way to know the member just doesn't exist. return(luaL.error(L, string.Format("'{0}' does not contain a definition for '{1}'", objType.UnderlyingSystemType.FullName, methodName))); case MemberTypes.Method: var wrapper = new lua.CFunction((new LuaMethodWrapper(translator, objType, methodName, bindingType)).call); if (cachedMember == null) { setMemberCache(objType, methodName, wrapper); } luaclr.pushcfunction(L, wrapper); lua.pushboolean(L, true); return(2); case MemberTypes.Field: if (!translator.memberIsAllowed(member)) { return(luaL.error(L, "field read failed (access denied)")); } try { value = ((FieldInfo)member).GetValue(obj); } catch { goto default; } translator.push(L, value); break; case MemberTypes.Property: // todo: support indexed properties if (!translator.memberIsAllowed(member)) { return(luaL.error(L, "property call failed (access denied)")); } try { value = ((PropertyInfo)member).GetValue(obj, null); } catch (TargetInvocationException ex) { return(translator.throwError(L, luaclr.verifyex(ex.InnerException))); } catch { goto default; } translator.push(L, value); break; case MemberTypes.Event: if (!translator.memberIsAllowed(member)) { return(luaL.error(L, "event read failed (access denied)")); } value = new RegisterEventHandler(translator.pendingEvents, obj, (EventInfo)member); translator.push(L, value); break; case MemberTypes.NestedType: var nestedType = (Type)member; if (translator.FindType(nestedType)) // don't hand out class references unless loaded/whitelisted { ObjectTranslator.pushType(L, nestedType); } else { lua.pushnil(L); } break; } if (cachedMember == null) { setMemberCache(objType, methodName, member); } // push false because we are NOT returning a function (see luaIndexFunction) lua.pushboolean(L, false); return(2); }
/* * Pushes the value of a member or a delegate to call it, depending on the type of * the member. Works with static or instance members. * Uses reflection to find members, and stores the reflected MemberInfo object in * a cache (indexed by the type of the object and the name of the member). */ private int getMember(IntPtr luaState, IReflect objType, object obj, string methodName, BindingFlags bindingType) { bool implicitStatic = false; MemberInfo member = null; object cachedMember = checkMemberCache(memberCache, objType, methodName); if (cachedMember is LuaCSFunction) { translator.pushFunction(luaState, (LuaCSFunction)cachedMember); translator.push(luaState, true); return(2); } else if (cachedMember != null) { member = (MemberInfo)cachedMember; } else { //CP: Removed NonPublic binding search MemberInfo[] members = objType.GetMember(methodName, bindingType | BindingFlags.Public | BindingFlags.IgnoreCase /*| BindingFlags.NonPublic*/); if (members.Length > 0) { member = members[0]; } else { members = objType.GetMember(methodName, bindingType | BindingFlags.Static | BindingFlags.Public | BindingFlags.IgnoreCase /*| BindingFlags.NonPublic*/); if (members.Length > 0) { member = members[0]; implicitStatic = true; } } } if (member != null) { if (member.MemberType == MemberTypes.Field) { FieldInfo field = (FieldInfo)member; if (cachedMember == null) { setMemberCache(memberCache, objType, methodName, member); } try { translator.push(luaState, field.GetValue(obj)); } catch { LuaAPI.lua_pushnil(luaState); } } else if (member.MemberType == MemberTypes.Property) { PropertyInfo property = (PropertyInfo)member; if (cachedMember == null) { setMemberCache(memberCache, objType, methodName, member); } try { object val = property.GetGetMethod().Invoke(obj, null); translator.push(luaState, val); } catch (ArgumentException) { if (objType is Type && !(((Type)objType) == typeof(object))) { return(getMember(luaState, ((Type)objType).BaseType, obj, methodName, bindingType)); } else { LuaAPI.lua_pushnil(luaState); } } catch (TargetInvocationException e) // Convert this exception into a Lua error { ThrowError(luaState, e); LuaAPI.lua_pushnil(luaState); } } else if (!implicitStatic) { if (member.MemberType == MemberTypes.NestedType) { // cache us if (cachedMember == null) { setMemberCache(memberCache, objType, methodName, member); } // Find the name of our class string name = member.Name; Type dectype = member.DeclaringType; // Build a new long name and try to find the type by name string longname = dectype.FullName + "+" + name; Type nestedType = translator.FindType(longname); translator.pushType(luaState, nestedType); } else { // Member type must be 'method' LuaCSFunction wrapper = new LuaCSFunction((new LuaMethodWrapper(translator, objType, methodName, bindingType)).call); if (cachedMember == null) { setMemberCache(memberCache, objType, methodName, wrapper); } translator.pushFunction(luaState, wrapper); translator.push(luaState, true); return(2); } } else { // If we reach this point we found a static method, but can't use it in this context because the user passed in an instance translator.throwError(luaState, "can't pass instance to static method " + methodName); LuaAPI.lua_pushnil(luaState); } } else { // kevinh - we want to throw an exception because meerly returning 'nil' in this case // is not sufficient. valid data members may return nil and therefore there must be some // way to know the member just doesn't exist. translator.throwError(luaState, "unknown member name " + methodName); LuaAPI.lua_pushnil(luaState); } // push false because we are NOT returning a function (see luaIndexFunction) translator.push(luaState, false); return(2); }