I want to be able to serialize functions that share the same upvalue and then restore the relationship on deserialization. This post from a few years ago has a patch for vanilla Lua to do the same thing, and more information on the problem: http://lua-users.org/lists/lua-l/2008-02/msg01173.html I went ahead and patched LuaJIT 2 (beta10) to do this (the patch and a very simple test is attached). It seems to work, but since I am not familiar with the internals of LuaJIT, I am not confident that the changes are completely correct. I am assuming that lua_shareupvalue is only called on lua functions right after deserialization and before they are first invoked. Can anyone comment on whether this code should work in general, and on any issues I might be missing? Thanks! Zach **For those on lua-l, sorry for the cross post--I didn't realize there was a luajit specific list.
extern "C" { #include "lua.h" #include "lualib.h" #include "lauxlib.h" } #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> const char * luainput = "local a = 0\n" "function up()\n" " a = a + 1\n" "end\n" "function get()\n" " print(a)\n" "end\n" "return up,get\n"; char buf[1024 * 1024]; size_t bsz = 0; int dumptobuf(lua_State * L, const void * p, size_t sz, void * ud) { assert(sz < 1024 * 1024); memcpy(buf+bsz,p,sz); bsz += sz; return 0; } int main() { lua_State * L = luaL_newstate(); luaL_openlibs(L); if(luaL_dostring(L,luainput)) { fprintf(stderr,"%s\n",luaL_checkstring(L,-1)); return 1; } { const void * uv0 = lua_getupvalueaddr(L,-1,1); const void * uv1 = lua_getupvalueaddr(L,-2,1); printf("upvalues (L) %p %p\n", uv0, uv1); } lua_State * L2 = luaL_newstate(); luaL_openlibs(L2); assert( 0 == lua_dump(L, dumptobuf,NULL) ); assert( 0 == luaL_loadbuffer(L2,buf,bsz,"get") ); bsz = 0; lua_pop(L,1); assert(lua_dump(L, dumptobuf,NULL) == 0); assert(0 == luaL_loadbuffer(L2,buf,bsz,"up")); lua_pushnumber(L2,42); assert(NULL != lua_setupvalue(L2,-2,1)); { const void * uv0 = lua_getupvalueaddr(L2,-1,1); const void * uv1 = lua_getupvalueaddr(L2,-2,1); printf("upvalues (L2 before) %p %p\n", uv0, uv1); } assert(0 == lua_shareupvalue(L2,-1,1,-2,1)); { const void * uv0 = lua_getupvalueaddr(L2,-1,1); const void * uv1 = lua_getupvalueaddr(L2,-2,1); printf("upvalues (L2 after) %p %p\n", uv0, uv1); } for(int i = 0; i < 10; i++) { lua_pushvalue(L2,-2); lua_pushvalue(L2,-2); lua_call(L2,0,0); lua_call(L2,0,0); } return 0; }