lib_table.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. /*
  2. ** Table library.
  3. ** Copyright (C) 2005-2023 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_buf.h"
  17. #include "lj_tab.h"
  18. #include "lj_ff.h"
  19. #include "lj_lib.h"
  20. /* ------------------------------------------------------------------------ */
  21. #define LJLIB_MODULE_table
  22. LJLIB_LUA(table_foreachi) /*
  23. function(t, f)
  24. CHECK_tab(t)
  25. CHECK_func(f)
  26. for i=1,#t do
  27. local r = f(i, t[i])
  28. if r ~= nil then return r end
  29. end
  30. end
  31. */
  32. LJLIB_LUA(table_foreach) /*
  33. function(t, f)
  34. CHECK_tab(t)
  35. CHECK_func(f)
  36. for k, v in PAIRS(t) do
  37. local r = f(k, v)
  38. if r ~= nil then return r end
  39. end
  40. end
  41. */
  42. LJLIB_LUA(table_getn) /*
  43. function(t)
  44. CHECK_tab(t)
  45. return #t
  46. end
  47. */
  48. LJLIB_CF(table_maxn)
  49. {
  50. GCtab *t = lj_lib_checktab(L, 1);
  51. TValue *array = tvref(t->array);
  52. Node *node;
  53. lua_Number m = 0;
  54. ptrdiff_t i;
  55. for (i = (ptrdiff_t)t->asize - 1; i >= 0; i--)
  56. if (!tvisnil(&array[i])) {
  57. m = (lua_Number)(int32_t)i;
  58. break;
  59. }
  60. node = noderef(t->node);
  61. for (i = (ptrdiff_t)t->hmask; i >= 0; i--)
  62. if (!tvisnil(&node[i].val) && tvisnumber(&node[i].key)) {
  63. lua_Number n = numberVnum(&node[i].key);
  64. if (n > m) m = n;
  65. }
  66. setnumV(L->top-1, m);
  67. return 1;
  68. }
  69. LJLIB_CF(table_insert) LJLIB_REC(.)
  70. {
  71. GCtab *t = lj_lib_checktab(L, 1);
  72. int32_t n, i = (int32_t)lj_tab_len(t) + 1;
  73. int nargs = (int)((char *)L->top - (char *)L->base);
  74. if (nargs != 2*sizeof(TValue)) {
  75. if (nargs != 3*sizeof(TValue))
  76. lj_err_caller(L, LJ_ERR_TABINS);
  77. /* NOBARRIER: This just moves existing elements around. */
  78. for (n = lj_lib_checkint(L, 2); i > n; i--) {
  79. /* The set may invalidate the get pointer, so need to do it first! */
  80. TValue *dst = lj_tab_setint(L, t, i);
  81. cTValue *src = lj_tab_getint(t, i-1);
  82. if (src) {
  83. copyTV(L, dst, src);
  84. } else {
  85. setnilV(dst);
  86. }
  87. }
  88. i = n;
  89. }
  90. {
  91. TValue *dst = lj_tab_setint(L, t, i);
  92. copyTV(L, dst, L->top-1); /* Set new value. */
  93. lj_gc_barriert(L, t, dst);
  94. }
  95. return 0;
  96. }
  97. LJLIB_LUA(table_remove) /*
  98. function(t, pos)
  99. CHECK_tab(t)
  100. local len = #t
  101. if pos == nil then
  102. if len ~= 0 then
  103. local old = t[len]
  104. t[len] = nil
  105. return old
  106. end
  107. else
  108. CHECK_int(pos)
  109. if pos >= 1 and pos <= len then
  110. local old = t[pos]
  111. for i=pos+1,len do
  112. t[i-1] = t[i]
  113. end
  114. t[len] = nil
  115. return old
  116. end
  117. end
  118. end
  119. */
  120. LJLIB_LUA(table_move) /*
  121. function(a1, f, e, t, a2)
  122. CHECK_tab(a1)
  123. CHECK_int(f)
  124. CHECK_int(e)
  125. CHECK_int(t)
  126. if a2 == nil then a2 = a1 end
  127. CHECK_tab(a2)
  128. if e >= f then
  129. local d = t - f
  130. if t > e or t <= f or a2 ~= a1 then
  131. for i=f,e do a2[i+d] = a1[i] end
  132. else
  133. for i=e,f,-1 do a2[i+d] = a1[i] end
  134. end
  135. end
  136. return a2
  137. end
  138. */
  139. LJLIB_CF(table_concat) LJLIB_REC(.)
  140. {
  141. GCtab *t = lj_lib_checktab(L, 1);
  142. GCstr *sep = lj_lib_optstr(L, 2);
  143. int32_t i = lj_lib_optint(L, 3, 1);
  144. int32_t e = (L->base+3 < L->top && !tvisnil(L->base+3)) ?
  145. lj_lib_checkint(L, 4) : (int32_t)lj_tab_len(t);
  146. SBuf *sb = lj_buf_tmp_(L);
  147. SBuf *sbx = lj_buf_puttab(sb, t, sep, i, e);
  148. if (LJ_UNLIKELY(!sbx)) { /* Error: bad element type. */
  149. int32_t idx = (int32_t)(intptr_t)sb->w;
  150. cTValue *o = lj_tab_getint(t, idx);
  151. lj_err_callerv(L, LJ_ERR_TABCAT,
  152. lj_obj_itypename[o ? itypemap(o) : ~LJ_TNIL], idx);
  153. }
  154. setstrV(L, L->top-1, lj_buf_str(L, sbx));
  155. lj_gc_check(L);
  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. LJLIB_NOREG LJLIB_CF(table_new) LJLIB_REC(.)
  269. {
  270. int32_t a = lj_lib_checkint(L, 1);
  271. int32_t h = lj_lib_checkint(L, 2);
  272. lua_createtable(L, a, h);
  273. return 1;
  274. }
  275. LJLIB_NOREG LJLIB_CF(table_clear) LJLIB_REC(.)
  276. {
  277. lj_tab_clear(lj_lib_checktab(L, 1));
  278. return 0;
  279. }
  280. static int luaopen_table_new(lua_State *L)
  281. {
  282. return lj_lib_postreg(L, lj_cf_table_new, FF_table_new, "new");
  283. }
  284. static int luaopen_table_clear(lua_State *L)
  285. {
  286. return lj_lib_postreg(L, lj_cf_table_clear, FF_table_clear, "clear");
  287. }
  288. /* ------------------------------------------------------------------------ */
  289. #include "lj_libdef.h"
  290. LUALIB_API int luaopen_table(lua_State *L)
  291. {
  292. LJ_LIB_REG(L, LUA_TABLIBNAME, table);
  293. #if LJ_52
  294. lua_getglobal(L, "unpack");
  295. lua_setfield(L, -2, "unpack");
  296. #endif
  297. lj_lib_prereg(L, LUA_TABLIBNAME ".new", luaopen_table_new, tabV(L->top-1));
  298. lj_lib_prereg(L, LUA_TABLIBNAME ".clear", luaopen_table_clear, tabV(L->top-1));
  299. return 1;
  300. }