示例#1
0
文件: Lua.cs 项目: yatagarasu25/NLua
        /// <summary>
        ///
        /// </summary>
        /// <param name = "chunk"></param>
        /// <param name = "name"></param>
        /// <returns></returns>
        public LuaFunction LoadString(byte[] chunk, string name)
        {
            int oldTop = LuaLib.LuaGetTop(luaState);

            executing = true;

            try {
                if (LuaLib.LuaLLoadBuffer(luaState, chunk, name) != 0)
                {
                    ThrowExceptionFromError(oldTop);
                }
            } finally {
                executing = false;
            }

            var result = translator.GetFunction(luaState, -1);

            translator.PopValues(luaState, oldTop);
            return(result);
        }
示例#2
0
        /*
         * Gets the values from the provided index to
         * the top of the stack and returns them in an array.
         */
        internal object[] PopValues(LuaState luaState, int oldTop)
        {
            int newTop = LuaLib.LuaGetTop(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.LuaSetTop(luaState, oldTop);
                return(returnValues.ToArray());
            }
        }
示例#3
0
        /*
         * Passes errors (argument e) to the Lua interpreter
         */
        internal void ThrowError(LuaState luaState, object e)
        {
            // We use this to remove anything pushed by luaL_where
            int oldTop = LuaLib.LuaGetTop(luaState);

            // Stack frame #1 is our C# wrapper, so not very interesting to the user
            // Stack frame #2 must be the lua code that called us, so that's what we want to use
            LuaLib.LuaLWhere(luaState, 1);
            var curlev = PopValues(luaState, oldTop);

            // Determine the position in the script where the exception was triggered
            string errLocation = string.Empty;

            if (curlev.Length > 0)
            {
                errLocation = curlev [0].ToString();
            }

            string message = e as string;

            if (message != null)
            {
                // Wrap Lua error (just a string) and store the error location
                e = new LuaScriptException(message, errLocation);
            }
            else
            {
                var ex = e as Exception;

                if (ex != null)
                {
                    // Wrap generic .NET exception as an InnerException and store the error location
                    e = new LuaScriptException(ex, errLocation);
                }
            }

            Push(luaState, e);
            LuaLib.LuaError(luaState);
        }
示例#4
0
文件: Lua.cs 项目: zwwl0801/NLua
        /// <summary>
        /// Executes a Lua chunk and returns all the chunk's return values in an array.
        /// </summary>
        /// <param name = "chunk">Chunk to execute</param>
        /// <param name = "chunkName">Name to associate with the chunk. Defaults to "chunk".</param>
        /// <returns></returns>
        public object[] DoString(string chunk, string chunkName = "chunk")
        {
            int oldTop = LuaLib.LuaGetTop(luaState);

            executing = true;

            if (LuaLib.LuaLLoadBuffer(luaState, chunk, chunkName) == 0)
            {
                int errfunction = 0;
                if (UseTraceback)
                {
                    errfunction = PushDebugTraceback(luaState, 0);
                    oldTop++;
                }

                try
                {
                    if (LuaLib.LuaPCall(luaState, 0, -1, errfunction) == 0)
                    {
                        return(translator.PopValues(luaState, oldTop));
                    }
                    else
                    {
                        ThrowExceptionFromError(oldTop);
                    }
                }
                finally
                {
                    executing = false;
                }
            }
            else
            {
                ThrowExceptionFromError(oldTop);
            }

            return(null);                               // Never reached - keeps compiler happy
        }
示例#5
0
        /*
         * Calls the object as a function with the provided arguments and
         * casting returned values to the types in returnTypes before returning
         * them in an array
         */
        internal object[] CallFunction(object function, object[] args, Type[] returnTypes)
        {
            int nArgs  = 0;
            int oldTop = LuaLib.LuaGetTop(luaState);

            if (!LuaLib.LuaCheckStack(luaState, args.Length + 6))
            {
                throw new LuaException("Lua stack overflow");
            }

            translator.Push(luaState, function);

            if (args != null)
            {
                nArgs = args.Length;

                for (int i = 0; i < args.Length; i++)
                {
                    translator.Push(luaState, args [i]);
                }
            }

            executing = true;

            try {
                int error = LuaLib.LuaPCall(luaState, nArgs, -1, 0);
                if (error != 0)
                {
                    ThrowExceptionFromError(oldTop);
                }
            } finally {
                executing = false;
            }

            return(returnTypes != null?translator.PopValues(luaState, oldTop, returnTypes) : translator.PopValues(luaState, oldTop));
        }
示例#6
0
        /// <summary>
        /// Pops a value from the lua stack.
        /// </summary>
        /// <returns>Returns the top value from the lua stack.</returns>
        public object Pop()
        {
            int top = LuaLib.LuaGetTop(luaState);

            return(translator.PopValues(luaState, top - 1) [0]);
        }
示例#7
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(LuaState luaState, MethodBase method, ref MethodCache methodCache)
        {
            ExtractValue extractValue;
            bool         isMethod        = true;
            var          paramInfo       = method.GetParameters();
            int          currentLuaParam = 1;
            int          nLuaParams      = LuaLib.LuaGetTop(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 (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);
        }