From Lua 5.2: Add lua_copy().

Contributed by François Perrad.
master
Mike Pall 2017-04-07 12:24:26 +02:00
parent c67a098292
commit ef23b70eb6
3 changed files with 21 additions and 11 deletions

View File

@ -572,8 +572,7 @@ LUALIB_API int luaopen_package(lua_State *L)
lj_lib_pushcf(L, lj_cf_package_unloadlib, 1);
lua_setfield(L, -2, "__gc");
luaL_register(L, LUA_LOADLIBNAME, package_lib);
lua_pushvalue(L, -1);
lua_replace(L, LUA_ENVIRONINDEX);
lua_copy(L, -1, LUA_ENVIRONINDEX);
lua_createtable(L, sizeof(package_loaders)/sizeof(package_loaders[0])-1, 0);
for (i = 0; package_loaders[i] != NULL; i++) {
lj_lib_pushcf(L, package_loaders[i], 1);

View File

@ -159,30 +159,40 @@ LUA_API void lua_insert(lua_State *L, int idx)
copyTV(L, p, L->top);
}
LUA_API void lua_replace(lua_State *L, int idx)
static void copy_slot(lua_State *L, TValue *f, int idx)
{
api_checknelems(L, 1);
if (idx == LUA_GLOBALSINDEX) {
api_check(L, tvistab(L->top-1));
api_check(L, tvistab(f));
/* NOBARRIER: A thread (i.e. L) is never black. */
setgcref(L->env, obj2gco(tabV(L->top-1)));
setgcref(L->env, obj2gco(tabV(f)));
} else if (idx == LUA_ENVIRONINDEX) {
GCfunc *fn = curr_func(L);
if (fn->c.gct != ~LJ_TFUNC)
lj_err_msg(L, LJ_ERR_NOENV);
api_check(L, tvistab(L->top-1));
setgcref(fn->c.env, obj2gco(tabV(L->top-1)));
lj_gc_barrier(L, fn, L->top-1);
api_check(L, tvistab(f));
setgcref(fn->c.env, obj2gco(tabV(f)));
lj_gc_barrier(L, fn, f);
} else {
TValue *o = index2adr(L, idx);
api_checkvalidindex(L, o);
copyTV(L, o, L->top-1);
copyTV(L, o, f);
if (idx < LUA_GLOBALSINDEX) /* Need a barrier for upvalues. */
lj_gc_barrier(L, curr_func(L), L->top-1);
lj_gc_barrier(L, curr_func(L), f);
}
}
LUA_API void lua_replace(lua_State *L, int idx)
{
api_checknelems(L, 1);
copy_slot(L, L->top - 1, idx);
L->top--;
}
LUA_API void lua_copy(lua_State *L, int fromidx, int toidx)
{
copy_slot(L, index2adr(L, fromidx), toidx);
}
LUA_API void lua_pushvalue(lua_State *L, int idx)
{
copyTV(L, L->top, index2adr(L, idx));

View File

@ -349,6 +349,7 @@ LUA_API void lua_upvaluejoin (lua_State *L, int idx1, int n1, int idx2, int n2);
LUA_API int lua_loadx (lua_State *L, lua_Reader reader, void *dt,
const char *chunkname, const char *mode);
LUA_API const lua_Number *lua_version (lua_State *L);
LUA_API void lua_copy (lua_State *L, int fromidx, int toidx);
struct lua_Debug {