Permalink
Browse files

feature: implemented the table.clone() builtin Lua API.

This change only support shallow clone. e.g

  local tab_clone = require "table.clone"
  local x = {x=12, y={5, 6, 7}}
  local y = tab_clone(x)
  ... use y ...

Deep clone will be supported by adding 'true' as the 2nd argument to table.clone

We observe 7% over-all speedup in the edgelang-fan compiler's compiling
speed whose Lua is generated by the fanlang compiler.

Signed-off-by: Yichun Zhang (agentzh) <agentzh@gmail.com>
  • Loading branch information...
Shuxin Yang authored and agentzh committed Jul 31, 2017
1 parent 4f07069 commit 617f118303b897bf23129076eab5167c143cc568
Showing with 32 additions and 0 deletions.
  1. +17 −0 src/lib_table.c
  2. +7 −0 src/lj_ffrecord.c
  3. +1 −0 src/lj_ircall.h
  4. +5 −0 src/lj_tab.c
  5. +2 −0 src/lj_tab.h
View
@@ -169,6 +169,17 @@ LJLIB_CF(table_concat) LJLIB_REC(.)
return 1;
}
LJLIB_NOREG LJLIB_CF(table_clone) LJLIB_REC(.)
{
GCtab *src = lj_lib_checktab(L, 1);
GCtab *dup = lj_tab_dup(L, src);
settabV(L, L->base, dup);
L->top = L->base+1;
return 1;
}
/* ------------------------------------------------------------------------ */
static void set2(lua_State *L, int i, int j)
@@ -304,6 +315,11 @@ 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_clone(lua_State *L)
{
return lj_lib_postreg(L, lj_cf_table_clone, FF_table_clone, "clone");
}
static int luaopen_table_clear(lua_State *L)
{
return lj_lib_postreg(L, lj_cf_table_clear, FF_table_clear, "clear");
@@ -321,6 +337,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 ".clone", luaopen_table_clone, tabV(L->top-1));
lj_lib_prereg(L, LUA_TABLIBNAME ".clear", luaopen_table_clear, tabV(L->top-1));
return 1;
}
View
@@ -1105,6 +1105,13 @@ static void LJ_FASTCALL recff_table_clear(jit_State *J, RecordFFData *rd)
} /* else: Interpreter will throw. */
}
static void LJ_FASTCALL recff_table_clone(jit_State *J, RecordFFData *rd)
{
TRef src = J->base[0];
J->base[0] = lj_ir_call(J, IRCALL_lj_tab_clone, src);
UNUSED(rd);
}
/* -- I/O library fast functions ------------------------------------------ */
/* Get FILE* for I/O function. Any I/O error aborts recording, so there's
View
@@ -167,6 +167,7 @@ typedef struct CCallInfo {
_(ANY, lj_tab_clear, 1, FS, NIL, 0) \
_(ANY, lj_tab_newkey, 3, S, PGC, CCI_L) \
_(ANY, lj_tab_len, 1, FL, INT, 0) \
_(ANY, lj_tab_clone, 2, FS, TAB, CCI_L) \
_(ANY, lj_gc_step_jit, 2, FS, NIL, CCI_L) \
_(ANY, lj_gc_barrieruv, 2, FS, NIL, 0) \
_(ANY, lj_mem_newgco, 2, FS, PGC, CCI_L) \
View
@@ -686,3 +686,8 @@ MSize LJ_FASTCALL lj_tab_len(GCtab *t)
return unbound_search(t, j);
}
GCtab * LJ_FASTCALL lj_tab_clone(lua_State *L, const GCtab *src)
{
return lj_tab_dup(L, src);
}
View
@@ -70,4 +70,6 @@ LJ_FUNC TValue *lj_tab_set(lua_State *L, GCtab *t, cTValue *key);
LJ_FUNCA int lj_tab_next(lua_State *L, GCtab *t, TValue *key);
LJ_FUNCA MSize LJ_FASTCALL lj_tab_len(GCtab *t);
LJ_FUNCA GCtab * LJ_FASTCALL lj_tab_clone(lua_State *L, const GCtab *src);
#endif

0 comments on commit 617f118

Please sign in to comment.