Add table.new().

This commit is contained in:
Mike Pall 2013-10-09 17:01:22 +02:00
parent 47df3ae513
commit c8cfca0557
11 changed files with 55 additions and 6 deletions

View File

@ -208,6 +208,15 @@ minor releases (2.0 → 2.1) or between any beta release. Foreign
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

View File

@ -40,7 +40,7 @@ lib_string.o: lib_string.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
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 \

View File

@ -18,6 +18,7 @@
#include "lj_err.h"
#include "lj_buf.h"
#include "lj_tab.h"
#include "lj_ff.h"
#include "lj_lib.h"
/* ------------------------------------------------------------------------ */
@ -264,6 +265,24 @@ LJLIB_CF(table_pack)
}
#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"
@ -275,6 +294,7 @@ LUALIB_API int luaopen_table(lua_State *L)
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;
}

View File

@ -640,10 +640,8 @@ LUA_API void lua_pushlightuserdata(lua_State *L, void *p)
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);
}

View File

@ -1659,6 +1659,9 @@ static void asm_ir(ASMState *as, IRIns *ir)
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;

View File

@ -1003,6 +1003,14 @@ static void LJ_FASTCALL recff_table_concat(jit_State *J, RecordFFData *rd)
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

View File

@ -139,6 +139,7 @@
\
/* Calls. */ \
_(CALLN, N , ref, lit) \
_(CALLA, A , ref, lit) \
_(CALLL, L , ref, lit) \
_(CALLS, S , ref, lit) \
_(CALLXS, S , ref, ref) \

View File

@ -25,6 +25,7 @@ typedef struct CCallInfo {
#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)
@ -140,6 +141,7 @@ typedef struct CCallInfo {
_(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) \

View File

@ -165,7 +165,7 @@ typedef IRRef (LJ_FASTCALL *FoldFunc)(jit_State *J);
(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 ------------------------------------- */
@ -2319,8 +2319,9 @@ LJFOLD(XSTORE any any)
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. */

View File

@ -149,6 +149,12 @@ GCtab *lj_tab_new(lua_State *L, uint32_t asize, uint32_t hbits)
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)
{

View File

@ -34,6 +34,7 @@ static LJ_AINLINE uint32_t hashrot(uint32_t lo, uint32_t hi)
#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