예제 #1
0
파일: VM.cs 프로젝트: weimingtom/cslua
        private void CallTM(ref TValue f, ref TValue p1, ref TValue p2, StkId p3, bool hasres)
        {
            var result = p3.Index;
            var func   = Top;

            StkId.inc(ref Top).V.SetObj(ref f);  // push function
            StkId.inc(ref Top).V.SetObj(ref p1); // push 1st argument
            StkId.inc(ref Top).V.SetObj(ref p2); // push 2nd argument
            if (!hasres)                         // no result? p3 is 3rd argument
            {
                StkId.inc(ref Top).V.SetObj(ref p3.V);
            }
            D_CheckStack(0);
            D_Call(func, (hasres ? 1 : 0), CI.IsLua);
            if (hasres)                         // if has result, move it ot its place
            {
                Top = Stack[Top.Index - 1];
                Stack[result].V.SetObj(ref Top.V);
            }
        }
예제 #2
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);
            }
        }
예제 #3
0
 private void IncrTop()
 {
     StkId.inc(ref Top);
     D_CheckStack(0);
 }
예제 #4
0
        /// <summary>
        /// return true if function has been executed
        /// </summary>
        private bool D_PreCall(StkId func, int nResults)
        {
            // prepare for Lua call

#if DEBUG_D_PRE_CALL
            ULDebug.Log("============================ D_PreCall func:" + func);
#endif

            int funcIndex = func.Index;
            if (!func.V.TtIsFunction())
            {
                // not a function
                // retry with `function' tag method
                func = tryFuncTM(func);

                // now it must be a function
                return(D_PreCall(func, nResults));
            }

            if (func.V.ClIsLuaClosure())
            {
                var cl = func.V.ClLValue();
                Utl.Assert(cl != null);
                var p = cl.Proto;

                D_CheckStack(p.MaxStackSize + p.NumParams);
                func = Stack[funcIndex];

                // 补全参数
                int n = (Top.Index - func.Index) - 1;
                for ( ; n < p.NumParams; ++n)
                {
                    StkId.inc(ref Top).V.SetNilValue();
                }

                int stackBase = (!p.IsVarArg) ? (func.Index + 1) : AdjustVarargs(p, n);

                CI            = ExtendCI();
                CI.NumResults = nResults;
                CI.FuncIndex  = func.Index;
                CI.BaseIndex  = stackBase;
                CI.TopIndex   = stackBase + p.MaxStackSize;
                Utl.Assert(CI.TopIndex <= StackLast);
                CI.SavedPc    = new InstructionPtr(p.Code, 0);
                CI.CallStatus = CallStatus.CIST_LUA;

                Top = Stack[CI.TopIndex];

                return(false);
            }

            if (func.V.ClIsCsClosure())
            {
                var cscl = func.V.ClCsValue();
                Utl.Assert(cscl != null);

                D_CheckStack(LuaDef.LUA_MINSTACK);
                func = Stack[funcIndex];

                CI            = ExtendCI();
                CI.NumResults = nResults;
                CI.FuncIndex  = func.Index;
                CI.TopIndex   = Top.Index + LuaDef.LUA_MINSTACK;
                CI.CallStatus = CallStatus.CIST_NONE;

                // do the actual call
                int n = cscl.F(this);

                // poscall
                D_PosCall(Top.Index - n);

                return(true);
            }

            throw new System.NotImplementedException();
        }