lua/ltests.c

Go to the documentation of this file.
00001 /*
00002 ** $Id: ltests.c,v 1.2 2004/03/23 05:09:14 jbj 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

Generated on Fri Oct 12 08:44:54 2007 for rpm by  doxygen 1.5.2