ltests.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676
  1. /*
  2. ** $Id: ltests.c,v 1.87 2001/07/05 20:31:14 roberto Exp roberto $
  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 LUA_PRIVATE
  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 "luadebug.h"
  25. #include "lualib.h"
  26. /*
  27. ** The whole module only makes sense with LUA_DEBUG on
  28. */
  29. #ifdef LUA_DEBUG
  30. lua_State *lua_state = NULL;
  31. int islocked = 0;
  32. static void setnameval (lua_State *L, const l_char *name, int val) {
  33. lua_pushstring(L, name);
  34. lua_pushnumber(L, val);
  35. lua_settable(L, -3);
  36. }
  37. /*
  38. ** {======================================================================
  39. ** Controlled version for realloc.
  40. ** =======================================================================
  41. */
  42. /* ensures maximum alignment for HEADER */
  43. #define HEADER (sizeof(union L_Umaxalign))
  44. #define MARKSIZE 32
  45. #define MARK 0x55 /* 01010101 (a nice pattern) */
  46. #define blocksize(b) ((size_t *)((l_char *)(b) - HEADER))
  47. unsigned long memdebug_numblocks = 0;
  48. unsigned long memdebug_total = 0;
  49. unsigned long memdebug_maxmem = 0;
  50. unsigned long memdebug_memlimit = ULONG_MAX;
  51. static void *checkblock (void *block) {
  52. size_t *b = blocksize(block);
  53. size_t size = *b;
  54. int i;
  55. for (i=0;i<MARKSIZE;i++)
  56. lua_assert(*(((l_char *)b)+HEADER+size+i) == MARK+i); /* corrupted block? */
  57. return b;
  58. }
  59. static void freeblock (void *block) {
  60. if (block) {
  61. size_t size = *blocksize(block);
  62. block = checkblock(block);
  63. memset(block, -1, size+HEADER+MARKSIZE); /* erase block */
  64. free(block); /* free original block */
  65. memdebug_numblocks--;
  66. memdebug_total -= size;
  67. }
  68. }
  69. void *debug_realloc (void *block, size_t oldsize, size_t size) {
  70. lua_assert((oldsize == 0) ? block == NULL : oldsize == *blocksize(block));
  71. if (size == 0) {
  72. freeblock(block);
  73. return NULL;
  74. }
  75. else if (memdebug_total+size-oldsize > memdebug_memlimit)
  76. return NULL; /* to test memory allocation errors */
  77. else {
  78. l_char *newblock;
  79. int i;
  80. size_t realsize = HEADER+size+MARKSIZE;
  81. if (realsize < size) return NULL; /* overflow! */
  82. newblock = (l_char *)malloc(realsize); /* alloc a new block */
  83. if (newblock == NULL) return NULL;
  84. if (oldsize > size) oldsize = size;
  85. if (block) {
  86. memcpy(newblock+HEADER, block, oldsize);
  87. freeblock(block); /* erase (and check) old copy */
  88. }
  89. /* initialize new part of the block with something `weird' */
  90. memset(newblock+HEADER+oldsize, -MARK, size-oldsize);
  91. memdebug_total += size;
  92. if (memdebug_total > memdebug_maxmem)
  93. memdebug_maxmem = memdebug_total;
  94. memdebug_numblocks++;
  95. *(size_t *)newblock = size;
  96. for (i=0;i<MARKSIZE;i++)
  97. *(newblock+HEADER+size+i) = (l_char)(MARK+i);
  98. return newblock+HEADER;
  99. }
  100. }
  101. /* }====================================================================== */
  102. /*
  103. ** {======================================================
  104. ** Disassembler
  105. ** =======================================================
  106. */
  107. static l_char *buildop (Proto *p, int pc, l_char *buff) {
  108. Instruction i = p->code[pc];
  109. OpCode o = GET_OPCODE(i);
  110. const l_char *name = luaP_opnames[o];
  111. sprintf(buff, l_s("%4d - "), pc);
  112. switch (getOpMode(o)) {
  113. case iABC:
  114. sprintf(buff+strlen(buff), l_s("%-12s%4d %4d %4d"), name,
  115. GETARG_A(i), GETARG_B(i), GETARG_C(i));
  116. break;
  117. case iABc:
  118. sprintf(buff+strlen(buff), l_s("%-12s%4d %4d"), name, GETARG_A(i), GETARG_Bc(i));
  119. break;
  120. case iAsBc:
  121. sprintf(buff+strlen(buff), l_s("%-12s%4d %4d"), name, GETARG_A(i), GETARG_sBc(i));
  122. break;
  123. }
  124. return buff;
  125. }
  126. static int listcode (lua_State *L) {
  127. int pc;
  128. Proto *p;
  129. luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
  130. 1, l_s("Lua function expected"));
  131. p = clvalue(luaA_index(L, 1))->f.l;
  132. lua_newtable(L);
  133. setnameval(L, l_s("maxstack"), p->maxstacksize);
  134. setnameval(L, l_s("numparams"), p->numparams);
  135. for (pc=0; pc<p->sizecode; pc++) {
  136. l_char buff[100];
  137. lua_pushnumber(L, pc+1);
  138. lua_pushstring(L, buildop(p, pc, buff));
  139. lua_settable(L, -3);
  140. }
  141. return 1;
  142. }
  143. static int listk (lua_State *L) {
  144. Proto *p;
  145. int i;
  146. luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
  147. 1, l_s("Lua function expected"));
  148. p = clvalue(luaA_index(L, 1))->f.l;
  149. lua_newtable(L);
  150. for (i=0; i<p->sizek; i++) {
  151. lua_pushnumber(L, i+1);
  152. luaA_pushobject(L, p->k+i);
  153. lua_settable(L, -3);
  154. }
  155. return 1;
  156. }
  157. static int listlocals (lua_State *L) {
  158. Proto *p;
  159. int pc = luaL_check_int(L, 2) - 1;
  160. int i = 0;
  161. const l_char *name;
  162. luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
  163. 1, l_s("Lua function expected"));
  164. p = clvalue(luaA_index(L, 1))->f.l;
  165. while ((name = luaF_getlocalname(p, ++i, pc)) != NULL)
  166. lua_pushstring(L, name);
  167. return i-1;
  168. }
  169. /* }====================================================== */
  170. static int pushbool (lua_State *L, int b) {
  171. if (b) lua_pushnumber(L, 1);
  172. else lua_pushnil(L);
  173. return 1;
  174. }
  175. static int get_limits (lua_State *L) {
  176. lua_newtable(L);
  177. setnameval(L, l_s("BITS_INT"), BITS_INT);
  178. setnameval(L, l_s("LFPF"), LFIELDS_PER_FLUSH);
  179. setnameval(L, l_s("MAXLOCALS"), MAXLOCALS);
  180. setnameval(L, l_s("MAXPARAMS"), MAXPARAMS);
  181. setnameval(L, l_s("MAXSTACK"), MAXSTACK);
  182. setnameval(L, l_s("MAXUPVALUES"), MAXUPVALUES);
  183. return 1;
  184. }
  185. static int mem_query (lua_State *L) {
  186. if (lua_isnull(L, 1)) {
  187. lua_pushnumber(L, memdebug_total);
  188. lua_pushnumber(L, memdebug_numblocks);
  189. lua_pushnumber(L, memdebug_maxmem);
  190. return 3;
  191. }
  192. else {
  193. memdebug_memlimit = luaL_check_int(L, 1);
  194. return 0;
  195. }
  196. }
  197. static int hash_query (lua_State *L) {
  198. if (lua_isnull(L, 2)) {
  199. luaL_arg_check(L, lua_tag(L, 1) == LUA_TSTRING, 1, l_s("string expected"));
  200. lua_pushnumber(L, tsvalue(luaA_index(L, 1))->tsv.hash);
  201. }
  202. else {
  203. TObject *o = luaA_index(L, 1);
  204. Hash *t;
  205. luaL_checktype(L, 2, LUA_TTABLE);
  206. t = hvalue(luaA_index(L, 2));
  207. lua_pushnumber(L, luaH_mainposition(t, o) - t->node);
  208. }
  209. return 1;
  210. }
  211. static int table_query (lua_State *L) {
  212. const Hash *t;
  213. int i = luaL_opt_int(L, 2, -1);
  214. luaL_checktype(L, 1, LUA_TTABLE);
  215. t = hvalue(luaA_index(L, 1));
  216. if (i == -1) {
  217. lua_pushnumber(L, t->size);
  218. lua_pushnumber(L, t->firstfree - t->node);
  219. return 2;
  220. }
  221. else if (i < t->size) {
  222. if (ttype(val(node(t, i))) != LUA_TNIL ||
  223. ttype(key(node(t, i))) == LUA_TNIL ||
  224. ttype(key(node(t, i))) == LUA_TNUMBER) {
  225. luaA_pushobject(L, key(node(t, i)));
  226. }
  227. else
  228. lua_pushstring(L, "<undef>");
  229. luaA_pushobject(L, &t->node[i].val);
  230. if (t->node[i].next) {
  231. lua_pushnumber(L, t->node[i].next - t->node);
  232. return 3;
  233. }
  234. else
  235. return 2;
  236. }
  237. return 0;
  238. }
  239. static int string_query (lua_State *L) {
  240. stringtable *tb = &G(L)->strt;
  241. int s = luaL_opt_int(L, 2, 0) - 1;
  242. if (s==-1) {
  243. lua_pushnumber(L ,tb->nuse);
  244. lua_pushnumber(L ,tb->size);
  245. return 2;
  246. }
  247. else if (s < tb->size) {
  248. TString *ts;
  249. int n = 0;
  250. for (ts = tb->hash[s]; ts; ts = ts->tsv.nexthash) {
  251. setsvalue(L->top, ts);
  252. incr_top;
  253. n++;
  254. }
  255. return n;
  256. }
  257. return 0;
  258. }
  259. static int tref (lua_State *L) {
  260. int level = lua_gettop(L);
  261. luaL_checkany(L, 1);
  262. lua_pushvalue(L, 1);
  263. lua_pushnumber(L, lua_ref(L, luaL_opt_int(L, 2, 1)));
  264. assert(lua_gettop(L) == level+1); /* +1 for result */
  265. return 1;
  266. }
  267. static int getref (lua_State *L) {
  268. int level = lua_gettop(L);
  269. if (lua_getref(L, luaL_check_int(L, 1))) {
  270. assert(lua_gettop(L) == level+1);
  271. return 1;
  272. }
  273. else {
  274. assert(lua_gettop(L) == level);
  275. return 0;
  276. }
  277. }
  278. static int unref (lua_State *L) {
  279. int level = lua_gettop(L);
  280. lua_unref(L, luaL_check_int(L, 1));
  281. assert(lua_gettop(L) == level);
  282. return 0;
  283. }
  284. static int newuserdata (lua_State *L) {
  285. size_t size = luaL_check_int(L, 1);
  286. l_char *p = (l_char *)lua_newuserdata(L, size);
  287. while (size--) *p++ = l_c('\0');
  288. return 1;
  289. }
  290. static int newuserdatabox (lua_State *L) {
  291. lua_newuserdatabox(L, (void *)luaL_check_int(L, 1));
  292. return 1;
  293. }
  294. static int settag (lua_State *L) {
  295. luaL_checkany(L, 1);
  296. lua_pushvalue(L, 1); /* push value */
  297. lua_settag(L, luaL_check_int(L, 2));
  298. return 1; /* return value */
  299. }
  300. static int udataval (lua_State *L) {
  301. luaL_checktype(L, 1, LUA_TUSERDATA);
  302. lua_pushnumber(L, (int)lua_touserdata(L, 1));
  303. return 1;
  304. }
  305. static int newtag (lua_State *L) {
  306. lua_pushnumber(L, lua_newtype(L, lua_tostring(L, 1),
  307. (int)lua_tonumber(L, 2)));
  308. return 1;
  309. }
  310. static int doonnewstack (lua_State *L) {
  311. lua_State *L1 = lua_newthread(L, luaL_check_int(L, 1));
  312. if (L1 == NULL) return 0;
  313. *((int **)L1) = &islocked; /* initialize the lock */
  314. lua_dostring(L1, luaL_check_string(L, 2));
  315. lua_pushnumber(L, 1);
  316. lua_close(L1);
  317. return 1;
  318. }
  319. static int s2d (lua_State *L) {
  320. lua_pushnumber(L, *(double *)luaL_check_string(L, 1));
  321. return 1;
  322. }
  323. static int d2s (lua_State *L) {
  324. double d = luaL_check_number(L, 1);
  325. lua_pushlstring(L, (l_char *)&d, sizeof(d));
  326. return 1;
  327. }
  328. static int newstate (lua_State *L) {
  329. lua_State *L1 = lua_open(luaL_check_int(L, 1));
  330. if (L1) {
  331. *((int **)L1) = &islocked; /* initialize the lock */
  332. lua_pushnumber(L, (unsigned long)L1);
  333. }
  334. else
  335. lua_pushnil(L);
  336. return 1;
  337. }
  338. static int loadlib (lua_State *L) {
  339. lua_State *L1 = (lua_State *)(unsigned long)luaL_check_number(L, 1);
  340. lua_register(L1, "mathlibopen", lua_mathlibopen);
  341. lua_register(L1, "strlibopen", lua_strlibopen);
  342. lua_register(L1, "iolibopen", lua_iolibopen);
  343. lua_register(L1, "dblibopen", lua_dblibopen);
  344. lua_register(L1, "baselibopen", lua_baselibopen);
  345. return 0;
  346. }
  347. static int closestate (lua_State *L) {
  348. lua_State *L1 = (lua_State *)(unsigned long)luaL_check_number(L, 1);
  349. lua_close(L1);
  350. lua_unlock(L); /* close cannot unlock that */
  351. return 0;
  352. }
  353. static int doremote (lua_State *L) {
  354. lua_State *L1;
  355. const l_char *code = luaL_check_string(L, 2);
  356. int status;
  357. L1 = (lua_State *)(unsigned long)luaL_check_number(L, 1);
  358. status = lua_dostring(L1, code);
  359. if (status != 0) {
  360. lua_pushnil(L);
  361. lua_pushnumber(L, status);
  362. return 2;
  363. }
  364. else {
  365. int i = 0;
  366. while (!lua_isnull(L1, ++i))
  367. lua_pushstring(L, lua_tostring(L1, i));
  368. lua_pop(L1, i-1);
  369. return i-1;
  370. }
  371. }
  372. static int settagmethod (lua_State *L) {
  373. int tag = luaL_check_int(L, 1);
  374. const l_char *event = luaL_check_string(L, 2);
  375. luaL_checkany(L, 3);
  376. lua_gettagmethod(L, tag, event);
  377. lua_pushvalue(L, 3);
  378. lua_settagmethod(L, tag, event);
  379. return 1;
  380. }
  381. static int equal (lua_State *L) {
  382. return pushbool(L, lua_equal(L, 1, 2));
  383. }
  384. /*
  385. ** {======================================================
  386. ** function to test the API with C. It interprets a kind of assembler
  387. ** language with calls to the API, so the test can be driven by Lua code
  388. ** =======================================================
  389. */
  390. static const l_char *const delimits = l_s(" \t\n,;");
  391. static void skip (const l_char **pc) {
  392. while (**pc != l_c('\0') && strchr(delimits, **pc)) (*pc)++;
  393. }
  394. static int getnum (lua_State *L, const l_char **pc) {
  395. int res = 0;
  396. int sig = 1;
  397. skip(pc);
  398. if (**pc == l_c('.')) {
  399. res = (int)lua_tonumber(L, -1);
  400. lua_pop(L, 1);
  401. (*pc)++;
  402. return res;
  403. }
  404. else if (**pc == l_c('-')) {
  405. sig = -1;
  406. (*pc)++;
  407. }
  408. while (isdigit(**pc)) res = res*10 + (*(*pc)++) - l_c('0');
  409. return sig*res;
  410. }
  411. static const l_char *getname (l_char *buff, const l_char **pc) {
  412. int i = 0;
  413. skip(pc);
  414. while (**pc != l_c('\0') && !strchr(delimits, **pc))
  415. buff[i++] = *(*pc)++;
  416. buff[i] = l_c('\0');
  417. return buff;
  418. }
  419. #define EQ(s1) (strcmp(s1, inst) == 0)
  420. #define getnum ((getnum)(L, &pc))
  421. #define getname ((getname)(buff, &pc))
  422. static int testC (lua_State *L) {
  423. l_char buff[30];
  424. const l_char *pc = luaL_check_string(L, 1);
  425. for (;;) {
  426. const l_char *inst = getname;
  427. if EQ(l_s("")) return 0;
  428. else if EQ(l_s("isnumber")) {
  429. lua_pushnumber(L, lua_isnumber(L, getnum));
  430. }
  431. else if EQ(l_s("isstring")) {
  432. lua_pushnumber(L, lua_isstring(L, getnum));
  433. }
  434. else if EQ(l_s("istable")) {
  435. lua_pushnumber(L, lua_istable(L, getnum));
  436. }
  437. else if EQ(l_s("iscfunction")) {
  438. lua_pushnumber(L, lua_iscfunction(L, getnum));
  439. }
  440. else if EQ(l_s("isfunction")) {
  441. lua_pushnumber(L, lua_isfunction(L, getnum));
  442. }
  443. else if EQ(l_s("isuserdata")) {
  444. lua_pushnumber(L, lua_isuserdata(L, getnum));
  445. }
  446. else if EQ(l_s("isnil")) {
  447. lua_pushnumber(L, lua_isnil(L, getnum));
  448. }
  449. else if EQ(l_s("isnull")) {
  450. lua_pushnumber(L, lua_isnull(L, getnum));
  451. }
  452. else if EQ(l_s("tonumber")) {
  453. lua_pushnumber(L, lua_tonumber(L, getnum));
  454. }
  455. else if EQ(l_s("tostring")) {
  456. const l_char *s = lua_tostring(L, getnum);
  457. lua_pushstring(L, s);
  458. }
  459. else if EQ(l_s("tonumber")) {
  460. lua_pushnumber(L, lua_tonumber(L, getnum));
  461. }
  462. else if EQ(l_s("strlen")) {
  463. lua_pushnumber(L, lua_strlen(L, getnum));
  464. }
  465. else if EQ(l_s("tocfunction")) {
  466. lua_pushcfunction(L, lua_tocfunction(L, getnum));
  467. }
  468. else if EQ(l_s("return")) {
  469. return getnum;
  470. }
  471. else if EQ(l_s("gettop")) {
  472. lua_pushnumber(L, lua_gettop(L));
  473. }
  474. else if EQ(l_s("settop")) {
  475. lua_settop(L, getnum);
  476. }
  477. else if EQ(l_s("pop")) {
  478. lua_pop(L, getnum);
  479. }
  480. else if EQ(l_s("pushnum")) {
  481. lua_pushnumber(L, getnum);
  482. }
  483. else if EQ(l_s("pushvalue")) {
  484. lua_pushvalue(L, getnum);
  485. }
  486. else if EQ(l_s("remove")) {
  487. lua_remove(L, getnum);
  488. }
  489. else if EQ(l_s("insert")) {
  490. lua_insert(L, getnum);
  491. }
  492. else if EQ(l_s("gettable")) {
  493. lua_gettable(L, getnum);
  494. }
  495. else if EQ(l_s("settable")) {
  496. lua_settable(L, getnum);
  497. }
  498. else if EQ(l_s("next")) {
  499. lua_next(L, -2);
  500. }
  501. else if EQ(l_s("concat")) {
  502. lua_concat(L, getnum);
  503. }
  504. else if EQ(l_s("lessthan")) {
  505. int a = getnum;
  506. if (lua_lessthan(L, a, getnum))
  507. lua_pushnumber(L, 1);
  508. else
  509. lua_pushnil(L);
  510. }
  511. else if EQ(l_s("rawcall")) {
  512. int narg = getnum;
  513. int nres = getnum;
  514. lua_rawcall(L, narg, nres);
  515. }
  516. else if EQ(l_s("call")) {
  517. int narg = getnum;
  518. int nres = getnum;
  519. lua_call(L, narg, nres);
  520. }
  521. else if EQ(l_s("dostring")) {
  522. lua_dostring(L, luaL_check_string(L, getnum));
  523. }
  524. else if EQ(l_s("settagmethod")) {
  525. int tag = getnum;
  526. const l_char *event = getname;
  527. lua_settagmethod(L, tag, event);
  528. }
  529. else if EQ(l_s("gettagmethod")) {
  530. int tag = getnum;
  531. const l_char *event = getname;
  532. lua_gettagmethod(L, tag, event);
  533. }
  534. else if EQ(l_s("type")) {
  535. lua_pushstring(L, lua_type(L, getnum));
  536. }
  537. else luaL_verror(L, l_s("unknown instruction %.30s"), buff);
  538. }
  539. return 0;
  540. }
  541. /* }====================================================== */
  542. static const struct luaL_reg tests_funcs[] = {
  543. {l_s("hash"), hash_query},
  544. {l_s("limits"), get_limits},
  545. {l_s("listcode"), listcode},
  546. {l_s("listk"), listk},
  547. {l_s("listlocals"), listlocals},
  548. {l_s("loadlib"), loadlib},
  549. {l_s("querystr"), string_query},
  550. {l_s("querytab"), table_query},
  551. {l_s("testC"), testC},
  552. {l_s("ref"), tref},
  553. {l_s("getref"), getref},
  554. {l_s("unref"), unref},
  555. {l_s("d2s"), d2s},
  556. {l_s("s2d"), s2d},
  557. {l_s("newuserdata"), newuserdata},
  558. {l_s("newuserdatabox"), newuserdatabox},
  559. {l_s("settag"), settag},
  560. {l_s("udataval"), udataval},
  561. {l_s("newtag"), newtag},
  562. {l_s("doonnewstack"), doonnewstack},
  563. {l_s("newstate"), newstate},
  564. {l_s("closestate"), closestate},
  565. {l_s("doremote"), doremote},
  566. {l_s("settagmethod"), settagmethod},
  567. {l_s("equal"), equal},
  568. {l_s("totalmem"), mem_query}
  569. };
  570. void luaB_opentests (lua_State *L) {
  571. *((int **)L) = &islocked; /* init lock */
  572. lua_state = L; /* keep first state to be opened */
  573. /* open lib in a new table */
  574. lua_newtable(L);
  575. lua_getglobals(L);
  576. lua_pushvalue(L, -2);
  577. lua_setglobals(L);
  578. luaL_openl(L, tests_funcs); /* open functions inside new table */
  579. lua_setglobals(L); /* restore old table of globals */
  580. lua_setglobal(L, l_s("T")); /* set new table as global T */
  581. }
  582. #endif