Skip to content

Commit

Permalink
feature: implemented the table.clone() builtin Lua API.
Browse files Browse the repository at this point in the history
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 Mar 16, 2018
1 parent 4f07069 commit 617f118
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 0 deletions.
17 changes: 17 additions & 0 deletions src/lib_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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");
Expand All @@ -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;
}
Expand Down
7 changes: 7 additions & 0 deletions src/lj_ffrecord.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions src/lj_ircall.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) \
Expand Down
5 changes: 5 additions & 0 deletions src/lj_tab.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
2 changes: 2 additions & 0 deletions src/lj_tab.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

4 comments on commit 617f118

@javierguerragiraldez
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not do shallow copy with TDUP bytecode?

@agentzh
Copy link
Member

@agentzh agentzh commented on 617f118 Feb 8, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@javierguerragiraldez Yeah, it could be re-implemented as a pure luajit bytecode routine.

@fsfod
Copy link

@fsfod fsfod commented on 617f118 Feb 9, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TDUP also does a GC step that seems to be missing from this code. If you use TDUP there are also some fold rules for IR_TDUP that will probably need to be changed.

@agentzh
Copy link
Member

@agentzh agentzh commented on 617f118 Feb 9, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Patches welcome :)

Please sign in to comment.