lua-users home
lua-l archive

Re: Differentiating upvalues and sharing

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


That patch was a little incomplete, I forgot to add the diff of the
function prototypes in lua.h. Attached is the correct patch.
Cheers,
-- 
-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月26日 22:43:45.000000000 -0700
@@ -1051,6 +1051,42 @@
 }
 
 
+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)
+{
+ return (void *) *(auxl_upvalue(L, funcindex, n));
+}
+
+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日 22:46:09.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月26日 23:06:09.000000000 -0700
+++ lua.h	2008年02月26日 23:17:59.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);

AltStyle によって変換されたページ (->オリジナル) /