diff options
| -rw-r--r-- | ltablib.c | 11 | ||||
| -rw-r--r-- | testes/sort.lua | 13 |
2 files changed, 20 insertions, 4 deletions
| @@ -42,15 +42,17 @@ static int checkfield (lua_State *L, const char *key, int n) { | |||
| 42 | 42 | ||
| 43 | /* | 43 | /* |
| 44 | ** Check that 'arg' either is a table or can behave like one (that is, | 44 | ** Check that 'arg' either is a table or can behave like one (that is, |
| 45 | ** has a metatable with the required metamethods) | 45 | ** has a metatable with the required metamethods). |
| 46 | */ | 46 | */ |
| 47 | static void checktab (lua_State *L, int arg, int what) { | 47 | static void checktab (lua_State *L, int arg, int what) { |
| 48 | if (lua_type(L, arg) != LUA_TTABLE) { /* is it not a table? */ | 48 | int tp = lua_type(L, arg); |
| 49 | if (tp != LUA_TTABLE) { /* is it not a table? */ | ||
| 49 | int n = 1; /* number of elements to pop */ | 50 | int n = 1; /* number of elements to pop */ |
| 50 | if (lua_getmetatable(L, arg) && /* must have metatable */ | 51 | if (lua_getmetatable(L, arg) && /* must have metatable */ |
| 51 | (!(what & TAB_R) || checkfield(L, "__index", ++n)) && | 52 | (!(what & TAB_R) || checkfield(L, "__index", ++n)) && |
| 52 | (!(what & TAB_W) || checkfield(L, "__newindex", ++n)) && | 53 | (!(what & TAB_W) || checkfield(L, "__newindex", ++n)) && |
| 53 | (!(what & TAB_L) || checkfield(L, "__len", ++n))) { | 54 | (!(what & TAB_L) || /* strings don't need '__len' to have a length */ |
| 55 | tp == LUA_TSTRING || checkfield(L, "__len", ++n))) { | ||
| 54 | lua_pop(L, n); /* pop metatable and tested metamethods */ | 56 | lua_pop(L, n); /* pop metatable and tested metamethods */ |
| 55 | } | 57 | } |
| 56 | else | 58 | else |
| @@ -204,8 +206,9 @@ static int tpack (lua_State *L) { | |||
| 204 | 206 | ||
| 205 | static int tunpack (lua_State *L) { | 207 | static int tunpack (lua_State *L) { |
| 206 | lua_Unsigned n; | 208 | lua_Unsigned n; |
| 209 | lua_Integer len = aux_getn(L, 1, TAB_R); | ||
| 207 | lua_Integer i = luaL_optinteger(L, 2, 1); | 210 | lua_Integer i = luaL_optinteger(L, 2, 1); |
| 208 | lua_Integer e = luaL_opt(L, luaL_checkinteger, 3, luaL_len(L, 1)); | 211 | lua_Integer e = luaL_opt(L, luaL_checkinteger, 3, len); |
| 209 | if (i > e) return 0; /* empty range */ | 212 | if (i > e) return 0; /* empty range */ |
| 210 | n = l_castS2U(e) - l_castS2U(i); /* number of elements minus 1 */ | 213 | n = l_castS2U(e) - l_castS2U(i); /* number of elements minus 1 */ |
| 211 | if (l_unlikely(n >= (unsigned int)INT_MAX || | 214 | if (l_unlikely(n >= (unsigned int)INT_MAX || |
diff --git a/testes/sort.lua b/testes/sort.lua index b0127660..92aaca3c 100644 --- a/testes/sort.lua +++ b/testes/sort.lua | |||
| @@ -72,6 +72,19 @@ assert(a==1 and x==nil) | |||
| 72 | a,x = unpack({1,2}, 1, 1) | 72 | a,x = unpack({1,2}, 1, 1) |
| 73 | assert(a==1 and x==nil) | 73 | assert(a==1 and x==nil) |
| 74 | 74 | ||
| 75 | |||
| 76 | do -- unpack with non-tables | ||
| 77 | local debug = require"debug" | ||
| 78 | local oldmt = debug.getmetatable(0) | ||
| 79 | local str = "hello" | ||
| 80 | debug.setmetatable(0, | ||
| 81 | { __len = function () return #str end, | ||
| 82 | __index = function (_, i) return string.sub(str, i, i) end}) | ||
| 83 | assert(table.concat({table.unpack(0)}) == str) | ||
| 84 | debug.setmetatable(0, oldmt) -- restore original metatable for numbers | ||
| 85 | end | ||
| 86 | |||
| 87 | |||
| 75 | do | 88 | do |
| 76 | local maxi = (1 << 31) - 1 -- maximum value for an int (usually) | 89 | local maxi = (1 << 31) - 1 -- maximum value for an int (usually) |
| 77 | local mini = -(1 << 31) -- minimum value for an int (usually) | 90 | local mini = -(1 << 31) -- minimum value for an int (usually) |
