Replace table.remove with bytecode builtin.

This commit is contained in:
Mike Pall 2013-02-24 17:59:04 +01:00
parent b8abb4b91d
commit 5e601891fc
3 changed files with 30 additions and 55 deletions

View File

@ -9,7 +9,11 @@ static const uint8_t libbc_code[] = {
59,8,5,0,66,6,3,2,10,6,0,0,88,7,1,128,76,6,2,0,79,2,248,127,75,0,1,0,0,2,10, 59,8,5,0,66,6,3,2,10,6,0,0,88,7,1,128,76,6,2,0,79,2,248,127,75,0,1,0,0,2,10,
0,0,0,16,16,0,12,0,16,1,9,0,43,2,0,0,18,3,0,0,41,4,0,0,88,5,7,128,18,7,1,0, 0,0,0,16,16,0,12,0,16,1,9,0,43,2,0,0,18,3,0,0,41,4,0,0,88,5,7,128,18,7,1,0,
18,8,5,0,18,9,6,0,66,7,3,2,10,7,0,0,88,8,1,128,76,7,2,0,70,5,3,3,82,5,247,127, 18,8,5,0,18,9,6,0,66,7,3,2,10,7,0,0,88,8,1,128,76,7,2,0,70,5,3,3,82,5,247,127,
75,0,1,0,0,1,2,0,0,0,3,16,0,12,0,21,1,0,0,76,1,2,0,0 75,0,1,0,0,1,2,0,0,0,3,16,0,12,0,21,1,0,0,76,1,2,0,0,2,10,0,0,2,30,16,0,12,
0,21,2,0,0,11,1,0,0,88,3,7,128,8,2,0,0,88,3,23,128,59,3,2,0,43,4,0,0,64,4,2,
0,76,3,2,0,88,3,18,128,16,1,14,0,41,3,1,0,3,3,1,0,88,3,14,128,3,1,2,0,88,3,
12,128,59,3,1,0,22,4,1,1,18,5,2,0,41,6,1,0,77,4,4,128,23,8,1,7,59,9,7,0,64,
9,8,0,79,4,252,127,43,4,0,0,64,4,2,0,76,3,2,0,75,0,1,0,0,2,0
}; };
static const struct { const char *name; int ofs; } libbc_map[] = { static const struct { const char *name; int ofs; } libbc_map[] = {
@ -18,6 +22,7 @@ static const struct { const char *name; int ofs; } libbc_map[] = {
{"table_foreachi",50}, {"table_foreachi",50},
{"table_foreach",117}, {"table_foreach",117},
{"table_getn",188}, {"table_getn",188},
{NULL,207} {"table_remove",207},
{NULL,336}
}; };

View File

@ -103,27 +103,29 @@ LJLIB_CF(table_insert) LJLIB_REC(.)
return 0; return 0;
} }
LJLIB_CF(table_remove) LJLIB_REC(.) LJLIB_LUA(table_remove) /*
{ function(t, pos)
GCtab *t = lj_lib_checktab(L, 1); CHECK_tab(t)
int32_t e = (int32_t)lj_tab_len(t); local len = #t
int32_t pos = lj_lib_optint(L, 2, e); if pos == nil then
if (!(1 <= pos && pos <= e)) /* Nothing to remove? */ if len ~= 0 then
return 0; local old = t[len]
lua_rawgeti(L, 1, pos); /* Get previous value. */ t[len] = nil
/* NOBARRIER: This just moves existing elements around. */ return old
for (; pos < e; pos++) { end
cTValue *src = lj_tab_getint(t, pos+1); else
TValue *dst = lj_tab_setint(L, t, pos); CHECK_int(pos)
if (src) { if pos >= 1 and pos <= len then
copyTV(L, dst, src); local old = t[pos]
} else { for i=pos+1,len do
setnilV(dst); t[i-1] = t[i]
} end
} t[len] = nil
setnilV(lj_tab_setint(L, t, e)); /* Remove (last) value. */ return old
return 1; /* Return previous value. */ end
} end
end
*/
LJLIB_CF(table_concat) LJLIB_CF(table_concat)
{ {

View File

@ -729,38 +729,6 @@ static void LJ_FASTCALL recff_string_range(jit_State *J, RecordFFData *rd)
/* -- Table library fast functions ---------------------------------------- */ /* -- Table library fast functions ---------------------------------------- */
static void LJ_FASTCALL recff_table_remove(jit_State *J, RecordFFData *rd)
{
TRef tab = J->base[0];
rd->nres = 0;
if (tref_istab(tab)) {
if (!J->base[1] || tref_isnil(J->base[1])) { /* Simple pop: t[#t] = nil */
TRef trlen = lj_ir_call(J, IRCALL_lj_tab_len, tab);
GCtab *t = tabV(&rd->argv[0]);
MSize len = lj_tab_len(t);
emitir(IRTGI(len ? IR_NE : IR_EQ), trlen, lj_ir_kint(J, 0));
if (len) {
RecordIndex ix;
ix.tab = tab;
ix.key = trlen;
settabV(J->L, &ix.tabv, t);
setintV(&ix.keyv, len);
ix.idxchain = 0;
if (results_wanted(J) != 0) { /* Specialize load only if needed. */
ix.val = 0;
J->base[0] = lj_record_idx(J, &ix); /* Load previous value. */
rd->nres = 1;
/* Assumes ix.key/ix.tab is not modified for raw lj_record_idx(). */
}
ix.val = TREF_NIL;
lj_record_idx(J, &ix); /* Remove value. */
}
} else { /* Complex case: remove in the middle. */
recff_nyiu(J);
}
} /* else: Interpreter will throw. */
}
static void LJ_FASTCALL recff_table_insert(jit_State *J, RecordFFData *rd) static void LJ_FASTCALL recff_table_insert(jit_State *J, RecordFFData *rd)
{ {
RecordIndex ix; RecordIndex ix;