Add table.clear().
This commit is contained in:
@@ -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_vm.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_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
|
||||
|
||||
@@ -273,11 +273,22 @@ LJLIB_NOREG LJLIB_CF(table_new) LJLIB_REC(.)
|
||||
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)
|
||||
{
|
||||
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"
|
||||
@@ -290,6 +301,7 @@ LUALIB_API int luaopen_table(lua_State *L)
|
||||
lua_setfield(L, -2, "unpack");
|
||||
#endif
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -1024,6 +1024,16 @@ static void LJ_FASTCALL recff_table_new(jit_State *J, RecordFFData *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 ------------------------------------------ */
|
||||
|
||||
/* 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_new1, 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_len, 1, FL, INT, 0) \
|
||||
_(ANY, lj_gc_step_jit, 2, FS, NIL, CCI_L) \
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "lj_ir.h"
|
||||
#include "lj_jit.h"
|
||||
#include "lj_iropt.h"
|
||||
#include "lj_ircall.h"
|
||||
|
||||
/* Some local macros to save typing. Undef'd at the end. */
|
||||
#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. */
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
IRRef ta = fins->op1;
|
||||
@@ -319,6 +320,14 @@ int LJ_FASTCALL lj_opt_fwd_tptr(jit_State *J, IRRef lim)
|
||||
return 0; /* Conflict. */
|
||||
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. */
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
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);
|
||||
#endif
|
||||
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);
|
||||
#if LJ_HASFFI
|
||||
LJ_FUNC void lj_tab_rehash(lua_State *L, GCtab *t);
|
||||
|
||||
Reference in New Issue
Block a user