Esempio n. 1
0
        void ILuaAPI.CallK(int numArgs, int numResults,
                           int context, CSharpFunctionDelegate continueFunc)
        {
            Utl.ApiCheck(continueFunc == null || !CI.IsLua,
                         "cannot use continuations inside hooks");
            Utl.ApiCheckNumElems(this, numArgs + 1);
            Utl.ApiCheck(Status == ThreadStatus.LUA_OK,
                         "cannot do calls on non-normal thread");
            CheckResults(numArgs, numResults);
            var func = Stack[Top.Index - (numArgs + 1)];

            // need to prepare continuation?
            if (continueFunc != null && NumNonYieldable == 0)
            {
                CI.ContinueFunc = continueFunc;
                CI.Context      = context;
                D_Call(func, numResults, true);
            }
            // no continuation or no yieldable
            else
            {
                D_Call(func, numResults, false);
            }
            AdjustResults(numResults);
        }
Esempio n. 2
0
 private void ApiIncrTop()
 {
     StkId.inc(ref Top);
     // ULDebug.Log( "[ApiIncrTop] ==== Top.Index:" + Top.Index );
     // ULDebug.Log( "[ApiIncrTop] ==== CI.Top.Index:" + CI.Top.Index );
     Utl.ApiCheck(Top.Index <= CI.TopIndex, "stack overflow");
 }
Esempio n. 3
0
        bool ILuaAPI.Compare(int index1, int index2, LuaEq op)
        {
            StkId addr1;

            if (!Index2Addr(index1, out addr1))
            {
                Utl.InvalidIndex();
            }

            StkId addr2;

            if (!Index2Addr(index2, out addr2))
            {
                Utl.InvalidIndex();
            }

            switch (op)
            {
            case LuaEq.LUA_OPEQ: return(EqualObj(ref addr1.V, ref addr2.V, false));

            case LuaEq.LUA_OPLT: return(V_LessThan(addr1, addr2));

            case LuaEq.LUA_OPLE: return(V_LessEqual(addr1, addr2));

            default: Utl.ApiCheck(false, "invalid option"); return(false);
            }
        }
Esempio n. 4
0
        ThreadStatus ILuaAPI.PCallK(int numArgs, int numResults, int errFunc,
                                    int context, CSharpFunctionDelegate continueFunc)
        {
            Utl.ApiCheck(continueFunc == null || !CI.IsLua,
                         "cannot use continuations inside hooks");
            Utl.ApiCheckNumElems(this, numArgs + 1);
            Utl.ApiCheck(Status == ThreadStatus.LUA_OK,
                         "cannot do calls on non-normal thread");
            CheckResults(numArgs, numResults);

            int func;

            if (errFunc == 0)
            {
                func = 0;
            }
            else
            {
                StkId addr;
                if (!Index2Addr(errFunc, out addr))
                {
                    Utl.InvalidIndex();
                }

                func = addr.Index;
            }

            ThreadStatus status;
            CallS        c = new CallS();

            c.L         = this;
            c.FuncIndex = Top.Index - (numArgs + 1);
            if (continueFunc == null || NumNonYieldable > 0) // no continuation or no yieldable?
            {
                c.NumResults = numResults;
                status       = D_PCall(DG_F_Call, ref c, c.FuncIndex, func);
            }
            else
            {
                int ciIndex = CI.Index;
                CI.ContinueFunc = continueFunc;
                CI.Context      = context;
                CI.ExtraIndex   = c.FuncIndex;
                CI.OldAllowHook = AllowHook;
                CI.OldErrFunc   = ErrFunc;
                ErrFunc         = func;
                CI.CallStatus  |= CallStatus.CIST_YPCALL;

                D_Call(Stack[c.FuncIndex], numResults, true);

                CallInfo ci = BaseCI[ciIndex];
                ci.CallStatus &= ~CallStatus.CIST_YPCALL;
                ErrFunc        = ci.OldErrFunc;
                status         = ThreadStatus.LUA_OK;
            }
            AdjustResults(numResults);
            return(status);
        }
