From: Mike Pall Date: Wed, 8 May 2013 09:10:46 +0000 (+0200) Subject: Merge branch 'master' into v2.1 X-Git-Tag: v2.1.0-beta1~246 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bb2cc1dcaff90406f431f90ef822ddd7df70200d;p=thirdparty%2FLuaJIT.git Merge branch 'master' into v2.1 --- bb2cc1dcaff90406f431f90ef822ddd7df70200d diff --cc src/lib_table.c index 4f5d9d0d,542ed1f8..80c7c8dc --- a/src/lib_table.c +++ b/src/lib_table.c @@@ -105,47 -119,52 +105,47 @@@ LJLIB_CF(table_insert) LJLIB_REC(. return 0; } -LJLIB_CF(table_remove) LJLIB_REC(.) -{ - GCtab *t = lj_lib_checktab(L, 1); - int32_t e = (int32_t)lj_tab_len(t); - int32_t pos = lj_lib_optint(L, 2, e); - if (!(1 <= pos && pos <= e)) /* Nothing to remove? */ - return 0; - lua_rawgeti(L, 1, pos); /* Get previous value. */ - /* NOBARRIER: This just moves existing elements around. */ - for (; pos < e; pos++) { - cTValue *src = lj_tab_getint(t, pos+1); - TValue *dst = lj_tab_setint(L, t, pos); - if (src) { - copyTV(L, dst, src); - } else { - setnilV(dst); - } - } - setnilV(lj_tab_setint(L, t, e)); /* Remove (last) value. */ - return 1; /* Return previous value. */ -} +LJLIB_LUA(table_remove) /* + function(t, pos) + CHECK_tab(t) + local len = #t + if pos == nil then + if len ~= 0 then + local old = t[len] + t[len] = nil + return old + end + else + CHECK_int(pos) + if pos >= 1 and pos <= len then + local old = t[pos] + for i=pos+1,len do + t[i-1] = t[i] + end + t[len] = nil + return old + end + end + end +*/ -LJLIB_CF(table_concat) +LJLIB_CF(table_concat) LJLIB_REC(.) { - luaL_Buffer b; GCtab *t = lj_lib_checktab(L, 1); GCstr *sep = lj_lib_optstr(L, 2); - MSize seplen = sep ? sep->len : 0; int32_t i = lj_lib_optint(L, 3, 1); - int32_t e = L->base+3 < L->top ? lj_lib_checkint(L, 4) : - (int32_t)lj_tab_len(t); + int32_t e = (L->base+3 < L->top && !tvisnil(L->base+3)) ? + lj_lib_checkint(L, 4) : (int32_t)lj_tab_len(t); - luaL_buffinit(L, &b); - if (i <= e) { - for (;;) { - cTValue *o; - lua_rawgeti(L, 1, i); - o = L->top-1; - if (!(tvisstr(o) || tvisnumber(o))) - lj_err_callerv(L, LJ_ERR_TABCAT, lj_typename(o), i); - luaL_addvalue(&b); - if (i++ == e) break; - if (seplen) - luaL_addlstring(&b, strdata(sep), seplen); - } + SBuf *sb = lj_buf_tmp_(L); + SBuf *sbx = lj_buf_puttab(sb, t, sep, i, e); + if (LJ_UNLIKELY(!sbx)) { /* Error: bad element type. */ + int32_t idx = (int32_t)(intptr_t)sbufP(sb); + cTValue *o = lj_tab_getint(t, idx); + lj_err_callerv(L, LJ_ERR_TABCAT, + lj_obj_itypename[o ? itypemap(o) : ~LJ_TNIL], idx); } - luaL_pushresult(&b); + setstrV(L, L->top-1, lj_buf_str(L, sbx)); + lj_gc_check(L); return 1; } diff --cc src/lj_ffrecord.c index 289c5775,35e2e88e..d1aa65c0 --- a/src/lj_ffrecord.c +++ b/src/lj_ffrecord.c @@@ -891,33 -798,6 +891,26 @@@ static void LJ_FASTCALL recff_table_ins } /* else: Interpreter will throw. */ } +static void LJ_FASTCALL recff_table_concat(jit_State *J, RecordFFData *rd) +{ + TRef tab = J->base[0]; + if (tref_istab(tab)) { - TRef sep = 0, tri = 0, tre = 0; - TRef hdr, tr; - if (J->base[1]) { - sep = lj_ir_tostr(J, J->base[1]); - if (J->base[2]) { - tri = lj_opt_narrow_toint(J, J->base[2]); - if (J->base[3]) - tre = lj_opt_narrow_toint(J, J->base[3]); - } - } else { - sep = lj_ir_knull(J, IRT_STR); - } - if (!tri) tri = lj_ir_kint(J, 1); - if (!tre) tre = lj_ir_call(J, IRCALL_lj_tab_len, tab); - hdr = emitir(IRT(IR_BUFHDR, IRT_P32), - lj_ir_kptr(J, &J2G(J)->tmpbuf), IRBUFHDR_RESET); - tr = lj_ir_call(J, IRCALL_lj_buf_puttab, hdr, tab, sep, tri, tre); ++ TRef sep = !tref_isnil(J->base[1]) ? ++ lj_ir_tostr(J, J->base[1]) : lj_ir_knull(J, IRT_STR); ++ TRef tri = (J->base[1] && !tref_isnil(J->base[2])) ? ++ lj_opt_narrow_toint(J, J->base[2]) : lj_ir_kint(J, 1); ++ TRef tre = (J->base[1] && J->base[2] && !tref_isnil(J->base[3])) ? ++ lj_opt_narrow_toint(J, J->base[3]) : ++ lj_ir_call(J, IRCALL_lj_tab_len, tab); ++ TRef hdr = emitir(IRT(IR_BUFHDR, IRT_P32), ++ lj_ir_kptr(J, &J2G(J)->tmpbuf), IRBUFHDR_RESET); ++ TRef tr = lj_ir_call(J, IRCALL_lj_buf_puttab, hdr, tab, sep, tri, tre); + emitir(IRTG(IR_NE, IRT_PTR), tr, lj_ir_kptr(J, NULL)); + J->base[0] = emitir(IRT(IR_BUFSTR, IRT_STR), tr, hdr); + } /* else: Interpreter will throw. */ + UNUSED(rd); +} + /* -- I/O library fast functions ------------------------------------------ */ /* Get FILE* for I/O function. Any I/O error aborts recording, so there's