예제 #1
0
파일: lapi.cs 프로젝트: weimingtom/cclua
        public static int lua_checkstack(lua_State L, int n)
        {
            int      res;
            CallInfo ci = L.ci;

            lua_lock(L);
            imp.api_check(n >= 0, "negative 'n'");
            if (L.stack_last - L.top > n) /* stack large enough? */
            {
                res = 1;                  /* yes; check is OK */
            }
            else                          /* no; need to grow stack */
            {
                int inuse = L.top + imp.EXTRA_STACK;
                if (inuse > imp.LUAI_MAXSTACK - n) /* can grow without overflow? */
                {
                    res = 0;                       /* no */
                }
                else  /* try to grow stack */
                {
                    res = (imp.luaD_rawrunprotected(L, imp.growstack, n) == LUA_OK ? 1 : 0);
                }
            }
            if (res > 0 && ci.top < L.top + n)
            {
                ci.top = L.top + n;  /* adjust frame top */
            }
            lua_unlock(L);
            return(res);
        }
예제 #2
0
파일: lstate.cs 프로젝트: weimingtom/cclua
        public static CallInfo luaE_extendCI(lua_State L)
        {
            CallInfo ci = luaM_newobject <CallInfo> (L);

            lua_assert(L.ci.next == null);
            L.ci.next   = ci;
            ci.previous = L.ci;
            ci.next     = null;
            return(ci);
        }
예제 #3
0
파일: ldebug.cs 프로젝트: weimingtom/cclua
        public static string findvararg(lua_State L, CallInfo ci, int n, ref int pos)
        {
            int nparam = clLvalue(L, ci.func).p.numparams;

            if (n >= ci.u.l.nbase - ci.func - nparam)
            {
                return(null);
            }
            else
            {
                pos = ci.func + nparam + n;
                return("(*vararg)");
            }
        }
예제 #4
0
파일: ldebug.cs 프로젝트: weimingtom/cclua
        /*
        ** Checks whether value 'o' came from an upvalue. (That can only happen
        ** with instructions OP_GETTABUP/OP_SETTABUP, which operate directly on
        ** upvalues.)
        */
        public static string getupvalname(lua_State L, CallInfo ci, TValue o, ref string name)
        {
            LClosure c = ci_func(L, ci);

            for (int i = 0; i < c.nupvalues; i++)
            {
                if (c.upvals[i].v == o)
                {
                    name = upvalname(c.p, i);
                    return("upvalue");
                }
            }
            return(null);
        }
예제 #5
0
파일: lapi.cs 프로젝트: weimingtom/cclua
        public static int lua_pcallk(lua_State L, int nargs, int nresults, int errfunc, long ctx, lua_KFunction k)
        {
            lua_lock(L);
            imp.api_check(k == null || imp.isLua(L.ci) == false, "cannot use continuations inside hooks");
            imp.api_checknelems(L, nargs + 1);
            imp.api_check(L.status == LUA_OK, "cannot do calls on non-normal thread");
            imp.checkresults(L, nargs, nresults);
            int func = 0;

            if (errfunc == 0)
            {
                func = 0;
            }
            else
            {
                TValue o = imp.index2addr(L, errfunc);
                imp.api_checkstackindex(errfunc, o);
                func = imp.savestack(L, errfunc);
            }
            CallS c = new CallS();

            c.func = L.top - (nargs + 1);  /* function to be called */
            int status = 0;

            if (k == null && L.nny > 0) /* no continuation or no yieldable? */
            {
                c.nresults = nresults;  /* do a 'conventional' protected call */
                status     = imp.luaD_pcall(L, imp.f_call, c, imp.savestack(L, c.func), func);
            }
            else    /* prepare continuation (call is already protected by 'resume') */
            {
                CallInfo ci = L.ci;
                ci.u.c.k   = k;   /* save continuation */
                ci.u.c.ctx = ctx; /* save context */
                /* save information for error recovery */
                ci.extra           = imp.savestack(L, c.func);
                ci.u.c.old_errfunc = L.errfunc;
                L.errfunc          = func;
                imp.setoah(ref ci.callstatus, L.allowhook); /* save value of 'allowhook' */
                ci.callstatus |= imp.CIST_YPCALL;           /* function can do error recovery */
                imp.luaD_call(L, c.func, nresults, 1);      /* do the call */
                ci.callstatus = (byte)(ci.callstatus & (~imp.CIST_YPCALL));
                L.errfunc     = ci.u.c.old_errfunc;
                status        = LUA_OK; /* if it is here, there were no errors */
            }
            imp.adjustresults(L, nresults);
            lua_unlock(L);
            return(status);
        }
