aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2013-02-24 17:59:04 +0100
committerMike Pall <mike>2013-02-24 17:59:04 +0100
commit5e601891fc9faf8cde836e6515bfdd273dd113e9 (patch)
tree2fbf828cd0fc714fe902f8ba81b20b09769247f9
parentb8abb4b91d006f884c81b9e95484373bd6eed2d9 (diff)
downloadluajit-5e601891fc9faf8cde836e6515bfdd273dd113e9.tar.gz
luajit-5e601891fc9faf8cde836e6515bfdd273dd113e9.tar.bz2
luajit-5e601891fc9faf8cde836e6515bfdd273dd113e9.zip
Replace table.remove with bytecode builtin.
-rw-r--r--src/host/buildvm_libbc.h9
-rw-r--r--src/lib_table.c44
-rw-r--r--src/lj_ffrecord.c32
3 files changed, 30 insertions, 55 deletions
diff --git a/src/host/buildvm_libbc.h b/src/host/buildvm_libbc.h
index a71aa630..ec2a55f8 100644
--- a/src/host/buildvm_libbc.h
+++ b/src/host/buildvm_libbc.h
@@ -9,7 +9,11 @@ static const uint8_t libbc_code[] = {
959,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, 959,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,
100,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, 100,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,
1118,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, 1118,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,
1275,0,1,0,0,1,2,0,0,0,3,16,0,12,0,21,1,0,0,76,1,2,0,0 1275,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,
130,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,
140,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,
1512,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,
169,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
13}; 17};
14 18
15static const struct { const char *name; int ofs; } libbc_map[] = { 19static const struct { const char *name; int ofs; } libbc_map[] = {
@@ -18,6 +22,7 @@ static const struct { const char *name; int ofs; } libbc_map[] = {
18{"table_foreachi",50}, 22{"table_foreachi",50},
19{"table_foreach",117}, 23{"table_foreach",117},
20{"table_getn",188}, 24{"table_getn",188},
21{NULL,207} 25{"table_remove",207},
26{NULL,336}
22}; 27};
23 28
diff --git a/src/lib_table.c b/src/lib_table.c
index 13aff24e..89884f77 100644
--- a/src/lib_table.c
+++ b/src/lib_table.c
@@ -103,27 +103,29 @@ LJLIB_CF(table_insert) LJLIB_REC(.)
103 return 0; 103 return 0;
104} 104}
105 105
106LJLIB_CF(table_remove) LJLIB_REC(.) 106LJLIB_LUA(table_remove) /*
107{ 107 function(t, pos)
108 GCtab *t = lj_lib_checktab(L, 1); 108 CHECK_tab(t)
109 int32_t e = (int32_t)lj_tab_len(t); 109 local len = #t
110 int32_t pos = lj_lib_optint(L, 2, e); 110 if pos == nil then
111 if (!(1 <= pos && pos <= e)) /* Nothing to remove? */ 111 if len ~= 0 then
112 return 0; 112 local old = t[len]
113 lua_rawgeti(L, 1, pos); /* Get previous value. */ 113 t[len] = nil
114 /* NOBARRIER: This just moves existing elements around. */ 114 return old
115 for (; pos < e; pos++) { 115 end
116 cTValue *src = lj_tab_getint(t, pos+1); 116 else
117 TValue *dst = lj_tab_setint(L, t, pos); 117 CHECK_int(pos)
118 if (src) { 118 if pos >= 1 and pos <= len then
119 copyTV(L, dst, src); 119 local old = t[pos]
120 } else { 120 for i=pos+1,len do
121 setnilV(dst); 121 t[i-1] = t[i]
122 } 122 end
123 } 123 t[len] = nil
124 setnilV(lj_tab_setint(L, t, e)); /* Remove (last) value. */ 124 return old
125 return 1; /* Return previous value. */ 125 end
126} 126 end
127 end
128*/
127 129
128LJLIB_CF(table_concat) 130LJLIB_CF(table_concat)
129{ 131{
diff --git a/src/lj_ffrecord.c b/src/lj_ffrecord.c
index 51981477..730d5c39 100644
--- a/src/lj_ffrecord.c
+++ b/src/lj_ffrecord.c
@@ -729,38 +729,6 @@ static void LJ_FASTCALL recff_string_range(jit_State *J, RecordFFData *rd)
729 729
730/* -- Table library fast functions ---------------------------------------- */ 730/* -- Table library fast functions ---------------------------------------- */
731 731
732static void LJ_FASTCALL recff_table_remove(jit_State *J, RecordFFData *rd)
733{
734 TRef tab = J->base[0];
735 rd->nres = 0;
736 if (tref_istab(tab)) {
737 if (!J->base[1] || tref_isnil(J->base[1])) { /* Simple pop: t[#t] = nil */
738 TRef trlen = lj_ir_call(J, IRCALL_lj_tab_len, tab);
739 GCtab *t = tabV(&rd->argv[0]);
740 MSize len = lj_tab_len(t);
741 emitir(IRTGI(len ? IR_NE : IR_EQ), trlen, lj_ir_kint(J, 0));
742 if (len) {
743 RecordIndex ix;
744 ix.tab = tab;
745 ix.key = trlen;
746 settabV(J->L, &ix.tabv, t);
747 setintV(&ix.keyv, len);
748 ix.idxchain = 0;
749 if (results_wanted(J) != 0) { /* Specialize load only if needed. */
750 ix.val = 0;
751 J->base[0] = lj_record_idx(J, &ix); /* Load previous value. */
752 rd->nres = 1;
753 /* Assumes ix.key/ix.tab is not modified for raw lj_record_idx(). */
754 }
755 ix.val = TREF_NIL;
756 lj_record_idx(J, &ix); /* Remove value. */
757 }
758 } else { /* Complex case: remove in the middle. */
759 recff_nyiu(J);
760 }
761 } /* else: Interpreter will throw. */
762}
763
764static void LJ_FASTCALL recff_table_insert(jit_State *J, RecordFFData *rd) 732static void LJ_FASTCALL recff_table_insert(jit_State *J, RecordFFData *rd)
765{ 733{
766 RecordIndex ix; 734 RecordIndex ix;