コード例 #1
0
ファイル: ObjectTranslator.cs プロジェクト: Azhei/NLua
		public ObjectTranslator (Lua interpreter, LuaCore.lua_State luaState)
		{
			this.interpreter = interpreter;
			typeChecker = new CheckType (this);
			metaFunctions = new MetaFunctions (this);
			assemblies = new List<Assembly> ();

			importTypeFunction = new LuaCore.lua_CFunction (ObjectTranslator.importType);
			loadAssemblyFunction = new LuaCore.lua_CFunction (ObjectTranslator.loadAssembly);
			registerTableFunction = new LuaCore.lua_CFunction (ObjectTranslator.registerTable);
			unregisterTableFunction = new LuaCore.lua_CFunction (ObjectTranslator.unregisterTable);
			getMethodSigFunction = new LuaCore.lua_CFunction (ObjectTranslator.getMethodSignature);
			getConstructorSigFunction = new LuaCore.lua_CFunction (ObjectTranslator.getConstructorSignature);

			createLuaObjectList (luaState);
			createIndexingMetaFunction (luaState);
			createBaseClassMetatable (luaState);
			createClassMetatable (luaState);
			createFunctionMetatable (luaState);
			setGlobalFunctions (luaState);
		}
コード例 #2
0
ファイル: ObjectTranslator.cs プロジェクト: Azhei/NLua
		private int registerTableInternal (LuaCore.lua_State luaState)
		{
			if (LuaLib.lua_type (luaState, 1) == LuaTypes.Table) {
				var luaTable = getTable (luaState, 1);
				string superclassName = LuaLib.lua_tostring (luaState, 2).ToString ();

				if (!superclassName.IsNull ()) {
					var klass = FindType (superclassName);

					if (!klass.IsNull ()) {
						// Creates and pushes the object in the stack, setting
						// it as the  metatable of the first argument
						object obj = CodeGeneration.Instance.GetClassInstance (klass, luaTable);
						pushObject (luaState, obj, "luaNet_metatable");
						LuaLib.lua_newtable (luaState);
						LuaLib.lua_pushstring (luaState, "__index");
						LuaLib.lua_pushvalue (luaState, -3);
						LuaLib.lua_settable (luaState, -3);
						LuaLib.lua_pushstring (luaState, "__newindex");
						LuaLib.lua_pushvalue (luaState, -3);
						LuaLib.lua_settable (luaState, -3);
						LuaLib.lua_setmetatable (luaState, 1);
						// Pushes the object again, this time as the base field
						// of the table and with the luaNet_searchbase metatable
						LuaLib.lua_pushstring (luaState, "base");
						int index = addObject (obj);
						pushNewObject (luaState, obj, index, "luaNet_searchbase");
						LuaLib.lua_rawset (luaState, 1);
					} else
						throwError (luaState, "register_table: can not find superclass '" + superclassName + "'");
				} else
					throwError (luaState, "register_table: superclass name can not be null");
			} else
				throwError (luaState, "register_table: first arg is not a table");

			return 0;
		}
コード例 #3
0
ファイル: Lua.cs プロジェクト: Azhei/NLua
		static int PanicCallback (LuaCore.lua_State luaState)
		{
			string reason = string.Format ("unprotected error in call to Lua API ({0})", LuaLib.lua_tostring (luaState, -1));
			throw new LuaException (reason);
		}
コード例 #4
0
ファイル: Lua.cs プロジェクト: Azhei/NLua
		internal void pushCSFunction (LuaCore.lua_CFunction function)
		{
			translator.pushFunction (luaState, function);
		}
コード例 #5
0
ファイル: Lua.cs プロジェクト: Azhei/NLua
		private static void DebugHookCallback (LuaCore.lua_State luaState, LuaCore.lua_Debug luaDebug)
		{
			var translator = ObjectTranslatorPool.Instance.Find (luaState);
			var lua = translator.Interpreter;

			lua.DebugHookCallbackInternal (luaState, luaDebug);
		}
