aboutsummaryrefslogtreecommitdiff
path: root/src/except.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/except.c62
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\*-------------------------------------------------------------------------*/
41static void wrap(lua_State *L) { 37static 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
50static int finalize(lua_State *L) { 45static 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
61static int do_nothing(lua_State *L) { 56static int do_nothing(lua_State *L) {
62 (void) L; 57 (void) L;
63 return 0; 58 return 0;
64} 59}
65 60
66static int global_newtry(lua_State *L) { 61static 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\*-------------------------------------------------------------------------*/
76static int unwrap(lua_State *L) { 73static 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
86static int protected_finish(lua_State *L, int status, lua_KContext ctx) { 86static int protected_finish(lua_State *L, int status, lua_KContext ctx) {
@@ -103,14 +103,17 @@ static int protected_cont(lua_State *L) {
103 103
104static int protected_(lua_State *L) { 104static 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
112static int global_protect(lua_State *L) { 112static 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\*-------------------------------------------------------------------------*/
120int except_open(lua_State *L) { 123int 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}