diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-11-05 14:48:31 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-11-05 14:48:31 -0200 |
commit | 5598b2bc558ba0c755068f21e786d3a6d59eb1ca (patch) | |
tree | 497a5239cfeda247eab7bf9c1140184570856089 | |
parent | 77077b39d59aa50bd64c7b7c5e660c6e187d11f2 (diff) | |
download | lua-5598b2bc558ba0c755068f21e786d3a6d59eb1ca.tar.gz lua-5598b2bc558ba0c755068f21e786d3a6d59eb1ca.tar.bz2 lua-5598b2bc558ba0c755068f21e786d3a6d59eb1ca.zip |
new functions to identify and join upvalues
-rw-r--r-- | lapi.c | 46 | ||||
-rw-r--r-- | ldblib.c | 35 | ||||
-rw-r--r-- | lua.h | 6 |
3 files changed, 84 insertions, 3 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lapi.c,v 2.93 2009/10/05 16:44:33 roberto Exp roberto $ | 2 | ** $Id: lapi.c,v 2.94 2009/10/23 19:12:19 roberto Exp roberto $ |
3 | ** Lua API | 3 | ** Lua API |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -1088,6 +1088,50 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { | |||
1088 | } | 1088 | } |
1089 | 1089 | ||
1090 | 1090 | ||
1091 | static UpVal **getupvalref (lua_State *L, int fidx, int n, Closure **pf) { | ||
1092 | Closure *f; | ||
1093 | Proto *p; | ||
1094 | StkId fi = index2addr(L, fidx); | ||
1095 | if (!ttisfunction(fi)) return NULL; /* not a function? */ | ||
1096 | f = clvalue(fi); | ||
1097 | if (f->c.isC) return NULL; /* not a Lua function? */ | ||
1098 | p = f->l.p; | ||
1099 | if (!(1 <= n && n <= p->sizeupvalues)) return NULL; | ||
1100 | else { | ||
1101 | if (pf) *pf = f; | ||
1102 | return &f->l.upvals[n - 1]; /* get its upvalue pointer */ | ||
1103 | } | ||
1104 | } | ||
1105 | |||
1106 | |||
1107 | LUA_API void *(lua_upvaladdr) (lua_State *L, int fidx, int n) { | ||
1108 | Closure *f; | ||
1109 | StkId fi = index2addr(L, fidx); | ||
1110 | if (!ttisfunction(fi)) return NULL; | ||
1111 | f = clvalue(fi); | ||
1112 | if (f->c.isC) { | ||
1113 | if (!(1 <= n && n <= f->c.nupvalues)) return NULL; | ||
1114 | else return &f->c.upvalue[n - 1]; | ||
1115 | } | ||
1116 | else { | ||
1117 | UpVal **uv = getupvalref(L, fidx, n, NULL); | ||
1118 | return (uv == NULL) ? NULL : *uv; | ||
1119 | } | ||
1120 | } | ||
1121 | |||
1122 | |||
1123 | LUA_API int (lua_upvaljoin) (lua_State *L, int fidx1, int n1, | ||
1124 | int fidx2, int n2) { | ||
1125 | Closure *f1; | ||
1126 | UpVal **up1 = getupvalref(L, fidx1, n1, &f1); | ||
1127 | UpVal **up2 = getupvalref(L, fidx2, n2, NULL); | ||
1128 | if (up1 == NULL || up2 == NULL) return 0; | ||
1129 | *up1 = *up2; | ||
1130 | luaC_objbarrier(L, f1, *up2); | ||
1131 | return 1; | ||
1132 | } | ||
1133 | |||
1134 | |||
1091 | LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) { | 1135 | LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) { |
1092 | lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_CPCALL); | 1136 | lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_CPCALL); |
1093 | lua_pushlightuserdata(L, &func); | 1137 | lua_pushlightuserdata(L, &func); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldblib.c,v 1.111 2009/08/04 18:27:57 roberto Exp roberto $ | 2 | ** $Id: ldblib.c,v 1.112 2009/09/09 20:32:19 roberto Exp roberto $ |
3 | ** Interface from Lua to its debug API | 3 | ** Interface from Lua to its debug API |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -199,6 +199,37 @@ static int db_setupvalue (lua_State *L) { | |||
199 | } | 199 | } |
200 | 200 | ||
201 | 201 | ||
202 | static int db_upvaladdr (lua_State *L) { | ||
203 | void *addr; | ||
204 | int n = luaL_checkint(L, 2); | ||
205 | luaL_checktype(L, 1, LUA_TFUNCTION); | ||
206 | addr = lua_upvaladdr(L, 1, n); | ||
207 | if (addr == NULL) lua_pushnil(L); | ||
208 | else lua_pushlightuserdata(L, addr); | ||
209 | return 1; | ||
210 | } | ||
211 | |||
212 | |||
213 | static int checkupval (lua_State *L, int argf, int argnup) { | ||
214 | lua_Debug ar; | ||
215 | int nup = luaL_checkint(L, argnup); | ||
216 | luaL_checktype(L, argf, LUA_TFUNCTION); | ||
217 | luaL_argcheck(L, !lua_iscfunction(L, argf), argf, | ||
218 | "cannot join upvalues of a C function"); | ||
219 | lua_pushvalue(L, argf); | ||
220 | lua_getinfo(L, ">u", &ar); | ||
221 | luaL_argcheck(L, 1 <= nup && nup <= ar.nups, argnup, "invalid upvalue index"); | ||
222 | return nup; | ||
223 | } | ||
224 | |||
225 | |||
226 | static int db_joinupval (lua_State *L) { | ||
227 | int n1 = checkupval(L, 1, 2); | ||
228 | int n2 = checkupval(L, 3, 4); | ||
229 | lua_upvaljoin(L, 1, n1, 3, n2); | ||
230 | return 0; | ||
231 | } | ||
232 | |||
202 | 233 | ||
203 | static const char KEY_HOOK = 'h'; | 234 | static const char KEY_HOOK = 'h'; |
204 | 235 | ||
@@ -338,6 +369,8 @@ static const luaL_Reg dblib[] = { | |||
338 | {"getregistry", db_getregistry}, | 369 | {"getregistry", db_getregistry}, |
339 | {"getmetatable", db_getmetatable}, | 370 | {"getmetatable", db_getmetatable}, |
340 | {"getupvalue", db_getupvalue}, | 371 | {"getupvalue", db_getupvalue}, |
372 | {"joinupval", db_joinupval}, | ||
373 | {"upvaladdr", db_upvaladdr}, | ||
341 | {"setfenv", db_setfenv}, | 374 | {"setfenv", db_setfenv}, |
342 | {"sethook", db_sethook}, | 375 | {"sethook", db_sethook}, |
343 | {"setlocal", db_setlocal}, | 376 | {"setlocal", db_setlocal}, |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lua.h,v 1.245 2009/10/05 16:44:33 roberto Exp roberto $ | 2 | ** $Id: lua.h,v 1.246 2009/10/11 20:02:19 roberto Exp roberto $ |
3 | ** Lua - A Scripting Language | 3 | ** Lua - A Scripting Language |
4 | ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) | 4 | ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) |
5 | ** See Copyright Notice at the end of this file | 5 | ** See Copyright Notice at the end of this file |
@@ -380,6 +380,10 @@ LUA_API const char *(lua_setlocal) (lua_State *L, const lua_Debug *ar, int n); | |||
380 | LUA_API const char *(lua_getupvalue) (lua_State *L, int funcindex, int n); | 380 | LUA_API const char *(lua_getupvalue) (lua_State *L, int funcindex, int n); |
381 | LUA_API const char *(lua_setupvalue) (lua_State *L, int funcindex, int n); | 381 | LUA_API const char *(lua_setupvalue) (lua_State *L, int funcindex, int n); |
382 | 382 | ||
383 | LUA_API void *(lua_upvaladdr) (lua_State *L, int fidx, int n); | ||
384 | LUA_API int (lua_upvaljoin) (lua_State *L, int fidx1, int n1, | ||
385 | int fidx2, int n2); | ||
386 | |||
383 | LUA_API int (lua_sethook) (lua_State *L, lua_Hook func, int mask, int count); | 387 | LUA_API int (lua_sethook) (lua_State *L, lua_Hook func, int mask, int count); |
384 | LUA_API lua_Hook (lua_gethook) (lua_State *L); | 388 | LUA_API lua_Hook (lua_gethook) (lua_State *L); |
385 | LUA_API int (lua_gethookmask) (lua_State *L); | 389 | LUA_API int (lua_gethookmask) (lua_State *L); |