コード例 #6
0
ファイル: ObjectTranslator.cs プロジェクト: Azhei/NLua
		/*
		 * Pushes the object into the Lua stack according to its type.
		 */
		internal void push (LuaCore.lua_State luaState, object o)
		{
			if (o.IsNull ())
				LuaLib.lua_pushnil (luaState);
			else if (o is sbyte || o is byte || o is short || o is ushort ||
				o is int || o is uint || o is long || o is float ||
				o is ulong || o is decimal || o is double) {
				double d = Convert.ToDouble (o);
				LuaLib.lua_pushnumber (luaState, d);
			} else if (o is char) {
				double d = (char)o;
				LuaLib.lua_pushnumber (luaState, d);
			} else if (o is string) {
				string str = (string)o;
				LuaLib.lua_pushstring (luaState, str);
			} else if (o is bool) {
				bool b = (bool)o;
				LuaLib.lua_pushboolean (luaState, b);
			} else if (IsILua (o))
				(((ILuaGeneratedType)o).LuaInterfaceGetLuaTable ()).push (luaState);
			else if (o is LuaTable)
				((LuaTable)o).push (luaState);
			else if (o is LuaCore.lua_CFunction)
				pushFunction (luaState, (LuaCore.lua_CFunction)o);
			else if (o is LuaFunction)
				((LuaFunction)o).push (luaState);
			else
				pushObject (luaState, o, "luaNet_metatable");
		}
コード例 #7
0
ファイル: ObjectTranslator.cs プロジェクト: Azhei/NLua
		/*
		 * Pushes the entire array into the Lua stack and returns the number
		 * of elements pushed.
		 */
		internal int returnValues (LuaCore.lua_State luaState, object[] returnValues)
		{
			if (LuaLib.lua_checkstack (luaState, returnValues.Length + 5)) {
				for (int i = 0; i < returnValues.Length; i++)
					push (luaState, returnValues [i]);

				return returnValues.Length;
			} else
				return 0;
		}
コード例 #8
0
ファイル: ObjectTranslator.cs プロジェクト: Azhei/NLua
		/*
		 * Pushes a type reference into the stack
		 */
		internal void pushType (LuaCore.lua_State luaState, Type t)
		{
			pushObject (luaState, new ProxyType (t), "luaNet_class");
		}
コード例 #9
0
ファイル: ObjectTranslator.cs プロジェクト: Azhei/NLua
		/*
		 * Pushes a delegate into the stack
		 */
		internal void pushFunction (LuaCore.lua_State luaState, LuaCore.lua_CFunction func)
		{
			pushObject (luaState, func, "luaNet_function");
		}
コード例 #10
0
ファイル: ObjectTranslator.cs プロジェクト: Azhei/NLua
		private static int getConstructorSignature (LuaCore.lua_State luaState)
		{
			var translator = ObjectTranslatorPool.Instance.Find (luaState);
			return translator.getConstructorSignatureInternal (luaState);
		}
コード例 #11
0
ファイル: ObjectTranslator.cs プロジェクト: Azhei/NLua
		private int getConstructorSignatureInternal (LuaCore.lua_State luaState)
		{
			IReflect klass = null;
			int udata = LuaLib.luanet_checkudata (luaState, 1, "luaNet_class");

			if (udata != -1)
				klass = (IReflect)objects [udata];

			if (klass.IsNull ())
				throwError (luaState, "get_constructor_bysig: first arg is invalid type reference");

			var signature = new Type[LuaLib.lua_gettop (luaState) - 1];

			for (int i = 0; i < signature.Length; i++)
				signature [i] = FindType (LuaLib.lua_tostring (luaState, i + 2).ToString ());

			try {
				ConstructorInfo constructor = klass.UnderlyingSystemType.GetConstructor (signature);
				pushFunction (luaState, new LuaCore.lua_CFunction ((new LuaMethodWrapper (this, null, klass, constructor)).invokeFunction));
			} catch (Exception e) {
				throwError (luaState, e);
				LuaLib.lua_pushnil (luaState);
			}

			return 1;
		}
