Abstract out some common buffer operations.

This commit is contained in:
Mike Pall 2013-04-26 19:20:21 +02:00
parent f9421f2b9f
commit a98e6a70c1
5 changed files with 24 additions and 17 deletions

View File

@ -205,7 +205,7 @@ LJLIB_CF(os_date)
const char *q; const char *q;
for (q = s; *q; q++) for (q = s; *q; q++)
sz += (*q == '%') ? 30 : 1; /* Overflow doesn't matter. */ sz += (*q == '%') ? 30 : 1; /* Overflow doesn't matter. */
setmref(sb->L, L); setsbufL(sb, L);
for (;;) { for (;;) {
char *buf = lj_buf_need(sb, sz); char *buf = lj_buf_need(sb, sz);
size_t len = strftime(buf, sbufsz(sb), s, stm); size_t len = strftime(buf, sbufsz(sb), s, stm);

View File

@ -155,9 +155,7 @@ LJLIB_CF(string_dump)
{ {
GCfunc *fn = lj_lib_checkfunc(L, 1); GCfunc *fn = lj_lib_checkfunc(L, 1);
int strip = L->base+1 < L->top && tvistruecond(L->base+1); int strip = L->base+1 < L->top && tvistruecond(L->base+1);
SBuf *sb = &G(L)->tmpbuf; /* Assumes lj_bcwrite() doesn't use tmpbuf. */ SBuf *sb = lj_buf_tmp_(L); /* Assumes lj_bcwrite() doesn't use tmpbuf. */
setmref(sb->L, L);
lj_buf_reset(sb);
L->top = L->base+1; L->top = L->base+1;
if (!isluafunc(fn) || lj_bcwrite(L, funcproto(fn), writer_buf, sb, strip)) if (!isluafunc(fn) || lj_bcwrite(L, funcproto(fn), writer_buf, sb, strip))
lj_err_caller(L, LJ_ERR_STRDUMP); lj_err_caller(L, LJ_ERR_STRDUMP);
@ -851,9 +849,7 @@ LJLIB_CF(string_format)
GCstr *sfmt = lj_lib_checkstr(L, arg); GCstr *sfmt = lj_lib_checkstr(L, arg);
const char *fmt = strdata(sfmt); const char *fmt = strdata(sfmt);
const char *efmt = fmt + sfmt->len; const char *efmt = fmt + sfmt->len;
SBuf *sb = &G(L)->tmpbuf; SBuf *sb = lj_buf_tmp_(L);
setmref(sb->L, L);
lj_buf_reset(sb);
while (fmt < efmt) { while (fmt < efmt) {
if (*fmt != L_ESC || *++fmt == L_ESC) { if (*fmt != L_ESC || *++fmt == L_ESC) {
lj_buf_putb(sb, *fmt++); lj_buf_putb(sb, *fmt++);

View File

@ -149,6 +149,15 @@ GCstr * LJ_FASTCALL lj_buf_tostr(SBuf *sb)
return lj_str_new(sbufL(sb), sbufB(sb), sbuflen(sb)); return lj_str_new(sbufL(sb), sbufB(sb), sbuflen(sb));
} }
GCstr *lj_buf_cat2str(lua_State *L, GCstr *s1, GCstr *s2)
{
MSize len1 = s1->len, len2 = s2->len;
char *buf = lj_buf_tmp(L, len1 + len2);
memcpy(buf, strdata(s1), len1);
memcpy(buf+len1, strdata(s2), len2);
return lj_str_new(L, buf, len1 + len2);
}
uint32_t LJ_FASTCALL lj_buf_ruleb128(const char **pp) uint32_t LJ_FASTCALL lj_buf_ruleb128(const char **pp)
{ {
const uint8_t *p = (const uint8_t *)*pp; const uint8_t *p = (const uint8_t *)*pp;

View File

@ -36,6 +36,7 @@ LJ_FUNCA SBuf * LJ_FASTCALL lj_buf_putstr_reverse(SBuf *sb, GCstr *s);
LJ_FUNCA SBuf * LJ_FASTCALL lj_buf_putstr_lower(SBuf *sb, GCstr *s); LJ_FUNCA SBuf * LJ_FASTCALL lj_buf_putstr_lower(SBuf *sb, GCstr *s);
LJ_FUNCA SBuf * LJ_FASTCALL lj_buf_putstr_upper(SBuf *sb, GCstr *s); LJ_FUNCA SBuf * LJ_FASTCALL lj_buf_putstr_upper(SBuf *sb, GCstr *s);
LJ_FUNCA GCstr * LJ_FASTCALL lj_buf_tostr(SBuf *sb); LJ_FUNCA GCstr * LJ_FASTCALL lj_buf_tostr(SBuf *sb);
LJ_FUNC GCstr *lj_buf_cat2str(lua_State *L, GCstr *s1, GCstr *s2);
LJ_FUNC uint32_t LJ_FASTCALL lj_buf_ruleb128(const char **pp); LJ_FUNC uint32_t LJ_FASTCALL lj_buf_ruleb128(const char **pp);
LJ_FUNC char * LJ_FASTCALL lj_buf_wuleb128(char *p, uint32_t v); LJ_FUNC char * LJ_FASTCALL lj_buf_wuleb128(char *p, uint32_t v);
@ -50,6 +51,14 @@ static LJ_AINLINE void lj_buf_reset(SBuf *sb)
setmrefr(sb->p, sb->b); setmrefr(sb->p, sb->b);
} }
static LJ_AINLINE SBuf *lj_buf_tmp_(lua_State *L)
{
SBuf *sb = &G(L)->tmpbuf;
setsbufL(sb, L);
lj_buf_reset(sb);
return sb;
}
static LJ_AINLINE void lj_buf_free(global_State *g, SBuf *sb) static LJ_AINLINE void lj_buf_free(global_State *g, SBuf *sb)
{ {
lj_mem_free(g, sbufB(sb), sbufsz(sb)); lj_mem_free(g, sbufB(sb), sbufsz(sb));

View File

@ -559,20 +559,13 @@ LJFOLDF(bufput_kgc)
{ {
if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD) && fright->o == IR_KGC) { if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD) && fright->o == IR_KGC) {
GCstr *s2 = ir_kstr(fright); GCstr *s2 = ir_kstr(fright);
MSize len2 = s2->len; if (s2->len == 0) { /* Empty string? */
if (len2 == 0) { /* Empty string? */
return LEFTFOLD; return LEFTFOLD;
} else { } else {
if (fleft->o == IR_BUFPUT && irref_isk(fleft->op2) && if (fleft->o == IR_BUFPUT && irref_isk(fleft->op2) &&
!irt_isphi(fleft->t)) { !irt_isphi(fleft->t)) { /* Join two constant string puts in a row. */
/* Join two constant string puts in a row. */
GCstr *s1 = ir_kstr(IR(fleft->op2)); GCstr *s1 = ir_kstr(IR(fleft->op2));
MSize len1 = s1->len; IRRef kref = lj_ir_kstr(J, lj_buf_cat2str(J->L, s1, s2));
char *buf = lj_buf_tmp(J->L, len1 + len2);
IRRef kref;
memcpy(buf, strdata(s1), len1);
memcpy(buf+len1, strdata(s2), len2);
kref = lj_ir_kstr(J, lj_str_new(J->L, buf, len1 + len2));
/* lj_ir_kstr() may realloc the IR and invalidates any IRIns *. */ /* lj_ir_kstr() may realloc the IR and invalidates any IRIns *. */
IR(fins->op1)->op2 = kref; /* Modify previous BUFPUT. */ IR(fins->op1)->op2 = kref; /* Modify previous BUFPUT. */
return fins->op1; return fins->op1;