diff options
author | Lua Team <team@lua.org> | 2014-10-23 12:00:00 +0000 |
---|---|---|
committer | repogen <> | 2014-10-23 12:00:00 +0000 |
commit | 92fdb95364ed274752b8634c8ba3dca1f1dc5fb3 (patch) | |
tree | d1747f7ed2d0ed06b83ee3073fe4256aefd4a928 /src/ltablib.c | |
parent | d7648e85b78d53a2248de909868192598ad0eb69 (diff) | |
download | lua-github-5.3.0-beta.tar.gz |
Lua 5.3.0-beta5.3.0-beta
Diffstat (limited to 'src/ltablib.c')
-rw-r--r-- | src/ltablib.c | 68 |
1 files changed, 25 insertions, 43 deletions
diff --git a/src/ltablib.c b/src/ltablib.c index bc353866..908acfbc 100644 --- a/src/ltablib.c +++ b/src/ltablib.c @@ -1,5 +1,5 @@ /* -** $Id: ltablib.c,v 1.73 2014/07/29 16:01:00 roberto Exp $ +** $Id: ltablib.c,v 1.77 2014/10/17 16:28:21 roberto Exp $ ** Library for Table Manipulation ** See Copyright Notice in lua.h */ @@ -28,41 +28,25 @@ typedef struct { /* -** equivalent to 'lua_rawgeti', but not raw -*/ -static int geti (lua_State *L, int idx, lua_Integer n) { - lua_pushinteger(L, n); - return lua_gettable(L, idx); /* assume 'idx' is not negative */ -} - - -/* -** equivalent to 'lua_rawseti', but not raw -*/ -static void seti (lua_State *L, int idx, lua_Integer n) { - lua_pushinteger(L, n); - lua_rotate(L, -2, 1); /* exchange key and value */ - lua_settable(L, idx); /* assume 'idx' is not negative */ -} - - -/* ** Check that 'arg' has a table and set access functions in 'ta' to raw ** or non-raw according to the presence of corresponding metamethods. */ static void checktab (lua_State *L, int arg, TabA *ta) { - luaL_checktype(L, arg, LUA_TTABLE); - if (!lua_getmetatable(L, arg)) { /* fast track */ - ta->geti = lua_rawgeti; /* with no metatable, all is raw */ - ta->seti = lua_rawseti; - } - else { + ta->geti = NULL; ta->seti = NULL; + if (lua_getmetatable(L, arg)) { lua_pushliteral(L, "__index"); /* 'index' metamethod */ - ta->geti = (lua_rawget(L, -2) == LUA_TNIL) ? lua_rawgeti : geti; + if (lua_rawget(L, -2) != LUA_TNIL) + ta->geti = lua_geti; lua_pushliteral(L, "__newindex"); /* 'newindex' metamethod */ - ta->seti = (lua_rawget(L, -3) == LUA_TNIL) ? lua_rawseti : seti; + if (lua_rawget(L, -3) != LUA_TNIL) + ta->seti = lua_seti; lua_pop(L, 3); /* pop metatable plus both metamethods */ } + if (ta->geti == NULL || ta->seti == NULL) { + luaL_checktype(L, arg, LUA_TTABLE); /* must be table for raw methods */ + if (ta->geti == NULL) ta->geti = lua_rawgeti; + if (ta->seti == NULL) ta->seti = lua_rawseti; + } } @@ -107,7 +91,7 @@ static int tinsert (lua_State *L) { break; } default: { - return luaL_error(L, "wrong number of arguments to " LUA_QL("insert")); + return luaL_error(L, "wrong number of arguments to 'insert'"); } } (*ta.seti)(L, 1, pos); /* t[pos] = v */ @@ -132,24 +116,22 @@ static int tremove (lua_State *L) { } -static int tcopy (lua_State *L) { +static int tmove (lua_State *L) { TabA ta; lua_Integer f = luaL_checkinteger(L, 2); lua_Integer e = luaL_checkinteger(L, 3); - lua_Integer t; - int tt = 4; /* destination table */ + lua_Integer t = luaL_checkinteger(L, 4); + int tt = !lua_isnoneornil(L, 5) ? 5 : 1; /* destination table */ /* the following restriction avoids several problems with overflows */ luaL_argcheck(L, f > 0, 2, "initial position must be positive"); - if (lua_istable(L, tt)) - t = luaL_checkinteger(L, 5); - else { - tt = 1; /* destination table is equal to source */ - t = luaL_checkinteger(L, 4); - } if (e >= f) { /* otherwise, nothing to move */ lua_Integer n, i; - ta.geti = (!luaL_getmetafield(L, 1, "__index")) ? lua_rawgeti : geti; - ta.seti = (!luaL_getmetafield(L, tt, "__newindex")) ? lua_rawseti : seti; + ta.geti = (luaL_getmetafield(L, 1, "__index") == LUA_TNIL) + ? (luaL_checktype(L, 1, LUA_TTABLE), lua_rawgeti) + : lua_geti; + ta.seti = (luaL_getmetafield(L, tt, "__newindex") == LUA_TNIL) + ? (luaL_checktype(L, tt, LUA_TTABLE), lua_rawseti) + : lua_seti; n = e - f + 1; /* number of elements to move */ if (t > f) { for (i = n - 1; i >= 0; i--) { @@ -172,8 +154,8 @@ static int tcopy (lua_State *L) { static void addfield (lua_State *L, luaL_Buffer *b, TabA *ta, lua_Integer i) { (*ta->geti)(L, 1, i); if (!lua_isstring(L, -1)) - luaL_error(L, "invalid value (%s) at index %d in table for " - LUA_QL("concat"), luaL_typename(L, -1), i); + luaL_error(L, "invalid value (%s) at index %d in table for 'concat'", + luaL_typename(L, -1), i); luaL_addvalue(b); } @@ -355,7 +337,7 @@ static const luaL_Reg tab_funcs[] = { {"pack", pack}, {"unpack", unpack}, {"remove", tremove}, - {"copy", tcopy}, + {"move", tmove}, {"sort", sort}, {NULL, NULL} }; |