new function lua_copy

This commit is contained in:
Roberto Ierusalimschy 2009-10-05 13:44:33 -03:00
parent ba21aa8b2b
commit a5382b763c
7 changed files with 46 additions and 30 deletions

46
lapi.c
View File

@ -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));

View File

@ -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 {

View File

@ -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);

View File

@ -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 */

View File

@ -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);
}

View File

@ -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);
}

3
lua.h
View File

@ -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);