예제 #6
0
파일: ldebug.cs 프로젝트: weimingtom/cclua
        public static string varinfo(lua_State L, TValue o)
        {
            string   name = null;
            CallInfo ci   = L.ci;
            string   kind = null;

            if (isLua(ci))
            {
                kind = getupvalname(L, ci, o, ref name);
                if (kind == null && isinstatck(ci, o))
                {
                    // TODO : reg
                    kind = getobjname(ci_func(L, ci).p, currentpc(L, ci), 0, ref name);
                }
            }
            return((kind != null) ? luaO_pushfstring(L, " (%s '%s')", kind, name) : "");
        }
예제 #7
0
파일: lstate.cs 프로젝트: weimingtom/cclua
        /*
        ** free half of the CallInfo structures not in use by a thread
        */
        public static void luaE_shrinkCI(lua_State L)
        {
            CallInfo ci = L.ci;

            while (ci.next != null)                /* while there is 'next' */
            {
                CallInfo next2 = ci.next.next;     /* next's next */
                if (next2 == null)
                {
                    break;
                }
                luaM_free(L, ci.next);            /* remove next */
                ci.next        = next2;           /* remove 'next' from the list */
                next2.previous = ci;
                ci             = next2;
            }
        }
예제 #8
0
파일: lstate.cs 프로젝트: weimingtom/cclua
        /*
        ** free all CallInfo structures not in use by a thread
        */
        public static void luaE_freeCI(lua_State L)
        {
            CallInfo ci   = L.ci;
            CallInfo next = ci.next;

            ci.next = null;
            while (true)
            {
                ci = next;
                if (ci == null)
                {
                    break;
                }
                next = ci.next;
                luaM_free(L, ci);
            }
        }
예제 #9
0
파일: ldebug.cs 프로젝트: weimingtom/cclua
        public static void luaG_traceexec(lua_State L)
        {
            CallInfo ci        = L.ci;
            byte     mask      = L.hookmask;
            bool     counthook = ((mask & cc.LUA_MASKCOUNT) != 0 && L.hookcount == 0);

            if (counthook)
            {
                resethookcount(L);                                         /* reset count */
            }
            if ((ci.callstatus & CIST_HOOKYIELD) != 0)                     /* called hook last time? */
            {
                ci.callstatus = (byte)(ci.callstatus & (~CIST_HOOKYIELD)); /* erase mark */
                return;                                                    /* do not call hook again (VM yielded, so it did not move) */
            }
            if (counthook)
            {
                luaD_hook(L, cc.LUA_HOOKCOUNT, -1);   /* call count hook */
            }
            if ((mask & cc.LUA_MASKLINE) != 0)
            {
                Proto p       = ci_func(L, ci).p;
                int   npc     = pcRel(ci.u.l.savedpc, p);
                int   newline = getfuncline(p, npc);
                if (npc == 0 ||                                   /* call linehook when enter a new function, */
                    ci.u.l.savedpc <= L.oldpc ||                  /* when jump back (loop), or when */
                    newline != getfuncline(p, pcRel(L.oldpc, p))) /* enter a new line */
                {
                    luaD_hook(L, cc.LUA_HOOKLINE, newline);       /* call line hook */
                }
            }
            L.oldpc = ci.u.l.savedpc;
            if (L.status == cc.LUA_YIELD)    /* did hook yield? */
            {
                if (counthook)
                {
                    L.hookcount = 1;             /* undo decrement to zero */
                }
                ci.u.l.savedpc--;                /* undo increment (resume will increment it again) */
                ci.callstatus |= CIST_HOOKYIELD; /* mark that it yielded */
                ci.func        = L.top - 1;      /* protect stack below results */
                luaD_throw(L, cc.LUA_YIELD);
            }
        }
예제 #10
0
파일: lstate.cs 프로젝트: weimingtom/cclua
        public static void stack_init(lua_State L1, lua_State L)
        {
            L1.stack     = luaM_fullvector <TValue> (L, lstate.BASIC_STACK_SIZE);
            L1.stacksize = lstate.BASIC_STACK_SIZE;
            for (int i = 0; i < lstate.BASIC_STACK_SIZE; i++)
            {
                setnilvalue(L1.stack[i]);   /* erase new stack */
            }
            L1.top        = 0;
            L1.stack_last = L1.stacksize - EXTRA_STACK;
            /* initialize first ci */
            CallInfo ci = L1.base_ci;

            ci.next       = null;
            ci.previous   = null;
            ci.callstatus = 0;
            ci.func       = L1.top;
            setnilvalue(L1.stack[L1.top++]);   /* 'function' entry for this 'ci' */
            ci.top = L1.top + cc.LUA_MINSTACK;
            L1.ci  = ci;
        }
