bytecode (e.g. from Lua 5.1) is incompatible and cannot be loaded.
</p>
+<h3 id="table_new"><tt>table.new(narray, nhash)</tt> allocates a pre-sized table</h3>
+<p>
+An extra library function <tt>table.new()</tt> can be made available via
+<tt>require("table.new")</tt>. This creates a pre-sized table, just like
+the C API equivalent <tt>lua_createtable()</tt>. This is useful for big
+tables if the final table size is known and automatic table resizing is
+too expensive.
+</p>
+
<h3 id="math_random">Enhanced PRNG for <tt>math.random()</tt></h3>
<p>
LuaJIT uses a Tausworthe PRNG with period 2^223 to implement
lj_char.h lj_strfmt.h lj_lib.h lj_libdef.h
lib_table.o: lib_table.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h \
- lj_tab.h lj_lib.h lj_libdef.h
+ lj_tab.h lj_ff.h lj_ffdef.h lj_lib.h lj_libdef.h
lj_alloc.o: lj_alloc.c lj_def.h lua.h luaconf.h lj_arch.h lj_alloc.h
lj_api.o: lj_api.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h lj_func.h lj_udata.h \
#include "lj_err.h"
#include "lj_buf.h"
#include "lj_tab.h"
+#include "lj_ff.h"
#include "lj_lib.h"
/* ------------------------------------------------------------------------ */
}
#endif
+LJLIB_NOREG LJLIB_CF(table_new) LJLIB_REC(.)
+{
+ int32_t a = lj_lib_checkint(L, 1);
+ int32_t h = lj_lib_checkint(L, 2);
+ lua_createtable(L, a, h);
+ return 1;
+}
+
+static int luaopen_table_new(lua_State *L)
+{
+ GCfunc *fn = lj_lib_pushcc(L, lj_cf_table_new, FF_table_new, 0);
+ GCtab *t = tabref(curr_func(L)->c.env); /* Reference to "table". */
+ setfuncV(L, lj_tab_setstr(L, t, lj_str_newlit(L, "new")), fn);
+ lj_gc_anybarriert(L, t);
+ setfuncV(L, L->top++, fn);
+ return 1;
+}
+
/* ------------------------------------------------------------------------ */
#include "lj_libdef.h"
lua_getglobal(L, "unpack");
lua_setfield(L, -2, "unpack");
#endif
+ lj_lib_prereg(L, LUA_TABLIBNAME ".new", luaopen_table_new, tabV(L->top-1));
return 1;
}
LUA_API void lua_createtable(lua_State *L, int narray, int nrec)
{
- GCtab *t;
lj_gc_check(L);
- t = lj_tab_new(L, (uint32_t)(narray > 0 ? narray+1 : 0), hsize2hbits(nrec));
- settabV(L, L->top, t);
+ settabV(L, L->top, lj_tab_new_ah(L, narray, nrec));
incr_top(L);
}
case IR_STRTO: asm_strto(as, ir); break;
/* Calls. */
+ case IR_CALLA:
+ as->gcsteps++;
+ /* fallthrough */
case IR_CALLN: case IR_CALLL: case IR_CALLS: asm_call(as, ir); break;
case IR_CALLXS: asm_callx(as, ir); break;
case IR_CARG: break;
UNUSED(rd);
}
+static void LJ_FASTCALL recff_table_new(jit_State *J, RecordFFData *rd)
+{
+ TRef tra = lj_opt_narrow_toint(J, J->base[0]);
+ TRef trh = lj_opt_narrow_toint(J, J->base[1]);
+ J->base[0] = lj_ir_call(J, IRCALL_lj_tab_new_ah, tra, trh);
+ UNUSED(rd);
+}
+
/* -- I/O library fast functions ------------------------------------------ */
/* Get FILE* for I/O function. Any I/O error aborts recording, so there's
\
/* Calls. */ \
_(CALLN, N , ref, lit) \
+ _(CALLA, A , ref, lit) \
_(CALLL, L , ref, lit) \
_(CALLS, S , ref, lit) \
_(CALLXS, S , ref, ref) \
#define CCI_OP(ci) ((ci)->flags >> CCI_OPSHIFT) /* Get op. */
#define CCI_CALL_N (IR_CALLN << CCI_OPSHIFT)
+#define CCI_CALL_A (IR_CALLA << CCI_OPSHIFT)
#define CCI_CALL_L (IR_CALLL << CCI_OPSHIFT)
#define CCI_CALL_S (IR_CALLS << CCI_OPSHIFT)
#define CCI_CALL_FN (CCI_CALL_N|CCI_CC_FASTCALL)
_(ANY, lj_buf_putstr_rep, 3, L, P32, 0) \
_(ANY, lj_buf_puttab, 5, L, P32, 0) \
_(ANY, lj_buf_tostr, 1, FL, STR, 0) \
+ _(ANY, lj_tab_new_ah, 3, A, TAB, CCI_L) \
_(ANY, lj_tab_new1, 2, FS, TAB, CCI_L) \
_(ANY, lj_tab_dup, 2, FS, TAB, CCI_L) \
_(ANY, lj_tab_newkey, 3, S, P32, CCI_L) \
(J->chain[IR_SNEW] || J->chain[IR_XSNEW] || \
J->chain[IR_TNEW] || J->chain[IR_TDUP] || \
J->chain[IR_CNEW] || J->chain[IR_CNEWI] || \
- J->chain[IR_BUFSTR] || J->chain[IR_TOSTR]))
+ J->chain[IR_BUFSTR] || J->chain[IR_TOSTR] || J->chain[IR_CALLA]))
/* -- Constant folding for FP numbers ------------------------------------- */
LJFOLDX(lj_opt_dse_xstore)
LJFOLD(NEWREF any any) /* Treated like a store. */
-LJFOLD(CALLS any any)
+LJFOLD(CALLA any any)
LJFOLD(CALLL any any) /* Safeguard fallback. */
+LJFOLD(CALLS any any)
LJFOLD(CALLXS any any)
LJFOLD(XBAR)
LJFOLD(RETF any any) /* Modifies BASE. */
return t;
}
+/* The API of this function conforms to lua_createtable(). */
+GCtab *lj_tab_new_ah(lua_State *L, int32_t a, int32_t h)
+{
+ return lj_tab_new(L, (uint32_t)(a > 0 ? a+1 : 0), hsize2hbits(h));
+}
+
#if LJ_HASJIT
GCtab * LJ_FASTCALL lj_tab_new1(lua_State *L, uint32_t ahsize)
{
#define hsize2hbits(s) ((s) ? ((s)==1 ? 1 : 1+lj_fls((uint32_t)((s)-1))) : 0)
LJ_FUNCA GCtab *lj_tab_new(lua_State *L, uint32_t asize, uint32_t hbits);
+LJ_FUNC GCtab *lj_tab_new_ah(lua_State *L, int32_t a, int32_t h);
#if LJ_HASJIT
LJ_FUNC GCtab * LJ_FASTCALL lj_tab_new1(lua_State *L, uint32_t ahsize);
#endif