Ejemplo n.º 1
0
 void ILuaAPI.Concat(int n)
 {
     Utl.ApiCheckNumElems(this, n);
     if (n >= 2)
     {
         V_Concat(n);
     }
     else if (n == 0)
     {
         Top.V.SetSValue("");
         ApiIncrTop();
     }
 }
Ejemplo n.º 2
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);
        }
Ejemplo n.º 3
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];
        }
Ejemplo n.º 4
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];
        }
Ejemplo n.º 5
0
        // do the work for `lua_resume' in protected mode
        private void Resume(int firstArg)
        {
            int      numCSharpCalls = NumCSharpCalls;
            CallInfo ci             = CI;

            if (numCSharpCalls >= LuaLimits.LUAI_MAXCCALLS)
            {
                ResumeError("C stack overflow", firstArg);
            }
            if (Status == ThreadStatus.LUA_OK) // may be starting a coroutine
            {
                if (ci.Index > 0)              // not in base level
                {
                    ResumeError("cannot resume non-suspended coroutine", firstArg);
                }
                if (!D_PreCall(Stack[firstArg - 1], LuaDef.LUA_MULTRET)) // Lua function?
                {
                    V_Execute();                                         // call it
                }
            }
            else if (Status != ThreadStatus.LUA_YIELD)
            {
                ResumeError("cannot resume dead coroutine", firstArg);
            }
            else // resume from previous yield
            {
                Status       = ThreadStatus.LUA_OK;
                ci.FuncIndex = ci.ExtraIndex;
                if (ci.IsLua)    // yielded inside a hook?
                {
                    V_Execute(); // just continue running Lua code
                }
                else // `common' yield
                {
                    if (ci.ContinueFunc != null)
                    {
                        ci.Status      = ThreadStatus.LUA_YIELD; // `default' status
                        ci.CallStatus |= CallStatus.CIST_YIELDED;
                        int n = ci.ContinueFunc(this);           // call continuation
                        Utl.ApiCheckNumElems(this, n);
                        firstArg = Top.Index - n;                // yield results come from continuation
                    }
                    D_PosCall(firstArg);
                }
                Unroll();
            }
            Utl.Assert(numCSharpCalls == NumCSharpCalls);
        }
Ejemplo n.º 6
0
        void ILuaAPI.SetTable(int index)
        {
            StkId addr;

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

            var key = Stack[Top.Index - 2];
            var val = Stack[Top.Index - 1];

            V_SetTable(addr, key, val);
            Top = Stack[Top.Index - 2];
        }
Ejemplo n.º 7
0
        ThreadStatus ILuaAPI.Resume(ILuaState from, int numArgs)
        {
            LuaState fromState = from as LuaState;

            NumCSharpCalls  = (fromState != null) ? fromState.NumCSharpCalls + 1 : 1;
            NumNonYieldable = 0; // allow yields

            Utl.ApiCheckNumElems(this, (Status == ThreadStatus.LUA_OK) ? numArgs + 1 : numArgs);

            var resumeParam = new ResumeParam();

            resumeParam.L        = this;
            resumeParam.firstArg = Top.Index - numArgs;
            ThreadStatus status = D_RawRunProtected(DG_Resume, ref resumeParam);

            if (status == ThreadStatus.LUA_RESUME_ERROR) // error calling `lua_resume'?
            {
                status = ThreadStatus.LUA_ERRRUN;
            }
            else // yield or regular error
            {
                while (status != ThreadStatus.LUA_OK && status != ThreadStatus.LUA_YIELD) // error?
                {
                    if (Recover(status)) // recover point?
                    {
                        var unrollParam = new UnrollParam();
                        unrollParam.L = this;
                        status        = D_RawRunProtected(DG_Unroll, ref unrollParam);
                    }
                    else // unrecoverable error
                    {
                        Status = status; // mark thread as `dead'
                        SetErrorObj(status, Top);
                        CI.TopIndex = Top.Index;
                        break;
                    }
                }
                Utl.Assert(status == Status);
            }

            NumNonYieldable = 1; // do not allow yields
            NumCSharpCalls--;
            Utl.Assert(NumCSharpCalls == ((fromState != null) ? fromState.NumCSharpCalls : 0));
            return(status);
        }
Ejemplo n.º 8
0
        DumpStatus ILuaAPI.Dump(LuaWriter writeFunc)
        {
            Utl.ApiCheckNumElems(this, 1);

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

            if (!below.V.TtIsFunction() || !below.V.ClIsLuaClosure())
            {
                return(DumpStatus.ERROR);
            }

            var o = below.V.ClLValue();

            if (o == null)
            {
                return(DumpStatus.ERROR);
            }

            return(DumpState.Dump(o.Proto, writeFunc, false));
        }
Ejemplo n.º 9
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);
            }
        }
Ejemplo n.º 10
0
        string ILuaAPI.SetUpvalue(int funcIndex, int n)
        {
            StkId addr;

            if (!Index2Addr(funcIndex, out addr))
            {
                return(null);
            }

            Utl.ApiCheckNumElems(this, 1);

            StkId val;
            var   name = AuxUpvalue(addr, n, out val);

            if (name == null)
            {
                return(null);
            }

            Top = Stack[Top.Index - 1];
            val.V.SetObj(ref Top.V);
            return(name);
        }
Ejemplo n.º 11
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);
        }
Ejemplo n.º 12
0
        private void FinishCSharpCall()
        {
            CallInfo ci = CI;

            Utl.Assert(ci.ContinueFunc != null); // must have a continuation
            Utl.Assert(NumNonYieldable == 0);
            // finish `CallK'
            AdjustResults(ci.NumResults);
            // call continuation function
            if ((ci.CallStatus & CallStatus.CIST_STAT) == 0) // no call status?
            {
                ci.Status = ThreadStatus.LUA_YIELD;          // `default' status
            }
            Utl.Assert(ci.Status != ThreadStatus.LUA_OK);
            ci.CallStatus = (ci.CallStatus
                             & ~(CallStatus.CIST_YPCALL | CallStatus.CIST_STAT))
                            | CallStatus.CIST_YIELDED;

            int n = ci.ContinueFunc(this); // call

            Utl.ApiCheckNumElems(this, n);
            // finish `D_PreCall'
            D_PosCall(Top.Index - n);
        }
Ejemplo n.º 13
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();
        }
Ejemplo n.º 14
0
 int ILuaAPI.Error()
 {
     Utl.ApiCheckNumElems(this, 1);
     G_ErrorMsg();
     return(0);
 }
Ejemplo n.º 15
0
 void ILuaAPI.Replace(int index)
 {
     Utl.ApiCheckNumElems(this, 1);
     MoveTo(Stack[Top.Index - 1], index);
     Top = Stack[Top.Index - 1];
 }
Ejemplo n.º 16
0
 public int Error()
 {
     Utl.ApiCheckNumElems(this, 1);
     G_ErrorMsg();
     return(0);
 }