|
@@ -231,10 +231,18 @@ static int tunpack (lua_State *L) {
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
|
|
-/* type for array indices */
|
|
|
|
|
|
+/*
|
|
|
|
+** Type for array indices. These indices are always limited by INT_MAX,
|
|
|
|
+** so it is safe to cast them to lua_Integer even for Lua 32 bits.
|
|
|
|
+*/
|
|
typedef unsigned int IdxT;
|
|
typedef unsigned int IdxT;
|
|
|
|
|
|
|
|
|
|
|
|
+/* Versions of lua_seti/lua_geti specialized for IdxT */
|
|
|
|
+#define geti(L,idt,idx) lua_geti(L, idt, l_castU2S(idx))
|
|
|
|
+#define seti(L,idt,idx) lua_seti(L, idt, l_castU2S(idx))
|
|
|
|
+
|
|
|
|
+
|
|
/*
|
|
/*
|
|
** Produce a "random" 'unsigned int' to randomize pivot choice. This
|
|
** Produce a "random" 'unsigned int' to randomize pivot choice. This
|
|
** macro is used only when 'sort' detects a big imbalance in the result
|
|
** macro is used only when 'sort' detects a big imbalance in the result
|
|
@@ -251,8 +259,8 @@ typedef unsigned int IdxT;
|
|
|
|
|
|
|
|
|
|
static void set2 (lua_State *L, IdxT i, IdxT j) {
|
|
static void set2 (lua_State *L, IdxT i, IdxT j) {
|
|
- lua_seti(L, 1, i);
|
|
|
|
- lua_seti(L, 1, j);
|
|
|
|
|
|
+ seti(L, 1, i);
|
|
|
|
+ seti(L, 1, j);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -289,14 +297,14 @@ static IdxT partition (lua_State *L, IdxT lo, IdxT up) {
|
|
/* loop invariant: a[lo .. i] <= P <= a[j .. up] */
|
|
/* loop invariant: a[lo .. i] <= P <= a[j .. up] */
|
|
for (;;) {
|
|
for (;;) {
|
|
/* next loop: repeat ++i while a[i] < P */
|
|
/* next loop: repeat ++i while a[i] < P */
|
|
- while ((void)lua_geti(L, 1, ++i), sort_comp(L, -1, -2)) {
|
|
|
|
|
|
+ while ((void)geti(L, 1, ++i), sort_comp(L, -1, -2)) {
|
|
if (l_unlikely(i == up - 1)) /* a[i] < P but a[up - 1] == P ?? */
|
|
if (l_unlikely(i == up - 1)) /* a[i] < P but a[up - 1] == P ?? */
|
|
luaL_error(L, "invalid order function for sorting");
|
|
luaL_error(L, "invalid order function for sorting");
|
|
lua_pop(L, 1); /* remove a[i] */
|
|
lua_pop(L, 1); /* remove a[i] */
|
|
}
|
|
}
|
|
/* after the loop, a[i] >= P and a[lo .. i - 1] < P */
|
|
/* after the loop, a[i] >= P and a[lo .. i - 1] < P */
|
|
/* next loop: repeat --j while P < a[j] */
|
|
/* next loop: repeat --j while P < a[j] */
|
|
- while ((void)lua_geti(L, 1, --j), sort_comp(L, -3, -1)) {
|
|
|
|
|
|
+ while ((void)geti(L, 1, --j), sort_comp(L, -3, -1)) {
|
|
if (l_unlikely(j < i)) /* j < i but a[j] > P ?? */
|
|
if (l_unlikely(j < i)) /* j < i but a[j] > P ?? */
|
|
luaL_error(L, "invalid order function for sorting");
|
|
luaL_error(L, "invalid order function for sorting");
|
|
lua_pop(L, 1); /* remove a[j] */
|
|
lua_pop(L, 1); /* remove a[j] */
|
|
@@ -335,8 +343,8 @@ static void auxsort (lua_State *L, IdxT lo, IdxT up, unsigned rnd) {
|
|
IdxT p; /* Pivot index */
|
|
IdxT p; /* Pivot index */
|
|
IdxT n; /* to be used later */
|
|
IdxT n; /* to be used later */
|
|
/* sort elements 'lo', 'p', and 'up' */
|
|
/* sort elements 'lo', 'p', and 'up' */
|
|
- lua_geti(L, 1, lo);
|
|
|
|
- lua_geti(L, 1, up);
|
|
|
|
|
|
+ geti(L, 1, lo);
|
|
|
|
+ geti(L, 1, up);
|
|
if (sort_comp(L, -1, -2)) /* a[up] < a[lo]? */
|
|
if (sort_comp(L, -1, -2)) /* a[up] < a[lo]? */
|
|
set2(L, lo, up); /* swap a[lo] - a[up] */
|
|
set2(L, lo, up); /* swap a[lo] - a[up] */
|
|
else
|
|
else
|
|
@@ -347,13 +355,13 @@ static void auxsort (lua_State *L, IdxT lo, IdxT up, unsigned rnd) {
|
|
p = (lo + up)/2; /* middle element is a good pivot */
|
|
p = (lo + up)/2; /* middle element is a good pivot */
|
|
else /* for larger intervals, it is worth a random pivot */
|
|
else /* for larger intervals, it is worth a random pivot */
|
|
p = choosePivot(lo, up, rnd);
|
|
p = choosePivot(lo, up, rnd);
|
|
- lua_geti(L, 1, p);
|
|
|
|
- lua_geti(L, 1, lo);
|
|
|
|
|
|
+ geti(L, 1, p);
|
|
|
|
+ geti(L, 1, lo);
|
|
if (sort_comp(L, -2, -1)) /* a[p] < a[lo]? */
|
|
if (sort_comp(L, -2, -1)) /* a[p] < a[lo]? */
|
|
set2(L, p, lo); /* swap a[p] - a[lo] */
|
|
set2(L, p, lo); /* swap a[p] - a[lo] */
|
|
else {
|
|
else {
|
|
lua_pop(L, 1); /* remove a[lo] */
|
|
lua_pop(L, 1); /* remove a[lo] */
|
|
- lua_geti(L, 1, up);
|
|
|
|
|
|
+ geti(L, 1, up);
|
|
if (sort_comp(L, -1, -2)) /* a[up] < a[p]? */
|
|
if (sort_comp(L, -1, -2)) /* a[up] < a[p]? */
|
|
set2(L, p, up); /* swap a[up] - a[p] */
|
|
set2(L, p, up); /* swap a[up] - a[p] */
|
|
else
|
|
else
|
|
@@ -361,9 +369,9 @@ static void auxsort (lua_State *L, IdxT lo, IdxT up, unsigned rnd) {
|
|
}
|
|
}
|
|
if (up - lo == 2) /* only 3 elements? */
|
|
if (up - lo == 2) /* only 3 elements? */
|
|
return; /* already sorted */
|
|
return; /* already sorted */
|
|
- lua_geti(L, 1, p); /* get middle element (Pivot) */
|
|
|
|
|
|
+ geti(L, 1, p); /* get middle element (Pivot) */
|
|
lua_pushvalue(L, -1); /* push Pivot */
|
|
lua_pushvalue(L, -1); /* push Pivot */
|
|
- lua_geti(L, 1, up - 1); /* push a[up - 1] */
|
|
|
|
|
|
+ geti(L, 1, up - 1); /* push a[up - 1] */
|
|
set2(L, p, up - 1); /* swap Pivot (a[p]) with a[up - 1] */
|
|
set2(L, p, up - 1); /* swap Pivot (a[p]) with a[up - 1] */
|
|
p = partition(L, lo, up);
|
|
p = partition(L, lo, up);
|
|
/* a[lo .. p - 1] <= a[p] == P <= a[p + 1 .. up] */
|
|
/* a[lo .. p - 1] <= a[p] == P <= a[p + 1 .. up] */
|