rpm
4.5
|
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