String buffer refactoring, part 4.

Add lua_State pointer to SBuf for buffer resizing.
This commit is contained in:
Mike Pall 2013-02-28 13:37:56 +01:00
parent 3c0157f426
commit 9ec869b362
11 changed files with 68 additions and 62 deletions

View File

@ -59,7 +59,7 @@ static LJ_NOINLINE void bcread_fill(LexState *ls, MSize len, int need)
lua_assert(ls->pe == sbufP(&ls->sb)); lua_assert(ls->pe == sbufP(&ls->sb));
if (ls->p != p) memmove(p, ls->p, n); if (ls->p != p) memmove(p, ls->p, n);
} else { /* Copy from buffer provided by reader. */ } else { /* Copy from buffer provided by reader. */
p = lj_buf_need(ls->L, &ls->sb, len); p = lj_buf_need(&ls->sb, len);
memcpy(p, ls->p, n); memcpy(p, ls->p, n);
} }
ls->p = p; ls->p = p;
@ -74,7 +74,7 @@ static LJ_NOINLINE void bcread_fill(LexState *ls, MSize len, int need)
} }
if (n) { /* Append to buffer. */ if (n) { /* Append to buffer. */
n += (MSize)sz; n += (MSize)sz;
p = lj_buf_need(ls->L, &ls->sb, n < len ? len : n); p = lj_buf_need(&ls->sb, n < len ? len : n);
memcpy(sbufP(&ls->sb), buf, sz); memcpy(sbufP(&ls->sb), buf, sz);
setsbufP(&ls->sb, p + n); setsbufP(&ls->sb, p + n);
ls->p = p; ls->p = p;

View File

@ -24,7 +24,6 @@
/* Context for bytecode writer. */ /* Context for bytecode writer. */
typedef struct BCWriteCtx { typedef struct BCWriteCtx {
SBuf sb; /* Output buffer. */ SBuf sb; /* Output buffer. */
lua_State *L; /* Lua state. */
GCproto *pt; /* Root prototype. */ GCproto *pt; /* Root prototype. */
lua_Writer wfunc; /* Writer callback. */ lua_Writer wfunc; /* Writer callback. */
void *wdata; /* Writer callback data. */ void *wdata; /* Writer callback data. */
@ -37,11 +36,11 @@ typedef struct BCWriteCtx {
/* Write a single constant key/value of a template table. */ /* Write a single constant key/value of a template table. */
static void bcwrite_ktabk(BCWriteCtx *ctx, cTValue *o, int narrow) static void bcwrite_ktabk(BCWriteCtx *ctx, cTValue *o, int narrow)
{ {
char *p = lj_buf_more(ctx->L, &ctx->sb, 1+10); char *p = lj_buf_more(&ctx->sb, 1+10);
if (tvisstr(o)) { if (tvisstr(o)) {
const GCstr *str = strV(o); const GCstr *str = strV(o);
MSize len = str->len; MSize len = str->len;
p = lj_buf_more(ctx->L, &ctx->sb, 5+len); p = lj_buf_more(&ctx->sb, 5+len);
p = lj_buf_wuleb128(p, BCDUMP_KTAB_STR+len); p = lj_buf_wuleb128(p, BCDUMP_KTAB_STR+len);
p = lj_buf_wmem(p, strdata(str), len); p = lj_buf_wmem(p, strdata(str), len);
} else if (tvisint(o)) { } else if (tvisint(o)) {
@ -143,7 +142,7 @@ static void bcwrite_kgc(BCWriteCtx *ctx, GCproto *pt)
need = 1+2*5; need = 1+2*5;
} }
/* Write constant type. */ /* Write constant type. */
p = lj_buf_more(ctx->L, &ctx->sb, need); p = lj_buf_more(&ctx->sb, need);
p = lj_buf_wuleb128(p, tp); p = lj_buf_wuleb128(p, tp);
/* Write constant data (if any). */ /* Write constant data (if any). */
if (tp >= BCDUMP_KGC_STR) { if (tp >= BCDUMP_KGC_STR) {
@ -171,7 +170,7 @@ static void bcwrite_knum(BCWriteCtx *ctx, GCproto *pt)
{ {
MSize i, sizekn = pt->sizekn; MSize i, sizekn = pt->sizekn;
cTValue *o = mref(pt->k, TValue); cTValue *o = mref(pt->k, TValue);
char *p = lj_buf_more(ctx->L, &ctx->sb, 10*sizekn); char *p = lj_buf_more(&ctx->sb, 10*sizekn);
for (i = 0; i < sizekn; i++, o++) { for (i = 0; i < sizekn; i++, o++) {
int32_t k; int32_t k;
if (tvisint(o)) { if (tvisint(o)) {
@ -211,7 +210,7 @@ static char *bcwrite_bytecode(BCWriteCtx *ctx, char *p, GCproto *pt)
#if LJ_HASJIT #if LJ_HASJIT
/* Unpatch modified bytecode containing ILOOP/JLOOP etc. */ /* Unpatch modified bytecode containing ILOOP/JLOOP etc. */
if ((pt->flags & PROTO_ILOOP) || pt->trace) { if ((pt->flags & PROTO_ILOOP) || pt->trace) {
jit_State *J = L2J(ctx->L); jit_State *J = L2J(sbufL(&ctx->sb));
MSize i; MSize i;
for (i = 0; i < nbc; i++, q += sizeof(BCIns)) { for (i = 0; i < nbc; i++, q += sizeof(BCIns)) {
BCOp op = (BCOp)q[LJ_ENDIAN_SELECT(0, 3)]; BCOp op = (BCOp)q[LJ_ENDIAN_SELECT(0, 3)];
@ -249,7 +248,7 @@ static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt)
} }
/* Start writing the prototype info to a buffer. */ /* Start writing the prototype info to a buffer. */
p = lj_buf_need(ctx->L, &ctx->sb, p = lj_buf_need(&ctx->sb,
5+4+6*5+(pt->sizebc-1)*(MSize)sizeof(BCIns)+pt->sizeuv*2); 5+4+6*5+(pt->sizebc-1)*(MSize)sizeof(BCIns)+pt->sizeuv*2);
p += 5; /* Leave room for final size. */ p += 5; /* Leave room for final size. */
@ -282,7 +281,7 @@ static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt)
/* Write debug info, if not stripped. */ /* Write debug info, if not stripped. */
if (sizedbg) { if (sizedbg) {
p = lj_buf_more(ctx->L, &ctx->sb, sizedbg); p = lj_buf_more(&ctx->sb, sizedbg);
p = lj_buf_wmem(p, proto_lineinfo(pt), sizedbg); p = lj_buf_wmem(p, proto_lineinfo(pt), sizedbg);
setsbufP(&ctx->sb, p); setsbufP(&ctx->sb, p);
} }
@ -294,7 +293,7 @@ static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt)
char *q = sbufB(&ctx->sb) + (5 - nn); char *q = sbufB(&ctx->sb) + (5 - nn);
p = lj_buf_wuleb128(q, n); /* Fill in final size. */ p = lj_buf_wuleb128(q, n); /* Fill in final size. */
lua_assert(p == sbufB(&ctx->sb) + 5); lua_assert(p == sbufB(&ctx->sb) + 5);
ctx->status = ctx->wfunc(ctx->L, q, nn+n, ctx->wdata); ctx->status = ctx->wfunc(sbufL(&ctx->sb), q, nn+n, ctx->wdata);
} }
} }
@ -304,7 +303,7 @@ static void bcwrite_header(BCWriteCtx *ctx)
GCstr *chunkname = proto_chunkname(ctx->pt); GCstr *chunkname = proto_chunkname(ctx->pt);
const char *name = strdata(chunkname); const char *name = strdata(chunkname);
MSize len = chunkname->len; MSize len = chunkname->len;
char *p = lj_buf_need(ctx->L, &ctx->sb, 5+5+len); char *p = lj_buf_need(&ctx->sb, 5+5+len);
*p++ = BCDUMP_HEAD1; *p++ = BCDUMP_HEAD1;
*p++ = BCDUMP_HEAD2; *p++ = BCDUMP_HEAD2;
*p++ = BCDUMP_HEAD3; *p++ = BCDUMP_HEAD3;
@ -316,7 +315,7 @@ static void bcwrite_header(BCWriteCtx *ctx)
p = lj_buf_wuleb128(p, len); p = lj_buf_wuleb128(p, len);
p = lj_buf_wmem(p, name, len); p = lj_buf_wmem(p, name, len);
} }
ctx->status = ctx->wfunc(ctx->L, sbufB(&ctx->sb), ctx->status = ctx->wfunc(sbufL(&ctx->sb), sbufB(&ctx->sb),
(MSize)(p - sbufB(&ctx->sb)), ctx->wdata); (MSize)(p - sbufB(&ctx->sb)), ctx->wdata);
} }
@ -325,7 +324,7 @@ static void bcwrite_footer(BCWriteCtx *ctx)
{ {
if (ctx->status == 0) { if (ctx->status == 0) {
uint8_t zero = 0; uint8_t zero = 0;
ctx->status = ctx->wfunc(ctx->L, &zero, 1, ctx->wdata); ctx->status = ctx->wfunc(sbufL(&ctx->sb), &zero, 1, ctx->wdata);
} }
} }
@ -333,8 +332,8 @@ static void bcwrite_footer(BCWriteCtx *ctx)
static TValue *cpwriter(lua_State *L, lua_CFunction dummy, void *ud) static TValue *cpwriter(lua_State *L, lua_CFunction dummy, void *ud)
{ {
BCWriteCtx *ctx = (BCWriteCtx *)ud; BCWriteCtx *ctx = (BCWriteCtx *)ud;
UNUSED(dummy); UNUSED(L); UNUSED(dummy);
lj_buf_need(L, &ctx->sb, 1024); /* Avoids resize for most prototypes. */ lj_buf_need(&ctx->sb, 1024); /* Avoids resize for most prototypes. */
bcwrite_header(ctx); bcwrite_header(ctx);
bcwrite_proto(ctx, ctx->pt); bcwrite_proto(ctx, ctx->pt);
bcwrite_footer(ctx); bcwrite_footer(ctx);
@ -347,16 +346,15 @@ int lj_bcwrite(lua_State *L, GCproto *pt, lua_Writer writer, void *data,
{ {
BCWriteCtx ctx; BCWriteCtx ctx;
int status; int status;
ctx.L = L;
ctx.pt = pt; ctx.pt = pt;
ctx.wfunc = writer; ctx.wfunc = writer;
ctx.wdata = data; ctx.wdata = data;
ctx.strip = strip; ctx.strip = strip;
ctx.status = 0; ctx.status = 0;
lj_buf_init(&ctx.sb); lj_buf_init(L, &ctx.sb);
status = lj_vm_cpcall(L, NULL, &ctx, cpwriter); status = lj_vm_cpcall(L, NULL, &ctx, cpwriter);
if (status == 0) status = ctx.status; if (status == 0) status = ctx.status;
lj_buf_free(G(ctx.L), &ctx.sb); lj_buf_free(G(sbufL(&ctx.sb)), &ctx.sb);
return status; return status;
} }

View File

@ -13,8 +13,9 @@
#include "lj_err.h" #include "lj_err.h"
#include "lj_buf.h" #include "lj_buf.h"
LJ_NOINLINE void lj_buf_grow(lua_State *L, SBuf *sb, char *en) LJ_NOINLINE void LJ_FASTCALL lj_buf_grow(SBuf *sb, char *en)
{ {
lua_State *L = sbufL(sb);
char *b = sbufB(sb); char *b = sbufB(sb);
MSize sz = (MSize)(en - b); MSize sz = (MSize)(en - b);
MSize osz = (MSize)(sbufE(sb) - b), nsz = osz; MSize osz = (MSize)(sbufE(sb) - b), nsz = osz;
@ -29,12 +30,14 @@ LJ_NOINLINE void lj_buf_grow(lua_State *L, SBuf *sb, char *en)
setmref(sb->e, b + nsz); setmref(sb->e, b + nsz);
} }
char *lj_buf_tmp(lua_State *L, MSize sz) char * LJ_FASTCALL lj_buf_tmp(lua_State *L, MSize sz)
{ {
return lj_buf_need(L, &G(L)->tmpbuf, sz); SBuf *sb = &G(L)->tmpbuf;
setmref(sb->L, L);
return lj_buf_need(sb, sz);
} }
void lj_buf_shrink(lua_State *L, SBuf *sb) void LJ_FASTCALL lj_buf_shrink(lua_State *L, SBuf *sb)
{ {
char *b = sbufB(sb); char *b = sbufB(sb);
MSize osz = (MSize)(sbufE(sb) - b); MSize osz = (MSize)(sbufE(sb) - b);
@ -54,14 +57,14 @@ char *lj_buf_wmem(char *p, const void *q, MSize len)
return p; return p;
} }
void lj_buf_putmem(lua_State *L, SBuf *sb, const void *q, MSize len) void lj_buf_putmem(SBuf *sb, const void *q, MSize len)
{ {
char *p = lj_buf_more(L, sb, len); char *p = lj_buf_more(sb, len);
p = lj_buf_wmem(p, q, len); p = lj_buf_wmem(p, q, len);
setsbufP(sb, p); setsbufP(sb, p);
} }
uint32_t 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;
uint32_t v = *p++; uint32_t v = *p++;
@ -74,7 +77,7 @@ uint32_t lj_buf_ruleb128(const char **pp)
return v; return v;
} }
char *lj_buf_wuleb128(char *p, uint32_t v) char * LJ_FASTCALL lj_buf_wuleb128(char *p, uint32_t v)
{ {
for (; v >= 0x80; v >>= 7) for (; v >= 0x80; v >>= 7)
*p++ = (char)((v & 0x7f) | 0x80); *p++ = (char)((v & 0x7f) | 0x80);

View File

@ -14,21 +14,24 @@
#define sbufB(sb) (mref((sb)->b, char)) #define sbufB(sb) (mref((sb)->b, char))
#define sbufP(sb) (mref((sb)->p, char)) #define sbufP(sb) (mref((sb)->p, char))
#define sbufE(sb) (mref((sb)->e, char)) #define sbufE(sb) (mref((sb)->e, char))
#define sbufL(sb) (mref((sb)->L, lua_State))
#define sbufsz(sb) ((MSize)(sbufE((sb)) - sbufB((sb)))) #define sbufsz(sb) ((MSize)(sbufE((sb)) - sbufB((sb))))
#define sbuflen(sb) ((MSize)(sbufP((sb)) - sbufB((sb)))) #define sbuflen(sb) ((MSize)(sbufP((sb)) - sbufB((sb))))
#define setsbufP(sb, q) (setmref((sb)->p, (q))) #define setsbufP(sb, q) (setmref((sb)->p, (q)))
#define setsbufL(sb, l) (setmref((sb)->L, (l)))
LJ_FUNC char *lj_buf_tmp(lua_State *L, MSize sz); LJ_FUNC char * LJ_FASTCALL lj_buf_tmp(lua_State *L, MSize sz);
LJ_FUNC void lj_buf_grow(lua_State *L, SBuf *sb, char *en); LJ_FUNC void LJ_FASTCALL lj_buf_grow(SBuf *sb, char *en);
LJ_FUNC void lj_buf_shrink(lua_State *L, SBuf *sb); LJ_FUNC void LJ_FASTCALL lj_buf_shrink(lua_State *L, SBuf *sb);
LJ_FUNC char *lj_buf_wmem(char *p, const void *q, MSize len); LJ_FUNC char *lj_buf_wmem(char *p, const void *q, MSize len);
LJ_FUNC void lj_buf_putmem(lua_State *L, SBuf *sb, const void *q, MSize len); LJ_FUNC void lj_buf_putmem(SBuf *sb, const void *q, MSize len);
LJ_FUNC uint32_t lj_buf_ruleb128(const char **pp); LJ_FUNC uint32_t LJ_FASTCALL lj_buf_ruleb128(const char **pp);
LJ_FUNC char *lj_buf_wuleb128(char *p, uint32_t v); LJ_FUNC char * LJ_FASTCALL lj_buf_wuleb128(char *p, uint32_t v);
static LJ_AINLINE void lj_buf_init(SBuf *sb) static LJ_AINLINE void lj_buf_init(lua_State *L, SBuf *sb)
{ {
setsbufL(sb, L);
setmref(sb->p, NULL); setmref(sb->e, NULL); setmref(sb->b, NULL); setmref(sb->p, NULL); setmref(sb->e, NULL); setmref(sb->b, NULL);
} }
@ -47,25 +50,25 @@ static LJ_AINLINE GCstr *lj_buf_str(lua_State *L, SBuf *sb)
return lj_str_new(L, sbufB(sb), sbuflen(sb)); return lj_str_new(L, sbufB(sb), sbuflen(sb));
} }
static LJ_AINLINE char *lj_buf_need(lua_State *L, SBuf *sb, MSize sz) static LJ_AINLINE char *lj_buf_need(SBuf *sb, MSize sz)
{ {
char *en = sbufB(sb) + sz; char *en = sbufB(sb) + sz;
if (LJ_UNLIKELY(en > sbufE(sb))) if (LJ_UNLIKELY(en > sbufE(sb)))
lj_buf_grow(L, sb, en); lj_buf_grow(sb, en);
return sbufB(sb); return sbufB(sb);
} }
static LJ_AINLINE char *lj_buf_more(lua_State *L, SBuf *sb, MSize sz) static LJ_AINLINE char *lj_buf_more(SBuf *sb, MSize sz)
{ {
char *en = sbufP(sb) + sz; char *en = sbufP(sb) + sz;
if (LJ_UNLIKELY(en > sbufE(sb))) if (LJ_UNLIKELY(en > sbufE(sb)))
lj_buf_grow(L, sb, en); lj_buf_grow(sb, en);
return sbufP(sb); return sbufP(sb);
} }
static LJ_AINLINE void lj_buf_putb(lua_State *L, SBuf *sb, int c) static LJ_AINLINE void lj_buf_putb(SBuf *sb, int c)
{ {
char *p = lj_buf_more(L, sb, 1); char *p = lj_buf_more(sb, 1);
*p++ = (char)c; *p++ = (char)c;
setsbufP(sb, p); setsbufP(sb, p);
} }

View File

@ -89,7 +89,7 @@ static LJ_AINLINE CPChar cp_get(CPState *cp)
/* Save character in buffer. */ /* Save character in buffer. */
static LJ_AINLINE void cp_save(CPState *cp, CPChar c) static LJ_AINLINE void cp_save(CPState *cp, CPChar c)
{ {
lj_buf_putb(cp->L, &cp->sb, c); lj_buf_putb(&cp->sb, c);
} }
/* Skip line break. Handles "\n", "\r", "\r\n" or "\n\r". */ /* Skip line break. Handles "\n", "\r", "\r\n" or "\n\r". */
@ -367,7 +367,7 @@ static void cp_init(CPState *cp)
cp->depth = 0; cp->depth = 0;
cp->curpack = 0; cp->curpack = 0;
cp->packstack[0] = 255; cp->packstack[0] = 255;
lj_buf_init(&cp->sb); lj_buf_init(cp->L, &cp->sb);
lua_assert(cp->p != NULL); lua_assert(cp->p != NULL);
cp_get(cp); /* Read-ahead first char. */ cp_get(cp); /* Read-ahead first char. */
cp->tok = 0; cp->tok = 0;

View File

@ -61,7 +61,7 @@ static LJ_AINLINE LexChar lex_next(LexState *ls)
/* Save character. */ /* Save character. */
static LJ_AINLINE void lex_save(LexState *ls, LexChar c) static LJ_AINLINE void lex_save(LexState *ls, LexChar c)
{ {
lj_buf_putb(ls->L, &ls->sb, c); lj_buf_putb(&ls->sb, c);
} }
/* Save previous character and get next character. */ /* Save previous character and get next character. */

View File

@ -55,7 +55,7 @@ LUA_API int lua_loadx(lua_State *L, lua_Reader reader, void *data,
ls.rdata = data; ls.rdata = data;
ls.chunkarg = chunkname ? chunkname : "?"; ls.chunkarg = chunkname ? chunkname : "?";
ls.mode = mode; ls.mode = mode;
lj_buf_init(&ls.sb); lj_buf_init(L, &ls.sb);
status = lj_vm_cpcall(L, NULL, &ls, cpparser); status = lj_vm_cpcall(L, NULL, &ls, cpparser);
lj_lex_cleanup(L, &ls); lj_lex_cleanup(L, &ls);
lj_gc_check(L); lj_gc_check(L);

View File

@ -124,6 +124,7 @@ typedef struct SBuf {
MRef p; /* String buffer pointer. */ MRef p; /* String buffer pointer. */
MRef e; /* String buffer end pointer. */ MRef e; /* String buffer end pointer. */
MRef b; /* String buffer base. */ MRef b; /* String buffer base. */
MRef L; /* lua_State, used for buffer resizing. */
} SBuf; } SBuf;
/* -- Tags and values ----------------------------------------------------- */ /* -- Tags and values ----------------------------------------------------- */
@ -516,7 +517,7 @@ typedef struct global_State {
lua_Alloc allocf; /* Memory allocator. */ lua_Alloc allocf; /* Memory allocator. */
void *allocd; /* Memory allocator data. */ void *allocd; /* Memory allocator data. */
GCState gc; /* Garbage collector. */ GCState gc; /* Garbage collector. */
SBuf tmpbuf; /* Temporary buffer for string concatenation. */ SBuf tmpbuf; /* Temporary string buffer. */
Node nilnode; /* Fallback 1-element hash part (nil key and value). */ Node nilnode; /* Fallback 1-element hash part (nil key and value). */
GCstr strempty; /* Empty string. */ GCstr strempty; /* Empty string. */
uint8_t stremptyz; /* Zero terminator of empty string. */ uint8_t stremptyz; /* Zero terminator of empty string. */

View File

@ -1441,7 +1441,7 @@ static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar)
for (i = 0, n = fs->nuv; i < n; i++) { for (i = 0, n = fs->nuv; i < n; i++) {
GCstr *s = strref(vs[fs->uvmap[i]].name); GCstr *s = strref(vs[fs->uvmap[i]].name);
MSize len = s->len+1; MSize len = s->len+1;
char *p = lj_buf_more(ls->L, &ls->sb, len); char *p = lj_buf_more(&ls->sb, len);
p = lj_buf_wmem(p, strdata(s), len); p = lj_buf_wmem(p, strdata(s), len);
setsbufP(&ls->sb, p); setsbufP(&ls->sb, p);
} }
@ -1454,11 +1454,11 @@ static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar)
BCPos startpc; BCPos startpc;
char *p; char *p;
if ((uintptr_t)s < VARNAME__MAX) { if ((uintptr_t)s < VARNAME__MAX) {
p = lj_buf_more(ls->L, &ls->sb, 1 + 2*5); p = lj_buf_more(&ls->sb, 1 + 2*5);
*p++ = (char)(uintptr_t)s; *p++ = (char)(uintptr_t)s;
} else { } else {
MSize len = s->len+1; MSize len = s->len+1;
p = lj_buf_more(ls->L, &ls->sb, len + 2*5); p = lj_buf_more(&ls->sb, len + 2*5);
p = lj_buf_wmem(p, strdata(s), len); p = lj_buf_wmem(p, strdata(s), len);
} }
startpc = vs->startpc; startpc = vs->startpc;
@ -1468,7 +1468,7 @@ static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar)
lastpc = startpc; lastpc = startpc;
} }
} }
lj_buf_putb(ls->L, &ls->sb, '\0'); /* Terminator for varinfo. */ lj_buf_putb(&ls->sb, '\0'); /* Terminator for varinfo. */
return sbuflen(&ls->sb); return sbuflen(&ls->sb);
} }

