lib_table.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. /*
  2. ** Table library.
  3. ** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h
  4. **
  5. ** Major portions taken verbatim or adapted from the Lua interpreter.
  6. ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
  7. */
  8. #define lib_table_c
  9. #define LUA_LIB
  10. #include "lua.h"
  11. #include "lauxlib.h"
  12. #include "lualib.h"
  13. #include "lj_obj.h"
  14. #include "lj_gc.h"
  15. #include "lj_err.h"
  16. #include "lj_tab.h"
  17. #include "lj_lib.h"
  18. /* ------------------------------------------------------------------------ */
  19. #define LJLIB_MODULE_table
  20. LJLIB_CF(table_foreachi)
  21. {
  22. GCtab *t = lj_lib_checktab(L, 1);
  23. GCfunc *func = lj_lib_checkfunc(L, 2);
  24. MSize i, n = lj_tab_len(t);
  25. for (i = 1; i <= n; i++) {
  26. cTValue *val;
  27. setfuncV(L, L->top, func);
  28. setintV(L->top+1, i);
  29. val = lj_tab_getint(t, (int32_t)i);
  30. if (val) { copyTV(L, L->top+2, val); } else { setnilV(L->top+2); }
  31. L->top += 3;
  32. lua_call(L, 2, 1);
  33. if (!tvisnil(L->top-1))
  34. return 1;
  35. L->top--;
  36. }
  37. return 0;
  38. }
  39. LJLIB_CF(table_foreach)
  40. {
  41. GCtab *t = lj_lib_checktab(L, 1);
  42. GCfunc *func = lj_lib_checkfunc(L, 2);
  43. L->top = L->base+3;
  44. setnilV(L->top-1);
  45. while (lj_tab_next(L, t, L->top-1)) {
  46. copyTV(L, L->top+2, L->top);
  47. copyTV(L, L->top+1, L->top-1);
  48. setfuncV(L, L->top, func);
  49. L->top += 3;
  50. lua_call(L, 2, 1);
  51. if (!tvisnil(L->top-1))
  52. return 1;
  53. L->top--;
  54. }
  55. return 0;
  56. }
  57. LJLIB_ASM(table_getn) LJLIB_REC(.)
  58. {
  59. lj_lib_checktab(L, 1);
  60. return FFH_UNREACHABLE;
  61. }
  62. LJLIB_CF(table_maxn)
  63. {
  64. GCtab *t = lj_lib_checktab(L, 1);
  65. TValue *array = tvref(t->array);
  66. Node *node;
  67. lua_Number m = 0;
  68. ptrdiff_t i;
  69. for (i = (ptrdiff_t)t->asize - 1; i >= 0; i--)
  70. if (!tvisnil(&array[i])) {
  71. m = (lua_Number)(int32_t)i;
  72. break;
  73. }
  74. node = noderef(t->node);
  75. for (i = (ptrdiff_t)t->hmask; i >= 0; i--)
  76. if (!tvisnil(&node[i].val) && tvisnumber(&node[i].key)) {
  77. lua_Number n = numberVnum(&node[i].key);
  78. if (n > m) m = n;
  79. }
  80. setnumV(L->top-1, m);
  81. return 1;
  82. }
  83. LJLIB_CF(table_insert) LJLIB_REC(.)
  84. {
  85. GCtab *t = lj_lib_checktab(L, 1);
  86. int32_t n, i = (int32_t)lj_tab_len(t) + 1;
  87. int nargs = (int)((char *)L->top - (char *)L->base);
  88. if (nargs != 2*sizeof(TValue)) {
  89. if (nargs != 3*sizeof(TValue))
  90. lj_err_caller(L, LJ_ERR_TABINS);
  91. /* NOBARRIER: This just moves existing elements around. */
  92. for (n = lj_lib_checkint(L, 2); i > n; i--) {
  93. /* The set may invalidate the get pointer, so need to do it first! */
  94. TValue *dst = lj_tab_setint(L, t, i);
  95. cTValue *src = lj_tab_getint(t, i-1);
  96. if (src) {
  97. copyTV(L, dst, src);
  98. } else {
  99. setnilV(dst);
  100. }
  101. }
  102. i = n;
  103. }
  104. {
  105. TValue *dst = lj_tab_setint(L, t, i);
  106. copyTV(L, dst, L->top-1); /* Set new value. */
  107. lj_gc_barriert(L, t, dst);
  108. }
  109. return 0;
  110. }
  111. LJLIB_CF(table_remove) LJLIB_REC(.)
  112. {
  113. GCtab *t = lj_lib_checktab(L, 1);
  114. int32_t e = (int32_t)lj_tab_len(t);
  115. int32_t pos = lj_lib_optint(L, 2, e);
  116. if (!(1 <= pos && pos <= e)) /* Nothing to remove? */
  117. return 0;
  118. lua_rawgeti(L, 1, pos); /* Get previous value. */
  119. /* NOBARRIER: This just moves existing elements around. */
  120. for (; pos < e; pos++) {
  121. cTValue *src = lj_tab_getint(t, pos+1);
  122. TValue *dst = lj_tab_setint(L, t, pos);
  123. if (src) {
  124. copyTV(L, dst, src);
  125. } else {
  126. setnilV(dst);
  127. }
  128. }
  129. setnilV(lj_tab_setint(L, t, e)); /* Remove (last) value. */
  130. return 1; /* Return previous value. */
  131. }
  132. LJLIB_CF(table_concat)
  133. {
  134. luaL_Buffer b;
  135. GCtab *t = lj_lib_checktab(L, 1);
  136. GCstr *sep = lj_lib_optstr(L, 2);
  137. MSize seplen = sep ? sep->len : 0;
  138. int32_t i = lj_lib_optint(L, 3, 1);
  139. int32_t e = (L->base+3 < L->top && !tvisnil(L->base+3)) ?
  140. lj_lib_checkint(L, 4) : (int32_t)lj_tab_len(t);
  141. luaL_buffinit(L, &b);
  142. if (i <= e) {
  143. for (;;) {
  144. cTValue *o;
  145. lua_rawgeti(L, 1, i);
  146. o = L->top-1;
  147. if (!(tvisstr(o) || tvisnumber(o)))
  148. lj_err_callerv(L, LJ_ERR_TABCAT, lj_typename(o), i);
  149. luaL_addvalue(&b);
  150. if (i++ == e) break;
  151. if (seplen)
  152. luaL_addlstring(&b, strdata(sep), seplen);
  153. }
  154. }
  155. luaL_pushresult(&b);
  156. return 1;
  157. }
  158. /* ------------------------------------------------------------------------ */
  159. static void set2(lua_State *L, int i, int j)
  160. {
  161. lua_rawseti(L, 1, i);
  162. lua_rawseti(L, 1, j);
  163. }
  164. static int sort_comp(lua_State *L, int a, int b)
  165. {
  166. if (!lua_isnil(L, 2)) { /* function? */
  167. int res;
  168. lua_pushvalue(L, 2);
  169. lua_pushvalue(L, a-1); /* -1 to compensate function */
  170. lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */
  171. lua_call(L, 2, 1);
  172. res = lua_toboolean(L, -1);
  173. lua_pop(L, 1);
  174. return res;
  175. } else { /* a < b? */
  176. return lua_lessthan(L, a, b);
  177. }
  178. }
  179. static void auxsort(lua_State *L, int l, int u)
  180. {
  181. while (l < u) { /* for tail recursion */
  182. int i, j;
  183. /* sort elements a[l], a[(l+u)/2] and a[u] */
  184. lua_rawgeti(L, 1, l);
  185. lua_rawgeti(L, 1, u);
  186. if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */
  187. set2(L, l, u); /* swap a[l] - a[u] */
  188. else
  189. lua_pop(L, 2);
  190. if (u-l == 1) break; /* only 2 elements */
  191. i = (l+u)/2;
  192. lua_rawgeti(L, 1, i);
  193. lua_rawgeti(L, 1, l);
  194. if (sort_comp(L, -2, -1)) { /* a[i]<a[l]? */
  195. set2(L, i, l);
  196. } else {
  197. lua_pop(L, 1); /* remove a[l] */
  198. lua_rawgeti(L, 1, u);
  199. if (sort_comp(L, -1, -2)) /* a[u]<a[i]? */
  200. set2(L, i, u);
  201. else
  202. lua_pop(L, 2);
  203. }
  204. if (u-l == 2) break; /* only 3 elements */
  205. lua_rawgeti(L, 1, i); /* Pivot */
  206. lua_pushvalue(L, -1);
  207. lua_rawgeti(L, 1, u-1);
  208. set2(L, i, u-1);
  209. /* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */
  210. i = l; j = u-1;
  211. for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */
  212. /* repeat ++i until a[i] >= P */
  213. while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
  214. if (i>=u) lj_err_caller(L, LJ_ERR_TABSORT);
  215. lua_pop(L, 1); /* remove a[i] */
  216. }
  217. /* repeat --j until a[j] <= P */
  218. while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
  219. if (j<=l) lj_err_caller(L, LJ_ERR_TABSORT);
  220. lua_pop(L, 1); /* remove a[j] */
  221. }
  222. if (j<i) {
  223. lua_pop(L, 3); /* pop pivot, a[i], a[j] */
  224. break;
  225. }
  226. set2(L, i, j);
  227. }
  228. lua_rawgeti(L, 1, u-1);
  229. lua_rawgeti(L, 1, i);
  230. set2(L, u-1, i); /* swap pivot (a[u-1]) with a[i] */
  231. /* a[l..i-1] <= a[i] == P <= a[i+1..u] */
  232. /* adjust so that smaller half is in [j..i] and larger one in [l..u] */
  233. if (i-l < u-i) {
  234. j=l; i=i-1; l=i+2;
  235. } else {
  236. j=i+1; i=u; u=j-2;
  237. }
  238. auxsort(L, j, i); /* call recursively the smaller one */
  239. } /* repeat the routine for the larger one */
  240. }
  241. LJLIB_CF(table_sort)
  242. {
  243. GCtab *t = lj_lib_checktab(L, 1);
  244. int32_t n = (int32_t)lj_tab_len(t);
  245. lua_settop(L, 2);
  246. if (!tvisnil(L->base+1))
  247. lj_lib_checkfunc(L, 2);
  248. auxsort(L, 1, n);
  249. return 0;
  250. }
  251. #if LJ_52
  252. LJLIB_PUSH("n")
  253. LJLIB_CF(table_pack)
  254. {
  255. TValue *array, *base = L->base;
  256. MSize i, n = (uint32_t)(L->top - base);
  257. GCtab *t = lj_tab_new(L, n ? n+1 : 0, 1);
  258. /* NOBARRIER: The table is new (marked white). */
  259. setintV(lj_tab_setstr(L, t, strV(lj_lib_upvalue(L, 1))), (int32_t)n);
  260. for (array = tvref(t->array) + 1, i = 0; i < n; i++)
  261. copyTV(L, &array[i], &base[i]);
  262. settabV(L, base, t);
  263. L->top = base+1;
  264. lj_gc_check(L);
  265. return 1;
  266. }
  267. #endif
  268. /* ------------------------------------------------------------------------ */
  269. #include "lj_libdef.h"
  270. LUALIB_API int luaopen_table(lua_State *L)
  271. {
  272. LJ_LIB_REG(L, LUA_TABLIBNAME, table);
  273. #if LJ_52
  274. lua_getglobal(L, "unpack");
  275. lua_setfield(L, -2, "unpack");
  276. #endif
  277. return 1;
  278. }