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

模拟服务器

开发平台:

Visual C++

  1. /*
  2. ** $Id: ltests.c,v 1.1 2004/08/20 02:26:56 JH Exp $
  3. ** Internal Module for Debugging of the Lua Implementation
  4. ** See Copyright Notice in lua.h
  5. */
  6. #include <ctype.h>
  7. #include <limits.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #define ltests_c
  12. #include "lua.h"
  13. #include "lapi.h"
  14. #include "lauxlib.h"
  15. #include "lcode.h"
  16. #include "ldebug.h"
  17. #include "ldo.h"
  18. #include "lfunc.h"
  19. #include "lmem.h"
  20. #include "lopcodes.h"
  21. #include "lstate.h"
  22. #include "lstring.h"
  23. #include "ltable.h"
  24. #include "lualib.h"
  25. /*
  26. ** The whole module only makes sense with LUA_DEBUG on
  27. */
  28. #ifdef LUA_DEBUG
  29. #define lua_pushintegral(L,i) lua_pushnumber(L, cast(lua_Number, (i)))
  30. static lua_State *lua_state = NULL;
  31. int islocked = 0;
  32. #define func_at(L,k) (L->ci->base+(k) - 1)
  33. static void setnameval (lua_State *L, const char *name, int val) {
  34.   lua_pushstring(L, name);
  35.   lua_pushintegral(L, val);
  36.   lua_settable(L, -3);
  37. }
  38. /*
  39. ** {======================================================================
  40. ** Controlled version for realloc.
  41. ** =======================================================================
  42. */
  43. #define MARK 0x55  /* 01010101 (a nice pattern) */
  44. #ifndef EXTERNMEMCHECK
  45. /* full memory check */
  46. #define HEADER (sizeof(L_Umaxalign)) /* ensures maximum alignment for HEADER */
  47. #define MARKSIZE 16  /* size of marks after each block */
  48. #define blockhead(b) (cast(char *, b) - HEADER)
  49. #define setsize(newblock, size) (*cast(size_t *, newblock) = size)
  50. #define checkblocksize(b, size) (size == (*cast(size_t *, blockhead(b))))
  51. #define fillmem(mem,size) memset(mem, -MARK, size)
  52. #else
  53. /* external memory check: don't do it twice */
  54. #define HEADER 0
  55. #define MARKSIZE 0
  56. #define blockhead(b) (b)
  57. #define setsize(newblock, size) /* empty */
  58. #define checkblocksize(b,size) (1)
  59. #define fillmem(mem,size) /* empty */
  60. #endif
  61. unsigned long memdebug_numblocks = 0;
  62. unsigned long memdebug_total = 0;
  63. unsigned long memdebug_maxmem = 0;
  64. unsigned long memdebug_memlimit = ULONG_MAX;
  65. static void *checkblock (void *block, size_t size) {
  66.   void *b = blockhead(block);
  67.   int i;
  68.   for (i=0;i<MARKSIZE;i++)
  69.     lua_assert(*(cast(char *, b)+HEADER+size+i) == MARK+i); /* corrupted block? */
  70.   return b;
  71. }
  72. static void freeblock (void *block, size_t size) {
  73.   if (block) {
  74.     lua_assert(checkblocksize(block, size));
  75.     block = checkblock(block, size);
  76.     fillmem(block, size+HEADER+MARKSIZE);  /* erase block */
  77.     free(block);  /* free original block */
  78.     memdebug_numblocks--;
  79.     memdebug_total -= size;
  80.   }
  81. }
  82. void *debug_realloc (void *block, size_t oldsize, size_t size) {
  83.   lua_assert(oldsize == 0 || checkblocksize(block, oldsize));
  84.   /* ISO does not specify what realloc(NULL, 0) does */
  85.   lua_assert(block != NULL || size > 0);
  86.   if (size == 0) {
  87.     freeblock(block, oldsize);
  88.     return NULL;
  89.   }
  90.   else if (size > oldsize && memdebug_total+size-oldsize > memdebug_memlimit)
  91.     return NULL;  /* to test memory allocation errors */
  92.   else {
  93.     void *newblock;
  94.     int i;
  95.     size_t realsize = HEADER+size+MARKSIZE;
  96.     size_t commonsize = (oldsize < size) ? oldsize : size;
  97.     if (realsize < size) return NULL;  /* overflow! */
  98.     newblock = malloc(realsize);  /* alloc a new block */
  99.     if (newblock == NULL) return NULL;
  100.     if (block) {
  101.       memcpy(cast(char *, newblock)+HEADER, block, commonsize);
  102.       freeblock(block, oldsize);  /* erase (and check) old copy */
  103.     }
  104.     /* initialize new part of the block with something `weird' */
  105.     fillmem(cast(char *, newblock)+HEADER+commonsize, size-commonsize);
  106.     memdebug_total += size;
  107.     if (memdebug_total > memdebug_maxmem)
  108.       memdebug_maxmem = memdebug_total;
  109.     memdebug_numblocks++;
  110.     setsize(newblock, size);
  111.     for (i=0;i<MARKSIZE;i++)
  112.       *(cast(char *, newblock)+HEADER+size+i) = cast(char, MARK+i);
  113.     return cast(char *, newblock)+HEADER;
  114.   }
  115. }
  116. /* }====================================================================== */
  117. /*
  118. ** {======================================================
  119. ** Disassembler
  120. ** =======================================================
  121. */
  122. static char *buildop (Proto *p, int pc, char *buff) {
  123.   Instruction i = p->code[pc];
  124.   OpCode o = GET_OPCODE(i);
  125.   const char *name = luaP_opnames[o];
  126.   int line = getline(p, pc);
  127.   sprintf(buff, "(%4d) %4d - ", line, pc);
  128.   switch (getOpMode(o)) {  
  129.     case iABC:
  130.       sprintf(buff+strlen(buff), "%-12s%4d %4d %4d", name,
  131.               GETARG_A(i), GETARG_B(i), GETARG_C(i));
  132.       break;
  133.     case iABx:
  134.       sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_Bx(i));
  135.       break;
  136.     case iAsBx:
  137.       sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_sBx(i));
  138.       break;
  139.   }
  140.   return buff;
  141. }
  142. #if 0
  143. void luaI_printcode (Proto *pt, int size) {
  144.   int pc;
  145.   for (pc=0; pc<size; pc++) {
  146.     char buff[100];
  147.     printf("%sn", buildop(pt, pc, buff));
  148.   }
  149.   printf("-------n");
  150. }
  151. #endif
  152. static int listcode (lua_State *L) {
  153.   int pc;
  154.   Proto *p;
  155.   luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
  156.                  1, "Lua function expected");
  157.   p = clvalue(func_at(L, 1))->l.p;
  158.   lua_newtable(L);
  159.   setnameval(L, "maxstack", p->maxstacksize);
  160.   setnameval(L, "numparams", p->numparams);
  161.   for (pc=0; pc<p->sizecode; pc++) {
  162.     char buff[100];
  163.     lua_pushintegral(L, pc+1);
  164.     lua_pushstring(L, buildop(p, pc, buff));
  165.     lua_settable(L, -3);
  166.   }
  167.   return 1;
  168. }
  169. static int listk (lua_State *L) {
  170.   Proto *p;
  171.   int i;
  172.   luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
  173.                  1, "Lua function expected");
  174.   p = clvalue(func_at(L, 1))->l.p;
  175.   lua_newtable(L);
  176.   for (i=0; i<p->sizek; i++) {
  177.     lua_pushintegral(L, i+1);
  178.     luaA_pushobject(L, p->k+i);
  179.     lua_settable(L, -3);
  180.   }
  181.   return 1;
  182. }
  183. static int listlocals (lua_State *L) {
  184.   Proto *p;
  185.   int pc = luaL_checkint(L, 2) - 1;
  186.   int i = 0;
  187.   const char *name;
  188.   luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
  189.                  1, "Lua function expected");
  190.   p = clvalue(func_at(L, 1))->l.p;
  191.   while ((name = luaF_getlocalname(p, ++i, pc)) != NULL)
  192.     lua_pushstring(L, name);
  193.   return i-1;
  194. }
  195. /* }====================================================== */
  196. static int get_limits (lua_State *L) {
  197.   lua_newtable(L);
  198.   setnameval(L, "BITS_INT", BITS_INT);
  199.   setnameval(L, "LFPF", LFIELDS_PER_FLUSH);
  200.   setnameval(L, "MAXVARS", MAXVARS);
  201.   setnameval(L, "MAXPARAMS", MAXPARAMS);
  202.   setnameval(L, "MAXSTACK", MAXSTACK);
  203.   setnameval(L, "MAXUPVALUES", MAXUPVALUES);
  204.   return 1;
  205. }
  206. static int mem_query (lua_State *L) {
  207.   if (lua_isnone(L, 1)) {
  208.     lua_pushintegral(L, memdebug_total);
  209.     lua_pushintegral(L, memdebug_numblocks);
  210.     lua_pushintegral(L, memdebug_maxmem);
  211.     return 3;
  212.   }
  213.   else {
  214.     memdebug_memlimit = luaL_checkint(L, 1);
  215.     return 0;
  216.   }
  217. }
  218. static int hash_query (lua_State *L) {
  219.   if (lua_isnone(L, 2)) {
  220.     luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "string expected");
  221.     lua_pushintegral(L, tsvalue(func_at(L, 1))->tsv.hash);
  222.   }
  223.   else {
  224.     TObject *o = func_at(L, 1);
  225.     Table *t;
  226.     luaL_checktype(L, 2, LUA_TTABLE);
  227.     t = hvalue(func_at(L, 2));
  228.     lua_pushintegral(L, luaH_mainposition(t, o) - t->node);
  229.   }
  230.   return 1;
  231. }
  232. static int stacklevel (lua_State *L) {
  233.   unsigned long a = 0;
  234.   lua_pushintegral(L, (int)(L->top - L->stack));
  235.   lua_pushintegral(L, (int)(L->stack_last - L->stack));
  236.   lua_pushintegral(L, (int)(L->ci - L->base_ci));
  237.   lua_pushintegral(L, (int)(L->end_ci - L->base_ci));
  238.   lua_pushintegral(L, (unsigned long)&a);
  239.   return 5;
  240. }
  241. static int table_query (lua_State *L) {
  242.   const Table *t;
  243.   int i = luaL_optint(L, 2, -1);
  244.   luaL_checktype(L, 1, LUA_TTABLE);
  245.   t = hvalue(func_at(L, 1));
  246.   if (i == -1) {
  247.     lua_pushintegral(L, t->sizearray);
  248.     lua_pushintegral(L, sizenode(t));
  249.     lua_pushintegral(L, t->firstfree - t->node);
  250.   }
  251.   else if (i < t->sizearray) {
  252.     lua_pushintegral(L, i);
  253.     luaA_pushobject(L, &t->array[i]);
  254.     lua_pushnil(L); 
  255.   }
  256.   else if ((i -= t->sizearray) < sizenode(t)) {
  257.     if (!ttisnil(gval(gnode(t, i))) ||
  258.         ttisnil(gkey(gnode(t, i))) ||
  259.         ttisnumber(gkey(gnode(t, i)))) {
  260.       luaA_pushobject(L, gkey(gnode(t, i)));
  261.     }
  262.     else
  263.       lua_pushstring(L, "<undef>");
  264.     luaA_pushobject(L, gval(gnode(t, i)));
  265.     if (t->node[i].next)
  266.       lua_pushintegral(L, t->node[i].next - t->node);
  267.     else
  268.       lua_pushnil(L);
  269.   }
  270.   return 3;
  271. }
  272. static int string_query (lua_State *L) {
  273.   stringtable *tb = &G(L)->strt;
  274.   int s = luaL_optint(L, 2, 0) - 1;
  275.   if (s==-1) {
  276.     lua_pushintegral(L ,tb->nuse);
  277.     lua_pushintegral(L ,tb->size);
  278.     return 2;
  279.   }
  280.   else if (s < tb->size) {
  281.     GCObject *ts;
  282.     int n = 0;
  283.     for (ts = tb->hash[s]; ts; ts = ts->gch.next) {
  284.       setsvalue2s(L->top, gcotots(ts));
  285.       incr_top(L);
  286.       n++;
  287.     }
  288.     return n;
  289.   }
  290.   return 0;
  291. }
  292. static int tref (lua_State *L) {
  293.   int level = lua_gettop(L);
  294.   int lock = luaL_optint(L, 2, 1);
  295.   luaL_checkany(L, 1);
  296.   lua_pushvalue(L, 1);
  297.   lua_pushintegral(L, lua_ref(L, lock));
  298.   assert(lua_gettop(L) == level+1);  /* +1 for result */
  299.   return 1;
  300. }
  301. static int getref (lua_State *L) {
  302.   int level = lua_gettop(L);
  303.   lua_getref(L, luaL_checkint(L, 1));
  304.   assert(lua_gettop(L) == level+1);
  305.   return 1;
  306. }
  307. static int unref (lua_State *L) {
  308.   int level = lua_gettop(L);
  309.   lua_unref(L, luaL_checkint(L, 1));
  310.   assert(lua_gettop(L) == level);
  311.   return 0;
  312. }
  313. static int metatable (lua_State *L) {
  314.   luaL_checkany(L, 1);
  315.   if (lua_isnone(L, 2)) {
  316.     if (lua_getmetatable(L, 1) == 0)
  317.       lua_pushnil(L);
  318.   }
  319.   else {
  320.     lua_settop(L, 2);
  321.     luaL_checktype(L, 2, LUA_TTABLE);
  322.     lua_setmetatable(L, 1);
  323.   }
  324.   return 1;
  325. }
  326. static int upvalue (lua_State *L) {
  327.   int n = luaL_checkint(L, 2);
  328.   luaL_checktype(L, 1, LUA_TFUNCTION);
  329.   if (lua_isnone(L, 3)) {
  330.     const char *name = lua_getupvalue(L, 1, n);
  331.     if (name == NULL) return 0;
  332.     lua_pushstring(L, name);
  333.     return 2;
  334.   }
  335.   else {
  336.     const char *name = lua_setupvalue(L, 1, n);
  337.     lua_pushstring(L, name);
  338.     return 1;
  339.   }
  340. }
  341. static int newuserdata (lua_State *L) {
  342.   size_t size = luaL_checkint(L, 1);
  343.   char *p = cast(char *, lua_newuserdata(L, size));
  344.   while (size--) *p++ = '';
  345.   return 1;
  346. }
  347. static int pushuserdata (lua_State *L) {
  348.   lua_pushlightuserdata(L, cast(void *, luaL_checkint(L, 1)));
  349.   return 1;
  350. }
  351. static int udataval (lua_State *L) {
  352.   lua_pushintegral(L, cast(int, lua_touserdata(L, 1)));
  353.   return 1;
  354. }
  355. static int doonnewstack (lua_State *L) {
  356.   lua_State *L1 = lua_newthread(L);
  357.   size_t l;
  358.   const char *s = luaL_checklstring(L, 1, &l);
  359.   int status = luaL_loadbuffer(L1, s, l, s);
  360.   if (status == 0)
  361.     status = lua_pcall(L1, 0, 0, 0);
  362.   lua_pushintegral(L, status);
  363.   return 1;
  364. }
  365. static int s2d (lua_State *L) {
  366.   lua_pushnumber(L, *cast(const double *, luaL_checkstring(L, 1)));
  367.   return 1;
  368. }
  369. static int d2s (lua_State *L) {
  370.   double d = luaL_checknumber(L, 1);
  371.   lua_pushlstring(L, cast(char *, &d), sizeof(d));
  372.   return 1;
  373. }
  374. static int newstate (lua_State *L) {
  375.   lua_State *L1 = lua_open();
  376.   if (L1) {
  377.     lua_userstateopen(L1);  /* init lock */
  378.     lua_pushintegral(L, (unsigned long)L1);
  379.   }
  380.   else
  381.     lua_pushnil(L);
  382.   return 1;
  383. }
  384. static int loadlib (lua_State *L) {
  385.   static const luaL_reg libs[] = {
  386.     {"mathlibopen", luaopen_math},
  387.     {"strlibopen", luaopen_string},
  388.     {"iolibopen", luaopen_io},
  389.     {"tablibopen", luaopen_table},
  390.     {"dblibopen", luaopen_debug},
  391.     {"baselibopen", luaopen_base},
  392.     {NULL, NULL}
  393.   };
  394.   lua_State *L1 = cast(lua_State *,
  395.                        cast(unsigned long, luaL_checknumber(L, 1)));
  396.   lua_pushvalue(L1, LUA_GLOBALSINDEX);
  397.   luaL_openlib(L1, NULL, libs, 0);
  398.   return 0;
  399. }
  400. static int closestate (lua_State *L) {
  401.   lua_State *L1 = cast(lua_State *, cast(unsigned long, luaL_checknumber(L, 1)));
  402.   lua_close(L1);
  403.   lua_unlock(L);  /* close cannot unlock that */
  404.   return 0;
  405. }
  406. static int doremote (lua_State *L) {
  407.   lua_State *L1 = cast(lua_State *,cast(unsigned long,luaL_checknumber(L, 1)));
  408.   size_t lcode;
  409.   const char *code = luaL_checklstring(L, 2, &lcode);
  410.   int status;
  411.   lua_settop(L1, 0);
  412.   status = luaL_loadbuffer(L1, code, lcode, code);
  413.   if (status == 0)
  414.     status = lua_pcall(L1, 0, LUA_MULTRET, 0);
  415.   if (status != 0) {
  416.     lua_pushnil(L);
  417.     lua_pushintegral(L, status);
  418.     lua_pushstring(L, lua_tostring(L1, -1));
  419.     return 3;
  420.   }
  421.   else {
  422.     int i = 0;
  423.     while (!lua_isnone(L1, ++i))
  424.       lua_pushstring(L, lua_tostring(L1, i));
  425.     lua_pop(L1, i-1);
  426.     return i-1;
  427.   }
  428. }
  429. static int log2_aux (lua_State *L) {
  430.   lua_pushintegral(L, luaO_log2(luaL_checkint(L, 1)));
  431.   return 1;
  432. }
  433. static int int2fb_aux (lua_State *L) {
  434.   int b = luaO_int2fb(luaL_checkint(L, 1));
  435.   lua_pushintegral(L, b);
  436.   lua_pushintegral(L, fb2int(b));
  437.   return 2;
  438. }
  439. static int test_do (lua_State *L) {
  440.   const char *p = luaL_checkstring(L, 1);
  441.   if (*p == '@')
  442.     lua_dofile(L, p+1);
  443.   else
  444.     lua_dostring(L, p);
  445.   return lua_gettop(L);
  446. }
  447. /*
  448. ** {======================================================
  449. ** function to test the API with C. It interprets a kind of assembler
  450. ** language with calls to the API, so the test can be driven by Lua code
  451. ** =======================================================
  452. */
  453. static const char *const delimits = " tn,;";
  454. static void skip (const char **pc) {
  455.   while (**pc != '' && strchr(delimits, **pc)) (*pc)++;
  456. }
  457. static int getnum_aux (lua_State *L, const char **pc) {
  458.   int res = 0;
  459.   int sig = 1;
  460.   skip(pc);
  461.   if (**pc == '.') {
  462.     res = cast(int, lua_tonumber(L, -1));
  463.     lua_pop(L, 1);
  464.     (*pc)++;
  465.     return res;
  466.   }
  467.   else if (**pc == '-') {
  468.     sig = -1;
  469.     (*pc)++;
  470.   }
  471.   while (isdigit(cast(int, **pc))) res = res*10 + (*(*pc)++) - '0';
  472.   return sig*res;
  473. }
  474.   
  475. static const char *getname_aux (char *buff, const char **pc) {
  476.   int i = 0;
  477.   skip(pc);
  478.   while (**pc != '' && !strchr(delimits, **pc))
  479.     buff[i++] = *(*pc)++;
  480.   buff[i] = '';
  481.   return buff;
  482. }
  483. #define EQ(s1) (strcmp(s1, inst) == 0)
  484. #define getnum (getnum_aux(L, &pc))
  485. #define getname (getname_aux(buff, &pc))
  486. static int testC (lua_State *L) {
  487.   char buff[30];
  488.   const char *pc = luaL_checkstring(L, 1);
  489.   for (;;) {
  490.     const char *inst = getname;
  491.     if EQ("") return 0;
  492.     else if EQ("isnumber") {
  493.       lua_pushintegral(L, lua_isnumber(L, getnum));
  494.     }
  495.     else if EQ("isstring") {
  496.       lua_pushintegral(L, lua_isstring(L, getnum));
  497.     }
  498.     else if EQ("istable") {
  499.       lua_pushintegral(L, lua_istable(L, getnum));
  500.     }
  501.     else if EQ("iscfunction") {
  502.       lua_pushintegral(L, lua_iscfunction(L, getnum));
  503.     }
  504.     else if EQ("isfunction") {
  505.       lua_pushintegral(L, lua_isfunction(L, getnum));
  506.     }
  507.     else if EQ("isuserdata") {
  508.       lua_pushintegral(L, lua_isuserdata(L, getnum));
  509.     }
  510.     else if EQ("isudataval") {
  511.       lua_pushintegral(L, lua_islightuserdata(L, getnum));
  512.     }
  513.     else if EQ("isnil") {
  514.       lua_pushintegral(L, lua_isnil(L, getnum));
  515.     }
  516.     else if EQ("isnull") {
  517.       lua_pushintegral(L, lua_isnone(L, getnum));
  518.     }
  519.     else if EQ("tonumber") {
  520.       lua_pushnumber(L, lua_tonumber(L, getnum));
  521.     }
  522.     else if EQ("tostring") {
  523.       const char *s = lua_tostring(L, getnum);
  524.       lua_pushstring(L, s);
  525.     }
  526.     else if EQ("strlen") {
  527.       lua_pushintegral(L, lua_strlen(L, getnum));
  528.     }
  529.     else if EQ("tocfunction") {
  530.       lua_pushcfunction(L, lua_tocfunction(L, getnum));
  531.     }
  532.     else if EQ("return") {
  533.       return getnum;
  534.     }
  535.     else if EQ("gettop") {
  536.       lua_pushintegral(L, lua_gettop(L));
  537.     }
  538.     else if EQ("settop") {
  539.       lua_settop(L, getnum);
  540.     }
  541.     else if EQ("pop") {
  542.       lua_pop(L, getnum);
  543.     }
  544.     else if EQ("pushnum") {
  545.       lua_pushintegral(L, getnum);
  546.     }
  547.     else if EQ("pushnil") {
  548.       lua_pushnil(L);
  549.     }
  550.     else if EQ("pushbool") {
  551.       lua_pushboolean(L, getnum);
  552.     }
  553.     else if EQ("tobool") {
  554.       lua_pushintegral(L, lua_toboolean(L, getnum));
  555.     }
  556.     else if EQ("pushvalue") {
  557.       lua_pushvalue(L, getnum);
  558.     }
  559.     else if EQ("pushcclosure") {
  560.       lua_pushcclosure(L, testC, getnum);
  561.     }
  562.     else if EQ("pushupvalues") {
  563.       lua_pushupvalues(L);
  564.     }
  565.     else if EQ("remove") {
  566.       lua_remove(L, getnum);
  567.     }
  568.     else if EQ("insert") {
  569.       lua_insert(L, getnum);
  570.     }
  571.     else if EQ("replace") {
  572.       lua_replace(L, getnum);
  573.     }
  574.     else if EQ("gettable") {
  575.       lua_gettable(L, getnum);
  576.     }
  577.     else if EQ("settable") {
  578.       lua_settable(L, getnum);
  579.     }
  580.     else if EQ("next") {
  581.       lua_next(L, -2);
  582.     }
  583.     else if EQ("concat") {
  584.       lua_concat(L, getnum);
  585.     }
  586.     else if EQ("lessthan") {
  587.       int a = getnum;
  588.       lua_pushboolean(L, lua_lessthan(L, a, getnum));
  589.     }
  590.     else if EQ("equal") {
  591.       int a = getnum;
  592.       lua_pushboolean(L, lua_equal(L, a, getnum));
  593.     }
  594.     else if EQ("rawcall") {
  595.       int narg = getnum;
  596.       int nres = getnum;
  597.       lua_call(L, narg, nres);
  598.     }
  599.     else if EQ("call") {
  600.       int narg = getnum;
  601.       int nres = getnum;
  602.       lua_pcall(L, narg, nres, 0);
  603.     }
  604.     else if EQ("loadstring") {
  605.       size_t sl;
  606.       const char *s = luaL_checklstring(L, getnum, &sl);
  607.       luaL_loadbuffer(L, s, sl, s);
  608.     }
  609.     else if EQ("loadfile") {
  610.       luaL_loadfile(L, luaL_checkstring(L, getnum));
  611.     }
  612.     else if EQ("setmetatable") {
  613.       lua_setmetatable(L, getnum);
  614.     }
  615.     else if EQ("getmetatable") {
  616.       if (lua_getmetatable(L, getnum) == 0)
  617.         lua_pushnil(L);
  618.     }
  619.     else if EQ("type") {
  620.       lua_pushstring(L, lua_typename(L, lua_type(L, getnum)));
  621.     }
  622.     else if EQ("getn") {
  623.       int i = getnum;
  624.       lua_pushintegral(L, luaL_getn(L, i));
  625.     }
  626.     else if EQ("setn") {
  627.       int i = getnum;
  628.       int n = cast(int, lua_tonumber(L, -1));
  629.       luaL_setn(L, i, n);
  630.       lua_pop(L, 1);
  631.     }
  632.     else luaL_error(L, "unknown instruction %s", buff);
  633.   }
  634.   return 0;
  635. }
  636. /* }====================================================== */
  637. /*
  638. ** {======================================================
  639. ** tests for yield inside hooks
  640. ** =======================================================
  641. */
  642. static void yieldf (lua_State *L, lua_Debug *ar) {
  643.   lua_yield(L, 0);
  644. }
  645. static int setyhook (lua_State *L) {
  646.   if (lua_isnoneornil(L, 1))
  647.     lua_sethook(L, NULL, 0, 0);  /* turn off hooks */
  648.   else {
  649.     const char *smask = luaL_checkstring(L, 1);
  650.     int count = luaL_optint(L, 2, 0);
  651.     int mask = 0;
  652.     if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
  653.     if (count > 0) mask |= LUA_MASKCOUNT;
  654.     lua_sethook(L, yieldf, mask, count);
  655.   }
  656.   return 0;
  657. }
  658. static int coresume (lua_State *L) {
  659.   int status;
  660.   lua_State *co = lua_tothread(L, 1);
  661.   luaL_argcheck(L, co, 1, "coroutine expected");
  662.   status = lua_resume(co, 0);
  663.   if (status != 0) {
  664.     lua_pushboolean(L, 0);
  665.     lua_insert(L, -2);
  666.     return 2;  /* return false + error message */
  667.   }
  668.   else {
  669.     lua_pushboolean(L, 1);
  670.     return 1;
  671.   }
  672. }
  673. /* }====================================================== */
  674. static const struct luaL_reg tests_funcs[] = {
  675.   {"hash", hash_query},
  676.   {"limits", get_limits},
  677.   {"listcode", listcode},
  678.   {"listk", listk},
  679.   {"listlocals", listlocals},
  680.   {"loadlib", loadlib},
  681.   {"stacklevel", stacklevel},
  682.   {"querystr", string_query},
  683.   {"querytab", table_query},
  684.   {"doit", test_do},
  685.   {"testC", testC},
  686.   {"ref", tref},
  687.   {"getref", getref},
  688.   {"unref", unref},
  689.   {"d2s", d2s},
  690.   {"s2d", s2d},
  691.   {"metatable", metatable},
  692.   {"upvalue", upvalue},
  693.   {"newuserdata", newuserdata},
  694.   {"pushuserdata", pushuserdata},
  695.   {"udataval", udataval},
  696.   {"doonnewstack", doonnewstack},
  697.   {"newstate", newstate},
  698.   {"closestate", closestate},
  699.   {"doremote", doremote},
  700.   {"log2", log2_aux},
  701.   {"int2fb", int2fb_aux},
  702.   {"totalmem", mem_query},
  703.   {"resume", coresume},
  704.   {"setyhook", setyhook},
  705.   {NULL, NULL}
  706. };
  707. static void fim (void) {
  708.   if (!islocked)
  709.     lua_close(lua_state);
  710.   lua_assert(memdebug_numblocks == 0);
  711.   lua_assert(memdebug_total == 0);
  712. }
  713. static int l_panic (lua_State *L) {
  714.   UNUSED(L);
  715.   fprintf(stderr, "unable to recover; exitingn");
  716.   return 0;
  717. }
  718. int luaB_opentests (lua_State *L) {
  719.   lua_atpanic(L, l_panic);
  720.   lua_userstateopen(L);  /* init lock */
  721.   lua_state = L;  /* keep first state to be opened */
  722.   luaL_openlib(L, "T", tests_funcs, 0);
  723.   atexit(fim);
  724.   return 0;
  725. }
  726. #undef main
  727. int main (int argc, char *argv[]) {
  728.   char *limit = getenv("MEMLIMIT");
  729.   if (limit)
  730.     memdebug_memlimit = strtoul(limit, NULL, 10);
  731.   l_main(argc, argv);
  732.   return 0;
  733. }
  734. #endif