Пример #1
0
        /// <summary>
        /// Assuming we have a Lua error string sitting on the stack, throw a C# exception out to the user's app
        /// </summary>
        /// <exception cref="LuaScriptException">Thrown if the script caused an exception</exception>
        void ThrowExceptionFromError(int oldTop)
        {
            object err = translator.getObject(luaState, -1);

            LuaDLL.lua_settop(luaState, oldTop);

            // A pre-wrapped exception - just rethrow it (stack trace of InnerException will be preserved)
            LuaException luaEx = err as LuaException;

            if (luaEx != null)
            {
                throw luaEx;
            }

            // A non-wrapped Lua error (best interpreted as a string) - wrap it and throw it
            if (err == null)
            {
                err = "Unknown Lua Error";
            }

            throw new LuaException(err.ToString());
        }
Пример #2
0
        public object getAsObject(SharpLua.Lua.LuaState luaState, int stackPos)
        {
            if (LuaDLL.lua_type(luaState, stackPos) == LuaTypes.LUA_TTABLE)
            {
                if (LuaDLL.luaL_getmetafield(luaState, stackPos, "__index"))
                {
                    if (LuaDLL.luaL_checkmetatable(luaState, -1))
                    {
                        LuaDLL.lua_insert(luaState, stackPos);
                        LuaDLL.lua_remove(luaState, stackPos + 1);
                    }
                    else
                    {
                        LuaDLL.lua_settop(luaState, -2);
                    }
                }
            }
            object obj = translator.getObject(luaState, stackPos);

            return(obj);
        }
Пример #3
0
        /*
         * Called by the __index metafunction of CLR objects in case the
         * method is not cached or it is a field/property/event.
         * Receives the object and the member name as arguments and returns
         * either the value of the member or a delegate to call it.
         * If the member does not exist returns nil.
         */
        private int getMethod(SharpLua.Lua.LuaState luaState)
        {
            object obj = translator.getRawNetObject(luaState, 1);

            if (obj == null)
            {
                translator.throwError(luaState, "trying to index an invalid object reference");
                LuaDLL.lua_pushnil(luaState);
                return(1);
            }

            object index     = translator.getObject(luaState, 2);
            Type   indexType = index.GetType();  //* not used

            string methodName = index as string; // will be null if not a string arg
            Type   objType    = obj.GetType();

            // Handle the most common case, looking up the method by name.

            // CP: This will fail when using indexers and attempting to get a value with the same name as a property of the object,
            // ie: xmlelement['item'] <- item is a property of xmlelement
            try
            {
                if (methodName != null && isMemberPresent(objType, methodName))
                {
                    return(getMember(luaState, objType, obj, methodName, BindingFlags.Instance | BindingFlags.IgnoreCase));
                }
            }
            catch { }
            bool failed = true;

            // Try to access by array if the type is right and index is an int (lua numbers always come across as double)
            if (objType.IsArray && index is double)
            {
                int   intIndex = (int)((double)index);
                Array aa       = obj as Array;
                if (intIndex >= aa.Length)
                {
                    return(translator.pushError(luaState, "array index out of bounds: " + intIndex + " " + aa.Length));
                }
                object val = aa.GetValue(intIndex);
                translator.push(luaState, val);
                failed = false;
            }
            else
            {
                // Try to use get_Item to index into this .net object
                //MethodInfo getter = objType.GetMethod("get_Item");
                // issue here is that there may be multiple indexers..
                MethodInfo[] methods = objType.GetMethods();

                foreach (MethodInfo mInfo in methods)
                {
                    if (mInfo.Name == "get_Item")
                    {
                        //check if the signature matches the input
                        if (mInfo.GetParameters().Length == 1)
                        {
                            MethodInfo      getter      = mInfo;
                            ParameterInfo[] actualParms = (getter != null) ? getter.GetParameters() : null;
                            if (actualParms == null || actualParms.Length != 1)
                            {
                                return(translator.pushError(luaState, "method not found (or no indexer): " + index));
                            }
                            else
                            {
                                // Get the index in a form acceptable to the getter
                                index = translator.getAsType(luaState, 2, actualParms[0].ParameterType);
                                // Just call the indexer - if out of bounds an exception will happen
                                try
                                {
                                    object result = getter.Invoke(obj, new object[] { index });
                                    translator.push(luaState, result);
                                    failed = false;
                                }
                                catch (TargetInvocationException e)
                                {
                                    // Provide a more readable description for the common case of key not found
                                    if (e.InnerException is KeyNotFoundException)
                                    {
                                        return(translator.pushError(luaState, "key '" + index + "' not found "));
                                    }
                                    else
                                    {
                                        return(translator.pushError(luaState, "exception indexing '" + index + "' " + e.Message));
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (failed)
            {
                return(translator.pushError(luaState, "cannot find " + index));
            }
            LuaDLL.lua_pushboolean(luaState, false);
            return(2);
        }