diff options
| -rw-r--r-- | ltests.c | 53 |
1 files changed, 52 insertions, 1 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltests.c,v 2.193 2014/11/07 18:07:17 roberto Exp roberto $ | 2 | ** $Id: ltests.c,v 2.194 2014/11/10 14:47:29 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 | */ |
| @@ -11,6 +11,7 @@ | |||
| 11 | 11 | ||
| 12 | 12 | ||
| 13 | #include <limits.h> | 13 | #include <limits.h> |
| 14 | #include <setjmp.h> | ||
| 14 | #include <stdio.h> | 15 | #include <stdio.h> |
| 15 | #include <stdlib.h> | 16 | #include <stdlib.h> |
| 16 | #include <string.h> | 17 | #include <string.h> |
| @@ -48,6 +49,9 @@ int islocked = 0; | |||
| 48 | #define obj_at(L,k) (L->ci->func + (k)) | 49 | #define obj_at(L,k) (L->ci->func + (k)) |
| 49 | 50 | ||
| 50 | 51 | ||
| 52 | static int runC (lua_State *L, lua_State *L1, const char *pc); | ||
| 53 | |||
| 54 | |||
| 51 | static void setnameval (lua_State *L, const char *name, int val) { | 55 | static void setnameval (lua_State *L, const char *name, int val) { |
| 52 | lua_pushstring(L, name); | 56 | lua_pushstring(L, name); |
| 53 | lua_pushinteger(L, val); | 57 | lua_pushinteger(L, val); |
| @@ -902,6 +906,49 @@ static int int2fb_aux (lua_State *L) { | |||
| 902 | } | 906 | } |
| 903 | 907 | ||
| 904 | 908 | ||
| 909 | struct Aux { jmp_buf jb; const char *msg; }; | ||
| 910 | |||
| 911 | /* | ||
| 912 | ** does a long-jump back to "main program". | ||
| 913 | */ | ||
| 914 | static int panicback (lua_State *L) { | ||
| 915 | struct Aux *b; | ||
| 916 | const char *msg = lua_tostring(L, -1); | ||
| 917 | lua_pop(L, 1); | ||
| 918 | lua_getfield(L, LUA_REGISTRYINDEX, "_jmpbuf"); /* get 'Aux' struct */ | ||
| 919 | b = (struct Aux *)lua_touserdata(L, -1); | ||
| 920 | lua_pop(L, 1); /* remove 'Aux' struct */ | ||
| 921 | b->msg = msg; | ||
| 922 | longjmp(b->jb, 1); | ||
| 923 | return 1; /* to avoid warnings */ | ||
| 924 | } | ||
| 925 | |||
| 926 | static int checkpanic (lua_State *L) { | ||
| 927 | struct Aux b; | ||
| 928 | void *ud; | ||
| 929 | const char *code = luaL_checkstring(L, 1); /* create new state */ | ||
| 930 | lua_Alloc f = lua_getallocf(L, &ud); | ||
| 931 | lua_State *L1 = lua_newstate(f, ud); | ||
| 932 | if (L1 == NULL) { /* error? */ | ||
| 933 | lua_pushnil(L); | ||
| 934 | return 1; | ||
| 935 | } | ||
| 936 | lua_atpanic(L1, panicback); /* set its panic function */ | ||
| 937 | lua_pushlightuserdata(L1, &b); | ||
| 938 | lua_setfield(L1, LUA_REGISTRYINDEX, "_jmpbuf"); /* store 'Aux' struct */ | ||
| 939 | if (setjmp(b.jb) == 0) { /* set jump buffer */ | ||
| 940 | runC(L, L1, code); /* run code unprotected */ | ||
| 941 | lua_pushliteral(L, "no errors"); | ||
| 942 | } | ||
| 943 | else { /* error handling */ | ||
| 944 | /* move error message to original state */ | ||
| 945 | lua_pushstring(L, b.msg); | ||
| 946 | } | ||
| 947 | lua_close(L1); | ||
| 948 | return 1; | ||
| 949 | } | ||
| 950 | |||
| 951 | |||
| 905 | 952 | ||
| 906 | /* | 953 | /* |
| 907 | ** {====================================================== | 954 | ** {====================================================== |
| @@ -1256,6 +1303,9 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) { | |||
| 1256 | int i = getindex; | 1303 | int i = getindex; |
| 1257 | lua_pushboolean(L1, luaL_testudata(L1, i, getstring) != NULL); | 1304 | lua_pushboolean(L1, luaL_testudata(L1, i, getstring) != NULL); |
| 1258 | } | 1305 | } |
| 1306 | else if EQ("error") { | ||
| 1307 | lua_error(L1); | ||
| 1308 | } | ||
| 1259 | else if EQ("throw") { | 1309 | else if EQ("throw") { |
| 1260 | #if defined(__cplusplus) | 1310 | #if defined(__cplusplus) |
| 1261 | static struct X { int x; } x; | 1311 | static struct X { int x; } x; |
| @@ -1453,6 +1503,7 @@ static const struct luaL_Reg tests_funcs[] = { | |||
| 1453 | {"listk", listk}, | 1503 | {"listk", listk}, |
| 1454 | {"listlocals", listlocals}, | 1504 | {"listlocals", listlocals}, |
| 1455 | {"loadlib", loadlib}, | 1505 | {"loadlib", loadlib}, |
| 1506 | {"checkpanic", checkpanic}, | ||
| 1456 | {"newstate", newstate}, | 1507 | {"newstate", newstate}, |
| 1457 | {"newuserdata", newuserdata}, | 1508 | {"newuserdata", newuserdata}, |
| 1458 | {"num2int", num2int}, | 1509 | {"num2int", num2int}, |
