/src/testdir/build/lua-master/source/ltablib.c
| Line | Count | Source | 
| 1 |  | /* | 
| 2 |  | ** $Id: ltablib.c $ | 
| 3 |  | ** Library for Table Manipulation | 
| 4 |  | ** See Copyright Notice in lua.h | 
| 5 |  | */ | 
| 6 |  |  | 
| 7 |  | #define ltablib_c | 
| 8 |  | #define LUA_LIB | 
| 9 |  |  | 
| 10 |  | #include "lprefix.h" | 
| 11 |  |  | 
| 12 |  |  | 
| 13 |  | #include <limits.h> | 
| 14 |  | #include <stddef.h> | 
| 15 |  | #include <string.h> | 
| 16 |  |  | 
| 17 |  | #include "lua.h" | 
| 18 |  |  | 
| 19 |  | #include "lauxlib.h" | 
| 20 |  | #include "lualib.h" | 
| 21 |  | #include "llimits.h" | 
| 22 |  |  | 
| 23 |  |  | 
| 24 |  | /* | 
| 25 |  | ** Operations that an object must define to mimic a table | 
| 26 |  | ** (some functions only need some of them) | 
| 27 |  | */ | 
| 28 | 3.76k | #define TAB_R 1      /* read */ | 
| 29 | 3.68k | #define TAB_W 2      /* write */ | 
| 30 | 136k | #define TAB_L 4      /* length */ | 
| 31 |  | #define TAB_RW  (TAB_R | TAB_W)   /* read/write */ | 
| 32 |  |  | 
| 33 |  |  | 
| 34 | 134k | #define aux_getn(L,n,w) (checktab(L, n, (w) | TAB_L), luaL_len(L, n)) | 
| 35 |  |  | 
| 36 |  |  | 
| 37 | 8.57k | static int checkfield (lua_State *L, const char *key, int n) { | 
| 38 | 8.57k |   lua_pushstring(L, key); | 
| 39 | 8.57k |   return (lua_rawget(L, -n) != LUA_TNIL); | 
| 40 | 8.57k | } | 
| 41 |  |  | 
| 42 |  |  | 
| 43 |  | /* | 
| 44 |  | ** Check that 'arg' either is a table or can behave like one (that is, | 
| 45 |  | ** has a metatable with the required metamethods) | 
| 46 |  | */ | 
| 47 | 134k | static void checktab (lua_State *L, int arg, int what) { | 
| 48 | 134k |   if (lua_type(L, arg) != LUA_TTABLE) {  /* is it not a table? */ | 
| 49 | 6.80k |     int n = 1;  /* number of elements to pop */ | 
| 50 | 6.80k |     if (lua_getmetatable(L, arg) &&  /* must have metatable */ | 
| 51 | 3.72k |         (!(what & TAB_R) || checkfield(L, "__index", ++n)) && | 
| 52 | 3.64k |         (!(what & TAB_W) || checkfield(L, "__newindex", ++n)) && | 
| 53 | 1.42k |         (!(what & TAB_L) || checkfield(L, "__len", ++n))) { | 
| 54 | 318 |       lua_pop(L, n);  /* pop metatable and tested metamethods */ | 
| 55 | 318 |     } | 
| 56 | 6.48k |     else | 
| 57 | 6.48k |       luaL_checktype(L, arg, LUA_TTABLE);  /* force an error */ | 
| 58 | 6.80k |   } | 
| 59 | 134k | } | 
| 60 |  |  | 
| 61 |  |  | 
| 62 | 0 | static int tcreate (lua_State *L) { | 
| 63 | 0 |   lua_Unsigned sizeseq = (lua_Unsigned)luaL_checkinteger(L, 1); | 
| 64 | 0 |   lua_Unsigned sizerest = (lua_Unsigned)luaL_optinteger(L, 2, 0); | 
| 65 | 0 |   luaL_argcheck(L, sizeseq <= cast_uint(INT_MAX), 1, "out of range"); | 
| 66 | 0 |   luaL_argcheck(L, sizerest <= cast_uint(INT_MAX), 2, "out of range"); | 
| 67 | 0 |   lua_createtable(L, cast_int(sizeseq), cast_int(sizerest)); | 
| 68 | 0 |   return 1; | 
| 69 | 0 | } | 
| 70 |  |  | 
| 71 |  |  | 
| 72 | 71.8k | static int tinsert (lua_State *L) { | 
| 73 | 71.8k |   lua_Integer pos;  /* where to insert new element */ | 
| 74 | 71.8k |   lua_Integer e = aux_getn(L, 1, TAB_RW); | 
| 75 | 71.8k |   e = luaL_intop(+, e, 1);  /* first empty element */ | 
| 76 | 71.8k |   switch (lua_gettop(L)) { | 
| 77 | 68.7k |     case 2: {  /* called with only 2 arguments */ | 
| 78 | 68.7k |       pos = e;  /* insert new element at the end */ | 
| 79 | 68.7k |       break; | 
| 80 | 0 |     } | 
| 81 | 0 |     case 3: { | 
| 82 | 0 |       lua_Integer i; | 
| 83 | 0 |       pos = luaL_checkinteger(L, 2);  /* 2nd argument is the position */ | 
| 84 |  |       /* check whether 'pos' is in [1, e] */ | 
| 85 | 0 |       luaL_argcheck(L, (lua_Unsigned)pos - 1u < (lua_Unsigned)e, 2, | 
| 86 | 0 |                        "position out of bounds"); | 
| 87 | 0 |       for (i = e; i > pos; i--) {  /* move up elements */ | 
| 88 | 0 |         lua_geti(L, 1, i - 1); | 
| 89 | 0 |         lua_seti(L, 1, i);  /* t[i] = t[i - 1] */ | 
| 90 | 0 |       } | 
| 91 | 0 |       break; | 
| 92 | 0 |     } | 
| 93 | 42 |     default: { | 
| 94 | 42 |       return luaL_error(L, "wrong number of arguments to 'insert'"); | 
| 95 | 0 |     } | 
| 96 | 71.8k |   } | 
| 97 | 68.7k |   lua_seti(L, 1, pos);  /* t[pos] = v */ | 
| 98 | 68.7k |   return 0; | 
| 99 | 71.8k | } | 
| 100 |  |  | 
| 101 |  |  | 
| 102 | 1.34k | static int tremove (lua_State *L) { | 
| 103 | 1.34k |   lua_Integer size = aux_getn(L, 1, TAB_RW); | 
| 104 | 1.34k |   lua_Integer pos = luaL_optinteger(L, 2, size); | 
| 105 | 1.34k |   if (pos != size)  /* validate 'pos' if given */ | 
| 106 |  |     /* check whether 'pos' is in [1, size + 1] */ | 
| 107 | 135 |     luaL_argcheck(L, (lua_Unsigned)pos - 1u <= (lua_Unsigned)size, 2, | 
| 108 | 1.34k |                      "position out of bounds"); | 
| 109 | 1.34k |   lua_geti(L, 1, pos);  /* result = t[pos] */ | 
| 110 | 1.68k |   for ( ; pos < size; pos++) { | 
| 111 | 343 |     lua_geti(L, 1, pos + 1); | 
| 112 | 343 |     lua_seti(L, 1, pos);  /* t[pos] = t[pos + 1] */ | 
| 113 | 343 |   } | 
| 114 | 1.34k |   lua_pushnil(L); | 
| 115 | 1.34k |   lua_seti(L, 1, pos);  /* remove entry t[pos] */ | 
| 116 | 1.34k |   return 1; | 
| 117 | 1.34k | } | 
| 118 |  |  | 
| 119 |  |  | 
| 120 |  | /* | 
| 121 |  | ** Copy elements (1[f], ..., 1[e]) into (tt[t], tt[t+1], ...). Whenever | 
| 122 |  | ** possible, copy in increasing order, which is better for rehashing. | 
| 123 |  | ** "possible" means destination after original range, or smaller | 
| 124 |  | ** than origin, or copying to another table. | 
| 125 |  | */ | 
| 126 | 42 | static int tmove (lua_State *L) { | 
| 127 | 42 |   lua_Integer f = luaL_checkinteger(L, 2); | 
| 128 | 42 |   lua_Integer e = luaL_checkinteger(L, 3); | 
| 129 | 42 |   lua_Integer t = luaL_checkinteger(L, 4); | 
| 130 | 42 |   int tt = !lua_isnoneornil(L, 5) ? 5 : 1;  /* destination table */ | 
| 131 | 42 |   checktab(L, 1, TAB_R); | 
| 132 | 42 |   checktab(L, tt, TAB_W); | 
| 133 | 42 |   if (e >= f) {  /* otherwise, nothing to move */ | 
| 134 | 0 |     lua_Integer n, i; | 
| 135 | 0 |     luaL_argcheck(L, f > 0 || e < LUA_MAXINTEGER + f, 3, | 
| 136 | 0 |                   "too many elements to move"); | 
| 137 | 0 |     n = e - f + 1;  /* number of elements to move */ | 
| 138 | 0 |     luaL_argcheck(L, t <= LUA_MAXINTEGER - n + 1, 4, | 
| 139 | 0 |                   "destination wrap around"); | 
| 140 | 0 |     if (t > e || t <= f || (tt != 1 && !lua_compare(L, 1, tt, LUA_OPEQ))) { | 
| 141 | 0 |       for (i = 0; i < n; i++) { | 
| 142 | 0 |         lua_geti(L, 1, f + i); | 
| 143 | 0 |         lua_seti(L, tt, t + i); | 
| 144 | 0 |       } | 
| 145 | 0 |     } | 
| 146 | 0 |     else { | 
| 147 | 0 |       for (i = n - 1; i >= 0; i--) { | 
| 148 | 0 |         lua_geti(L, 1, f + i); | 
| 149 | 0 |         lua_seti(L, tt, t + i); | 
| 150 | 0 |       } | 
| 151 | 0 |     } | 
| 152 | 0 |   } | 
| 153 | 42 |   lua_pushvalue(L, tt);  /* return destination table */ | 
| 154 | 42 |   return 1; | 
| 155 | 42 | } | 
| 156 |  |  | 
| 157 |  |  | 
| 158 | 24.9M | static void addfield (lua_State *L, luaL_Buffer *b, lua_Integer i) { | 
| 159 | 24.9M |   lua_geti(L, 1, i); | 
| 160 | 24.9M |   if (l_unlikely(!lua_isstring(L, -1))) | 
| 161 | 1 |     luaL_error(L, "invalid value (%s) at index %I in table for 'concat'", | 
| 162 | 1 |                   luaL_typename(L, -1), (LUAI_UACINT)i); | 
| 163 | 24.9M |   luaL_addvalue(b); | 
| 164 | 24.9M | } | 
| 165 |  |  | 
| 166 |  |  | 
| 167 | 37.8k | static int tconcat (lua_State *L) { | 
| 168 | 37.8k |   luaL_Buffer b; | 
| 169 | 37.8k |   lua_Integer last = aux_getn(L, 1, TAB_R); | 
| 170 | 37.8k |   size_t lsep; | 
| 171 | 37.8k |   const char *sep = luaL_optlstring(L, 2, "", &lsep); | 
| 172 | 37.8k |   lua_Integer i = luaL_optinteger(L, 3, 1); | 
| 173 | 37.8k |   last = luaL_optinteger(L, 4, last); | 
| 174 | 37.8k |   luaL_buffinit(L, &b); | 
| 175 | 24.9M |   for (; i < last; i++) { | 
| 176 | 24.8M |     addfield(L, &b, i); | 
| 177 | 24.8M |     luaL_addlstring(&b, sep, lsep); | 
| 178 | 24.8M |   } | 
| 179 | 37.8k |   if (i == last)  /* add last value (if interval was not empty) */ | 
| 180 | 36.1k |     addfield(L, &b, i); | 
| 181 | 37.8k |   luaL_pushresult(&b); | 
| 182 | 37.8k |   return 1; | 
| 183 | 37.8k | } | 
| 184 |  |  | 
| 185 |  |  | 
| 186 |  | /* | 
| 187 |  | ** {====================================================== | 
| 188 |  | ** Pack/unpack | 
| 189 |  | ** ======================================================= | 
| 190 |  | */ | 
| 191 |  |  | 
| 192 | 115k | static int tpack (lua_State *L) { | 
| 193 | 115k |   int i; | 
| 194 | 115k |   int n = lua_gettop(L);  /* number of elements to pack */ | 
| 195 | 115k |   lua_createtable(L, n, 1);  /* create result table */ | 
| 196 | 115k |   lua_insert(L, 1);  /* put it at index 1 */ | 
| 197 | 236k |   for (i = n; i >= 1; i--)  /* assign elements */ | 
| 198 | 120k |     lua_seti(L, 1, i); | 
| 199 | 115k |   lua_pushinteger(L, n); | 
| 200 | 115k |   lua_setfield(L, 1, "n");  /* t.n = number of elements */ | 
| 201 | 115k |   return 1;  /* return table */ | 
| 202 | 115k | } | 
| 203 |  |  | 
| 204 |  |  | 
| 205 | 33.0k | static int tunpack (lua_State *L) { | 
| 206 | 33.0k |   lua_Unsigned n; | 
| 207 | 33.0k |   lua_Integer i = luaL_optinteger(L, 2, 1); | 
| 208 | 33.0k |   lua_Integer e = luaL_opt(L, luaL_checkinteger, 3, luaL_len(L, 1)); | 
| 209 | 33.0k |   if (i > e) return 0;  /* empty range */ | 
| 210 | 32.7k |   n = l_castS2U(e) - l_castS2U(i);  /* number of elements minus 1 */ | 
| 211 | 32.7k |   if (l_unlikely(n >= (unsigned int)INT_MAX  || | 
| 212 | 32.7k |                  !lua_checkstack(L, (int)(++n)))) | 
| 213 | 0 |     return luaL_error(L, "too many results to unpack"); | 
| 214 | 15.4M |   for (; i < e; i++) {  /* push arg[i..e - 1] (to avoid overflows) */ | 
| 215 | 15.4M |     lua_geti(L, 1, i); | 
| 216 | 15.4M |   } | 
| 217 | 32.7k |   lua_geti(L, 1, e);  /* push last element */ | 
| 218 | 32.7k |   return (int)n; | 
| 219 | 32.7k | } | 
| 220 |  |  | 
| 221 |  | /* }====================================================== */ | 
| 222 |  |  | 
| 223 |  |  | 
| 224 |  |  | 
| 225 |  | /* | 
| 226 |  | ** {====================================================== | 
| 227 |  | ** Quicksort | 
| 228 |  | ** (based on 'Algorithms in MODULA-3', Robert Sedgewick; | 
| 229 |  | **  Addison-Wesley, 1993.) | 
| 230 |  | ** ======================================================= | 
| 231 |  | */ | 
| 232 |  |  | 
| 233 |  |  | 
| 234 |  | /* | 
| 235 |  | ** Type for array indices. These indices are always limited by INT_MAX, | 
| 236 |  | ** so it is safe to cast them to lua_Integer even for Lua 32 bits. | 
| 237 |  | */ | 
| 238 |  | typedef unsigned int IdxT; | 
| 239 |  |  | 
| 240 |  |  | 
| 241 |  | /* Versions of lua_seti/lua_geti specialized for IdxT */ | 
| 242 | 515k | #define geti(L,idt,idx) lua_geti(L, idt, l_castU2S(idx)) | 
| 243 | 277k | #define seti(L,idt,idx) lua_seti(L, idt, l_castU2S(idx)) | 
| 244 |  |  | 
| 245 |  |  | 
| 246 |  | /* | 
| 247 |  | ** Produce a "random" 'unsigned int' to randomize pivot choice. This | 
| 248 |  | ** macro is used only when 'sort' detects a big imbalance in the result | 
| 249 |  | ** of a partition. (If you don't want/need this "randomness", ~0 is a | 
| 250 |  | ** good choice.) | 
| 251 |  | */ | 
| 252 |  | #if !defined(l_randomizePivot) | 
| 253 | 0 | #define l_randomizePivot(L) luaL_makeseed(L) | 
| 254 |  | #endif          /* } */ | 
| 255 |  |  | 
| 256 |  |  | 
| 257 |  | /* arrays larger than 'RANLIMIT' may use randomized pivots */ | 
| 258 | 72.6k | #define RANLIMIT  100u | 
| 259 |  |  | 
| 260 |  |  | 
| 261 | 138k | static void set2 (lua_State *L, IdxT i, IdxT j) { | 
| 262 | 138k |   seti(L, 1, i); | 
| 263 | 138k |   seti(L, 1, j); | 
| 264 | 138k | } | 
| 265 |  |  | 
| 266 |  |  | 
| 267 |  | /* | 
| 268 |  | ** Return true iff value at stack index 'a' is less than the value at | 
| 269 |  | ** index 'b' (according to the order of the sort). | 
| 270 |  | */ | 
| 271 | 378k | static int sort_comp (lua_State *L, int a, int b) { | 
| 272 | 378k |   if (lua_isnil(L, 2))  /* no function? */ | 
| 273 | 378k |     return lua_compare(L, a, b, LUA_OPLT);  /* a < b */ | 
| 274 | 0 |   else {  /* function */ | 
| 275 | 0 |     int res; | 
| 276 | 0 |     lua_pushvalue(L, 2);    /* push function */ | 
| 277 | 0 |     lua_pushvalue(L, a-1);  /* -1 to compensate function */ | 
| 278 | 0 |     lua_pushvalue(L, b-2);  /* -2 to compensate function and 'a' */ | 
| 279 | 0 |     lua_call(L, 2, 1);      /* call function */ | 
| 280 | 0 |     res = lua_toboolean(L, -1);  /* get result */ | 
| 281 | 0 |     lua_pop(L, 1);          /* pop result */ | 
| 282 | 0 |     return res; | 
| 283 | 0 |   } | 
| 284 | 378k | } | 
| 285 |  |  | 
| 286 |  |  | 
| 287 |  | /* | 
| 288 |  | ** Does the partition: Pivot P is at the top of the stack. | 
| 289 |  | ** precondition: a[lo] <= P == a[up-1] <= a[up], | 
| 290 |  | ** so it only needs to do the partition from lo + 1 to up - 2. | 
| 291 |  | ** Pos-condition: a[lo .. i - 1] <= a[i] == P <= a[i + 1 .. up] | 
| 292 |  | ** returns 'i'. | 
| 293 |  | */ | 
| 294 | 24.5k | static IdxT partition (lua_State *L, IdxT lo, IdxT up) { | 
| 295 | 24.5k |   IdxT i = lo;  /* will be incremented before first use */ | 
| 296 | 24.5k |   IdxT j = up - 1;  /* will be decremented before first use */ | 
| 297 |  |   /* loop invariant: a[lo .. i] <= P <= a[j .. up] */ | 
| 298 | 82.4k |   for (;;) { | 
| 299 |  |     /* next loop: repeat ++i while a[i] < P */ | 
| 300 | 128k |     while ((void)geti(L, 1, ++i), sort_comp(L, -1, -2)) { | 
| 301 | 45.7k |       if (l_unlikely(i == up - 1))  /* a[up - 1] < P == a[up - 1] */ | 
| 302 | 0 |         luaL_error(L, "invalid order function for sorting"); | 
| 303 | 45.7k |       lua_pop(L, 1);  /* remove a[i] */ | 
| 304 | 45.7k |     } | 
| 305 |  |     /* after the loop, a[i] >= P and a[lo .. i - 1] < P  (a) */ | 
| 306 |  |     /* next loop: repeat --j while P < a[j] */ | 
| 307 | 140k |     while ((void)geti(L, 1, --j), sort_comp(L, -3, -1)) { | 
| 308 | 58.1k |       if (l_unlikely(j < i))  /* j <= i - 1 and a[j] > P, contradicts (a) */ | 
| 309 | 0 |         luaL_error(L, "invalid order function for sorting"); | 
| 310 | 58.1k |       lua_pop(L, 1);  /* remove a[j] */ | 
| 311 | 58.1k |     } | 
| 312 |  |     /* after the loop, a[j] <= P and a[j + 1 .. up] >= P */ | 
| 313 | 82.4k |     if (j < i) {  /* no elements out of place? */ | 
| 314 |  |       /* a[lo .. i - 1] <= P <= a[j + 1 .. i .. up] */ | 
| 315 | 24.5k |       lua_pop(L, 1);  /* pop a[j] */ | 
| 316 |  |       /* swap pivot (a[up - 1]) with a[i] to satisfy pos-condition */ | 
| 317 | 24.5k |       set2(L, up - 1, i); | 
| 318 | 24.5k |       return i; | 
| 319 | 24.5k |     } | 
| 320 |  |     /* otherwise, swap a[i] - a[j] to restore invariant and repeat */ | 
| 321 | 57.9k |     set2(L, i, j); | 
| 322 | 57.9k |   } | 
| 323 | 24.5k | } | 
| 324 |  |  | 
| 325 |  |  | 
| 326 |  | /* | 
| 327 |  | ** Choose an element in the middle (2nd-3th quarters) of [lo,up] | 
| 328 |  | ** "randomized" by 'rnd' | 
| 329 |  | */ | 
| 330 | 0 | static IdxT choosePivot (IdxT lo, IdxT up, unsigned int rnd) { | 
| 331 | 0 |   IdxT r4 = (up - lo) / 4;  /* range/4 */ | 
| 332 | 0 |   IdxT p = (rnd ^ lo ^ up) % (r4 * 2) + (lo + r4); | 
| 333 | 0 |   lua_assert(lo + r4 <= p && p <= up - r4); | 
| 334 | 0 |   return p; | 
| 335 | 0 | } | 
| 336 |  |  | 
| 337 |  |  | 
| 338 |  | /* | 
| 339 |  | ** Quicksort algorithm (recursive function) | 
| 340 |  | */ | 
| 341 | 35.0k | static void auxsort (lua_State *L, IdxT lo, IdxT up, unsigned rnd) { | 
| 342 | 60.3k |   while (lo < up) {  /* loop for tail recursion */ | 
| 343 | 48.6k |     IdxT p;  /* Pivot index */ | 
| 344 | 48.6k |     IdxT n;  /* to be used later */ | 
| 345 |  |     /* sort elements 'lo', 'p', and 'up' */ | 
| 346 | 48.6k |     geti(L, 1, lo); | 
| 347 | 48.6k |     geti(L, 1, up); | 
| 348 | 48.6k |     if (sort_comp(L, -1, -2))  /* a[up] < a[lo]? */ | 
| 349 | 10.8k |       set2(L, lo, up);  /* swap a[lo] - a[up] */ | 
| 350 | 37.7k |     else | 
| 351 | 37.7k |       lua_pop(L, 2);  /* remove both values */ | 
| 352 | 48.6k |     if (up - lo == 1)  /* only 2 elements? */ | 
| 353 | 12.3k |       return;  /* already sorted */ | 
| 354 | 36.3k |     if (up - lo < RANLIMIT || rnd == 0)  /* small interval or no randomize? */ | 
| 355 | 35.5k |       p = (lo + up)/2;  /* middle element is a good pivot */ | 
| 356 | 780 |     else  /* for larger intervals, it is worth a random pivot */ | 
| 357 | 780 |       p = choosePivot(lo, up, rnd); | 
| 358 | 36.3k |     geti(L, 1, p); | 
| 359 | 36.3k |     geti(L, 1, lo); | 
| 360 | 36.3k |     if (sort_comp(L, -2, -1))  /* a[p] < a[lo]? */ | 
| 361 | 10.4k |       set2(L, p, lo);  /* swap a[p] - a[lo] */ | 
| 362 | 25.8k |     else { | 
| 363 | 25.8k |       lua_pop(L, 1);  /* remove a[lo] */ | 
| 364 | 25.8k |       geti(L, 1, up); | 
| 365 | 25.8k |       if (sort_comp(L, -1, -2))  /* a[up] < a[p]? */ | 
| 366 | 10.1k |         set2(L, p, up);  /* swap a[up] - a[p] */ | 
| 367 | 15.6k |       else | 
| 368 | 15.6k |         lua_pop(L, 2); | 
| 369 | 25.8k |     } | 
| 370 | 36.3k |     if (up - lo == 2)  /* only 3 elements? */ | 
| 371 | 11.0k |       return;  /* already sorted */ | 
| 372 | 25.3k |     geti(L, 1, p);  /* get middle element (Pivot) */ | 
| 373 | 25.3k |     lua_pushvalue(L, -1);  /* push Pivot */ | 
| 374 | 25.3k |     geti(L, 1, up - 1);  /* push a[up - 1] */ | 
| 375 | 25.3k |     set2(L, p, up - 1);  /* swap Pivot (a[p]) with a[up - 1] */ | 
| 376 | 25.3k |     p = partition(L, lo, up); | 
| 377 |  |     /* a[lo .. p - 1] <= a[p] == P <= a[p + 1 .. up] */ | 
| 378 | 25.3k |     if (p - lo < up - p) {  /* lower interval is smaller? */ | 
| 379 | 11.0k |       auxsort(L, lo, p - 1, rnd);  /* call recursively for lower interval */ | 
| 380 | 11.0k |       n = p - lo;  /* size of smaller interval */ | 
| 381 | 11.0k |       lo = p + 1;  /* tail call for [p + 1 .. up] (upper interval) */ | 
| 382 | 11.0k |     } | 
| 383 | 14.2k |     else { | 
| 384 | 14.2k |       auxsort(L, p + 1, up, rnd);  /* call recursively for upper interval */ | 
| 385 | 14.2k |       n = up - p;  /* size of smaller interval */ | 
| 386 | 14.2k |       up = p - 1;  /* tail call for [lo .. p - 1]  (lower interval) */ | 
| 387 | 14.2k |     } | 
| 388 | 25.3k |     if ((up - lo) / 128 > n) /* partition too imbalanced? */ | 
| 389 | 0 |       rnd = l_randomizePivot(L);  /* try a new randomization */ | 
| 390 | 25.3k |   }  /* tail call auxsort(L, lo, up, rnd) */ | 
| 391 | 35.0k | } | 
| 392 |  |  | 
| 393 |  |  | 
| 394 | 23.5k | static int sort (lua_State *L) { | 
| 395 | 23.5k |   lua_Integer n = aux_getn(L, 1, TAB_RW); | 
| 396 | 23.5k |   if (n > 1) {  /* non-trivial interval? */ | 
| 397 | 10.5k |     luaL_argcheck(L, n < INT_MAX, 1, "array too big"); | 
| 398 | 10.5k |     if (!lua_isnoneornil(L, 2))  /* is there a 2nd argument? */ | 
| 399 | 0 |       luaL_checktype(L, 2, LUA_TFUNCTION);  /* must be a function */ | 
| 400 | 10.5k |     lua_settop(L, 2);  /* make sure there are two arguments */ | 
| 401 | 10.5k |     auxsort(L, 1, (IdxT)n, 0); | 
| 402 | 10.5k |   } | 
| 403 | 23.5k |   return 0; | 
| 404 | 23.5k | } | 
| 405 |  |  | 
| 406 |  | /* }====================================================== */ | 
| 407 |  |  | 
| 408 |  |  | 
| 409 |  | static const luaL_Reg tab_funcs[] = { | 
| 410 |  |   {"concat", tconcat}, | 
| 411 |  |   {"create", tcreate}, | 
| 412 |  |   {"insert", tinsert}, | 
| 413 |  |   {"pack", tpack}, | 
| 414 |  |   {"unpack", tunpack}, | 
| 415 |  |   {"remove", tremove}, | 
| 416 |  |   {"move", tmove}, | 
| 417 |  |   {"sort", sort}, | 
| 418 |  |   {NULL, NULL} | 
| 419 |  | }; | 
| 420 |  |  | 
| 421 |  |  | 
| 422 | 29.6k | LUAMOD_API int luaopen_table (lua_State *L) { | 
| 423 | 29.6k |   luaL_newlib(L, tab_funcs); | 
| 424 | 29.6k |   return 1; | 
| 425 | 29.6k | } | 
| 426 |  |  |