diff options
Diffstat (limited to '')
-rw-r--r-- | src/except.c | 62 |
1 files changed, 34 insertions, 28 deletions
diff --git a/src/except.c b/src/except.c index 261ac98..9c3317f 100644 --- a/src/except.c +++ b/src/except.c | |||
@@ -2,17 +2,13 @@ | |||
2 | * Simple exception support | 2 | * Simple exception support |
3 | * LuaSocket toolkit | 3 | * LuaSocket toolkit |
4 | \*=========================================================================*/ | 4 | \*=========================================================================*/ |
5 | #include <stdio.h> | 5 | #include "luasocket.h" |
6 | |||
7 | #include "lua.h" | ||
8 | #include "lauxlib.h" | ||
9 | #include "compat.h" | ||
10 | |||
11 | #include "except.h" | 6 | #include "except.h" |
7 | #include <stdio.h> | ||
12 | 8 | ||
13 | #if LUA_VERSION_NUM < 502 | 9 | #if LUA_VERSION_NUM < 502 |
14 | #define lua_pcallk(L, na, nr, err, ctx, cont) \ | 10 | #define lua_pcallk(L, na, nr, err, ctx, cont) \ |
15 | ((void)ctx,(void)cont,lua_pcall(L, na, nr, err)) | 11 | (((void)ctx),((void)cont),lua_pcall(L, na, nr, err)) |
16 | #endif | 12 | #endif |
17 | 13 | ||
18 | #if LUA_VERSION_NUM < 503 | 14 | #if LUA_VERSION_NUM < 503 |
@@ -39,18 +35,17 @@ static luaL_Reg func[] = { | |||
39 | * Try factory | 35 | * Try factory |
40 | \*-------------------------------------------------------------------------*/ | 36 | \*-------------------------------------------------------------------------*/ |
41 | static void wrap(lua_State *L) { | 37 | static void wrap(lua_State *L) { |
42 | lua_newtable(L); | 38 | lua_createtable(L, 1, 0); |
43 | lua_pushnumber(L, 1); | 39 | lua_pushvalue(L, -2); |
44 | lua_pushvalue(L, -3); | 40 | lua_rawseti(L, -2, 1); |
45 | lua_settable(L, -3); | 41 | lua_pushvalue(L, lua_upvalueindex(1)); |
46 | lua_insert(L, -2); | 42 | lua_setmetatable(L, -2); |
47 | lua_pop(L, 1); | ||
48 | } | 43 | } |
49 | 44 | ||
50 | static int finalize(lua_State *L) { | 45 | static int finalize(lua_State *L) { |
51 | if (!lua_toboolean(L, 1)) { | 46 | if (!lua_toboolean(L, 1)) { |
52 | lua_pushvalue(L, lua_upvalueindex(1)); | 47 | lua_pushvalue(L, lua_upvalueindex(2)); |
53 | lua_pcall(L, 0, 0, 0); | 48 | lua_call(L, 0, 0); |
54 | lua_settop(L, 2); | 49 | lua_settop(L, 2); |
55 | wrap(L); | 50 | wrap(L); |
56 | lua_error(L); | 51 | lua_error(L); |
@@ -58,15 +53,17 @@ static int finalize(lua_State *L) { | |||
58 | } else return lua_gettop(L); | 53 | } else return lua_gettop(L); |
59 | } | 54 | } |
60 | 55 | ||
61 | static int do_nothing(lua_State *L) { | 56 | static int do_nothing(lua_State *L) { |
62 | (void) L; | 57 | (void) L; |
63 | return 0; | 58 | return 0; |
64 | } | 59 | } |
65 | 60 | ||
66 | static int global_newtry(lua_State *L) { | 61 | static int global_newtry(lua_State *L) { |
67 | lua_settop(L, 1); | 62 | lua_settop(L, 1); |
68 | if (lua_isnil(L, 1)) lua_pushcfunction(L, do_nothing); | 63 | if (lua_isnil(L, 1)) lua_pushcfunction(L, do_nothing); |
69 | lua_pushcclosure(L, finalize, 1); | 64 | lua_pushvalue(L, lua_upvalueindex(1)); |
65 | lua_insert(L, -2); | ||
66 | lua_pushcclosure(L, finalize, 2); | ||
70 | return 1; | 67 | return 1; |
71 | } | 68 | } |
72 | 69 | ||
@@ -74,13 +71,16 @@ static int global_newtry(lua_State *L) { | |||
74 | * Protect factory | 71 | * Protect factory |
75 | \*-------------------------------------------------------------------------*/ | 72 | \*-------------------------------------------------------------------------*/ |
76 | static int unwrap(lua_State *L) { | 73 | static int unwrap(lua_State *L) { |
77 | if (lua_istable(L, -1)) { | 74 | if (lua_istable(L, -1) && lua_getmetatable(L, -1)) { |
78 | lua_pushnumber(L, 1); | 75 | int r = lua_rawequal(L, -1, lua_upvalueindex(1)); |
79 | lua_gettable(L, -2); | 76 | lua_pop(L, 1); |
80 | lua_pushnil(L); | 77 | if (r) { |
81 | lua_insert(L, -2); | 78 | lua_pushnil(L); |
82 | return 1; | 79 | lua_rawgeti(L, -2, 1); |
83 | } else return 0; | 80 | return 1; |
81 | } | ||
82 | } | ||
83 | return 0; | ||
84 | } | 84 | } |
85 | 85 | ||
86 | static int protected_finish(lua_State *L, int status, lua_KContext ctx) { | 86 | static int protected_finish(lua_State *L, int status, lua_KContext ctx) { |
@@ -103,14 +103,17 @@ static int protected_cont(lua_State *L) { | |||
103 | 103 | ||
104 | static int protected_(lua_State *L) { | 104 | static int protected_(lua_State *L) { |
105 | int status; | 105 | int status; |
106 | lua_pushvalue(L, lua_upvalueindex(1)); | 106 | lua_pushvalue(L, lua_upvalueindex(2)); |
107 | lua_insert(L, 1); | 107 | lua_insert(L, 1); |
108 | status = lua_pcallk(L, lua_gettop(L) - 1, LUA_MULTRET, 0, 0, protected_cont); | 108 | status = lua_pcallk(L, lua_gettop(L) - 1, LUA_MULTRET, 0, 0, protected_cont); |
109 | return protected_finish(L, status, 0); | 109 | return protected_finish(L, status, 0); |
110 | } | 110 | } |
111 | 111 | ||
112 | static int global_protect(lua_State *L) { | 112 | static int global_protect(lua_State *L) { |
113 | lua_pushcclosure(L, protected_, 1); | 113 | lua_settop(L, 1); |
114 | lua_pushvalue(L, lua_upvalueindex(1)); | ||
115 | lua_insert(L, 1); | ||
116 | lua_pushcclosure(L, protected_, 2); | ||
114 | return 1; | 117 | return 1; |
115 | } | 118 | } |
116 | 119 | ||
@@ -118,6 +121,9 @@ static int global_protect(lua_State *L) { | |||
118 | * Init module | 121 | * Init module |
119 | \*-------------------------------------------------------------------------*/ | 122 | \*-------------------------------------------------------------------------*/ |
120 | int except_open(lua_State *L) { | 123 | int except_open(lua_State *L) { |
121 | luaL_setfuncs(L, func, 0); | 124 | lua_newtable(L); /* metatable for wrapped exceptions */ |
125 | lua_pushboolean(L, 0); | ||
126 | lua_setfield(L, -2, "__metatable"); | ||
127 | luaL_setfuncs(L, func, 1); | ||
122 | return 0; | 128 | return 0; |
123 | } | 129 | } |