diff options
| -rw-r--r-- | ltablib.c | 43 |
1 files changed, 22 insertions, 21 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltablib.c,v 1.72 2014/07/25 18:46:00 roberto Exp roberto $ | 2 | ** $Id: ltablib.c,v 1.73 2014/07/29 16:01:00 roberto Exp roberto $ |
| 3 | ** Library for Table Manipulation | 3 | ** Library for Table Manipulation |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -51,18 +51,21 @@ static void seti (lua_State *L, int idx, lua_Integer n) { | |||
| 51 | ** or non-raw according to the presence of corresponding metamethods. | 51 | ** or non-raw according to the presence of corresponding metamethods. |
| 52 | */ | 52 | */ |
| 53 | static void checktab (lua_State *L, int arg, TabA *ta) { | 53 | static void checktab (lua_State *L, int arg, TabA *ta) { |
| 54 | luaL_checktype(L, arg, LUA_TTABLE); | 54 | ta->geti = NULL; ta->seti = NULL; |
| 55 | if (!lua_getmetatable(L, arg)) { /* fast track */ | 55 | if (lua_getmetatable(L, arg)) { |
| 56 | ta->geti = lua_rawgeti; /* with no metatable, all is raw */ | ||
| 57 | ta->seti = lua_rawseti; | ||
| 58 | } | ||
| 59 | else { | ||
| 60 | lua_pushliteral(L, "__index"); /* 'index' metamethod */ | 56 | lua_pushliteral(L, "__index"); /* 'index' metamethod */ |
| 61 | ta->geti = (lua_rawget(L, -2) == LUA_TNIL) ? lua_rawgeti : geti; | 57 | if (lua_rawget(L, -2) != LUA_TNIL) |
| 58 | ta->geti = geti; | ||
| 62 | lua_pushliteral(L, "__newindex"); /* 'newindex' metamethod */ | 59 | lua_pushliteral(L, "__newindex"); /* 'newindex' metamethod */ |
| 63 | ta->seti = (lua_rawget(L, -3) == LUA_TNIL) ? lua_rawseti : seti; | 60 | if (lua_rawget(L, -3) != LUA_TNIL) |
| 61 | ta->seti = seti; | ||
| 64 | lua_pop(L, 3); /* pop metatable plus both metamethods */ | 62 | lua_pop(L, 3); /* pop metatable plus both metamethods */ |
| 65 | } | 63 | } |
| 64 | if (ta->geti == NULL || ta->seti == NULL) { | ||
| 65 | luaL_checktype(L, arg, LUA_TTABLE); /* must be table for raw methods */ | ||
| 66 | if (ta->geti == NULL) ta->geti = lua_rawgeti; | ||
| 67 | if (ta->seti == NULL) ta->seti = lua_rawseti; | ||
| 68 | } | ||
| 66 | } | 69 | } |
| 67 | 70 | ||
| 68 | 71 | ||
| @@ -132,24 +135,22 @@ static int tremove (lua_State *L) { | |||
| 132 | } | 135 | } |
| 133 | 136 | ||
| 134 | 137 | ||
| 135 | static int tcopy (lua_State *L) { | 138 | static int tmove (lua_State *L) { |
| 136 | TabA ta; | 139 | TabA ta; |
| 137 | lua_Integer f = luaL_checkinteger(L, 2); | 140 | lua_Integer f = luaL_checkinteger(L, 2); |
| 138 | lua_Integer e = luaL_checkinteger(L, 3); | 141 | lua_Integer e = luaL_checkinteger(L, 3); |
| 139 | lua_Integer t; | 142 | lua_Integer t = luaL_checkinteger(L, 4); |
| 140 | int tt = 4; /* destination table */ | 143 | int tt = !lua_isnoneornil(L, 5) ? 5 : 1; /* destination table */ |
| 141 | /* the following restriction avoids several problems with overflows */ | 144 | /* the following restriction avoids several problems with overflows */ |
| 142 | luaL_argcheck(L, f > 0, 2, "initial position must be positive"); | 145 | luaL_argcheck(L, f > 0, 2, "initial position must be positive"); |
| 143 | if (lua_istable(L, tt)) | ||
| 144 | t = luaL_checkinteger(L, 5); | ||
| 145 | else { | ||
| 146 | tt = 1; /* destination table is equal to source */ | ||
| 147 | t = luaL_checkinteger(L, 4); | ||
| 148 | } | ||
| 149 | if (e >= f) { /* otherwise, nothing to move */ | 146 | if (e >= f) { /* otherwise, nothing to move */ |
| 150 | lua_Integer n, i; | 147 | lua_Integer n, i; |
| 151 | ta.geti = (!luaL_getmetafield(L, 1, "__index")) ? lua_rawgeti : geti; | 148 | ta.geti = (!luaL_getmetafield(L, 1, "__index")) |
| 152 | ta.seti = (!luaL_getmetafield(L, tt, "__newindex")) ? lua_rawseti : seti; | 149 | ? (luaL_checktype(L, 1, LUA_TTABLE), lua_rawgeti) |
| 150 | : geti; | ||
| 151 | ta.seti = (!luaL_getmetafield(L, tt, "__newindex")) | ||
| 152 | ? (luaL_checktype(L, tt, LUA_TTABLE), lua_rawseti) | ||
| 153 | : seti; | ||
| 153 | n = e - f + 1; /* number of elements to move */ | 154 | n = e - f + 1; /* number of elements to move */ |
| 154 | if (t > f) { | 155 | if (t > f) { |
| 155 | for (i = n - 1; i >= 0; i--) { | 156 | for (i = n - 1; i >= 0; i--) { |
| @@ -355,7 +356,7 @@ static const luaL_Reg tab_funcs[] = { | |||
| 355 | {"pack", pack}, | 356 | {"pack", pack}, |
| 356 | {"unpack", unpack}, | 357 | {"unpack", unpack}, |
| 357 | {"remove", tremove}, | 358 | {"remove", tremove}, |
| 358 | {"copy", tcopy}, | 359 | {"move", tmove}, |
| 359 | {"sort", sort}, | 360 | {"sort", sort}, |
| 360 | {NULL, NULL} | 361 | {NULL, NULL} |
| 361 | }; | 362 | }; |