コード例 #12
0
ファイル: ObjectTranslator.cs プロジェクト: Azhei/NLua
		private int getMethodSignatureInternal (LuaCore.lua_State luaState)
		{
			IReflect klass;
			object target;
			int udata = LuaLib.luanet_checkudata (luaState, 1, "luaNet_class");

			if (udata != -1) {
				klass = (IReflect)objects [udata];
				target = null;
			} else {
				target = getRawNetObject (luaState, 1);

				if (target.IsNull ()) {
					throwError (luaState, "get_method_bysig: first arg is not type or object reference");
					LuaLib.lua_pushnil (luaState);
					return 1;
				}

				klass = target.GetType ();
			}

			string methodName = LuaLib.lua_tostring (luaState, 2).ToString ();
			var signature = new Type[LuaLib.lua_gettop (luaState) - 2];

			for (int i = 0; i < signature.Length; i++)
				signature [i] = FindType (LuaLib.lua_tostring (luaState, i + 3).ToString ());

			try {
				//CP: Added ignore case
				var method = klass.GetMethod (methodName, BindingFlags.Public | BindingFlags.Static |
					BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.IgnoreCase, null, signature, null);
				pushFunction (luaState, new LuaCore.lua_CFunction ((new LuaMethodWrapper (this, target, klass, method)).invokeFunction));
			} catch (Exception e) {
				throwError (luaState, e);
				LuaLib.lua_pushnil (luaState);
			}

			return 1;
		}
コード例 #13
0
ファイル: ObjectTranslator.cs プロジェクト: Azhei/NLua
		private int unregisterTableInternal (LuaCore.lua_State luaState)
		{
			try {
				if (LuaLib.lua_getmetatable (luaState, 1) != 0) {
					LuaLib.lua_pushstring (luaState, "__index");
					LuaLib.lua_gettable (luaState, -2);
					object obj = getRawNetObject (luaState, -1);

					if (obj.IsNull ())
						throwError (luaState, "unregister_table: arg is not valid table");

					var luaTableField = obj.GetType ().GetField ("__luaInterface_luaTable");

					if (luaTableField.IsNull ())
						throwError (luaState, "unregister_table: arg is not valid table");

					luaTableField.SetValue (obj, null);
					LuaLib.lua_pushnil (luaState);
					LuaLib.lua_setmetatable (luaState, 1);
					LuaLib.lua_pushstring (luaState, "base");
					LuaLib.lua_pushnil (luaState);
					LuaLib.lua_settable (luaState, 1);
				} else
					throwError (luaState, "unregister_table: arg is not valid table");
			} catch (Exception e) {
				throwError (luaState, e.Message);
			}

			return 0;
		}
コード例 #14
0
ファイル: ObjectTranslator.cs プロジェクト: Azhei/NLua
		private static int unregisterTable (LuaCore.lua_State luaState)
		{
			var translator = ObjectTranslatorPool.Instance.Find (luaState);
			return translator.unregisterTableInternal (luaState);
		}
コード例 #15
0
ファイル: ObjectTranslator.cs プロジェクト: Azhei/NLua
		/*
		 * Gets the CLR object in the index positon of the Lua stack. Returns
		 * delegates as Lua functions.
		 */
		internal object getNetObject (LuaCore.lua_State luaState, int index)
		{
			int idx = LuaLib.luanet_tonetobject (luaState, index);
			return idx != -1 ? objects [idx] : null;
		}
