lua-users home
lua-l archive

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


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);