diff options
author | Philipp Janda <siffiejoe@gmx.net> | 2016-02-21 11:59:44 +0100 |
---|---|---|
committer | Philipp Janda <siffiejoe@gmx.net> | 2016-02-21 11:59:44 +0100 |
commit | d075e7322f0ac1de505b025fd3004b8d4123cc56 (patch) | |
tree | affc3d07fad31a226c0b112f5f989c27ce962a9a | |
parent | bf13ec7fd4fb05666964cf629e9b10591356ff67 (diff) | |
download | luasocket-d075e7322f0ac1de505b025fd3004b8d4123cc56.tar.gz luasocket-d075e7322f0ac1de505b025fd3004b8d4123cc56.tar.bz2 luasocket-d075e7322f0ac1de505b025fd3004b8d4123cc56.zip |
Support table errors.
LuaSocket wraps error messages raised by newtry() in a table and unpacks
them later so that (string) errors raised by 3rd-party code can be
passed through as-is. This obviously didn't work when the 3rd-party code
raised a table as an error message. This change sets a private metatable
on all wrapped LuaSocket exceptions to distinguish them from 3rd-party
table errors.
-rw-r--r-- | src/except.c | 46 |
1 files changed, 27 insertions, 19 deletions
diff --git a/src/except.c b/src/except.c index 261ac98..def35a0 100644 --- a/src/except.c +++ b/src/except.c | |||
@@ -12,7 +12,7 @@ | |||
12 | 12 | ||
13 | #if LUA_VERSION_NUM < 502 | 13 | #if LUA_VERSION_NUM < 502 |
14 | #define lua_pcallk(L, na, nr, err, ctx, cont) \ | 14 | #define lua_pcallk(L, na, nr, err, ctx, cont) \ |
15 | ((void)ctx,(void)cont,lua_pcall(L, na, nr, err)) | 15 | (((void)ctx),((void)cont),lua_pcall(L, na, nr, err)) |
16 | #endif | 16 | #endif |
17 | 17 | ||
18 | #if LUA_VERSION_NUM < 503 | 18 | #if LUA_VERSION_NUM < 503 |
@@ -39,12 +39,11 @@ static luaL_Reg func[] = { | |||
39 | * Try factory | 39 | * Try factory |
40 | \*-------------------------------------------------------------------------*/ | 40 | \*-------------------------------------------------------------------------*/ |
41 | static void wrap(lua_State *L) { | 41 | static void wrap(lua_State *L) { |
42 | lua_newtable(L); | 42 | lua_createtable(L, 1, 0); |
43 | lua_pushnumber(L, 1); | 43 | lua_pushvalue(L, -2); |
44 | lua_pushvalue(L, -3); | 44 | lua_rawseti(L, -2, 1); |
45 | lua_settable(L, -3); | 45 | lua_pushvalue(L, lua_upvalueindex(2)); |
46 | lua_insert(L, -2); | 46 | lua_setmetatable(L, -2); |
47 | lua_pop(L, 1); | ||
48 | } | 47 | } |
49 | 48 | ||
50 | static int finalize(lua_State *L) { | 49 | static int finalize(lua_State *L) { |
@@ -58,15 +57,16 @@ static int finalize(lua_State *L) { | |||
58 | } else return lua_gettop(L); | 57 | } else return lua_gettop(L); |
59 | } | 58 | } |
60 | 59 | ||
61 | static int do_nothing(lua_State *L) { | 60 | static int do_nothing(lua_State *L) { |
62 | (void) L; | 61 | (void) L; |
63 | return 0; | 62 | return 0; |
64 | } | 63 | } |
65 | 64 | ||
66 | static int global_newtry(lua_State *L) { | 65 | static int global_newtry(lua_State *L) { |
67 | lua_settop(L, 1); | 66 | lua_settop(L, 1); |
68 | if (lua_isnil(L, 1)) lua_pushcfunction(L, do_nothing); | 67 | if (lua_isnil(L, 1)) lua_pushcfunction(L, do_nothing); |
69 | lua_pushcclosure(L, finalize, 1); | 68 | lua_pushvalue(L, lua_upvalueindex(1)); |
69 | lua_pushcclosure(L, finalize, 2); | ||
70 | return 1; | 70 | return 1; |
71 | } | 71 | } |
72 | 72 | ||
@@ -74,13 +74,16 @@ static int global_newtry(lua_State *L) { | |||
74 | * Protect factory | 74 | * Protect factory |
75 | \*-------------------------------------------------------------------------*/ | 75 | \*-------------------------------------------------------------------------*/ |
76 | static int unwrap(lua_State *L) { | 76 | static int unwrap(lua_State *L) { |
77 | if (lua_istable(L, -1)) { | 77 | if (lua_istable(L, -1) && lua_getmetatable(L, -1)) { |
78 | lua_pushnumber(L, 1); | 78 | int r = lua_rawequal(L, -1, lua_upvalueindex(2)); |
79 | lua_gettable(L, -2); | 79 | lua_pop(L, 1); |
80 | lua_pushnil(L); | 80 | if (r) { |
81 | lua_insert(L, -2); | 81 | lua_pushnil(L); |
82 | return 1; | 82 | lua_rawgeti(L, -2, 1); |
83 | } else return 0; | 83 | return 1; |
84 | } | ||
85 | } | ||
86 | return 0; | ||
84 | } | 87 | } |
85 | 88 | ||
86 | static int protected_finish(lua_State *L, int status, lua_KContext ctx) { | 89 | static int protected_finish(lua_State *L, int status, lua_KContext ctx) { |
@@ -110,7 +113,9 @@ static int protected_(lua_State *L) { | |||
110 | } | 113 | } |
111 | 114 | ||
112 | static int global_protect(lua_State *L) { | 115 | static int global_protect(lua_State *L) { |
113 | lua_pushcclosure(L, protected_, 1); | 116 | lua_settop(L, 1); |
117 | lua_pushvalue(L, lua_upvalueindex(1)); | ||
118 | lua_pushcclosure(L, protected_, 2); | ||
114 | return 1; | 119 | return 1; |
115 | } | 120 | } |
116 | 121 | ||
@@ -118,6 +123,9 @@ static int global_protect(lua_State *L) { | |||
118 | * Init module | 123 | * Init module |
119 | \*-------------------------------------------------------------------------*/ | 124 | \*-------------------------------------------------------------------------*/ |
120 | int except_open(lua_State *L) { | 125 | int except_open(lua_State *L) { |
121 | luaL_setfuncs(L, func, 0); | 126 | lua_newtable(L); /* metatable for wrapped exceptions */ |
127 | lua_pushboolean(L, 0); | ||
128 | lua_setfield(L, -2, "__metatable"); | ||
129 | luaL_setfuncs(L, func, 1); | ||
122 | return 0; | 130 | return 0; |
123 | } | 131 | } |