コード例 #16
0
ファイル: ObjectTranslator.cs プロジェクト: Azhei/NLua
		/*
		 * Pushes a CLR object into the Lua stack as an userdata
		 * with the provided metatable
		 */
		internal void pushObject (LuaCore.lua_State luaState, object o, string metatable)
		{
			int index = -1;

			// Pushes nil
			if (o.IsNull ()) {
				LuaLib.lua_pushnil (luaState);
				return;
			}

			// Object already in the list of Lua objects? Push the stored reference.
			bool found = objectsBackMap.TryGetValue (o, out index);

			if (found) {
				LuaLib.luaL_getmetatable (luaState, "luaNet_objects");
				LuaLib.lua_rawgeti (luaState, -1, index);

				// Note: starting with lua5.1 the garbage collector may remove weak reference items (such as our luaNet_objects values) when the initial GC sweep 
				// occurs, but the actual call of the __gc finalizer for that object may not happen until a little while later.  During that window we might call
				// this routine and find the element missing from luaNet_objects, but collectObject() has not yet been called.  In that case, we go ahead and call collect
				// object here
				// did we find a non nil object in our table? if not, we need to call collect object
				var type = LuaLib.lua_type (luaState, -1);
				if (type != LuaTypes.Nil) {
					LuaLib.lua_remove (luaState, -2);	 // drop the metatable - we're going to leave our object on the stack
					return;
				}

				// MetaFunctions.dumpStack(this, luaState);
				LuaLib.lua_remove (luaState, -1);	// remove the nil object value
				LuaLib.lua_remove (luaState, -1);	// remove the metatable
				collectObject (o, index);			// Remove from both our tables and fall out to get a new ID
			}

			index = addObject (o);
			pushNewObject (luaState, o, index, metatable);
		}
コード例 #17
0
ファイル: ObjectTranslator.cs プロジェクト: Azhei/NLua
		/*
		 * Gets the CLR object in the index position of the Lua stack. Returns
		 * delegates as is.
		 */
		internal object getRawNetObject (LuaCore.lua_State luaState, int index)
		{
			int udata = LuaLib.luanet_rawnetobj (luaState, index);
			return udata != -1 ? objects [udata] : null;
		}
コード例 #18
0
ファイル: ObjectTranslator.cs プロジェクト: Azhei/NLua
		/*
		 * Pushes a new object into the Lua stack with the provided
		 * metatable
		 */
		private void pushNewObject (LuaCore.lua_State luaState, object o, int index, string metatable)
		{
			if (metatable == "luaNet_metatable") {
				// Gets or creates the metatable for the object's type
				LuaLib.luaL_getmetatable (luaState, o.GetType ().AssemblyQualifiedName);

				if (LuaLib.lua_isnil (luaState, -1)) {
					LuaLib.lua_settop (luaState, -2);
					LuaLib.luaL_newmetatable (luaState, o.GetType ().AssemblyQualifiedName);
					LuaLib.lua_pushstring (luaState, "cache");
					LuaLib.lua_newtable (luaState);
					LuaLib.lua_rawset (luaState, -3);
					LuaLib.lua_pushlightuserdata (luaState, LuaLib.luanet_gettag ());
					LuaLib.lua_pushnumber (luaState, 1);
					LuaLib.lua_rawset (luaState, -3);
					LuaLib.lua_pushstring (luaState, "__index");
					LuaLib.lua_pushstring (luaState, "luaNet_indexfunction");
					LuaLib.lua_rawget (luaState, (int)LuaIndexes.Registry);
					LuaLib.lua_rawset (luaState, -3);
					LuaLib.lua_pushstring (luaState, "__gc");
					LuaLib.lua_pushstdcallcfunction (luaState, metaFunctions.gcFunction);
					LuaLib.lua_rawset (luaState, -3);
					LuaLib.lua_pushstring (luaState, "__tostring");
					LuaLib.lua_pushstdcallcfunction (luaState, metaFunctions.toStringFunction);
					LuaLib.lua_rawset (luaState, -3);
					LuaLib.lua_pushstring (luaState, "__newindex");
					LuaLib.lua_pushstdcallcfunction (luaState, metaFunctions.newindexFunction);
					LuaLib.lua_rawset (luaState, -3);
				}
			} else
				LuaLib.luaL_getmetatable (luaState, metatable);

			// Stores the object index in the Lua list and pushes the
			// index into the Lua stack
			LuaLib.luaL_getmetatable (luaState, "luaNet_objects");
			LuaLib.luanet_newudata (luaState, index);
			LuaLib.lua_pushvalue (luaState, -3);
			LuaLib.lua_remove (luaState, -4);
			LuaLib.lua_setmetatable (luaState, -2);
			LuaLib.lua_pushvalue (luaState, -1);
			LuaLib.lua_rawseti (luaState, -3, index);
			LuaLib.lua_remove (luaState, -2);
		}
