Browse Source

new function lua_copy

Roberto Ierusalimschy 16 years ago
parent
commit
a5382b763c
7 changed files with 45 additions and 29 deletions
  1. 29 15
      lapi.c
  2. 3 3
      lauxlib.c
  3. 2 3
      lbaselib.c
  4. 2 3
      loadlib.c
  5. 2 3
      lstate.c
  6. 5 1
      ltests.c
  7. 2 1
      lua.h

+ 29 - 15
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));

+ 3 - 3
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 {

+ 2 - 3
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);

+ 2 - 3
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 */

+ 2 - 3
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);
 }
 

+ 5 - 1
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);
     }

+ 2 - 1
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);