static void Ap_sort(js_State *J) { unsigned int len, i, k; int hasx, hasy, hasfn; len = js_getlength(J, 0); hasfn = js_iscallable(J, 1); for (i = 1; i < len; ++i) { k = i; while (k > 0 && compare(J, k - 1, k, &hasx, &hasy, hasfn) > 0) { if (hasx && hasy) { js_setindex(J, 0, k - 1); js_setindex(J, 0, k); } else if (hasx) { js_delindex(J, 0, k - 1); js_setindex(J, 0, k); } else if (hasy) { js_setindex(J, 0, k - 1); js_delindex(J, 0, k); } --k; } } js_copy(J, 0); }
static void Ap_reverse(js_State *J) { unsigned int len, middle, lower; len = js_getlength(J, 0); middle = len / 2; lower = 0; while (lower != middle) { unsigned int upper = len - lower - 1; int haslower = js_hasindex(J, 0, lower); int hasupper = js_hasindex(J, 0, upper); if (haslower && hasupper) { js_setindex(J, 0, lower); js_setindex(J, 0, upper); } else if (hasupper) { js_setindex(J, 0, lower); js_delindex(J, 0, upper); } else if (haslower) { js_setindex(J, 0, upper); js_delindex(J, 0, lower); } ++lower; } js_copy(J, 0); }
static void Ap_splice(js_State *J) { unsigned int top = js_gettop(J); unsigned int len, start, del, add, k; double f; js_newarray(J); len = js_getlength(J, 0); f = js_tointeger(J, 1); if (f < 0) f = f + len; start = f < 0 ? 0 : f > len ? len : f; f = js_tointeger(J, 2); del = f < 0 ? 0 : f > len - start ? len - start : f; /* copy deleted items to return array */ for (k = 0; k < del; ++k) if (js_hasindex(J, 0, start + k)) js_setindex(J, -2, k); js_setlength(J, -1, del); /* shift the tail to resize the hole left by deleted items */ add = top - 3; if (add < del) { for (k = start; k < len - del; ++k) { if (js_hasindex(J, 0, k + del)) js_setindex(J, 0, k + add); else js_delindex(J, 0, k + add); } for (k = len; k > len - del + add; --k) js_delindex(J, 0, k - 1); } else if (add > del) { for (k = len - del; k > start; --k) { if (js_hasindex(J, 0, k + del - 1)) js_setindex(J, 0, k + add - 1); else js_delindex(J, 0, k + add - 1); } } /* copy new items into the hole */ for (k = 0; k < add; ++k) { js_copy(J, 3 + k); js_setindex(J, 0, start + k); } js_setlength(J, 0, len - del + add); }
static void Ap_unshift(js_State *J) { unsigned int i, top = js_gettop(J); unsigned int k, len; len = js_getlength(J, 0); for (k = len; k > 0; --k) { int from = k - 1; int to = k + top - 2; if (js_hasindex(J, 0, from)) js_setindex(J, 0, to); else js_delindex(J, 0, to); } for (i = 1; i < top; ++i) { js_copy(J, i); js_setindex(J, 0, i - 1); } js_setlength(J, 0, len + top - 1); js_pushnumber(J, len + top - 1); }
static void Ap_sort(js_State *J) { struct sortslot *array = NULL; int i, n, len; len = js_getlength(J, 0); if (len <= 0) { js_copy(J, 0); return; } if (len >= INT_MAX / (int)sizeof(*array)) js_rangeerror(J, "array is too large to sort"); array = js_malloc(J, len * sizeof *array); /* Holding objects where the GC cannot see them is illegal, but if we * don't allow the GC to run we can use qsort() on a temporary array of * js_Values for fast sorting. */ ++J->gcpause; if (js_try(J)) { --J->gcpause; js_free(J, array); js_throw(J); } n = 0; for (i = 0; i < len; ++i) { if (js_hasindex(J, 0, i)) { array[n].v = *js_tovalue(J, -1); array[n].J = J; js_pop(J, 1); ++n; } } qsort(array, n, sizeof *array, sortcmp); for (i = 0; i < n; ++i) { js_pushvalue(J, array[i].v); js_setindex(J, 0, i); } for (i = n; i < len; ++i) { js_delindex(J, 0, i); } --J->gcpause; js_endtry(J); js_free(J, array); js_copy(J, 0); }
static void Ap_shift(js_State *J) { unsigned int k, len; len = js_getlength(J, 0); if (len == 0) { js_setlength(J, 0, 0); js_pushundefined(J); return; } js_getindex(J, 0, 0); for (k = 1; k < len; ++k) { if (js_hasindex(J, 0, k)) js_setindex(J, 0, k - 1); else js_delindex(J, 0, k - 1); } js_delindex(J, 0, len - 1); js_setlength(J, 0, len - 1); }
static void Ap_pop(js_State *J) { unsigned int n; n = js_getlength(J, 0); if (n > 0) { js_getindex(J, 0, n - 1); js_delindex(J, 0, n - 1); js_setlength(J, 0, n - 1); } else { js_setlength(J, 0, 0); js_pushundefined(J); } }