- Main Page
- Related Pages
- Modules
- Data Structures
- Files

# lua/ltests.c

Go to the documentation of this file.

    00001 /*
    00002 ** $Id: ltests.c,v 1.1 2004/03/16 21:58:30 niemeyer Exp $
    00003 ** Internal Module for Debugging of the Lua Implementation
    00004 ** See Copyright Notice in lua.h
    00005 */
    00006
    00007
    00008 #include <ctype.h>
    00009 #include <limits.h>
    00010 #include <stdio.h>
    00011 #include <stdlib.h>
    00012 #include <string.h>
    00013
    00014 #define ltests_c
    00015
    00016 #include "lua.h"
    00017
    00018 #include "lapi.h"
    00019 #include "lauxlib.h"
    00020 #include "lcode.h"
    00021 #include "ldebug.h"
    00022 #include "ldo.h"
    00023 #include "lfunc.h"
    00024 #include "lmem.h"
    00025 #include "lopcodes.h"
    00026 #include "lstate.h"
    00027 #include "lstring.h"
    00028 #include "ltable.h"
    00029 #include "lualib.h"
    00030
    00031
    00032
    00033 /*
    00034 ** The whole module only makes sense with LUA_DEBUG on
    00035 */
    00036 #ifdef LUA_DEBUG
    00037
    00038
    00039 #define lua_pushintegral(L,i)   lua_pushnumber(L, cast(lua_Number, (i)))
    00040
    00041
    00042 static lua_State *lua_state = NULL;
    00043
    00044 int islocked = 0;
    00045
    00046
    00047 #define func_at(L,k)    (L->ci->base+(k) - 1)
    00048
    00049
    00050 static void setnameval (lua_State *L, const char *name, int val)
    00051         /*@*/
    00052 {
    00053   lua_pushstring(L, name);
    00054   lua_pushintegral(L, val);
    00055   lua_settable(L, -3);
    00056 }
    00057
    00058
    00059 /*
    00060 ** {======================================================================
    00061 ** Controlled version for realloc.
    00062 ** =======================================================================
    00063 */
    00064
    00065 #define MARK            0x55  /* 01010101 (a nice pattern) */
    00066
    00067 #ifndef EXTERNMEMCHECK
    00068 /* full memory check */
    00069 #define HEADER  (sizeof(L_Umaxalign)) /* ensures maximum alignment for HEADER */
    00070 #define MARKSIZE        16  /* size of marks after each block */
    00071 #define blockhead(b)    (cast(char *, b) - HEADER)
    00072 #define setsize(newblock, size) (*cast(size_t *, newblock) = size)
    00073 #define checkblocksize(b, size) (size == (*cast(size_t *, blockhead(b))))
    00074 #define fillmem(mem,size)       memset(mem, -MARK, size)
    00075 #else
    00076 /* external memory check: don't do it twice */
    00077 #define HEADER          0
    00078 #define MARKSIZE        0
    00079 #define blockhead(b)    (b)
    00080 #define setsize(newblock, size) /* empty */
    00081 #define checkblocksize(b,size)  (1)
    00082 #define fillmem(mem,size)       /* empty */
    00083 #endif
    00084
    00085 unsigned long memdebug_numblocks = 0;
    00086 unsigned long memdebug_total = 0;
    00087 unsigned long memdebug_maxmem = 0;
    00088 unsigned long memdebug_memlimit = ULONG_MAX;
    00089
    00090
    00091 static void *checkblock (void *block, size_t size)
    00092         /*@*/
    00093 {
    00094   void *b = blockhead(block);
    00095   int i;
    00096   for (i=0;i<MARKSIZE;i++)
    00097     lua_assert(*(cast(char *, b)+HEADER+size+i) == MARK+i); /* corrupted block? */
    00098   return b;
    00099 }
    00100
    00101
    00102 static void freeblock (void *block, size_t size)
    00103         /*@*/
    00104 {
    00105   if (block) {
    00106     lua_assert(checkblocksize(block, size));
    00107     block = checkblock(block, size);
    00108     fillmem(block, size+HEADER+MARKSIZE);  /* erase block */
    00109     free(block);  /* free original block */
    00110     memdebug_numblocks--;
    00111     memdebug_total -= size;
    00112   }
    00113 }
    00114
    00115
    00116 void *debug_realloc (void *block, size_t oldsize, size_t size) {
    00117   lua_assert(oldsize == 0 || checkblocksize(block, oldsize));
    00118   /* ISO does not specify what realloc(NULL, 0) does */
    00119   lua_assert(block != NULL || size > 0);
    00120   if (size == 0) {
    00121     freeblock(block, oldsize);
    00122     return NULL;
    00123   }
    00124   else if (size > oldsize && memdebug_total+size-oldsize > memdebug_memlimit)
    00125     return NULL;  /* to test memory allocation errors */
    00126   else {
    00127     void *newblock;
    00128     int i;
    00129     size_t realsize = HEADER+size+MARKSIZE;
    00130     size_t commonsize = (oldsize < size) ? oldsize : size;
    00131     if (realsize < size) return NULL;  /* overflow! */
    00132     newblock = malloc(realsize);  /* alloc a new block */
    00133     if (newblock == NULL) return NULL;
    00134     if (block) {
    00135       memcpy(cast(char *, newblock)+HEADER, block, commonsize);
    00136       freeblock(block, oldsize);  /* erase (and check) old copy */
    00137     }
    00138     /* initialize new part of the block with something `weird' */
    00139     fillmem(cast(char *, newblock)+HEADER+commonsize, size-commonsize);
    00140     memdebug_total += size;
    00141     if (memdebug_total > memdebug_maxmem)
    00142       memdebug_maxmem = memdebug_total;
    00143     memdebug_numblocks++;
    00144     setsize(newblock, size);
    00145     for (i=0;i<MARKSIZE;i++)
    00146       *(cast(char *, newblock)+HEADER+size+i) = cast(char, MARK+i);
    00147     return cast(char *, newblock)+HEADER;
    00148   }
    00149 }
    00150
    00151
    00152 /* }====================================================================== */
    00153
    00154
    00155
    00156 /*
    00157 ** {======================================================
    00158 ** Disassembler
    00159 ** =======================================================
    00160 */
    00161
    00162
    00163 static char *buildop (Proto *p, int pc, char *buff)
    00164         /*@*/
    00165 {
    00166   Instruction i = p->code[pc];
    00167   OpCode o = GET_OPCODE(i);
    00168   const char *name = luaP_opnames[o];
    00169   int line = getline(p, pc);
    00170   sprintf(buff, "(%4d) %4d - ", line, pc);
    00171   switch (getOpMode(o)) {
    00172     case iABC:
    00173       sprintf(buff+strlen(buff), "%-12s%4d %4d %4d", name,
    00174               GETARG_A(i), GETARG_B(i), GETARG_C(i));
    00175       break;
    00176     case iABx:
    00177       sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_Bx(i));
    00178       break;
    00179     case iAsBx:
    00180       sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_sBx(i));
    00181       break;
    00182   }
    00183   return buff;
    00184 }
    00185
    00186
    00187 #if 0
    00188 void luaI_printcode (Proto *pt, int size) {
    00189   int pc;
    00190   for (pc=0; pc<size; pc++) {
    00191     char buff[100];
    00192     printf("%s\n", buildop(pt, pc, buff));
    00193   }
    00194   printf("-------\n");
    00195 }
    00196 #endif
    00197
    00198
    00199 static int listcode (lua_State *L)
    00200         /*@*/
    00201 {
    00202   int pc;
    00203   Proto *p;
    00204   luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
    00205                  1, "Lua function expected");
    00206   p = clvalue(func_at(L, 1))->l.p;
    00207   lua_newtable(L);
    00208   setnameval(L, "maxstack", p->maxstacksize);
    00209   setnameval(L, "numparams", p->numparams);
    00210   for (pc=0; pc<p->sizecode; pc++) {
    00211     char buff[100];
    00212     lua_pushintegral(L, pc+1);
    00213     lua_pushstring(L, buildop(p, pc, buff));
    00214     lua_settable(L, -3);
    00215   }
    00216   return 1;
    00217 }
    00218
    00219
    00220 static int listk (lua_State *L)
    00221         /*@*/
    00222 {
    00223   Proto *p;
    00224   int i;
    00225   luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
    00226                  1, "Lua function expected");
    00227   p = clvalue(func_at(L, 1))->l.p;
    00228   lua_newtable(L);
    00229   for (i=0; i<p->sizek; i++) {
    00230     lua_pushintegral(L, i+1);
    00231     luaA_pushobject(L, p->k+i);
    00232     lua_settable(L, -3);
    00233   }
    00234   return 1;
    00235 }
    00236
    00237
    00238 static int listlocals (lua_State *L)
    00239         /*@*/
    00240 {
    00241   Proto *p;
    00242   int pc = luaL_checkint(L, 2) - 1;
    00243   int i = 0;
    00244   const char *name;
    00245   luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
    00246                  1, "Lua function expected");
    00247   p = clvalue(func_at(L, 1))->l.p;
    00248   while ((name = luaF_getlocalname(p, ++i, pc)) != NULL)
    00249     lua_pushstring(L, name);
    00250   return i-1;
    00251 }
    00252
    00253 /* }====================================================== */
    00254
    00255
    00256
    00257
    00258 static int get_limits (lua_State *L)
    00259         /*@*/
    00260 {
    00261   lua_newtable(L);
    00262   setnameval(L, "BITS_INT", BITS_INT);
    00263   setnameval(L, "LFPF", LFIELDS_PER_FLUSH);
    00264   setnameval(L, "MAXVARS", MAXVARS);
    00265   setnameval(L, "MAXPARAMS", MAXPARAMS);
    00266   setnameval(L, "MAXSTACK", MAXSTACK);
    00267   setnameval(L, "MAXUPVALUES", MAXUPVALUES);
    00268   return 1;
    00269 }
    00270
    00271
    00272 static int mem_query (lua_State *L)
    00273         /*@*/
    00274 {
    00275   if (lua_isnone(L, 1)) {
    00276     lua_pushintegral(L, memdebug_total);
    00277     lua_pushintegral(L, memdebug_numblocks);
    00278     lua_pushintegral(L, memdebug_maxmem);
    00279     return 3;
    00280   }
    00281   else {
    00282     memdebug_memlimit = luaL_checkint(L, 1);
    00283     return 0;
    00284   }
    00285 }
    00286
    00287
    00288 static int hash_query (lua_State *L)
    00289         /*@*/
    00290 {
    00291   if (lua_isnone(L, 2)) {
    00292     luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "string expected");
    00293     lua_pushintegral(L, tsvalue(func_at(L, 1))->tsv.hash);
    00294   }
    00295   else {
    00296     TObject *o = func_at(L, 1);
    00297     Table *t;
    00298     luaL_checktype(L, 2, LUA_TTABLE);
    00299     t = hvalue(func_at(L, 2));
    00300     lua_pushintegral(L, luaH_mainposition(t, o) - t->node);
    00301   }
    00302   return 1;
    00303 }
    00304
    00305
    00306 static int stacklevel (lua_State *L)
    00307         /*@*/
    00308 {
    00309   unsigned long a = 0;
    00310   lua_pushintegral(L, (int)(L->top - L->stack));
    00311   lua_pushintegral(L, (int)(L->stack_last - L->stack));
    00312   lua_pushintegral(L, (int)(L->ci - L->base_ci));
    00313   lua_pushintegral(L, (int)(L->end_ci - L->base_ci));
    00314   lua_pushintegral(L, (unsigned long)&a);
    00315   return 5;
    00316 }
    00317
    00318
    00319 static int table_query (lua_State *L)
    00320         /*@*/
    00321 {
    00322   const Table *t;
    00323   int i = luaL_optint(L, 2, -1);
    00324   luaL_checktype(L, 1, LUA_TTABLE);
    00325   t = hvalue(func_at(L, 1));
    00326   if (i == -1) {
    00327     lua_pushintegral(L, t->sizearray);
    00328     lua_pushintegral(L, sizenode(t));
    00329     lua_pushintegral(L, t->firstfree - t->node);
    00330   }
    00331   else if (i < t->sizearray) {
    00332     lua_pushintegral(L, i);
    00333     luaA_pushobject(L, &t->array[i]);
    00334     lua_pushnil(L);
    00335   }
    00336   else if ((i -= t->sizearray) < sizenode(t)) {
    00337     if (!ttisnil(gval(gnode(t, i))) ||
    00338         ttisnil(gkey(gnode(t, i))) ||
    00339         ttisnumber(gkey(gnode(t, i)))) {
    00340       luaA_pushobject(L, gkey(gnode(t, i)));
    00341     }
    00342     else
    00343       lua_pushstring(L, "<undef>");
    00344     luaA_pushobject(L, gval(gnode(t, i)));
    00345     if (t->node[i].next)
    00346       lua_pushintegral(L, t->node[i].next - t->node);
    00347     else
    00348       lua_pushnil(L);
    00349   }
    00350   return 3;
    00351 }
    00352
    00353
    00354 static int string_query (lua_State *L)
    00355         /*@*/
    00356 {
    00357   stringtable *tb = &G(L)->strt;
    00358   int s = luaL_optint(L, 2, 0) - 1;
    00359   if (s==-1) {
    00360     lua_pushintegral(L ,tb->nuse);
    00361     lua_pushintegral(L ,tb->size);
    00362     return 2;
    00363   }
    00364   else if (s < tb->size) {
    00365     GCObject *ts;
    00366     int n = 0;
    00367     for (ts = tb->hash[s]; ts; ts = ts->gch.next) {
    00368       setsvalue2s(L->top, gcotots(ts));
    00369       incr_top(L);
    00370       n++;
    00371     }
    00372     return n;
    00373   }
    00374   return 0;
    00375 }
    00376
    00377
    00378 static int tref (lua_State *L)
    00379         /*@*/
    00380 {
    00381   int level = lua_gettop(L);
    00382   int lock = luaL_optint(L, 2, 1);
    00383   luaL_checkany(L, 1);
    00384   lua_pushvalue(L, 1);
    00385   lua_pushintegral(L, lua_ref(L, lock));
    00386   assert(lua_gettop(L) == level+1);  /* +1 for result */
    00387   return 1;
    00388 }
    00389
    00390 static int getref (lua_State *L)
    00391         /*@*/
    00392 {
    00393   int level = lua_gettop(L);
    00394   lua_getref(L, luaL_checkint(L, 1));
    00395   assert(lua_gettop(L) == level+1);
    00396   return 1;
    00397 }
    00398
    00399 static int unref (lua_State *L)
    00400         /*@*/
    00401 {
    00402   int level = lua_gettop(L);
    00403   lua_unref(L, luaL_checkint(L, 1));
    00404   assert(lua_gettop(L) == level);
    00405   return 0;
    00406 }
    00407
    00408 static int metatable (lua_State *L)
    00409         /*@*/
    00410 {
    00411   luaL_checkany(L, 1);
    00412   if (lua_isnone(L, 2)) {
    00413     if (lua_getmetatable(L, 1) == 0)
    00414       lua_pushnil(L);
    00415   }
    00416   else {
    00417     lua_settop(L, 2);
    00418     luaL_checktype(L, 2, LUA_TTABLE);
    00419     lua_setmetatable(L, 1);
    00420   }
    00421   return 1;
    00422 }
    00423
    00424
    00425 static int upvalue (lua_State *L)
    00426         /*@*/
    00427 {
    00428   int n = luaL_checkint(L, 2);
    00429   luaL_checktype(L, 1, LUA_TFUNCTION);
    00430   if (lua_isnone(L, 3)) {
    00431     const char *name = lua_getupvalue(L, 1, n);
    00432     if (name == NULL) return 0;
    00433     lua_pushstring(L, name);
    00434     return 2;
    00435   }
    00436   else {
    00437     const char *name = lua_setupvalue(L, 1, n);
    00438     lua_pushstring(L, name);
    00439     return 1;
    00440   }
    00441 }
    00442
    00443
    00444 static int newuserdata (lua_State *L)
    00445         /*@*/
    00446 {
    00447   size_t size = luaL_checkint(L, 1);
    00448   char *p = cast(char *, lua_newuserdata(L, size));
    00449   while (size--) *p++ = '\0';
    00450   return 1;
    00451 }
    00452
    00453
    00454 static int pushuserdata (lua_State *L)
    00455         /*@*/
    00456 {
    00457   lua_pushlightuserdata(L, cast(void *, luaL_checkint(L, 1)));
    00458   return 1;
    00459 }
    00460
    00461
    00462 static int udataval (lua_State *L)
    00463         /*@*/
    00464 {
    00465   lua_pushintegral(L, cast(int, lua_touserdata(L, 1)));
    00466   return 1;
    00467 }
    00468
    00469
    00470 static int doonnewstack (lua_State *L)
    00471         /*@*/
    00472 {
    00473   lua_State *L1 = lua_newthread(L);
    00474   size_t l;
    00475   const char *s = luaL_checklstring(L, 1, &l);
    00476   int status = luaL_loadbuffer(L1, s, l, s);
    00477   if (status == 0)
    00478     status = lua_pcall(L1, 0, 0, 0);
    00479   lua_pushintegral(L, status);
    00480   return 1;
    00481 }
    00482
    00483
    00484 static int s2d (lua_State *L)
    00485         /*@*/
    00486 {
    00487   lua_pushnumber(L, *cast(const double *, luaL_checkstring(L, 1)));
    00488   return 1;
    00489 }
    00490
    00491 static int d2s (lua_State *L)
    00492         /*@*/
    00493 {
    00494   double d = luaL_checknumber(L, 1);
    00495   lua_pushlstring(L, cast(char *, &d), sizeof(d));
    00496   return 1;
    00497 }
    00498
    00499
    00500 static int newstate (lua_State *L)
    00501         /*@*/
    00502 {
    00503   lua_State *L1 = lua_open();
    00504   if (L1) {
    00505     lua_userstateopen(L1);  /* init lock */
    00506     lua_pushintegral(L, (unsigned long)L1);
    00507   }
    00508   else
    00509     lua_pushnil(L);
    00510   return 1;
    00511 }
    00512
    00513
    00514 static int loadlib (lua_State *L)
    00515         /*@*/
    00516 {
    00517   static const luaL_reg libs[] = {
    00518     {"mathlibopen", luaopen_math},
    00519     {"strlibopen", luaopen_string},
    00520     {"iolibopen", luaopen_io},
    00521     {"tablibopen", luaopen_table},
    00522     {"dblibopen", luaopen_debug},
    00523     {"baselibopen", luaopen_base},
    00524     {NULL, NULL}
    00525   };
    00526   lua_State *L1 = cast(lua_State *,
    00527                        cast(unsigned long, luaL_checknumber(L, 1)));
    00528   lua_pushvalue(L1, LUA_GLOBALSINDEX);
    00529   luaL_openlib(L1, NULL, libs, 0);
    00530   return 0;
    00531 }
    00532
    00533 static int closestate (lua_State *L)
    00534         /*@*/
    00535 {
    00536   lua_State *L1 = cast(lua_State *, cast(unsigned long, luaL_checknumber(L, 1)));
    00537   lua_close(L1);
    00538   lua_unlock(L);  /* close cannot unlock that */
    00539   return 0;
    00540 }
    00541
    00542 static int doremote (lua_State *L)
    00543         /*@*/
    00544 {
    00545   lua_State *L1 = cast(lua_State *,cast(unsigned long,luaL_checknumber(L, 1)));
    00546   size_t lcode;
    00547   const char *code = luaL_checklstring(L, 2, &lcode);
    00548   int status;
    00549   lua_settop(L1, 0);
    00550   status = luaL_loadbuffer(L1, code, lcode, code);
    00551   if (status == 0)
    00552     status = lua_pcall(L1, 0, LUA_MULTRET, 0);
    00553   if (status != 0) {
    00554     lua_pushnil(L);
    00555     lua_pushintegral(L, status);
    00556     lua_pushstring(L, lua_tostring(L1, -1));
    00557     return 3;
    00558   }
    00559   else {
    00560     int i = 0;
    00561     while (!lua_isnone(L1, ++i))
    00562       lua_pushstring(L, lua_tostring(L1, i));
    00563     lua_pop(L1, i-1);
    00564     return i-1;
    00565   }
    00566 }
    00567
    00568
    00569 static int log2_aux (lua_State *L)
    00570         /*@*/
    00571 {
    00572   lua_pushintegral(L, luaO_log2(luaL_checkint(L, 1)));
    00573   return 1;
    00574 }
    00575
    00576 static int int2fb_aux (lua_State *L)
    00577         /*@*/
    00578 {
    00579   int b = luaO_int2fb(luaL_checkint(L, 1));
    00580   lua_pushintegral(L, b);
    00581   lua_pushintegral(L, fb2int(b));
    00582   return 2;
    00583 }
    00584
    00585
    00586 static int test_do (lua_State *L)
    00587         /*@*/
    00588 {
    00589   const char *p = luaL_checkstring(L, 1);
    00590   if (*p == '@')
    00591     lua_dofile(L, p+1);
    00592   else
    00593     lua_dostring(L, p);
    00594   return lua_gettop(L);
    00595 }
    00596
    00597
    00598
    00599 /*
    00600 ** {======================================================
    00601 ** function to test the API with C. It interprets a kind of assembler
    00602 ** language with calls to the API, so the test can be driven by Lua code
    00603 ** =======================================================
    00604 */
    00605
    00606 static const char *const delimits = " \t\n,;";
    00607
    00608 static void skip (const char **pc)
    00609         /*@*/
    00610 {
    00611   while (**pc != '\0' && strchr(delimits, **pc)) (*pc)++;
    00612 }
    00613
    00614 static int getnum_aux (lua_State *L, const char **pc)
    00615         /*@*/
    00616 {
    00617   int res = 0;
    00618   int sig = 1;
    00619   skip(pc);
    00620   if (**pc == '.') {
    00621     res = cast(int, lua_tonumber(L, -1));
    00622     lua_pop(L, 1);
    00623     (*pc)++;
    00624     return res;
    00625   }
    00626   else if (**pc == '-') {
    00627     sig = -1;
    00628     (*pc)++;
    00629   }
    00630   while (isdigit(cast(int, **pc))) res = res*10 + (*(*pc)++) - '0';
    00631   return sig*res;
    00632 }
    00633
    00634 static const char *getname_aux (char *buff, const char **pc)
    00635         /*@*/
    00636 {
    00637   int i = 0;
    00638   skip(pc);
    00639   while (**pc != '\0' && !strchr(delimits, **pc))
    00640     buff[i++] = *(*pc)++;
    00641   buff[i] = '\0';
    00642   return buff;
    00643 }
    00644
    00645
    00646 #define EQ(s1)  (strcmp(s1, inst) == 0)
    00647
    00648 #define getnum  (getnum_aux(L, &pc))
    00649 #define getname (getname_aux(buff, &pc))
    00650
    00651
    00652 static int testC (lua_State *L)
    00653         /*@*/
    00654 {
    00655   char buff[30];
    00656   const char *pc = luaL_checkstring(L, 1);
    00657   for (;;) {
    00658     const char *inst = getname;
    00659     if EQ("") return 0;
    00660     else if EQ("isnumber") {
    00661       lua_pushintegral(L, lua_isnumber(L, getnum));
    00662     }
    00663     else if EQ("isstring") {
    00664       lua_pushintegral(L, lua_isstring(L, getnum));
    00665     }
    00666     else if EQ("istable") {
    00667       lua_pushintegral(L, lua_istable(L, getnum));
    00668     }
    00669     else if EQ("iscfunction") {
    00670       lua_pushintegral(L, lua_iscfunction(L, getnum));
    00671     }
    00672     else if EQ("isfunction") {
    00673       lua_pushintegral(L, lua_isfunction(L, getnum));
    00674     }
    00675     else if EQ("isuserdata") {
    00676       lua_pushintegral(L, lua_isuserdata(L, getnum));
    00677     }
    00678     else if EQ("isudataval") {
    00679       lua_pushintegral(L, lua_islightuserdata(L, getnum));
    00680     }
    00681     else if EQ("isnil") {
    00682       lua_pushintegral(L, lua_isnil(L, getnum));
    00683     }
    00684     else if EQ("isnull") {
    00685       lua_pushintegral(L, lua_isnone(L, getnum));
    00686     }
    00687     else if EQ("tonumber") {
    00688       lua_pushnumber(L, lua_tonumber(L, getnum));
    00689     }
    00690     else if EQ("tostring") {
    00691       const char *s = lua_tostring(L, getnum);
    00692       lua_pushstring(L, s);
    00693     }
    00694     else if EQ("strlen") {
    00695       lua_pushintegral(L, lua_strlen(L, getnum));
    00696     }
    00697     else if EQ("tocfunction") {
    00698       lua_pushcfunction(L, lua_tocfunction(L, getnum));
    00699     }
    00700     else if EQ("return") {
    00701       return getnum;
    00702     }
    00703     else if EQ("gettop") {
    00704       lua_pushintegral(L, lua_gettop(L));
    00705     }
    00706     else if EQ("settop") {
    00707       lua_settop(L, getnum);
    00708     }
    00709     else if EQ("pop") {
    00710       lua_pop(L, getnum);
    00711     }
    00712     else if EQ("pushnum") {
    00713       lua_pushintegral(L, getnum);
    00714     }
    00715     else if EQ("pushnil") {
    00716       lua_pushnil(L);
    00717     }
    00718     else if EQ("pushbool") {
    00719       lua_pushboolean(L, getnum);
    00720     }
    00721     else if EQ("tobool") {
    00722       lua_pushintegral(L, lua_toboolean(L, getnum));
    00723     }
    00724     else if EQ("pushvalue") {
    00725       lua_pushvalue(L, getnum);
    00726     }
    00727     else if EQ("pushcclosure") {
    00728       lua_pushcclosure(L, testC, getnum);
    00729     }
    00730     else if EQ("pushupvalues") {
    00731       lua_pushupvalues(L);
    00732     }
    00733     else if EQ("remove") {
    00734       lua_remove(L, getnum);
    00735     }
    00736     else if EQ("insert") {
    00737       lua_insert(L, getnum);
    00738     }
    00739     else if EQ("replace") {
    00740       lua_replace(L, getnum);
    00741     }
    00742     else if EQ("gettable") {
    00743       lua_gettable(L, getnum);
    00744     }
    00745     else if EQ("settable") {
    00746       lua_settable(L, getnum);
    00747     }
    00748     else if EQ("next") {
    00749       lua_next(L, -2);
    00750     }
    00751     else if EQ("concat") {
    00752       lua_concat(L, getnum);
    00753     }
    00754     else if EQ("lessthan") {
    00755       int a = getnum;
    00756       lua_pushboolean(L, lua_lessthan(L, a, getnum));
    00757     }
    00758     else if EQ("equal") {
    00759       int a = getnum;
    00760       lua_pushboolean(L, lua_equal(L, a, getnum));
    00761     }
    00762     else if EQ("rawcall") {
    00763       int narg = getnum;
    00764       int nres = getnum;
    00765       lua_call(L, narg, nres);
    00766     }
    00767     else if EQ("call") {
    00768       int narg = getnum;
    00769       int nres = getnum;
    00770       lua_pcall(L, narg, nres, 0);
    00771     }
    00772     else if EQ("loadstring") {
    00773       size_t sl;
    00774       const char *s = luaL_checklstring(L, getnum, &sl);
    00775       luaL_loadbuffer(L, s, sl, s);
    00776     }
    00777     else if EQ("loadfile") {
    00778       luaL_loadfile(L, luaL_checkstring(L, getnum));
    00779     }
    00780     else if EQ("setmetatable") {
    00781       lua_setmetatable(L, getnum);
    00782     }
    00783     else if EQ("getmetatable") {
    00784       if (lua_getmetatable(L, getnum) == 0)
    00785         lua_pushnil(L);
    00786     }
    00787     else if EQ("type") {
    00788       lua_pushstring(L, lua_typename(L, lua_type(L, getnum)));
    00789     }
    00790     else if EQ("getn") {
    00791       int i = getnum;
    00792       lua_pushintegral(L, luaL_getn(L, i));
    00793     }
    00794     else if EQ("setn") {
    00795       int i = getnum;
    00796       int n = cast(int, lua_tonumber(L, -1));
    00797       luaL_setn(L, i, n);
    00798       lua_pop(L, 1);
    00799     }
    00800     else luaL_error(L, "unknown instruction %s", buff);
    00801   }
    00802   return 0;
    00803 }
    00804
    00805 /* }====================================================== */
    00806
    00807
    00808 /*
    00809 ** {======================================================
    00810 ** tests for yield inside hooks
    00811 ** =======================================================
    00812 */
    00813
    00814 static void yieldf (lua_State *L, lua_Debug *ar)
    00815         /*@*/
    00816 {
    00817   lua_yield(L, 0);
    00818 }
    00819
    00820 static int setyhook (lua_State *L)
    00821         /*@*/
    00822 {
    00823   if (lua_isnoneornil(L, 1))
    00824     lua_sethook(L, NULL, 0, 0);  /* turn off hooks */
    00825   else {
    00826     const char *smask = luaL_checkstring(L, 1);
    00827     int count = luaL_optint(L, 2, 0);
    00828     int mask = 0;
    00829     if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
    00830     if (count > 0) mask |= LUA_MASKCOUNT;
    00831     lua_sethook(L, yieldf, mask, count);
    00832   }
    00833   return 0;
    00834 }
    00835
    00836
    00837 static int coresume (lua_State *L)
    00838         /*@*/
    00839 {
    00840   int status;
    00841   lua_State *co = lua_tothread(L, 1);
    00842   luaL_argcheck(L, co, 1, "coroutine expected");
    00843   status = lua_resume(co, 0);
    00844   if (status != 0) {
    00845     lua_pushboolean(L, 0);
    00846     lua_insert(L, -2);
    00847     return 2;  /* return false + error message */
    00848   }
    00849   else {
    00850     lua_pushboolean(L, 1);
    00851     return 1;
    00852   }
    00853 }
    00854
    00855 /* }====================================================== */
    00856
    00857
    00858
    00859 static const struct luaL_reg tests_funcs[] = {
    00860   {"hash", hash_query},
    00861   {"limits", get_limits},
    00862   {"listcode", listcode},
    00863   {"listk", listk},
    00864   {"listlocals", listlocals},
    00865   {"loadlib", loadlib},
    00866   {"stacklevel", stacklevel},
    00867   {"querystr", string_query},
    00868   {"querytab", table_query},
    00869   {"doit", test_do},
    00870   {"testC", testC},
    00871   {"ref", tref},
    00872   {"getref", getref},
    00873   {"unref", unref},
    00874   {"d2s", d2s},
    00875   {"s2d", s2d},
    00876   {"metatable", metatable},
    00877   {"upvalue", upvalue},
    00878   {"newuserdata", newuserdata},
    00879   {"pushuserdata", pushuserdata},
    00880   {"udataval", udataval},
    00881   {"doonnewstack", doonnewstack},
    00882   {"newstate", newstate},
    00883   {"closestate", closestate},
    00884   {"doremote", doremote},
    00885   {"log2", log2_aux},
    00886   {"int2fb", int2fb_aux},
    00887   {"totalmem", mem_query},
    00888   {"resume", coresume},
    00889   {"setyhook", setyhook},
    00890   {NULL, NULL}
    00891 };
    00892
    00893
    00894 static void fim (void)
    00895         /*@*/
    00896 {
    00897   if (!islocked)
    00898     lua_close(lua_state);
    00899   lua_assert(memdebug_numblocks == 0);
    00900   lua_assert(memdebug_total == 0);
    00901 }
    00902
    00903
    00904 static int l_panic (lua_State *L)
    00905         /*@*/
    00906 {
    00907   UNUSED(L);
    00908   fprintf(stderr, "unable to recover; exiting\n");
    00909   return 0;
    00910 }
    00911
    00912
    00913 int luaB_opentests (lua_State *L) {
    00914   lua_atpanic(L, l_panic);
    00915   lua_userstateopen(L);  /* init lock */
    00916   lua_state = L;  /* keep first state to be opened */
    00917   luaL_openlib(L, "T", tests_funcs, 0);
    00918   atexit(fim);
    00919   return 0;
    00920 }
    00921
    00922
    00923 #undef main
    00924 int main (int argc, char *argv[]) {
    00925   char *limit = getenv("MEMLIMIT");
    00926   if (limit)
    00927     memdebug_memlimit = strtoul(limit, NULL, 10);
    00928   l_main(argc, argv);
    00929   return 0;
    00930 }
    00931
    00932 #endif