mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
Add table.clear().
This commit is contained in:
parent
c378f7dbb8
commit
4593fb5e29
@ -217,6 +217,22 @@ tables if the final table size is known and automatic table resizing is
|
|||||||
too expensive.
|
too expensive.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<h3 id="table_clear"><tt>table.clear(tab)</tt> clears a table</h3>
|
||||||
|
<p>
|
||||||
|
An extra library function <tt>table.clear()</tt> can be made available
|
||||||
|
via <tt>require("table.clear")</tt>. This clears all keys and values
|
||||||
|
from a table, but preserves the allocated array/hash sizes. This is
|
||||||
|
useful when a table, which is linked from multiple places, needs to be
|
||||||
|
cleared and/or when recycling a table for use by the same context. This
|
||||||
|
avoids managing backlinks, saves an allocation and the overhead of
|
||||||
|
incremental array/hash part growth.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Please note this function is meant for very specific situations. In most
|
||||||
|
cases it's better to replace the (usually single) link with a new table
|
||||||
|
and let the GC do its work.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h3 id="math_random">Enhanced PRNG for <tt>math.random()</tt></h3>
|
<h3 id="math_random">Enhanced PRNG for <tt>math.random()</tt></h3>
|
||||||
<p>
|
<p>
|
||||||
LuaJIT uses a Tausworthe PRNG with period 2^223 to implement
|
LuaJIT uses a Tausworthe PRNG with period 2^223 to implement
|
||||||
|
@ -155,7 +155,7 @@ lj_opt_loop.o: lj_opt_loop.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
|||||||
lj_iropt.h lj_trace.h lj_dispatch.h lj_bc.h lj_traceerr.h lj_snap.h \
|
lj_iropt.h lj_trace.h lj_dispatch.h lj_bc.h lj_traceerr.h lj_snap.h \
|
||||||
lj_vm.h
|
lj_vm.h
|
||||||
lj_opt_mem.o: lj_opt_mem.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
lj_opt_mem.o: lj_opt_mem.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||||
lj_tab.h lj_ir.h lj_jit.h lj_iropt.h
|
lj_tab.h lj_ir.h lj_jit.h lj_iropt.h lj_ircall.h
|
||||||
lj_opt_narrow.o: lj_opt_narrow.c lj_obj.h lua.h luaconf.h lj_def.h \
|
lj_opt_narrow.o: lj_opt_narrow.c lj_obj.h lua.h luaconf.h lj_def.h \
|
||||||
lj_arch.h lj_bc.h lj_ir.h lj_jit.h lj_iropt.h lj_trace.h lj_dispatch.h \
|
lj_arch.h lj_bc.h lj_ir.h lj_jit.h lj_iropt.h lj_trace.h lj_dispatch.h \
|
||||||
lj_traceerr.h lj_vm.h lj_strscan.h
|
lj_traceerr.h lj_vm.h lj_strscan.h
|
||||||
|
@ -273,11 +273,22 @@ LJLIB_NOREG LJLIB_CF(table_new) LJLIB_REC(.)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LJLIB_NOREG LJLIB_CF(table_clear) LJLIB_REC(.)
|
||||||
|
{
|
||||||
|
lj_tab_clear(lj_lib_checktab(L, 1));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int luaopen_table_new(lua_State *L)
|
static int luaopen_table_new(lua_State *L)
|
||||||
{
|
{
|
||||||
return lj_lib_postreg(L, lj_cf_table_new, FF_table_new, "new");
|
return lj_lib_postreg(L, lj_cf_table_new, FF_table_new, "new");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int luaopen_table_clear(lua_State *L)
|
||||||
|
{
|
||||||
|
return lj_lib_postreg(L, lj_cf_table_clear, FF_table_clear, "clear");
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
#include "lj_libdef.h"
|
#include "lj_libdef.h"
|
||||||
@ -290,6 +301,7 @@ LUALIB_API int luaopen_table(lua_State *L)
|
|||||||
lua_setfield(L, -2, "unpack");
|
lua_setfield(L, -2, "unpack");
|
||||||
#endif
|
#endif
|
||||||
lj_lib_prereg(L, LUA_TABLIBNAME ".new", luaopen_table_new, tabV(L->top-1));
|
lj_lib_prereg(L, LUA_TABLIBNAME ".new", luaopen_table_new, tabV(L->top-1));
|
||||||
|
lj_lib_prereg(L, LUA_TABLIBNAME ".clear", luaopen_table_clear, tabV(L->top-1));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1024,6 +1024,16 @@ static void LJ_FASTCALL recff_table_new(jit_State *J, RecordFFData *rd)
|
|||||||
UNUSED(rd);
|
UNUSED(rd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void LJ_FASTCALL recff_table_clear(jit_State *J, RecordFFData *rd)
|
||||||
|
{
|
||||||
|
TRef tr = J->base[0];
|
||||||
|
if (tref_istab(tr)) {
|
||||||
|
rd->nres = 0;
|
||||||
|
lj_ir_call(J, IRCALL_lj_tab_clear, tr);
|
||||||
|
J->needsnap = 1;
|
||||||
|
} /* else: Interpreter will throw. */
|
||||||
|
}
|
||||||
|
|
||||||
/* -- I/O library fast functions ------------------------------------------ */
|
/* -- I/O library fast functions ------------------------------------------ */
|
||||||
|
|
||||||
/* Get FILE* for I/O function. Any I/O error aborts recording, so there's
|
/* Get FILE* for I/O function. Any I/O error aborts recording, so there's
|
||||||
|
@ -144,6 +144,7 @@ typedef struct CCallInfo {
|
|||||||
_(ANY, lj_tab_new_ah, 3, A, TAB, CCI_L) \
|
_(ANY, lj_tab_new_ah, 3, A, TAB, CCI_L) \
|
||||||
_(ANY, lj_tab_new1, 2, FS, TAB, CCI_L) \
|
_(ANY, lj_tab_new1, 2, FS, TAB, CCI_L) \
|
||||||
_(ANY, lj_tab_dup, 2, FS, TAB, CCI_L) \
|
_(ANY, lj_tab_dup, 2, FS, TAB, CCI_L) \
|
||||||
|
_(ANY, lj_tab_clear, 1, FS, NIL, 0) \
|
||||||
_(ANY, lj_tab_newkey, 3, S, P32, CCI_L) \
|
_(ANY, lj_tab_newkey, 3, S, P32, CCI_L) \
|
||||||
_(ANY, lj_tab_len, 1, FL, INT, 0) \
|
_(ANY, lj_tab_len, 1, FL, INT, 0) \
|
||||||
_(ANY, lj_gc_step_jit, 2, FS, NIL, CCI_L) \
|
_(ANY, lj_gc_step_jit, 2, FS, NIL, CCI_L) \
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "lj_ir.h"
|
#include "lj_ir.h"
|
||||||
#include "lj_jit.h"
|
#include "lj_jit.h"
|
||||||
#include "lj_iropt.h"
|
#include "lj_iropt.h"
|
||||||
|
#include "lj_ircall.h"
|
||||||
|
|
||||||
/* Some local macros to save typing. Undef'd at the end. */
|
/* Some local macros to save typing. Undef'd at the end. */
|
||||||
#define IR(ref) (&J->cur.ir[(ref)])
|
#define IR(ref) (&J->cur.ir[(ref)])
|
||||||
@ -308,7 +309,7 @@ int LJ_FASTCALL lj_opt_fwd_href_nokey(jit_State *J)
|
|||||||
return 1; /* No conflict. Can fold to niltv. */
|
return 1; /* No conflict. Can fold to niltv. */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check whether there's no aliasing NEWREF for the left operand. */
|
/* Check whether there's no aliasing NEWREF/table.clear for the left operand. */
|
||||||
int LJ_FASTCALL lj_opt_fwd_tptr(jit_State *J, IRRef lim)
|
int LJ_FASTCALL lj_opt_fwd_tptr(jit_State *J, IRRef lim)
|
||||||
{
|
{
|
||||||
IRRef ta = fins->op1;
|
IRRef ta = fins->op1;
|
||||||
@ -319,6 +320,14 @@ int LJ_FASTCALL lj_opt_fwd_tptr(jit_State *J, IRRef lim)
|
|||||||
return 0; /* Conflict. */
|
return 0; /* Conflict. */
|
||||||
ref = newref->prev;
|
ref = newref->prev;
|
||||||
}
|
}
|
||||||
|
ref = J->chain[IR_CALLS];
|
||||||
|
while (ref > lim) {
|
||||||
|
IRIns *calls = IR(ref);
|
||||||
|
if (calls->op2 == IRCALL_lj_tab_clear &&
|
||||||
|
(ta == calls->op1 || aa_table(J, ta, calls->op1) != ALIAS_NO))
|
||||||
|
return 0; /* Conflict. */
|
||||||
|
ref = calls->prev;
|
||||||
|
}
|
||||||
return 1; /* No conflict. Can safely FOLD/CSE. */
|
return 1; /* No conflict. Can safely FOLD/CSE. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
src/lj_tab.c
11
src/lj_tab.c
@ -204,6 +204,17 @@ GCtab * LJ_FASTCALL lj_tab_dup(lua_State *L, const GCtab *kt)
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clear a table. */
|
||||||
|
void LJ_FASTCALL lj_tab_clear(GCtab *t)
|
||||||
|
{
|
||||||
|
clearapart(t);
|
||||||
|
if (t->hmask > 0) {
|
||||||
|
Node *node = noderef(t->node);
|
||||||
|
setmref(node->freetop, &node[t->hmask+1]);
|
||||||
|
clearhpart(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Free a table. */
|
/* Free a table. */
|
||||||
void LJ_FASTCALL lj_tab_free(global_State *g, GCtab *t)
|
void LJ_FASTCALL lj_tab_free(global_State *g, GCtab *t)
|
||||||
{
|
{
|
||||||
|
@ -39,6 +39,7 @@ LJ_FUNC GCtab *lj_tab_new_ah(lua_State *L, int32_t a, int32_t h);
|
|||||||
LJ_FUNC GCtab * LJ_FASTCALL lj_tab_new1(lua_State *L, uint32_t ahsize);
|
LJ_FUNC GCtab * LJ_FASTCALL lj_tab_new1(lua_State *L, uint32_t ahsize);
|
||||||
#endif
|
#endif
|
||||||
LJ_FUNCA GCtab * LJ_FASTCALL lj_tab_dup(lua_State *L, const GCtab *kt);
|
LJ_FUNCA GCtab * LJ_FASTCALL lj_tab_dup(lua_State *L, const GCtab *kt);
|
||||||
|
LJ_FUNC void LJ_FASTCALL lj_tab_clear(GCtab *t);
|
||||||
LJ_FUNC void LJ_FASTCALL lj_tab_free(global_State *g, GCtab *t);
|
LJ_FUNC void LJ_FASTCALL lj_tab_free(global_State *g, GCtab *t);
|
||||||
#if LJ_HASFFI
|
#if LJ_HASFFI
|
||||||
LJ_FUNC void lj_tab_rehash(lua_State *L, GCtab *t);
|
LJ_FUNC void lj_tab_rehash(lua_State *L, GCtab *t);
|
||||||
|
Loading…
Reference in New Issue
Block a user