Пример #1
0
        internal object[] Call(object[] args, IntPtr?stateOverride = null, bool isResuming = false)
        {
            var state = stateOverride ?? MainState;

            Debug.Assert(LuaApi.GetMainState(state) == MainState, "State override did not match main state.");
            Debug.Assert(isResuming || LuaApi.Type(state, -1) == LuaType.Function, "Stack doesn't have function on top.");

            var oldTop  = isResuming ? 0 : LuaApi.GetTop(state) - 1;
            var numArgs = args.Length;

            if (oldTop + numArgs > LuaApi.MinStackSize && !LuaApi.CheckStack(state, numArgs))
            {
                throw new LuaException("Not enough stack space for arguments.");
            }

            foreach (var arg in args)
            {
                PushObject(arg, state);
            }

            var status = isResuming ? LuaApi.Resume(state, MainState, numArgs) : LuaApi.PCallK(state, numArgs);

            if (status != LuaStatus.Ok && status != LuaStatus.Yield)
            {
                var errorMessage = LuaApi.ToString(state, -1);
                LuaApi.Pop(state, 1);
                throw new LuaException(errorMessage);
            }

            // This is a fast path for functions returning nothing since we avoid a SetTop call.
            var top = LuaApi.GetTop(state);

            if (top == oldTop)
            {
                return(EmptyObjectArray);
            }

            if (top + 1 > LuaApi.MinStackSize && !LuaApi.CheckStack(state, 1))
            {
                throw new LuaException("Not enough scratch stack space.");
            }

            var results = ToObjects(oldTop + 1, top, state);

            LuaApi.SetTop(state, oldTop);
            return(results);
        }