예제 #11
0
파일: lapi.cs 프로젝트: weimingtom/cclua
        public static TValue index2addr(lua_State L, int idx)
        {
            CallInfo ci = L.ci;

            if (idx > 0)
            {
                api_check(idx <= ci.top - (ci.func + 1), "unacceptable index");
                if (ci.func + idx >= L.top)
                {
                    return(lapi.NONVALIDVALUE);
                }
                else
                {
                    return(L.stack[ci.func + idx]);
                }
            }
            else if (ispseudo(idx) == false)     /* negative index */
            {
                api_check(idx != 0 && -idx <= L.top - (ci.func + 1), "invalid index");
                return(L.stack[L.top + idx]);
            }
            else if (idx == cc.LUA_REGISTRYINDEX)
            {
                return(G(L).l_registry);
            }
            else    /* upvalues */
            {
                idx = cc.LUA_REGISTRYINDEX - idx;
                api_check(idx <= MAXUPVAL + 1, "upvalue index too large");
                if (ttislcf(L.stack[ci.func]))   /* light C function? */
                {
                    return(lapi.NONVALIDVALUE);  /* it has no upvalues */
                }
                else
                {
                    CClosure func = clCvalue(L.stack[ci.func]);
                    return((idx <= func.nupvalues) ? func.upvalue[idx - 1] : lapi.NONVALIDVALUE);
                }
            }
        }
예제 #12
0
파일: ldebug.cs 프로젝트: weimingtom/cclua
        public static string findlocal(lua_State L, CallInfo ci, int n, ref int pos)
        {
            string name  = null;
            int    sbase = 0;

            if (isLua(ci))
            {
                if (n < 0)                  /* access to vararg values? */
                {
                    return(findvararg(L, ci, -n, ref pos));
                }
                else
                {
                    sbase = ci.u.l.nbase;
                    name  = luaF_getlocalname(ci_func(L, ci).p, n, currentpc(L, ci));
                }
            }
            else
            {
                sbase = ci.func + 1;
            }
            if (name == null)                /* no 'standard' name? */
            {
                int limit = (ci == L.ci ? L.top : ci.next.func);
                if (limit - sbase >= n && n > 0)                /* is 'n' inside 'ci' stack? */
                {
                    name = "(*temporary)";                      /* generic name for any valid slot */
                }
                else
                {
                    return(null);                     /* no name */
                }
            }
            pos = sbase + (n - 1);
            return(name);
        }
예제 #13
0
파일: ldebug.cs 프로젝트: weimingtom/cclua
        public static int auxgetinfo(lua_State L, string what, int index, lua_Debug ar, Closure f, CallInfo ci)
        {
            int status = 1;

            for (int i = index; i < what.Length; i++)
            {
                switch (what[i])
                {
                case 'S': {
                    funcinfo(ar, f);
                    break;
                }

                case 'l': {
                    ar.currentline = (ci != null && isLua(ci)) ? currentline(L, ci) : -1;
                    break;
                }

                case 'u': {
                    ar.nups = (byte)((f == null) ? 0 : f.c.nupvalues);
                    if (ldebug.noLuaClosure(f))
                    {
                        ar.isvararg = 1;
                        ar.nparams  = 0;
                    }
                    else
                    {
                        ar.isvararg = f.l.p.is_vararg;
                        ar.nparams  = f.l.p.numparams;
                    }
                    break;
                }

                case 't': {
                    ar.istailcall = (byte)((ci != null) ? (ci.callstatus & CIST_TAIL) : 0);
                    break;
                }

                case 'n': {
                    /* calling function is a known Lua function? */
                    if (ci != null && ((ci.callstatus & CIST_TAIL) != 0) && isLua(ci.previous))
                    {
                        ar.namewhat = getfuncname(L, ci.previous, ref ar.name);
                    }
                    else
                    {
                        ar.namewhat = null;
                    }
                    if (ar.namewhat == null)
                    {
                        ar.namewhat = "";      /* not found */
                        ar.name     = null;
                    }
                    break;
                }

                case 'L': goto case 'f';

                case 'f':      /* handled by lua_getinfo */
                    break;

                default: {
                    status = 0;      /* invalid option */
                    break;
                }
                }
            }
            return(status);
        }
예제 #14
0
파일: lstate.cs 프로젝트: weimingtom/cclua
 public lua_State()
 {
     base_ci = imp.luaM_newobject <CallInfo> (null);
 }
