[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Differentiating upvalues and sharing
- From: "Patrick Donnelly" <batrick.donnelly@...>
- Date: Wed, 27 Feb 2008 10:07:40 -0700
My initial lua_upvalue() api function may attempt to dereference 0x0
(oops!), attached is the correct version.
Sorry for the extra noise.
--
-Patrick Donnelly
"One of the lessons of history is that nothing is often a good thing
to do and always a clever thing to say."
-Will Durant
--- ../realsrc/lapi.c 2008-02-15 19:04:41.000000000 -0700
+++ lapi.c 2008-02-27 10:01:22.000000000 -0700
@@ -1051,6 +1051,43 @@
}
+static UpVal **auxl_upvalue (lua_State *L, int funcindex, int n)
+{
+ Closure *f;
+ StkId fi;
+ UpVal **u;
+ lua_lock(L);
+ fi = index2adr(L, funcindex);
+ if (!ttisfunction(fi) || lua_iscfunction(L, funcindex))
+ return NULL; /* must be function, cfunctions don't have real upvalues */
+ f = clvalue(fi);
+ Proto *p = f->l.p;
+ if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
+ u = &(f->l.upvals[n-1]);
+ lua_unlock(L);
+ return u;
+}
+
+LUA_API void *lua_upvalue (lua_State *L, int funcindex, int n)
+{
+ UpVal **u = auxl_upvalue(L, funcindex, n);
+ return u ? (void *) *u : NULL;
+}
+
+LUA_API int lua_shareupvalue (lua_State *L, int funcindex1, int n1,
+ int funcindex2, int n2)
+{
+ UpVal **u1, **u2;
+ lua_lock(L);
+ u1 = auxl_upvalue(L, funcindex1, n1);
+ u2 = auxl_upvalue(L, funcindex2, n2);
+ if (!(u1 && u2))
+ return 0; /* one is not valid */
+ *u1 = *u2;
+ return 1;
+}
+
+
LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
const char *name;
TValue *val;
--- ../realsrc/ldblib.c 2008-02-15 19:04:41.000000000 -0700
+++ ldblib.c 2008-02-26 23:10:19.000000000 -0700
@@ -198,7 +198,30 @@
return auxupvalue(L, 0);
}
+static int db_upvalue (lua_State *L) {
+ void *p;
+ luaL_checktype(L, 1, LUA_TFUNCTION);
+ p = lua_upvalue(L, 1, luaL_checkint(L, 2));
+ if (p)
+ lua_pushlightuserdata(L, p);
+ else
+ lua_pushnil(L);
+ return 1;
+}
+static int db_shareupvalue (lua_State *L) {
+ int n1, n2;
+ luaL_checktype(L, 1, LUA_TFUNCTION);
+ luaL_checktype(L, 3, LUA_TFUNCTION);
+ if (lua_iscfunction(L, 1) || lua_iscfunction(L, 3)) {
+ lua_pushboolean(L, 0);
+ return 1; /* cannot touch C upvalues from Lua */
+ }
+ n1 = luaL_checkint(L, 2);
+ n2 = luaL_checkint(L, 4);
+ lua_pushboolean(L, lua_shareupvalue(L, 1, n1, 3, n2));
+ return 1;
+}
static const char KEY_HOOK = 'h';
@@ -385,6 +408,8 @@
{"setlocal", db_setlocal},
{"setmetatable", db_setmetatable},
{"setupvalue", db_setupvalue},
+ {"upvalue", db_upvalue},
+ {"shareupvalue", db_shareupvalue},
{"traceback", db_errorfb},
{NULL, NULL}
};
--- ../realsrc/lua.h 2008-02-15 19:04:41.000000000 -0700
+++ lua.h 2008-02-26 23:20:25.000000000 -0700
@@ -336,6 +336,9 @@
LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n);
LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n);
+LUA_API void *lua_upvalue (lua_State *L, int funcindex, int n);
+LUA_API int lua_shareupvalue (lua_State *L, int funcindex1, int n1,
+ int funcindex2, int n2);
LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count);
LUA_API lua_Hook lua_gethook (lua_State *L);