ltests.c
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:13k
源码类别:

模拟服务器

开发平台:

C/C++

  1. /*
  2. ** $Id: ltests.c,v 1.54 2000/10/31 13:10:24 roberto Exp $
  3. ** Internal Module for Debugging of the Lua Implementation
  4. ** See Copyright Notice in lua.h
  5. */
  6. #include <ctype.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include "lua.h"
  11. #include "lapi.h"
  12. #include "lauxlib.h"
  13. #include "lcode.h"
  14. #include "ldebug.h"
  15. #include "ldo.h"
  16. #include "lfunc.h"
  17. #include "lmem.h"
  18. #include "lopcodes.h"
  19. #include "lstate.h"
  20. #include "lstring.h"
  21. #include "ltable.h"
  22. #include "luadebug.h"
  23. #include "lualib.h"
  24. void luaB_opentests (lua_State *L);
  25. /*
  26. ** The whole module only makes sense with LUA_DEBUG on
  27. */
  28. #ifdef LUA_DEBUG
  29. static void setnameval (lua_State *L, const char *name, int val) {
  30.   lua_pushstring(L, name);
  31.   lua_pushnumber(L, val);
  32.   lua_settable(L, -3);
  33. }
  34. /*
  35. ** {======================================================
  36. ** Disassembler
  37. ** =======================================================
  38. */
  39. static const char *const instrname[NUM_OPCODES] = {
  40.   "END", "RETURN", "CALL", "TAILCALL", "PUSHNIL", "POP", "PUSHINT", 
  41.   "PUSHSTRING", "PUSHNUM", "PUSHNEGNUM", "PUSHUPVALUE", "GETLOCAL", 
  42.   "GETGLOBAL", "GETTABLE", "GETDOTTED", "GETINDEXED", "PUSHSELF", 
  43.   "CREATETABLE", "SETLOCAL", "SETGLOBAL", "SETTABLE", "SETLIST", "SETMAP", 
  44.   "ADD", "ADDI", "SUB", "MULT", "DIV", "POW", "CONCAT", "MINUS", "NOT", 
  45.   "JMPNE", "JMPEQ", "JMPLT", "JMPLE", "JMPGT", "JMPGE", "JMPT", "JMPF", 
  46.   "JMPONT", "JMPONF", "JMP", "PUSHNILJMP", "FORPREP", "FORLOOP", "LFORPREP", 
  47.   "LFORLOOP", "CLOSURE"
  48. };
  49. static int pushop (lua_State *L, Proto *p, int pc) {
  50.   char buff[100];
  51.   Instruction i = p->code[pc];
  52.   OpCode o = GET_OPCODE(i);
  53.   const char *name = instrname[o];
  54.   sprintf(buff, "%5d - ", luaG_getline(p->lineinfo, pc, 1, NULL));
  55.   switch ((enum Mode)luaK_opproperties[o].mode) {  
  56.     case iO:
  57.       sprintf(buff+8, "%-12s", name);
  58.       break;
  59.     case iU:
  60.       sprintf(buff+8, "%-12s%4u", name, GETARG_U(i));
  61.       break;
  62.     case iS:
  63.       sprintf(buff+8, "%-12s%4d", name, GETARG_S(i));
  64.       break;
  65.     case iAB:
  66.       sprintf(buff+8, "%-12s%4d %4d", name, GETARG_A(i), GETARG_B(i));
  67.       break;
  68.   }
  69.   lua_pushstring(L, buff);
  70.   return (o != OP_END);
  71. }
  72. static int listcode (lua_State *L) {
  73.   int pc;
  74.   Proto *p;
  75.   int res;
  76.   luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
  77.                  1, "Lua function expected");
  78.   p = clvalue(luaA_index(L, 1))->f.l;
  79.   lua_newtable(L);
  80.   setnameval(L, "maxstack", p->maxstacksize);
  81.   setnameval(L, "numparams", p->numparams);
  82.   pc = 0;
  83.   do {
  84.     lua_pushnumber(L, pc+1);
  85.     res = pushop(L, p, pc++);
  86.     lua_settable(L, -3);
  87.   } while (res);
  88.   return 1;
  89. }
  90. static int liststrings (lua_State *L) {
  91.   Proto *p;
  92.   int i;
  93.   luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
  94.                  1, "Lua function expected");
  95.   p = clvalue(luaA_index(L, 1))->f.l;
  96.   lua_newtable(L);
  97.   for (i=0; i<p->nkstr; i++) {
  98.     lua_pushnumber(L, i+1);
  99.     lua_pushstring(L, p->kstr[i]->str);
  100.     lua_settable(L, -3);
  101.   }
  102.   return 1;
  103. }
  104. static int listlocals (lua_State *L) {
  105.   Proto *p;
  106.   int pc = luaL_check_int(L, 2) - 1;
  107.   int i = 0;
  108.   const char *name;
  109.   luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
  110.                  1, "Lua function expected");
  111.   p = clvalue(luaA_index(L, 1))->f.l;
  112.   while ((name = luaF_getlocalname(p, ++i, pc)) != NULL)
  113.     lua_pushstring(L, name);
  114.   return i-1;
  115. }
  116. /* }====================================================== */
  117. static int get_limits (lua_State *L) {
  118.   lua_newtable(L);
  119.   setnameval(L, "BITS_INT", BITS_INT);
  120.   setnameval(L, "LFPF", LFIELDS_PER_FLUSH);
  121.   setnameval(L, "MAXARG_A", MAXARG_A);
  122.   setnameval(L, "MAXARG_B", MAXARG_B);
  123.   setnameval(L, "MAXARG_S", MAXARG_S);
  124.   setnameval(L, "MAXARG_U", MAXARG_U);
  125.   setnameval(L, "MAXLOCALS", MAXLOCALS);
  126.   setnameval(L, "MAXPARAMS", MAXPARAMS);
  127.   setnameval(L, "MAXSTACK", MAXSTACK);
  128.   setnameval(L, "MAXUPVALUES", MAXUPVALUES);
  129.   setnameval(L, "MAXVARSLH", MAXVARSLH);
  130.   setnameval(L, "RFPF", RFIELDS_PER_FLUSH);
  131.   setnameval(L, "SIZE_A", SIZE_A);
  132.   setnameval(L, "SIZE_B", SIZE_B);
  133.   setnameval(L, "SIZE_OP", SIZE_OP);
  134.   setnameval(L, "SIZE_U", SIZE_U);
  135.   return 1;
  136. }
  137. static int mem_query (lua_State *L) {
  138.   if (lua_isnull(L, 1)) {
  139.     lua_pushnumber(L, memdebug_total);
  140.     lua_pushnumber(L, memdebug_numblocks);
  141.     lua_pushnumber(L, memdebug_maxmem);
  142.     return 3;
  143.   }
  144.   else {
  145.     memdebug_memlimit = luaL_check_int(L, 1);
  146.     return 0;
  147.   }
  148. }
  149. static int hash_query (lua_State *L) {
  150.   if (lua_isnull(L, 2)) {
  151.     luaL_arg_check(L, lua_tag(L, 1) == LUA_TSTRING, 1, "string expected");
  152.     lua_pushnumber(L, tsvalue(luaA_index(L, 1))->u.s.hash);
  153.   }
  154.   else {
  155.     Hash *t;
  156.     luaL_checktype(L, 2, LUA_TTABLE);
  157.     t = hvalue(luaA_index(L, 2));
  158.     lua_pushnumber(L, luaH_mainposition(t, luaA_index(L, 1)) - t->node);
  159.   }
  160.   return 1;
  161. }
  162. static int table_query (lua_State *L) {
  163.   const Hash *t;
  164.   int i = luaL_opt_int(L, 2, -1);
  165.   luaL_checktype(L, 1, LUA_TTABLE);
  166.   t = hvalue(luaA_index(L, 1));
  167.   if (i == -1) {
  168.     lua_pushnumber(L, t->size);
  169.     lua_pushnumber(L, t->firstfree - t->node);
  170.     return 2;
  171.   }
  172.   else if (i < t->size) {
  173.     luaA_pushobject(L, &t->node[i].key);
  174.     luaA_pushobject(L, &t->node[i].val);
  175.     if (t->node[i].next) {
  176.       lua_pushnumber(L, t->node[i].next - t->node);
  177.       return 3;
  178.     }
  179.     else
  180.       return 2;
  181.   }
  182.   return 0;
  183. }
  184. static int string_query (lua_State *L) {
  185.   stringtable *tb = (*luaL_check_string(L, 1) == 's') ? &L->strt : &L->udt;
  186.   int s = luaL_opt_int(L, 2, 0) - 1;
  187.   if (s==-1) {
  188.     lua_pushnumber(L ,tb->nuse);
  189.     lua_pushnumber(L ,tb->size);
  190.     return 2;
  191.   }
  192.   else if (s < tb->size) {
  193.     TString *ts;
  194.     int n = 0;
  195.     for (ts = tb->hash[s]; ts; ts = ts->nexthash) {
  196.       ttype(L->top) = LUA_TSTRING;
  197.       tsvalue(L->top) = ts;
  198.       incr_top;
  199.       n++;
  200.     }
  201.     return n;
  202.   }
  203.   return 0;
  204. }
  205. static int tref (lua_State *L) {
  206.   luaL_checkany(L, 1);
  207.   lua_pushvalue(L, 1);
  208.   lua_pushnumber(L, lua_ref(L, luaL_opt_int(L, 2, 1)));
  209.   return 1;
  210. }
  211. static int getref (lua_State *L) {
  212.   if (lua_getref(L, luaL_check_int(L, 1)))
  213.     return 1;
  214.   else
  215.     return 0;
  216. }
  217. static int unref (lua_State *L) {
  218.   lua_unref(L, luaL_check_int(L, 1));
  219.   return 0;
  220. }
  221. static int newuserdata (lua_State *L) {
  222.   if (lua_isnumber(L, 2))
  223.     lua_pushusertag(L, (void *)luaL_check_int(L, 1), luaL_check_int(L, 2));
  224.   else
  225.     lua_newuserdata(L, luaL_check_int(L, 1));
  226.   return 1;
  227. }
  228. static int udataval (lua_State *L) {
  229.   luaL_checktype(L, 1, LUA_TUSERDATA);
  230.   lua_pushnumber(L, (int)lua_touserdata(L, 1));
  231.   return 1;
  232. }
  233. static int newstate (lua_State *L) {
  234.   lua_State *L1 = lua_open(luaL_check_int(L, 1));
  235.   if (L1)
  236.     lua_pushuserdata(L, L1);
  237.   else
  238.     lua_pushnil(L);
  239.   return 1;
  240. }
  241. static int loadlib (lua_State *L) {
  242.   lua_State *L1 = (lua_State *)lua_touserdata(L, 1);
  243.   switch (*luaL_check_string(L, 2)) {
  244.     case 'm': lua_mathlibopen(L1); break;
  245.     case 's': lua_strlibopen(L1); break;
  246.     case 'i': lua_iolibopen(L1); break;
  247.     case 'd': lua_dblibopen(L1); break;
  248.     case 'b': lua_baselibopen(L1); break;
  249.     default: luaL_argerror(L, 2, "invalid option");
  250.   }
  251.   return 0;
  252. }
  253. static int closestate (lua_State *L) {
  254.   luaL_checktype(L, 1, LUA_TUSERDATA);
  255.   lua_close((lua_State *)lua_touserdata(L, 1));
  256.   return 0;
  257. }
  258. static int doremote (lua_State *L) {
  259.   lua_State *L1;
  260.   const char *code = luaL_check_string(L, 2);
  261.   int status;
  262.   luaL_checktype(L, 1, LUA_TUSERDATA);
  263.   L1 = (lua_State *)lua_touserdata(L, 1);
  264.   status = lua_dostring(L1, code);
  265.   if (status != 0) {
  266.     lua_pushnil(L);
  267.     lua_pushnumber(L, status);
  268.     return 2;
  269.   }
  270.   else {
  271.     int i = 0;
  272.     while (!lua_isnull(L1, ++i))
  273.       lua_pushstring(L, lua_tostring(L1, i));
  274.     return i-1;
  275.   }
  276. }
  277. static int settagmethod (lua_State *L) {
  278.   int tag = luaL_check_int(L, 1);
  279.   const char *event = luaL_check_string(L, 2);
  280.   luaL_checkany(L, 3);
  281.   lua_gettagmethod(L, tag, event);
  282.   lua_pushvalue(L, 3);
  283.   lua_settagmethod(L, tag, event);
  284.   return 1;
  285. }
  286. static int pushbool (lua_State *L, int b) {
  287.   if (b) lua_pushnumber(L, 1);
  288.   else lua_pushnil(L);
  289.   return 1;
  290. }
  291. static int equal (lua_State *L) {
  292.   return pushbool(L, lua_equal(L, 1, 2));
  293. }
  294.   
  295. /*
  296. ** {======================================================
  297. ** function to test the API with C. It interprets a kind of "assembler"
  298. ** language with calls to the API, so the test can be driven by Lua code
  299. ** =======================================================
  300. */
  301. static const char *const delimits = " tn,;";
  302. static void skip (const char **pc) {
  303.   while (**pc != '' && strchr(delimits, **pc)) (*pc)++;
  304. }
  305. static int getnum (lua_State *L, const char **pc) {
  306.   int res = 0;
  307.   int sig = 1;
  308.   skip(pc);
  309.   if (**pc == '.') {
  310.     res = (int)lua_tonumber(L, -1);
  311.     lua_pop(L, 1);
  312.     (*pc)++;
  313.     return res;
  314.   }
  315.   else if (**pc == '-') {
  316.     sig = -1;
  317.     (*pc)++;
  318.   }
  319.   while (isdigit(**pc)) res = res*10 + (*(*pc)++) - '0';
  320.   return sig*res;
  321. }
  322.   
  323. static const char *getname (char *buff, const char **pc) {
  324.   int i = 0;
  325.   skip(pc);
  326.   while (**pc != '' && !strchr(delimits, **pc))
  327.     buff[i++] = *(*pc)++;
  328.   buff[i] = '';
  329.   return buff;
  330. }
  331. #define EQ(s1) (strcmp(s1, inst) == 0)
  332. #define getnum ((getnum)(L, &pc))
  333. #define getname ((getname)(buff, &pc))
  334. static int testC (lua_State *L) {
  335.   char buff[30];
  336.   const char *pc = luaL_check_string(L, 1);
  337.   for (;;) {
  338.     const char *inst = getname;
  339.     if EQ("") return 0;
  340.     else if EQ("isnumber") {
  341.       lua_pushnumber(L, lua_isnumber(L, getnum));
  342.     }
  343.     else if EQ("isstring") {
  344.       lua_pushnumber(L, lua_isstring(L, getnum));
  345.     }
  346.     else if EQ("istable") {
  347.       lua_pushnumber(L, lua_istable(L, getnum));
  348.     }
  349.     else if EQ("iscfunction") {
  350.       lua_pushnumber(L, lua_iscfunction(L, getnum));
  351.     }
  352.     else if EQ("isfunction") {
  353.       lua_pushnumber(L, lua_isfunction(L, getnum));
  354.     }
  355.     else if EQ("isuserdata") {
  356.       lua_pushnumber(L, lua_isuserdata(L, getnum));
  357.     }
  358.     else if EQ("isnil") {
  359.       lua_pushnumber(L, lua_isnil(L, getnum));
  360.     }
  361.     else if EQ("isnull") {
  362.       lua_pushnumber(L, lua_isnull(L, getnum));
  363.     }
  364.     else if EQ("tonumber") {
  365.       lua_pushnumber(L, lua_tonumber(L, getnum));
  366.     }
  367.     else if EQ("tostring") {
  368.       lua_pushstring(L, lua_tostring(L, getnum));
  369.     }
  370.     else if EQ("tonumber") {
  371.       lua_pushnumber(L, lua_tonumber(L, getnum));
  372.     }
  373.     else if EQ("strlen") {
  374.       lua_pushnumber(L, lua_strlen(L, getnum));
  375.     }
  376.     else if EQ("tocfunction") {
  377.       lua_pushcfunction(L, lua_tocfunction(L, getnum));
  378.     }
  379.     else if EQ("return") {
  380.       return getnum;
  381.     }
  382.     else if EQ("gettop") {
  383.       lua_pushnumber(L, lua_gettop(L));
  384.     }
  385.     else if EQ("settop") {
  386.       lua_settop(L, getnum);
  387.     }
  388.     else if EQ("pop") {
  389.       lua_pop(L, getnum);
  390.     }
  391.     else if EQ("pushnum") {
  392.       lua_pushnumber(L, getnum);
  393.     }
  394.     else if EQ("pushvalue") {
  395.       lua_pushvalue(L, getnum);
  396.     }
  397.     else if EQ("remove") {
  398.       lua_remove(L, getnum);
  399.     }
  400.     else if EQ("insert") {
  401.       lua_insert(L, getnum);
  402.     }
  403.     else if EQ("gettable") {
  404.       lua_gettable(L, getnum);
  405.     }
  406.     else if EQ("settable") {
  407.       lua_settable(L, getnum);
  408.     }
  409.     else if EQ("next") {
  410.       lua_next(L, -2);
  411.     }
  412.     else if EQ("concat") {
  413.       lua_concat(L, getnum);
  414.     }
  415.     else if EQ("rawcall") {
  416.       int narg = getnum;
  417.       int nres = getnum;
  418.       lua_rawcall(L, narg, nres);
  419.     }
  420.     else if EQ("call") {
  421.       int narg = getnum;
  422.       int nres = getnum;
  423.       lua_call(L, narg, nres);
  424.     }
  425.     else if EQ("dostring") {
  426.       lua_dostring(L, luaL_check_string(L, getnum));
  427.     }
  428.     else if EQ("settagmethod") {
  429.       int tag = getnum;
  430.       const char *event = getname;
  431.       lua_settagmethod(L, tag, event);
  432.     }
  433.     else if EQ("gettagmethod") {
  434.       int tag = getnum;
  435.       const char *event = getname;
  436.       lua_gettagmethod(L, tag, event);
  437.     }
  438.     else if EQ("type") {
  439.       lua_pushstring(L, lua_typename(L, lua_type(L, getnum)));
  440.     }
  441.     else luaL_verror(L, "unknown instruction %.30s", buff);
  442.   }
  443.   return 0;
  444. }
  445. /* }====================================================== */
  446. static const struct luaL_reg tests_funcs[] = {
  447.   {"hash", hash_query},
  448.   {"limits", get_limits},
  449.   {"listcode", listcode},
  450.   {"liststrings", liststrings},
  451.   {"listlocals", listlocals},
  452.   {"loadlib", loadlib},
  453.   {"querystr", string_query},
  454.   {"querytab", table_query},
  455.   {"testC", testC},
  456.   {"ref", tref},
  457.   {"getref", getref},
  458.   {"unref", unref},
  459.   {"newuserdata", newuserdata},
  460.   {"udataval", udataval},
  461.   {"newstate", newstate},
  462.   {"closestate", closestate},
  463.   {"doremote", doremote},
  464.   {"settagmethod", settagmethod},
  465.   {"equal", equal},
  466.   {"totalmem", mem_query}
  467. };
  468. void luaB_opentests (lua_State *L) {
  469.   lua_newtable(L);
  470.   lua_getglobals(L);
  471.   lua_pushvalue(L, -2);
  472.   lua_setglobals(L);
  473.   luaL_openl(L, tests_funcs);  /* open functions inside new table */
  474.   lua_setglobals(L);  /* restore old table of globals */
  475.   lua_setglobal(L, "T");  /* set new table as global T */
  476. }
  477. #endif