ldebug.c
上传用户:jxpjxmjjw
上传日期:2009-12-07
资源大小:5877k
文件大小:14k
源码类别:

模拟服务器

开发平台:

Visual C++

  1. /*
  2. ** $Id: ldebug.c,v 1.1 2004/08/20 02:26:56 JH Exp $
  3. ** Debug Interface
  4. ** See Copyright Notice in lua.h
  5. */
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #define ldebug_c
  9. #include "lua.h"
  10. #include "lapi.h"
  11. #include "lcode.h"
  12. #include "ldebug.h"
  13. #include "ldo.h"
  14. #include "lfunc.h"
  15. #include "lobject.h"
  16. #include "lopcodes.h"
  17. #include "lstate.h"
  18. #include "lstring.h"
  19. #include "ltable.h"
  20. #include "ltm.h"
  21. #include "lvm.h"
  22. static const char *getfuncname (CallInfo *ci, const char **name);
  23. #define isLua(ci) (!((ci)->state & CI_C))
  24. static int currentpc (CallInfo *ci) {
  25.   if (!isLua(ci)) return -1;  /* function is not a Lua function? */
  26.   if (ci->state & CI_HASFRAME)  /* function has a frame? */
  27.     ci->u.l.savedpc = *ci->u.l.pc;  /* use `pc' from there */
  28.   /* function's pc is saved */
  29.   return pcRel(ci->u.l.savedpc, ci_func(ci)->l.p);
  30. }
  31. static int currentline (CallInfo *ci) {
  32.   int pc = currentpc(ci);
  33.   if (pc < 0)
  34.     return -1;  /* only active lua functions have current-line information */
  35.   else
  36.     return getline(ci_func(ci)->l.p, pc);
  37. }
  38. void luaG_inithooks (lua_State *L) {
  39.   CallInfo *ci;
  40.   for (ci = L->ci; ci != L->base_ci; ci--)  /* update all `savedpc's */
  41.     currentpc(ci);
  42.   L->hookinit = 1;
  43. }
  44. /*
  45. ** this function can be called asynchronous (e.g. during a signal)
  46. */
  47. LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
  48.   if (func == NULL || mask == 0) {  /* turn off hooks? */
  49.     mask = 0;
  50.     func = NULL;
  51.   }
  52.   L->hook = func;
  53.   L->basehookcount = count;
  54.   resethookcount(L);
  55.   L->hookmask = cast(lu_byte, mask);
  56.   L->hookinit = 0;
  57.   return 1;
  58. }
  59. LUA_API lua_Hook lua_gethook (lua_State *L) {
  60.   return L->hook;
  61. }
  62. LUA_API int lua_gethookmask (lua_State *L) {
  63.   return L->hookmask;
  64. }
  65. LUA_API int lua_gethookcount (lua_State *L) {
  66.   return L->basehookcount;
  67. }
  68. LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
  69.   int status;
  70.   CallInfo *ci;
  71.   lua_lock(L);
  72.   for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) {
  73.     level--;
  74.     if (!(ci->state & CI_C))  /* Lua function? */
  75.       level -= ci->u.l.tailcalls;  /* skip lost tail calls */
  76.   }
  77.   if (level > 0 || ci == L->base_ci) status = 0;  /* there is no such level */
  78.   else if (level < 0) {  /* level is of a lost tail call */
  79.     status = 1;
  80.     ar->i_ci = 0;
  81.   }
  82.   else {
  83.     status = 1;
  84.     ar->i_ci = ci - L->base_ci;
  85.   }
  86.   lua_unlock(L);
  87.   return status;
  88. }
  89. static Proto *getluaproto (CallInfo *ci) {
  90.   return (isLua(ci) ? ci_func(ci)->l.p : NULL);
  91. }
  92. LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
  93.   const char *name;
  94.   CallInfo *ci;
  95.   Proto *fp;
  96.   lua_lock(L);
  97.   name = NULL;
  98.   ci = L->base_ci + ar->i_ci;
  99.   fp = getluaproto(ci);
  100.   if (fp) {  /* is a Lua function? */
  101.     name = luaF_getlocalname(fp, n, currentpc(ci));
  102.     if (name)
  103.       luaA_pushobject(L, ci->base+(n-1));  /* push value */
  104.   }
  105.   lua_unlock(L);
  106.   return name;
  107. }
  108. LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
  109.   const char *name;
  110.   CallInfo *ci;
  111.   Proto *fp;
  112.   lua_lock(L);
  113.   name = NULL;
  114.   ci = L->base_ci + ar->i_ci;
  115.   fp = getluaproto(ci);
  116.   L->top--;  /* pop new value */
  117.   if (fp) {  /* is a Lua function? */
  118.     name = luaF_getlocalname(fp, n, currentpc(ci));
  119.     if (!name || name[0] == '(')  /* `(' starts private locals */
  120.       name = NULL;
  121.     else
  122.       setobjs2s(ci->base+(n-1), L->top);
  123.   }
  124.   lua_unlock(L);
  125.   return name;
  126. }
  127. static void funcinfo (lua_Debug *ar, StkId func) {
  128.   Closure *cl = clvalue(func);
  129.   if (cl->c.isC) {
  130.     ar->source = "=[C]";
  131.     ar->linedefined = -1;
  132.     ar->what = "C";
  133.   }
  134.   else {
  135.     ar->source = getstr(cl->l.p->source);
  136.     ar->linedefined = cl->l.p->lineDefined;
  137.     ar->what = (ar->linedefined == 0) ? "main" : "Lua";
  138.   }
  139.   luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
  140. }
  141. static const char *travglobals (lua_State *L, const TObject *o) {
  142.   Table *g = hvalue(gt(L));
  143.   int i = sizenode(g);
  144.   while (i--) {
  145.     Node *n = gnode(g, i);
  146.     if (luaO_rawequalObj(o, gval(n)) && ttisstring(gkey(n)))
  147.       return getstr(tsvalue(gkey(n)));
  148.   }
  149.   return NULL;
  150. }
  151. static void info_tailcall (lua_State *L, lua_Debug *ar) {
  152.   ar->name = ar->namewhat = "";
  153.   ar->what = "tail";
  154.   ar->linedefined = ar->currentline = -1;
  155.   ar->source = "=(tail call)";
  156.   luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
  157.   ar->nups = 0;
  158.   setnilvalue(L->top);
  159. }
  160. static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
  161.                     StkId f, CallInfo *ci) {
  162.   int status = 1;
  163.   for (; *what; what++) {
  164.     switch (*what) {
  165.       case 'S': {
  166.         funcinfo(ar, f);
  167.         break;
  168.       }
  169.       case 'l': {
  170.         ar->currentline = (ci) ? currentline(ci) : -1;
  171.         break;
  172.       }
  173.       case 'u': {
  174.         ar->nups = clvalue(f)->c.nupvalues;
  175.         break;
  176.       }
  177.       case 'n': {
  178.         ar->namewhat = (ci) ? getfuncname(ci, &ar->name) : NULL;
  179.         if (ar->namewhat == NULL) {
  180.           /* try to find a global name */
  181.           if ((ar->name = travglobals(L, f)) != NULL)
  182.             ar->namewhat = "global";
  183.           else ar->namewhat = "";  /* not found */
  184.         }
  185.         break;
  186.       }
  187.       case 'f': {
  188.         setobj2s(L->top, f);
  189.         break;
  190.       }
  191.       default: status = 0;  /* invalid option */
  192.     }
  193.   }
  194.   return status;
  195. }
  196. LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
  197.   int status = 1;
  198.   lua_lock(L);
  199.   if (*what == '>') {
  200.     StkId f = L->top - 1;
  201.     if (!ttisfunction(f))
  202.       luaG_runerror(L, "value for `lua_getinfo' is not a function");
  203.     status = auxgetinfo(L, what + 1, ar, f, NULL);
  204.     L->top--;  /* pop function */
  205.   }
  206.   else if (ar->i_ci != 0) {  /* no tail call? */
  207.     CallInfo *ci = L->base_ci + ar->i_ci;
  208.     lua_assert(ttisfunction(ci->base - 1));
  209.     status = auxgetinfo(L, what, ar, ci->base - 1, ci);
  210.   }
  211.   else
  212.     info_tailcall(L, ar);
  213.   if (strchr(what, 'f')) incr_top(L);
  214.   lua_unlock(L);
  215.   return status;
  216. }
  217. /*
  218. ** {======================================================
  219. ** Symbolic Execution and code checker
  220. ** =======================================================
  221. */
  222. #define check(x) if (!(x)) return 0;
  223. #define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode)
  224. #define checkreg(pt,reg) check((reg) < (pt)->maxstacksize)
  225. static int precheck (const Proto *pt) {
  226.   check(pt->maxstacksize <= MAXSTACK);
  227.   check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0);
  228.   lua_assert(pt->numparams+pt->is_vararg <= pt->maxstacksize);
  229.   check(GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN);
  230.   return 1;
  231. }
  232. static int checkopenop (const Proto *pt, int pc) {
  233.   Instruction i = pt->code[pc+1];
  234.   switch (GET_OPCODE(i)) {
  235.     case OP_CALL:
  236.     case OP_TAILCALL:
  237.     case OP_RETURN: {
  238.       check(GETARG_B(i) == 0);
  239.       return 1;
  240.     }
  241.     case OP_SETLISTO: return 1;
  242.     default: return 0;  /* invalid instruction after an open call */
  243.   }
  244. }
  245. static int checkRK (const Proto *pt, int r) {
  246.   return (r < pt->maxstacksize || (r >= MAXSTACK && r-MAXSTACK < pt->sizek));
  247. }
  248. static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
  249.   int pc;
  250.   int last;  /* stores position of last instruction that changed `reg' */
  251.   last = pt->sizecode-1;  /* points to final return (a `neutral' instruction) */
  252.   check(precheck(pt));
  253.   for (pc = 0; pc < lastpc; pc++) {
  254.     const Instruction i = pt->code[pc];
  255.     OpCode op = GET_OPCODE(i);
  256.     int a = GETARG_A(i);
  257.     int b = 0;
  258.     int c = 0;
  259.     checkreg(pt, a);
  260.     switch (getOpMode(op)) {
  261.       case iABC: {
  262.         b = GETARG_B(i);
  263.         c = GETARG_C(i);
  264.         if (testOpMode(op, OpModeBreg)) {
  265.           checkreg(pt, b);
  266.         }
  267.         else if (testOpMode(op, OpModeBrk))
  268.           check(checkRK(pt, b));
  269.         if (testOpMode(op, OpModeCrk))
  270.           check(checkRK(pt, c));
  271.         break;
  272.       }
  273.       case iABx: {
  274.         b = GETARG_Bx(i);
  275.         if (testOpMode(op, OpModeK)) check(b < pt->sizek);
  276.         break;
  277.       }
  278.       case iAsBx: {
  279.         b = GETARG_sBx(i);
  280.         break;
  281.       }
  282.     }
  283.     if (testOpMode(op, OpModesetA)) {
  284.       if (a == reg) last = pc;  /* change register `a' */
  285.     }
  286.     if (testOpMode(op, OpModeT)) {
  287.       check(pc+2 < pt->sizecode);  /* check skip */
  288.       check(GET_OPCODE(pt->code[pc+1]) == OP_JMP);
  289.     }
  290.     switch (op) {
  291.       case OP_LOADBOOL: {
  292.         check(c == 0 || pc+2 < pt->sizecode);  /* check its jump */
  293.         break;
  294.       }
  295.       case OP_LOADNIL: {
  296.         if (a <= reg && reg <= b)
  297.           last = pc;  /* set registers from `a' to `b' */
  298.         break;
  299.       }
  300.       case OP_GETUPVAL:
  301.       case OP_SETUPVAL: {
  302.         check(b < pt->nups);
  303.         break;
  304.       }
  305.       case OP_GETGLOBAL:
  306.       case OP_SETGLOBAL: {
  307.         check(ttisstring(&pt->k[b]));
  308.         break;
  309.       }
  310.       case OP_SELF: {
  311.         checkreg(pt, a+1);
  312.         if (reg == a+1) last = pc;
  313.         break;
  314.       }
  315.       case OP_CONCAT: {
  316.         /* `c' is a register, and at least two operands */
  317.         check(c < MAXSTACK && b < c);
  318.         break;
  319.       }
  320.       case OP_TFORLOOP:
  321.         checkreg(pt, a+c+5);
  322.         if (reg >= a) last = pc;  /* affect all registers above base */
  323.         /* go through */
  324.       case OP_FORLOOP:
  325.         checkreg(pt, a+2);
  326.         /* go through */
  327.       case OP_JMP: {
  328.         int dest = pc+1+b;
  329. check(0 <= dest && dest < pt->sizecode);
  330.         /* not full check and jump is forward and do not skip `lastpc'? */
  331.         if (reg != NO_REG && pc < dest && dest <= lastpc)
  332.           pc += b;  /* do the jump */
  333.         break;
  334.       }
  335.       case OP_CALL:
  336.       case OP_TAILCALL: {
  337.         if (b != 0) {
  338.           checkreg(pt, a+b-1);
  339.         }
  340.         c--;  /* c = num. returns */
  341.         if (c == LUA_MULTRET) {
  342.           check(checkopenop(pt, pc));
  343.         }
  344.         else if (c != 0)
  345.           checkreg(pt, a+c-1);
  346.         if (reg >= a) last = pc;  /* affect all registers above base */
  347.         break;
  348.       }
  349.       case OP_RETURN: {
  350.         b--;  /* b = num. returns */
  351.         if (b > 0) checkreg(pt, a+b-1);
  352.         break;
  353.       }
  354.       case OP_SETLIST: {
  355.         checkreg(pt, a + (b&(LFIELDS_PER_FLUSH-1)) + 1);
  356.         break;
  357.       }
  358.       case OP_CLOSURE: {
  359.         int nup;
  360.         check(b < pt->sizep);
  361.         nup = pt->p[b]->nups;
  362.         check(pc + nup < pt->sizecode);
  363.         for (; nup>0; nup--) {
  364.           OpCode op1 = GET_OPCODE(pt->code[pc+nup]);
  365.           check(op1 == OP_GETUPVAL || op1 == OP_MOVE);
  366.         }
  367.         break;
  368.       }
  369.       default: break;
  370.     }
  371.   }
  372.   return pt->code[last];
  373. }
  374. #undef check
  375. #undef checkjump
  376. #undef checkreg
  377. /* }====================================================== */
  378. int luaG_checkcode (const Proto *pt) {
  379.   return luaG_symbexec(pt, pt->sizecode, NO_REG);
  380. }
  381. static const char *kname (Proto *p, int c) {
  382.   c = c - MAXSTACK;
  383.   if (c >= 0 && ttisstring(&p->k[c]))
  384.     return svalue(&p->k[c]);
  385.   else
  386.     return "?";
  387. }
  388. static const char *getobjname (CallInfo *ci, int stackpos, const char **name) {
  389.   if (isLua(ci)) {  /* a Lua function? */
  390.     Proto *p = ci_func(ci)->l.p;
  391.     int pc = currentpc(ci);
  392.     Instruction i;
  393.     *name = luaF_getlocalname(p, stackpos+1, pc);
  394.     if (*name)  /* is a local? */
  395.       return "local";
  396.     i = luaG_symbexec(p, pc, stackpos);  /* try symbolic execution */
  397.     lua_assert(pc != -1);
  398.     switch (GET_OPCODE(i)) {
  399.       case OP_GETGLOBAL: {
  400.         int g = GETARG_Bx(i);  /* global index */
  401.         lua_assert(ttisstring(&p->k[g]));
  402.         *name = svalue(&p->k[g]);
  403.         return "global";
  404.       }
  405.       case OP_MOVE: {
  406.         int a = GETARG_A(i);
  407.         int b = GETARG_B(i);  /* move from `b' to `a' */
  408.         if (b < a)
  409.           return getobjname(ci, b, name);  /* get name for `b' */
  410.         break;
  411.       }
  412.       case OP_GETTABLE: {
  413.         int k = GETARG_C(i);  /* key index */
  414.         *name = kname(p, k);
  415.         return "field";
  416.       }
  417.       case OP_SELF: {
  418.         int k = GETARG_C(i);  /* key index */
  419.         *name = kname(p, k);
  420.         return "method";
  421.       }
  422.       default: break;
  423.     }
  424.   }
  425.   return NULL;  /* no useful name found */
  426. }
  427. static const char *getfuncname (CallInfo *ci, const char **name) {
  428.   Instruction i;
  429.   if ((isLua(ci) && ci->u.l.tailcalls > 0) || !isLua(ci - 1))
  430.     return NULL;  /* calling function is not Lua (or is unknown) */
  431.   ci--;  /* calling function */
  432.   i = ci_func(ci)->l.p->code[currentpc(ci)];
  433.   if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL)
  434.     return getobjname(ci, GETARG_A(i), name);
  435.   else
  436.     return NULL;  /* no useful name can be found */
  437. }
  438. /* only ANSI way to check whether a pointer points to an array */
  439. static int isinstack (CallInfo *ci, const TObject *o) {
  440.   StkId p;
  441.   for (p = ci->base; p < ci->top; p++)
  442.     if (o == p) return 1;
  443.   return 0;
  444. }
  445. void luaG_typeerror (lua_State *L, const TObject *o, const char *op) {
  446.   const char *name = NULL;
  447.   const char *t = luaT_typenames[ttype(o)];
  448.   const char *kind = (isinstack(L->ci, o)) ?
  449.                          getobjname(L->ci, o - L->base, &name) : NULL;
  450.   if (kind)
  451.     luaG_runerror(L, "attempt to %s %s `%s' (a %s value)",
  452.                 op, kind, name, t);
  453.   else
  454.     luaG_runerror(L, "attempt to %s a %s value", op, t);
  455. }
  456. void luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
  457.   if (ttisstring(p1)) p1 = p2;
  458.   lua_assert(!ttisstring(p1));
  459.   luaG_typeerror(L, p1, "concatenate");
  460. }
  461. void luaG_aritherror (lua_State *L, const TObject *p1, const TObject *p2) {
  462.   TObject temp;
  463.   if (luaV_tonumber(p1, &temp) == NULL)
  464.     p2 = p1;  /* first operand is wrong */
  465.   luaG_typeerror(L, p2, "perform arithmetic on");
  466. }
  467. int luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2) {
  468.   const char *t1 = luaT_typenames[ttype(p1)];
  469.   const char *t2 = luaT_typenames[ttype(p2)];
  470.   if (t1[2] == t2[2])
  471.     luaG_runerror(L, "attempt to compare two %s values", t1);
  472.   else
  473.     luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
  474.   return 0;
  475. }
  476. static void addinfo (lua_State *L, const char *msg) {
  477.   CallInfo *ci = L->ci;
  478.   if (isLua(ci)) {  /* is Lua code? */
  479.     char buff[LUA_IDSIZE];  /* add file:line information */
  480.     int line = currentline(ci);
  481.     luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE);
  482.     luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
  483.   }
  484. }
  485. void luaG_errormsg (lua_State *L) {
  486.   if (L->errfunc != 0) {  /* is there an error handling function? */
  487.     StkId errfunc = restorestack(L, L->errfunc);
  488.     if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
  489.     setobjs2s(L->top, L->top - 1);  /* move argument */
  490.     setobjs2s(L->top - 1, errfunc);  /* push function */
  491.     incr_top(L);
  492.     luaD_call(L, L->top - 2, 1);  /* call it */
  493.   }
  494.   luaD_throw(L, LUA_ERRRUN);
  495. }
  496. void luaG_runerror (lua_State *L, const char *fmt, ...) {
  497.   va_list argp;
  498.   va_start(argp, fmt);
  499.   addinfo(L, luaO_pushvfstring(L, fmt, argp));
  500.   va_end(argp);
  501.   luaG_errormsg(L);
  502. }