diff --git a/src/lib_debug.c b/src/lib_debug.c index d90c422f..0330f1d2 100644 --- a/src/lib_debug.c +++ b/src/lib_debug.c @@ -224,6 +224,37 @@ LJLIB_CF(debug_setupvalue) return debug_getupvalue(L, 0); } +LJLIB_CF(debug_upvalueid) +{ + GCfunc *fn = lj_lib_checkfunc(L, 1); + int32_t n = lj_lib_checkint(L, 2) - 1; + if ((uint32_t)n >= fn->l.nupvalues) + lj_err_arg(L, 2, LJ_ERR_IDXRNG); + setlightudV(L->top-1, isluafunc(fn) ? (void *)gcref(fn->l.uvptr[n]) : + (void *)&fn->c.upvalue[n]); + return 1; +} + +LJLIB_CF(debug_upvaluejoin) +{ + GCfunc *fn[2]; + GCRef *p[2]; + int i; + for (i = 0; i < 2; i++) { + int32_t n; + fn[i] = lj_lib_checkfunc(L, 2*i+1); + if (!isluafunc(fn[i])) + lj_err_arg(L, 2*i+1, LJ_ERR_NOLFUNC); + n = lj_lib_checkint(L, 2*i+2) - 1; + if ((uint32_t)n >= fn[i]->l.nupvalues) + lj_err_arg(L, 2*i+2, LJ_ERR_IDXRNG); + p[i] = &fn[i]->l.uvptr[n]; + } + setgcrefr(*p[0], *p[1]); + lj_gc_objbarrier(L, fn[0], gcref(*p[1])); + return 0; +} + /* ------------------------------------------------------------------------ */ static const char KEY_HOOK = 'h'; diff --git a/src/lj_api.c b/src/lj_api.c index bfd471d2..a9ea38d8 100644 --- a/src/lj_api.c +++ b/src/lj_api.c @@ -852,6 +852,26 @@ LUA_API const char *lua_getupvalue(lua_State *L, int idx, int n) return name; } +LUA_API void *lua_upvalueid(lua_State *L, int idx, int n) +{ + GCfunc *fn = funcV(index2adr(L, idx)); + n--; + api_check(L, (uint32_t)n < fn->l.nupvalues); + return isluafunc(fn) ? (void *)gcref(fn->l.uvptr[n]) : + (void *)&fn->c.upvalue[n]; +} + +LUA_API void lua_upvaluejoin(lua_State *L, int idx1, int n1, int idx2, int n2) +{ + GCfunc *fn1 = funcV(index2adr(L, idx1)); + GCfunc *fn2 = funcV(index2adr(L, idx2)); + n1--; n2--; + api_check(L, isluafunc(fn1) && (uint32_t)n1 < fn1->l.nupvalues); + api_check(L, isluafunc(fn2) && (uint32_t)n2 < fn2->l.nupvalues); + setgcrefr(fn1->l.uvptr[n1], fn2->l.uvptr[n2]); + lj_gc_objbarrier(L, fn1, gcref(fn1->l.uvptr[n1])); +} + LUALIB_API void *luaL_checkudata(lua_State *L, int idx, const char *tname) { cTValue *o = index2adr(L, idx); diff --git a/src/lj_errmsg.h b/src/lj_errmsg.h index c07d4387..28c5ca08 100644 --- a/src/lj_errmsg.h +++ b/src/lj_errmsg.h @@ -44,6 +44,7 @@ ERRDEF(BADVAL, "invalid value") ERRDEF(NOVAL, "value expected") ERRDEF(NOCORO, "coroutine expected") ERRDEF(NOTABN, "nil or table expected") +ERRDEF(NOLFUNC, "Lua function expected") ERRDEF(NOFUNCL, "function or level expected") ERRDEF(NOSFT, "string/function/table expected") ERRDEF(NOPROXY, "boolean or proxy expected") diff --git a/src/lua.h b/src/lua.h index 0e98b374..9e9357a8 100644 --- a/src/lua.h +++ b/src/lua.h @@ -336,12 +336,15 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); 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 int lua_sethook (lua_State *L, lua_Hook func, int mask, int count); LUA_API lua_Hook lua_gethook (lua_State *L); LUA_API int lua_gethookmask (lua_State *L); LUA_API int lua_gethookcount (lua_State *L); +/* From Lua 5.2. */ +LUA_API void *lua_upvalueid (lua_State *L, int idx, int n); +LUA_API void lua_upvaluejoin (lua_State *L, int idx1, int n1, int idx2, int n2); + struct lua_Debug { int event;