Skip to content

Commit 617f118

Browse files
Shuxin Yangagentzh
authored andcommitted
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>
1 parent 4f07069 commit 617f118

File tree

5 files changed

+32
-0
lines changed

5 files changed

+32
-0
lines changed

src/lib_table.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,17 @@ LJLIB_CF(table_concat) LJLIB_REC(.)
169169
return 1;
170170
}
171171

172+
LJLIB_NOREG LJLIB_CF(table_clone) LJLIB_REC(.)
173+
{
174+
GCtab *src = lj_lib_checktab(L, 1);
175+
GCtab *dup = lj_tab_dup(L, src);
176+
177+
settabV(L, L->base, dup);
178+
L->top = L->base+1;
179+
180+
return 1;
181+
}
182+
172183
/* ------------------------------------------------------------------------ */
173184

174185
static void set2(lua_State *L, int i, int j)
@@ -304,6 +315,11 @@ static int luaopen_table_new(lua_State *L)
304315
return lj_lib_postreg(L, lj_cf_table_new, FF_table_new, "new");
305316
}
306317

318+
static int luaopen_table_clone(lua_State *L)
319+
{
320+
return lj_lib_postreg(L, lj_cf_table_clone, FF_table_clone, "clone");
321+
}
322+
307323
static int luaopen_table_clear(lua_State *L)
308324
{
309325
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)
321337
lua_setfield(L, -2, "unpack");
322338
#endif
323339
lj_lib_prereg(L, LUA_TABLIBNAME ".new", luaopen_table_new, tabV(L->top-1));
340+
lj_lib_prereg(L, LUA_TABLIBNAME ".clone", luaopen_table_clone, tabV(L->top-1));
324341
lj_lib_prereg(L, LUA_TABLIBNAME ".clear", luaopen_table_clear, tabV(L->top-1));
325342
return 1;
326343
}

src/lj_ffrecord.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,6 +1105,13 @@ static void LJ_FASTCALL recff_table_clear(jit_State *J, RecordFFData *rd)
11051105
} /* else: Interpreter will throw. */
11061106
}
11071107

1108+
static void LJ_FASTCALL recff_table_clone(jit_State *J, RecordFFData *rd)
1109+
{
1110+
TRef src = J->base[0];
1111+
J->base[0] = lj_ir_call(J, IRCALL_lj_tab_clone, src);
1112+
UNUSED(rd);
1113+
}
1114+
11081115
/* -- I/O library fast functions ------------------------------------------ */
11091116

11101117
/* Get FILE* for I/O function. Any I/O error aborts recording, so there's

src/lj_ircall.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ typedef struct CCallInfo {
167167
_(ANY, lj_tab_clear, 1, FS, NIL, 0) \
168168
_(ANY, lj_tab_newkey, 3, S, PGC, CCI_L) \
169169
_(ANY, lj_tab_len, 1, FL, INT, 0) \
170+
_(ANY, lj_tab_clone, 2, FS, TAB, CCI_L) \
170171
_(ANY, lj_gc_step_jit, 2, FS, NIL, CCI_L) \
171172
_(ANY, lj_gc_barrieruv, 2, FS, NIL, 0) \
172173
_(ANY, lj_mem_newgco, 2, FS, PGC, CCI_L) \

src/lj_tab.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,3 +686,8 @@ MSize LJ_FASTCALL lj_tab_len(GCtab *t)
686686
return unbound_search(t, j);
687687
}
688688

689+
690+
GCtab * LJ_FASTCALL lj_tab_clone(lua_State *L, const GCtab *src)
691+
{
692+
return lj_tab_dup(L, src);
693+
}

src/lj_tab.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,6 @@ LJ_FUNC TValue *lj_tab_set(lua_State *L, GCtab *t, cTValue *key);
7070
LJ_FUNCA int lj_tab_next(lua_State *L, GCtab *t, TValue *key);
7171
LJ_FUNCA MSize LJ_FASTCALL lj_tab_len(GCtab *t);
7272

73+
LJ_FUNCA GCtab * LJ_FASTCALL lj_tab_clone(lua_State *L, const GCtab *src);
74+
7375
#endif

0 commit comments

Comments
 (0)