Esempio n. 5
0
        private bool Index2Addr(int index, out StkId addr)
        {
            CallInfo ci = CI;

            if (index > 0)
            {
                var addrIndex = ci.FuncIndex + index;
                Utl.ApiCheck(index <= ci.TopIndex - (ci.FuncIndex + 1), "unacceptable index");
                if (addrIndex >= Top.Index)
                {
                    addr = default(StkId);
                    return(false);
                }

                addr = Stack[addrIndex];
                return(true);
            }
            else if (index > LuaDef.LUA_REGISTRYINDEX)
            {
                Utl.ApiCheck(index != 0 && -index <= Top.Index - (ci.FuncIndex + 1), "invalid index");
                addr = Stack[Top.Index + index];
                return(true);
            }
            else if (index == LuaDef.LUA_REGISTRYINDEX)
            {
                addr = G.Registry;
                return(true);
            }
            // upvalues
            else
            {
                index = LuaDef.LUA_REGISTRYINDEX - index;
                Utl.ApiCheck(index <= LuaLimits.MAXUPVAL + 1, "upvalue index too large");
                var func = Stack[ci.FuncIndex];
                Utl.Assert(func.V.TtIsFunction());

                if (func.V.ClIsLcsClosure())
                {
                    addr = default(StkId);
                    return(false);
                }

                Utl.Assert(func.V.ClIsCsClosure());
                var clcs = func.V.ClCsValue();
                if (index > clcs.Upvals.Length)
                {
                    addr = default(StkId);
                    return(false);
                }

                addr = clcs.Upvals[index - 1];
                return(true);
            }
        }
Esempio n. 6
0
        bool ILuaAPI.SetMetaTable(int index)
        {
            Utl.ApiCheckNumElems(this, 1);

            StkId addr;

            if (!Index2Addr(index, out addr))
            {
                Utl.InvalidIndex();
            }

            var      below = Stack[Top.Index - 1];
            LuaTable mt;

            if (below.V.TtIsNil())
            {
                mt = null;
            }
            else
            {
                Utl.ApiCheck(below.V.TtIsTable(), "table expected");
                mt = below.V.HValue();
            }

            switch (addr.V.Tt)
            {
            case (int)LuaType.LUA_TTABLE:
            {
                var tbl = addr.V.HValue();
                tbl.MetaTable = mt;
                break;
            }

            case (int)LuaType.LUA_TUSERDATA:
            {
                var ud = addr.V.RawUValue();
                ud.MetaTable = mt;
                break;
            }

            default:
            {
                G.MetaTables[addr.V.Tt] = mt;
                break;
            }
            }
            Top = Stack[Top.Index - 1];
            return(true);
        }
Esempio n. 7
0
        void ILuaAPI.RawSet(int index)
        {
            Utl.ApiCheckNumElems(this, 2);
            StkId addr;

            if (!Index2Addr(index, out addr))
            {
                Utl.InvalidIndex();
            }
            Utl.ApiCheck(addr.V.TtIsTable(), "table expected");
            var tbl = addr.V.HValue();

            tbl.Set(ref Stack[Top.Index - 2].V, ref Stack[Top.Index - 1].V);
            Top = Stack[Top.Index - 2];
        }
Esempio n. 8
0
        public void RawSetI(int index, int n)
        {
            Utl.ApiCheckNumElems(this, 1);
            StkId addr;

            if (!Index2Addr(index, out addr))
            {
                Utl.InvalidIndex();
            }
            Utl.ApiCheck(addr.V.TtIsTable(), "table expected");
            var tbl = addr.V.HValue();

            tbl.SetInt(n, ref Stack[Top.Index - 1].V);
            Top = Stack[Top.Index - 1];
        }
Esempio n. 9
0
        void ILuaAPI.RawGetI(int index, int n)
        {
            StkId addr;

            if (!Index2Addr(index, out addr))
            {
                Utl.ApiCheck(false, "table expected");
            }

            var tbl = addr.V.HValue();

            Utl.ApiCheck(tbl != null, "table expected");

            Top.V.SetObj(ref tbl.GetInt(n).V);
            ApiIncrTop();
        }
Esempio n. 10
0
 void ILuaAPI.SetTop(int index)
 {
     if (index >= 0)
     {
         Utl.ApiCheck(index <= StackLast - (CI.FuncIndex + 1), "new top too large");
         int newTop = CI.FuncIndex + 1 + index;
         for (int i = Top.Index; i < newTop; ++i)
         {
             Stack[i].V.SetNilValue();
         }
         Top = Stack[newTop];
     }
     else
     {
         Utl.ApiCheck(-(index + 1) <= (Top.Index - (CI.FuncIndex + 1)), "invalid new top");
         Top = Stack[Top.Index + index + 1];
     }
 }