View File

@ -204,7 +204,7 @@ LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud)
setnilV(&g->nilnode.val); setnilV(&g->nilnode.val);
setnilV(&g->nilnode.key); setnilV(&g->nilnode.key);
setmref(g->nilnode.freetop, &g->nilnode); setmref(g->nilnode.freetop, &g->nilnode);
lj_buf_init(&g->tmpbuf); lj_buf_init(NULL, &g->tmpbuf);
g->gc.state = GCSpause; g->gc.state = GCSpause;
setgcref(g->gc.root, obj2gco(L)); setgcref(g->gc.root, obj2gco(L));
setmref(g->gc.sweep, &g->gc.root); setmref(g->gc.sweep, &g->gc.root);

View File

@ -222,27 +222,28 @@ GCstr * LJ_FASTCALL lj_str_fromnumber(lua_State *L, cTValue *o)
const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp) const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp)
{ {
SBuf *sb = &G(L)->tmpbuf; SBuf *sb = &G(L)->tmpbuf;
lj_buf_need(L, sb, (MSize)strlen(fmt)); setsbufL(sb, L);
lj_buf_need(sb, (MSize)strlen(fmt));
lj_buf_reset(sb); lj_buf_reset(sb);
for (;;) { for (;;) {
const char *e = strchr(fmt, '%'); const char *e = strchr(fmt, '%');
if (e == NULL) break; if (e == NULL) break;
lj_buf_putmem(L, sb, fmt, (MSize)(e-fmt)); lj_buf_putmem(sb, fmt, (MSize)(e-fmt));
/* This function only handles %s, %c, %d, %f and %p formats. */ /* This function only handles %s, %c, %d, %f and %p formats. */
switch (e[1]) { switch (e[1]) {
case 's': { case 's': {
const char *s = va_arg(argp, char *); const char *s = va_arg(argp, char *);
if (s == NULL) s = "(null)"; if (s == NULL) s = "(null)";
lj_buf_putmem(L, sb, s, (MSize)strlen(s)); lj_buf_putmem(sb, s, (MSize)strlen(s));
break; break;
} }
case 'c': case 'c':
lj_buf_putb(L, sb, va_arg(argp, int)); lj_buf_putb(sb, va_arg(argp, int));
break; break;
case 'd': { case 'd': {
char buf[LJ_STR_INTBUF]; char buf[LJ_STR_INTBUF];
char *p = lj_str_bufint(buf, va_arg(argp, int32_t)); char *p = lj_str_bufint(buf, va_arg(argp, int32_t));
lj_buf_putmem(L, sb, p, (MSize)(buf+LJ_STR_INTBUF-p)); lj_buf_putmem(sb, p, (MSize)(buf+LJ_STR_INTBUF-p));
break; break;
} }
case 'f': { case 'f': {
@ -251,7 +252,7 @@ const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp)
MSize len; MSize len;
tv.n = (lua_Number)(va_arg(argp, LUAI_UACNUMBER)); tv.n = (lua_Number)(va_arg(argp, LUAI_UACNUMBER));
len = (MSize)lj_str_bufnum(buf, &tv); len = (MSize)lj_str_bufnum(buf, &tv);
lj_buf_putmem(L, sb, buf, len); lj_buf_putmem(sb, buf, len);
break; break;
} }
case 'p': { case 'p': {
@ -260,7 +261,7 @@ const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp)
ptrdiff_t p = (ptrdiff_t)(va_arg(argp, void *)); ptrdiff_t p = (ptrdiff_t)(va_arg(argp, void *));
ptrdiff_t i, lasti = 2+FMTP_CHARS; ptrdiff_t i, lasti = 2+FMTP_CHARS;
if (p == 0) { if (p == 0) {
lj_buf_putmem(L, sb, "NULL", 4); lj_buf_putmem(sb, "NULL", 4);
break; break;
} }
#if LJ_64 #if LJ_64
@ -271,20 +272,20 @@ const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp)
buf[1] = 'x'; buf[1] = 'x';
for (i = lasti-1; i >= 2; i--, p >>= 4) for (i = lasti-1; i >= 2; i--, p >>= 4)
buf[i] = "0123456789abcdef"[(p & 15)]; buf[i] = "0123456789abcdef"[(p & 15)];
lj_buf_putmem(L, sb, buf, (MSize)lasti); lj_buf_putmem(sb, buf, (MSize)lasti);
break; break;
} }
case '%': case '%':
lj_buf_putb(L, sb, '%'); lj_buf_putb(sb, '%');
break; break;
default: default:
lj_buf_putb(L, sb, '%'); lj_buf_putb(sb, '%');
lj_buf_putb(L, sb, e[1]); lj_buf_putb(sb, e[1]);
break; break;
} }
fmt = e+2; fmt = e+2;
} }
lj_buf_putmem(L, sb, fmt, (MSize)strlen(fmt)); lj_buf_putmem(sb, fmt, (MSize)strlen(fmt));
setstrV(L, L->top, lj_buf_str(L, sb)); setstrV(L, L->top, lj_buf_str(L, sb));
incr_top(L); incr_top(L);
return strVdata(L->top - 1); return strVdata(L->top - 1);