From a5382b763c2faa4c47e55ee0e49889b4c47daac4 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Mon, 5 Oct 2009 13:44:33 -0300 Subject: [PATCH] new function lua_copy --- lapi.c | 46 ++++++++++++++++++++++++++++++---------------- lauxlib.c | 6 +++--- lbaselib.c | 5 ++--- loadlib.c | 5 ++--- lstate.c | 5 ++--- ltests.c | 6 +++++- lua.h | 3 ++- 7 files changed, 46 insertions(+), 30 deletions(-) diff --git a/lapi.c b/lapi.c index 08a42516..8426dea0 100644 --- a/lapi.c +++ b/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 2.91 2009/09/21 12:09:52 roberto Exp roberto $ +** $Id: lapi.c,v 2.92 2009/09/28 16:32:50 roberto Exp roberto $ ** Lua API ** See Copyright Notice in lua.h */ @@ -185,32 +185,46 @@ LUA_API void lua_insert (lua_State *L, int idx) { } +static void moveto (lua_State *L, TValue *fr, int idx) { + TValue *to = index2addr(L, idx); + api_checkvalidindex(L, to); + if (idx == LUA_ENVIRONINDEX) { + Closure *func = curr_func(L); + api_check(L, ttistable(fr), "table expected"); + func->c.env = hvalue(fr); + luaC_barrier(L, func, fr); + } + else { + setobj(L, to, fr); + if (idx < LUA_GLOBALSINDEX) /* function upvalue? */ + luaC_barrier(L, curr_func(L), fr); + } + /* LUA_GLOBALSINDEX does not need gc barrier (threads are never black) */ +} + + LUA_API void lua_replace (lua_State *L, int idx) { - StkId o; lua_lock(L); /* explicit test for incompatible code */ if (idx == LUA_ENVIRONINDEX && L->ci->previous == NULL) luaG_runerror(L, "no calling environment"); api_checknelems(L, 1); - o = index2addr(L, idx); - api_checkvalidindex(L, o); - if (idx == LUA_ENVIRONINDEX) { - Closure *func = curr_func(L); - api_check(L, ttistable(L->top - 1), "table expected"); - func->c.env = hvalue(L->top - 1); - luaC_barrier(L, func, L->top - 1); - } - else { - setobj(L, o, L->top - 1); - if (idx < LUA_GLOBALSINDEX) /* function upvalue? */ - luaC_barrier(L, curr_func(L), L->top - 1); - } - /* LUA_GLOBALSINDEX does not need gc barrier (threads are never black) */ + moveto(L, L->top - 1, idx); L->top--; lua_unlock(L); } +LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) { + TValue *fr; + lua_lock(L); + fr = index2addr(L, fromidx); + api_checkvalidindex(L, fr); + moveto(L, fr, toidx); + lua_unlock(L); +} + + LUA_API void lua_pushvalue (lua_State *L, int idx) { lua_lock(L); setobj2s(L, L->top, index2addr(L, idx)); diff --git a/lauxlib.c b/lauxlib.c index ed82e8cd..2d33adf6 100644 --- a/lauxlib.c +++ b/lauxlib.c @@ -1,5 +1,5 @@ /* -** $Id: lauxlib.c,v 1.191 2009/09/18 18:58:45 roberto Exp roberto $ +** $Id: lauxlib.c,v 1.192 2009/09/28 12:36:40 roberto Exp roberto $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ @@ -75,8 +75,8 @@ static int pushglobalfuncname (lua_State *L, lua_Debug *ar) { lua_getinfo(L, "f", ar); /* push function */ lua_pushvalue(L, LUA_GLOBALSINDEX); /* push global table */ if (findfield(L, top + 1, 2)) { - lua_replace(L, top + 1); /* move name to proper place */ - lua_pop(L, 1); /* remove other pushed value */ + lua_copy(L, -1, top + 1); /* move name to proper place */ + lua_pop(L, 2); /* remove pushed values */ return 1; } else { diff --git a/lbaselib.c b/lbaselib.c index edd72dcd..aa6fe1dc 100644 --- a/lbaselib.c +++ b/lbaselib.c @@ -1,5 +1,5 @@ /* -** $Id: lbaselib.c,v 1.217 2009/07/15 17:35:20 roberto Exp roberto $ +** $Id: lbaselib.c,v 1.218 2009/08/04 18:20:18 roberto Exp roberto $ ** Basic library ** See Copyright Notice in lua.h */ @@ -432,8 +432,7 @@ static int luaB_xpcall (lua_State *L) { int n = lua_gettop(L); luaL_argcheck(L, n >= 2, 2, "value expected"); lua_pushvalue(L, 1); /* exchange function... */ - lua_pushvalue(L, 2); /* ...and error handler */ - lua_replace(L, 1); + lua_copy(L, 2, 1); /* ...and error handler */ lua_replace(L, 2); status = lua_pcallk(L, n - 2, LUA_MULTRET, 1, 1, pcallcont); luaL_checkstack(L, 1, NULL); diff --git a/loadlib.c b/loadlib.c index d21c654f..3e807c2c 100644 --- a/loadlib.c +++ b/loadlib.c @@ -1,5 +1,5 @@ /* -** $Id: loadlib.c,v 1.64 2009/07/15 17:49:48 roberto Exp roberto $ +** $Id: loadlib.c,v 1.65 2009/09/07 14:24:12 roberto Exp roberto $ ** Dynamic library loader for Lua ** See Copyright Notice in lua.h ** @@ -655,8 +655,7 @@ LUALIB_API int luaopen_package (lua_State *L) { lua_setfield(L, -2, "__gc"); /* create `package' table */ luaL_register(L, LUA_LOADLIBNAME, pk_funcs); - lua_pushvalue(L, -1); - lua_replace(L, LUA_ENVIRONINDEX); + lua_copy(L, -1, LUA_ENVIRONINDEX); /* create `loaders' table */ lua_createtable(L, sizeof(loaders)/sizeof(loaders[0]) - 1, 0); /* fill it with pre-defined loaders */ diff --git a/lstate.c b/lstate.c index bc56079f..b571c828 100644 --- a/lstate.c +++ b/lstate.c @@ -1,5 +1,5 @@ /* -** $Id: lstate.c,v 2.60 2009/09/28 13:50:19 roberto Exp roberto $ +** $Id: lstate.c,v 2.61 2009/09/30 20:49:47 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -100,8 +100,7 @@ static int cpcall (lua_State *L) { lua_CFunction f = *(lua_CFunction *)lua_touserdata(L, 1); lua_remove(L, 1); /* remove f from stack */ /* restore original environment for 'cpcall' */ - lua_pushvalue(L, LUA_GLOBALSINDEX); - lua_replace(L, LUA_ENVIRONINDEX); + lua_copy(L, LUA_GLOBALSINDEX, LUA_ENVIRONINDEX); return f(L); } diff --git a/ltests.c b/ltests.c index 46730667..40a7f965 100644 --- a/ltests.c +++ b/ltests.c @@ -1,5 +1,5 @@ /* -** $Id: ltests.c,v 2.73 2009/09/28 16:32:50 roberto Exp roberto $ +** $Id: ltests.c,v 2.74 2009/09/30 20:49:25 roberto Exp roberto $ ** Internal Module for Debugging of the Lua Implementation ** See Copyright Notice in lua.h */ @@ -971,6 +971,10 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) { else if EQ("replace") { lua_replace(L1, getindex); } + else if EQ("copy") { + int f = getindex; + lua_copy(L1, f, getindex); + } else if EQ("gettable") { lua_gettable(L1, getindex); } diff --git a/lua.h b/lua.h index e440e30c..478374e3 100644 --- a/lua.h +++ b/lua.h @@ -1,5 +1,5 @@ /* -** $Id: lua.h,v 1.243 2009/09/17 18:04:21 roberto Exp roberto $ +** $Id: lua.h,v 1.244 2009/09/21 12:09:52 roberto Exp roberto $ ** Lua - An Extensible Extension Language ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) ** See Copyright Notice at the end of this file @@ -135,6 +135,7 @@ LUA_API void (lua_pushvalue) (lua_State *L, int idx); LUA_API void (lua_remove) (lua_State *L, int idx); LUA_API void (lua_insert) (lua_State *L, int idx); LUA_API void (lua_replace) (lua_State *L, int idx); +LUA_API void (lua_copy) (lua_State *L, int fromidx, int toidx); LUA_API int (lua_checkstack) (lua_State *L, int sz); LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n);