]> git.ipfire.org Git - thirdparty/LuaJIT.git/commitdiff
Merge branch 'master' into v2.1
authorMike Pall <mike>
Wed, 8 May 2013 09:10:46 +0000 (11:10 +0200)
committerMike Pall <mike>
Wed, 8 May 2013 09:10:46 +0000 (11:10 +0200)
1  2 
src/lib_table.c
src/lj_ffrecord.c

diff --cc src/lib_table.c
index 4f5d9d0d5edf71c8a524a4f2e40d29d29fc52363,542ed1f8641e3a3ad662d599a31b222aadee4495..80c7c8dcba506dc4b90fda518825a232bec42343
@@@ -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;
  }
  
index 289c5775e7dee1c64fcbdea3abf8e2824824bae4,35e2e88e317fad4143fd69a327fc57827d8ed4c3..d1aa65c0d49dacf75be66cd2d13f9266acbda703
@@@ -891,33 -798,6 +891,26 @@@ static void LJ_FASTCALL recff_table_ins
    }  /* else: Interpreter will throw. */
  }
  
-     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);
 +static void LJ_FASTCALL recff_table_concat(jit_State *J, RecordFFData *rd)
 +{
 +  TRef tab = J->base[0];
 +  if (tref_istab(tab)) {
++    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