Esempio n. 11
0
        void ILuaAPI.XMove(ILuaState to, int n)
        {
            var toLua = to as LuaState;

            if ((LuaState)this == toLua)
            {
                return;
            }

            Utl.ApiCheckNumElems(this, n);
            Utl.ApiCheck(G == toLua.G, "moving among independent states");
            Utl.ApiCheck(toLua.CI.TopIndex - toLua.Top.Index >= n, "not enough elements to move");

            int index = Top.Index - n;

            Top = Stack[index];
            for (int i = 0; i < n; ++i)
            {
                StkId.inc(ref toLua.Top).V.SetObj(ref Stack[index + i].V);
            }
        }
Esempio n. 12
0
        public int GetInfo(string what, LuaDebug ar)
        {
            CallInfo ci;
            StkId    func;

            int pos = 0;

            if (what[pos] == '>')
            {
                ci   = null;
                func = Stack[Top.Index - 1];

                Utl.ApiCheck(func.V.TtIsFunction(), "function expected");
                pos++;

                Top = Stack[Top.Index - 1];
            }
            else
            {
                ci   = BaseCI[ar.ActiveCIIndex];
                func = Stack[ci.FuncIndex];
                Utl.Assert(Stack[ci.FuncIndex].V.TtIsFunction());
            }

            // var IsClosure( func.Value ) ? func.Value
            int status = AuxGetInfo(what, ar, func, ci);

            if (what.Contains("f"))
            {
                Top.V.SetObj(ref func.V);
                IncrTop();
            }
            if (what.Contains("L"))
            {
                CollectValidLines(func);
            }
            return(status);
        }
Esempio n. 13
0
        int ILuaAPI.YieldK(int numResults,
                           int context, CSharpFunctionDelegate continueFunc)
        {
            CallInfo ci = CI;

            Utl.ApiCheckNumElems(this, numResults);

            if (NumNonYieldable > 0)
            {
                if (this != G.MainThread)
                {
                    G_RunError("attempt to yield across metamethod/C-call boundary");
                }
                else
                {
                    G_RunError("attempt to yield from outside a coroutine");
                }
            }
            Status        = ThreadStatus.LUA_YIELD;
            ci.ExtraIndex = ci.FuncIndex; // save current `func'
            if (ci.IsLua)                 // inside a hook
            {
                Utl.ApiCheck(continueFunc == null, "hooks cannot continue after yielding");
            }
            else
            {
                ci.ContinueFunc = continueFunc;
                if (ci.ContinueFunc != null) // is there a continuation
                {
                    ci.Context = context;
                }
                ci.FuncIndex = Top.Index - (numResults + 1);
                D_Throw(ThreadStatus.LUA_YIELD);
            }
            Utl.Assert((ci.CallStatus & CallStatus.CIST_HOOKED) != 0); // must be inside a hook
            return(0);
        }
Esempio n. 14
0
        void ILuaAPI.PushCSharpClosure(CSharpFunctionDelegate f, int n)
        {
            if (n == 0)
            {
                Top.V.SetClCsValue(new LuaCsClosureValue(f));
            }
            else
            {
                // 带 UpValue 的 C# function
                Utl.ApiCheckNumElems(this, n);
                Utl.ApiCheck(n <= LuaLimits.MAXUPVAL, "upvalue index too large");

                LuaCsClosureValue cscl = new LuaCsClosureValue(f, n);
                int index = Top.Index - n;
                Top = Stack[index];
                for (int i = 0; i < n; ++i)
                {
                    cscl.Upvals[i].V.SetObj(ref Stack[index + i].V);
                }

                Top.V.SetClCsValue(cscl);
            }
            ApiIncrTop();
        }
Esempio n. 15
0
 private void CheckResults(int numArgs, int numResults)
 {
     Utl.ApiCheck(numResults == LuaDef.LUA_MULTRET ||
                  CI.TopIndex - Top.Index >= numResults - numArgs,
                  "results from function overflow current stack size");
 }