diff options
Diffstat (limited to '')
| -rw-r--r-- | ltests.c | 152 |
1 files changed, 144 insertions, 8 deletions
| @@ -1,11 +1,12 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltests.c,v 1.9 2000/03/10 18:37:44 roberto Exp roberto $ | 2 | ** $Id: ltests.c,v 1.10 2000/03/16 20:35:07 roberto Exp roberto $ |
| 3 | ** Internal Module for Debugging of the Lua Implementation | 3 | ** Internal Module for Debugging of the Lua Implementation |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | 7 | ||
| 8 | #include <ctype.h> | 8 | #include <ctype.h> |
| 9 | #include <stdio.h> | ||
| 9 | #include <stdlib.h> | 10 | #include <stdlib.h> |
| 10 | #include <string.h> | 11 | #include <string.h> |
| 11 | 12 | ||
| @@ -14,6 +15,7 @@ | |||
| 14 | #include "lapi.h" | 15 | #include "lapi.h" |
| 15 | #include "lauxlib.h" | 16 | #include "lauxlib.h" |
| 16 | #include "lmem.h" | 17 | #include "lmem.h" |
| 18 | #include "lopcodes.h" | ||
| 17 | #include "lstate.h" | 19 | #include "lstate.h" |
| 18 | #include "lstring.h" | 20 | #include "lstring.h" |
| 19 | #include "ltable.h" | 21 | #include "ltable.h" |
| @@ -30,6 +32,131 @@ void luaB_opentests (lua_State *L); | |||
| 30 | #ifdef DEBUG | 32 | #ifdef DEBUG |
| 31 | 33 | ||
| 32 | 34 | ||
| 35 | |||
| 36 | static void setnameval (lua_State *L, lua_Object t, const char *name, int val) { | ||
| 37 | lua_pushobject(L, t); | ||
| 38 | lua_pushstring(L, name); | ||
| 39 | lua_pushnumber(L, val); | ||
| 40 | lua_settable(L); | ||
| 41 | } | ||
| 42 | |||
| 43 | |||
| 44 | /* | ||
| 45 | ** {====================================================== | ||
| 46 | ** Disassembler | ||
| 47 | ** ======================================================= | ||
| 48 | */ | ||
| 49 | |||
| 50 | |||
| 51 | #define O(o) sprintf(buff, "%s", o) | ||
| 52 | #define U(o) sprintf(buff, "%-12s%4u", o, GETARG_U(i)) | ||
| 53 | #define S(o) sprintf(buff, "%-12s%4d", o, GETARG_S(i)) | ||
| 54 | #define AB(o) sprintf(buff, "%-12s%4d %4d", o, GETARG_A(i), GETARG_B(i)) | ||
| 55 | #define sAB(o) sprintf(buff, "%-12s%4d %4d", o, GETARG_sA(i), GETARG_B(i)) | ||
| 56 | |||
| 57 | |||
| 58 | |||
| 59 | static int printop (lua_State *L, Instruction i) { | ||
| 60 | char buff[100]; | ||
| 61 | switch (GET_OPCODE(i)) { | ||
| 62 | case OP_END: O("END"); lua_pushstring(L, buff); return 0; | ||
| 63 | case OP_RETURN: U("RETURN"); break; | ||
| 64 | case OP_CALL: AB("CALL"); break; | ||
| 65 | case OP_TAILCALL: AB("TAILCALL"); break; | ||
| 66 | case OP_PUSHNIL: U("PUSHNIL"); break; | ||
| 67 | case OP_POP: U("POP"); break; | ||
| 68 | case OP_PUSHINT: S("PUSHINT"); break; | ||
| 69 | case OP_PUSHSTRING: U("PUSHSTRING"); break; | ||
| 70 | case OP_PUSHNUM: U("PUSHNUM"); break; | ||
| 71 | case OP_PUSHNEGNUM: U("PUSHNEGNUM"); break; | ||
| 72 | case OP_PUSHUPVALUE: U("PUSHUPVALUE"); break; | ||
| 73 | case OP_PUSHLOCAL: U("PUSHLOCAL"); break; | ||
| 74 | case OP_GETGLOBAL: U("GETGLOBAL"); break; | ||
| 75 | case OP_GETTABLE: O("GETTABLE"); break; | ||
| 76 | case OP_GETDOTTED: U("GETDOTTED"); break; | ||
| 77 | case OP_PUSHSELF: U("PUSHSELF"); break; | ||
| 78 | case OP_CREATETABLE: U("CREATETABLE"); break; | ||
| 79 | case OP_SETLOCAL: U("SETLOCAL"); break; | ||
| 80 | case OP_SETGLOBAL: U("SETGLOBAL"); break; | ||
| 81 | case OP_SETTABLEPOP: O("SETTABLEPOP"); break; | ||
| 82 | case OP_SETTABLE: U("SETTABLE"); break; | ||
| 83 | case OP_SETLIST: AB("SETLIST"); break; | ||
| 84 | case OP_SETMAP: U("SETMAP"); break; | ||
| 85 | case OP_ADD: O("ADD"); break; | ||
| 86 | case OP_INCLOCAL: sAB("INCLOCAL"); break; | ||
| 87 | case OP_ADDI: S("ADDI"); break; | ||
| 88 | case OP_SUB: O("SUB"); break; | ||
| 89 | case OP_MULT: O("MULT"); break; | ||
| 90 | case OP_DIV: O("DIV"); break; | ||
| 91 | case OP_POW: O("POW"); break; | ||
| 92 | case OP_CONC: U("CONC"); break; | ||
| 93 | case OP_MINUS: O("MINUS"); break; | ||
| 94 | case OP_NOT: O("NOT"); break; | ||
| 95 | case OP_JMPNEQ: S("JMPNEQ"); break; | ||
| 96 | case OP_JMPEQ: S("JMPEQ"); break; | ||
| 97 | case OP_JMPLT: S("JMPLT"); break; | ||
| 98 | case OP_JMPLE: S("JMPLE"); break; | ||
| 99 | case OP_JMPGT: S("JMPGT"); break; | ||
| 100 | case OP_JMPGE: S("JMPGE"); break; | ||
| 101 | case OP_JMPONT: S("JMPONT"); break; | ||
| 102 | case OP_JMPONF: S("JMPONF"); break; | ||
| 103 | case OP_JMP: S("JMP"); break; | ||
| 104 | case OP_PUSHNILJMP: O("PUSHNILJMP"); break; | ||
| 105 | case OP_JMPT: S("JMPT"); break; | ||
| 106 | case OP_JMPF: S("JMPF"); break; | ||
| 107 | case OP_CLOSURE: AB("CLOSURE"); break; | ||
| 108 | case OP_SETLINE: U("SETLINE"); break; | ||
| 109 | } | ||
| 110 | lua_pushstring(L, buff); | ||
| 111 | return 1; | ||
| 112 | } | ||
| 113 | |||
| 114 | static void printcode (lua_State *L) { | ||
| 115 | lua_Object o = luaL_nonnullarg(L, 1); | ||
| 116 | lua_Object t = lua_createtable(L); | ||
| 117 | Instruction *pc; | ||
| 118 | Proto *p; | ||
| 119 | int res; | ||
| 120 | luaL_arg_check(L, ttype(o) == TAG_LCLOSURE, 1, "Lua function expected"); | ||
| 121 | p = clvalue(o)->f.l; | ||
| 122 | setnameval(L, t, "maxstack", p->maxstacksize); | ||
| 123 | setnameval(L, t, "numparams", p->numparams); | ||
| 124 | pc = p->code; | ||
| 125 | do { | ||
| 126 | lua_pushobject(L, t); | ||
| 127 | lua_pushnumber(L, pc - p->code + 1); | ||
| 128 | res = printop(L, *pc++); | ||
| 129 | lua_settable(L); | ||
| 130 | } while (res); | ||
| 131 | lua_pushobject(L, t); | ||
| 132 | } | ||
| 133 | |||
| 134 | /* }====================================================== */ | ||
| 135 | |||
| 136 | |||
| 137 | |||
| 138 | static void get_limits (lua_State *L) { | ||
| 139 | lua_Object t = lua_createtable(L); | ||
| 140 | setnameval(L, t, "SIZE_OP", SIZE_OP); | ||
| 141 | setnameval(L, t, "SIZE_U", SIZE_U); | ||
| 142 | setnameval(L, t, "SIZE_A", SIZE_A); | ||
| 143 | setnameval(L, t, "SIZE_B", SIZE_B); | ||
| 144 | setnameval(L, t, "MAXARG_U", MAXARG_U); | ||
| 145 | setnameval(L, t, "MAXARG_S", MAXARG_S); | ||
| 146 | setnameval(L, t, "MAXARG_A", MAXARG_A); | ||
| 147 | setnameval(L, t, "MAXARG_B", MAXARG_B); | ||
| 148 | setnameval(L, t, "MAXARG_sA", MAXARG_sA); | ||
| 149 | setnameval(L, t, "MAXSTACK", MAXSTACK); | ||
| 150 | setnameval(L, t, "MAXLOCALS", MAXLOCALS); | ||
| 151 | setnameval(L, t, "MAXUPVALUES", MAXUPVALUES); | ||
| 152 | setnameval(L, t, "MAXVARSLH", MAXVARSLH); | ||
| 153 | setnameval(L, t, "MAXPARAMS", MAXPARAMS); | ||
| 154 | setnameval(L, t, "LFPF", LFIELDS_PER_FLUSH); | ||
| 155 | setnameval(L, t, "RFPF", RFIELDS_PER_FLUSH); | ||
| 156 | lua_pushobject(L, t); | ||
| 157 | } | ||
| 158 | |||
| 159 | |||
| 33 | static void mem_query (lua_State *L) { | 160 | static void mem_query (lua_State *L) { |
| 34 | lua_pushnumber(L, memdebug_total); | 161 | lua_pushnumber(L, memdebug_total); |
| 35 | lua_pushnumber(L, memdebug_numblocks); | 162 | lua_pushnumber(L, memdebug_numblocks); |
| @@ -66,7 +193,7 @@ static void table_query (lua_State *L) { | |||
| 66 | } | 193 | } |
| 67 | 194 | ||
| 68 | 195 | ||
| 69 | static void query_strings (lua_State *L) { | 196 | static void string_query (lua_State *L) { |
| 70 | int h = luaL_check_int(L, 1) - 1; | 197 | int h = luaL_check_int(L, 1) - 1; |
| 71 | int s = luaL_opt_int(L, 2, 0) - 1; | 198 | int s = luaL_opt_int(L, 2, 0) - 1; |
| 72 | if (s==-1) { | 199 | if (s==-1) { |
| @@ -85,7 +212,14 @@ static void query_strings (lua_State *L) { | |||
| 85 | } | 212 | } |
| 86 | 213 | ||
| 87 | 214 | ||
| 88 | static const char *delimits = " \t\n,;"; | 215 | /* |
| 216 | ** {====================================================== | ||
| 217 | ** function to test the API with C. It interprets a kind of "assembler" | ||
| 218 | ** language with calls to the API, so the test can be driven by Lua code | ||
| 219 | ** ======================================================= | ||
| 220 | */ | ||
| 221 | |||
| 222 | static const char *const delimits = " \t\n,;"; | ||
| 89 | 223 | ||
| 90 | static void skip (const char **pc) { | 224 | static void skip (const char **pc) { |
| 91 | while (**pc != '\0' && strchr(delimits, **pc)) (*pc)++; | 225 | while (**pc != '\0' && strchr(delimits, **pc)) (*pc)++; |
| @@ -117,10 +251,7 @@ static const char *getname (const char **pc) { | |||
| 117 | 251 | ||
| 118 | #define EQ(s1) (strcmp(s1, inst) == 0) | 252 | #define EQ(s1) (strcmp(s1, inst) == 0) |
| 119 | 253 | ||
| 120 | /* | 254 | |
| 121 | ** function to test the API with C. It interprets a kind of "assembler" | ||
| 122 | ** language with calls to the API, so the test can be driven by Lua code | ||
| 123 | */ | ||
| 124 | static void testC (lua_State *L) { | 255 | static void testC (lua_State *L) { |
| 125 | lua_Object reg[10]; | 256 | lua_Object reg[10]; |
| 126 | const char *pc = luaL_check_string(L, 1); | 257 | const char *pc = luaL_check_string(L, 1); |
| @@ -265,10 +396,15 @@ static void testC (lua_State *L) { | |||
| 265 | } | 396 | } |
| 266 | } | 397 | } |
| 267 | 398 | ||
| 399 | /* }====================================================== */ | ||
| 400 | |||
| 401 | |||
| 268 | 402 | ||
| 269 | static const struct luaL_reg tests_funcs[] = { | 403 | static const struct luaL_reg tests_funcs[] = { |
| 270 | {"hash", hash_query}, | 404 | {"hash", hash_query}, |
| 271 | {"querystr", query_strings}, | 405 | {"limits", get_limits}, |
| 406 | {"printcode", printcode}, | ||
| 407 | {"querystr", string_query}, | ||
| 272 | {"querytab", table_query}, | 408 | {"querytab", table_query}, |
| 273 | {"testC", testC}, | 409 | {"testC", testC}, |
| 274 | {"totalmem", mem_query} | 410 | {"totalmem", mem_query} |