コード例 #19
0
ファイル: ObjectTranslator.cs プロジェクト: Azhei/NLua
		/*
		 * Gets the values from the provided index to
		 * the top of the stack and returns them in an array.
		 */
		internal object[] popValues (LuaCore.lua_State luaState, int oldTop)
		{
			int newTop = LuaLib.lua_gettop (luaState);

			if (oldTop == newTop)
				return null;
			else {
				var returnValues = new List<object> ();
				for (int i = oldTop+1; i <= newTop; i++)
					returnValues.Add (getObject (luaState, i));

				LuaLib.lua_settop (luaState, oldTop);
				return returnValues.ToArray ();
			}
		}
コード例 #20
0
ファイル: ObjectTranslator.cs プロジェクト: Azhei/NLua
		/*
		 * Gets an object from the Lua stack with the desired type, if it matches, otherwise
		 * returns null.
		 */
		internal object getAsType (LuaCore.lua_State luaState, int stackPos, Type paramType)
		{
			var extractor = typeChecker.checkType (luaState, stackPos, paramType);
			return !extractor.IsNull () ? extractor (luaState, stackPos) : null;
		}
コード例 #21
0
ファイル: ObjectTranslator.cs プロジェクト: Azhei/NLua
		/*
		 * Gets the values from the provided index to
		 * the top of the stack and returns them in an array, casting
		 * them to the provided types.
		 */
		internal object[] popValues (LuaCore.lua_State luaState, int oldTop, Type[] popTypes)
		{
			int newTop = LuaLib.lua_gettop (luaState);

			if (oldTop == newTop)
				return null;
			else {
				int iTypes;
				var returnValues = new List<object> ();

				if (popTypes [0] == typeof(void))
					iTypes = 1;
				else
					iTypes = 0;

				for (int i = oldTop+1; i <= newTop; i++) {
					returnValues.Add (getAsType (luaState, i, popTypes [iTypes]));
					iTypes++;
				}

				LuaLib.lua_settop (luaState, oldTop);
				return returnValues.ToArray ();
			}
		}
コード例 #22
0
ファイル: ObjectTranslator.cs プロジェクト: Azhei/NLua
		/*
		 * Gets an object from the Lua stack according to its Lua type.
		 */
		internal object getObject (LuaCore.lua_State luaState, int index)
		{
			var type = LuaLib.lua_type (luaState, index);

			switch (type) {
			case LuaTypes.Number:
				{
					return LuaLib.lua_tonumber (luaState, index);
				}
			case LuaTypes.String: 
				{
					return LuaLib.lua_tostring (luaState, index);
				}
			case LuaTypes.Boolean:
				{
					return LuaLib.lua_toboolean (luaState, index);
				}
			case LuaTypes.Table: 
				{
					return getTable (luaState, index);
				}
			case LuaTypes.Function:
				{
					return getFunction (luaState, index);
				}
			case LuaTypes.UserData:
				{
					int udata = LuaLib.luanet_tonetobject (luaState, index);
					return udata != -1 ? objects [udata] : getUserData (luaState, index);
				}
			default:
				return null;
			}
		}
コード例 #23
0
ファイル: ObjectTranslator.cs プロジェクト: Azhei/NLua
		/*
		 * Checks if the method matches the arguments in the Lua stack, getting
		 * the arguments if it does.
		 */
		internal bool matchParameters (LuaCore.lua_State luaState, MethodBase method, ref MethodCache methodCache)
		{
			return metaFunctions.matchParameters (luaState, method, ref methodCache);
        }
コード例 #24
0
ファイル: ObjectTranslator.cs プロジェクト: Azhei/NLua
		/*
		 * Gets the table in the index positon of the Lua stack.
		 */
		internal LuaTable getTable (LuaCore.lua_State luaState, int index)
		{
			LuaLib.lua_pushvalue (luaState, index);
			return new LuaTable (LuaLib.lua_ref (luaState, 1), interpreter);
		}
