commit a5382b763c2faa4c47e55ee0e49889b4c47daac4
parent ba21aa8b2b29f516f1f488f996fc899c62f7105b
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Mon, 5 Oct 2009 13:44:09 -0300
new function lua_copy
Diffstat:
7 files changed, 45 insertions(+), 29 deletions(-)
diff --git 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) {
}
-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);
+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(L->top - 1), "table expected");
- func->c.env = hvalue(L->top - 1);
- luaC_barrier(L, func, L->top - 1);
+ api_check(L, ttistable(fr), "table expected");
+ func->c.env = hvalue(fr);
+ luaC_barrier(L, func, fr);
}
else {
- setobj(L, o, L->top - 1);
+ setobj(L, to, fr);
if (idx < LUA_GLOBALSINDEX) /* function upvalue? */
- luaC_barrier(L, curr_func(L), L->top - 1);
+ 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) {
+ 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);
+ 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);