예제 #15
0
파일: ldebug.cs 프로젝트: weimingtom/cclua
 public static int currentpc(lua_State L, CallInfo ci)
 {
     lua_assert(isLua(ci));
     return(pcRel(ci.u.l.savedpc, ci_func(L, ci).p));
 }
예제 #16
0
파일: ldebug.cs 프로젝트: weimingtom/cclua
        /* }====================================================== */



        /*
        ** The subtraction of two potentially unrelated pointers is
        ** not ISO C, but it should not crash a program; the subsequent
        ** checks are ISO C and ensure a correct result.
        */
        public static bool isinstatck(CallInfo ci, TValue o)
        {
            // TODO
            return(false);
        }
예제 #17
0
파일: ldebug.cs 프로젝트: weimingtom/cclua
 public static int currentline(lua_State L, CallInfo ci)
 {
     return(getfuncline(ci_func(L, ci).p, currentpc(L, ci)));
 }
예제 #18
0
파일: ldebug.cs 프로젝트: weimingtom/cclua
        public static string getfuncname(lua_State L, CallInfo ci, ref string name)
        {
            TMS   tm = (TMS)0;                      /* to avoid warnings */
            Proto p  = ci_func(L, ci).p;            /* calling function */
            int   pc = currentpc(L, ci);            /* calling instruction index */
            uint  i  = p.code[pc];                  /* calling instruction */

            if ((ci.callstatus & CIST_HOOKED) != 0) /* was it called inside a hook? */
            {
                name = "?";
                return("hook");
            }
            switch (GET_OPCODE(i))
            {
            case OpCode.OP_CALL: goto case OpCode.OP_TAILCALL;

            case OpCode.OP_TAILCALL:      /* get function name */
                return(getobjname(p, pc, GETARG_A(i), ref name));

            case OpCode.OP_TFORCALL: {      /* for iterator */
                name = "for iterator";
                return("for iterator");
            }

            /* all other instructions can call only through metamethods */
            case OpCode.OP_SELF: goto case OpCode.OP_GETTABLE;

            case OpCode.OP_GETTABUP: goto case OpCode.OP_GETTABLE;

            case OpCode.OP_GETTABLE:
                tm = TMS.TM_INDEX;
                break;

            case OpCode.OP_SETTABUP: goto case OpCode.OP_SETTABLE;

            case OpCode.OP_SETTABLE:
                tm = TMS.TM_NEWINDEX;
                break;

            case OpCode.OP_ADD: goto case OpCode.OP_SHR;

            case OpCode.OP_SUB: goto case OpCode.OP_SHR;

            case OpCode.OP_MUL: goto case OpCode.OP_SHR;

            case OpCode.OP_MOD: goto case OpCode.OP_SHR;

            case OpCode.OP_POW: goto case OpCode.OP_SHR;

            case OpCode.OP_DIV: goto case OpCode.OP_SHR;

            case OpCode.OP_IDIV: goto case OpCode.OP_SHR;

            case OpCode.OP_BAND: goto case OpCode.OP_SHR;

            case OpCode.OP_BOR: goto case OpCode.OP_SHR;

            case OpCode.OP_BXOR: goto case OpCode.OP_SHR;

            case OpCode.OP_SHL: goto case OpCode.OP_SHR;

            case OpCode.OP_SHR: {
                int offset = GET_OPCODE(i) - OpCode.OP_ADD; /* ORDER OP */
                tm = TMS.TM_ADD + offset;                   /* ORDER TM */
                break;
            }

            case OpCode.OP_UNM: tm = TMS.TM_UNM; break;

            case OpCode.OP_BNOT: tm = TMS.TM_BNOT; break;

            case OpCode.OP_LEN: tm = TMS.TM_LEN; break;

            case OpCode.OP_CONCAT: tm = TMS.TM_CONCAT; break;

            case OpCode.OP_EQ: tm = TMS.TM_EQ; break;

            case OpCode.OP_LT: tm = TMS.TM_LT; break;

            case OpCode.OP_LE: tm = TMS.TM_LE; break;

            default: lua_assert(false); break;       /* other instructions cannot call a function */
            }
            name = getsstr(G(L).tmname[(int)tm]);
            return("metamethod");
        }
예제 #19
0
파일: ldebug.cs 프로젝트: weimingtom/cclua
 /* Active Lua function (given call info) */
 public static LClosure ci_func(lua_State L, CallInfo ci)
 {
     return(clLvalue(L, ci.func));
 }
예제 #20
0
파일: lstate.cs 프로젝트: weimingtom/cclua
        public const int CIST_HOOKYIELD = 1 << 6;    /* last hook called yielded */

        public static bool isLua(CallInfo ci)
        {
            return((ci.callstatus & CIST_LUA) != 0);
        }