コード例 #25
0
ファイル: Lua.cs プロジェクト: Azhei/NLua
		private void DebugHookCallbackInternal (LuaCore.lua_State luaState, LuaCore.lua_Debug luaDebug)
		{
			try {
				var temp = DebugHook;

				if (!temp.IsNull ())
					temp (this, new DebugHookEventArgs (luaDebug));
			} catch (Exception ex) {
				OnHookException (new HookExceptionEventArgs (ex));
			}
		}
コード例 #26
0
ファイル: ObjectTranslator.cs プロジェクト: Azhei/NLua
		/*
		 * Gets the userdata in the index positon of the Lua stack.
		 */
		internal LuaUserData getUserData (LuaCore.lua_State luaState, int index)
		{
			LuaLib.lua_pushvalue (luaState, index);
			return new LuaUserData (LuaLib.lua_ref (luaState, 1), interpreter);
		}
コード例 #27
0
ファイル: Lua.cs プロジェクト: Azhei/NLua
		/*
			* CAUTION: NLua.Lua instances can't share the same lua state! 
			*/
		public Lua (LuaCore.lua_State lState)
		{
			LuaLib.lua_pushstring (lState, "LUAINTERFACE LOADED");
			LuaLib.lua_gettable (lState, (int)LuaIndexes.Registry);
			
			if (LuaLib.lua_toboolean (lState, -1)) {
				LuaLib.lua_settop (lState, -2);
				throw new LuaException ("There is already a NLua.Lua instance associated with this Lua state");
			} else {
				LuaLib.lua_settop (lState, -2);
				LuaLib.lua_pushstring (lState, "LUAINTERFACE LOADED");
				LuaLib.lua_pushboolean (lState, true);
				LuaLib.lua_settable (lState, (int)LuaIndexes.Registry);
				luaState = lState;
				LuaLib.lua_pushvalue (lState, (int)LuaIndexes.Globals);
				LuaLib.lua_getglobal (lState, "luanet");
				LuaLib.lua_pushstring (lState, "getmetatable");
				LuaLib.lua_getglobal (lState, "getmetatable");
				LuaLib.lua_settable (lState, -3);
				LuaLib.lua_replace (lState, (int)LuaIndexes.Globals);
				translator = new ObjectTranslator (this, luaState);
				ObjectTranslatorPool.Instance.Add (luaState, translator);
				LuaLib.lua_replace (lState, (int)LuaIndexes.Globals);
				LuaLib.luaL_dostring (lState, Lua.init_luanet);	// steffenj: lua_dostring renamed to luaL_dostring
			}
				
			_StatePassed = true;
		}
コード例 #28
0
ファイル: ObjectTranslator.cs プロジェクト: Azhei/NLua
		/*
		 * Gets the function in the index positon of the Lua stack.
		 */
		internal LuaFunction getFunction (LuaCore.lua_State luaState, int index)
		{
			LuaLib.lua_pushvalue (luaState, index);
			return new LuaFunction (LuaLib.lua_ref (luaState, 1), interpreter);
		}
コード例 #29
0
ファイル: Lua.cs プロジェクト: Azhei/NLua
		/// <summary>
		/// Sets local (see lua docs)
		/// </summary>
		/// <param name = "luaDebug">lua debug structure</param>
		/// <param name = "n">see lua docs</param>
		/// <returns>see lua docs</returns>
		/// <author>Reinhard Ostermeier</author>
		public string SetLocal (LuaCore.lua_Debug luaDebug, int n)
		{
			return LuaCore.lua_setlocal (luaState, luaDebug, n).ToString ();
		}
コード例 #30
0
ファイル: ObjectTranslator.cs プロジェクト: Azhei/NLua
		private int importTypeInternal (LuaCore.lua_State luaState)
		{
			string className = LuaLib.lua_tostring (luaState, 1).ToString ();
			var klass = FindType (className);

			if (!klass.IsNull ())
				pushType (luaState, klass);
			else
				LuaLib.lua_pushnil (luaState);

			return 1;
		}