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));
if (ls->p != p) memmove(p, ls->p, n);
} 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);
}
ls->p = p;
@ -74,7 +74,7 @@ static LJ_NOINLINE void bcread_fill(LexState *ls, MSize len, int need)
}
if (n) { /* Append to buffer. */
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);
setsbufP(&ls->sb, p + n);
ls->p = p;

View File

@ -24,7 +24,6 @@
/* Context for bytecode writer. */
typedef struct BCWriteCtx {
SBuf sb; /* Output buffer. */
lua_State *L; /* Lua state. */
GCproto *pt; /* Root prototype. */
lua_Writer wfunc; /* Writer callback. */
void *wdata; /* Writer callback data. */
@ -37,11 +36,11 @@ typedef struct BCWriteCtx {
/* Write a single constant key/value of a template table. */
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)) {
const GCstr *str = strV(o);
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_wmem(p, strdata(str), len);
} else if (tvisint(o)) {
@ -143,7 +142,7 @@ static void bcwrite_kgc(BCWriteCtx *ctx, GCproto *pt)
need = 1+2*5;
}
/* 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);
/* Write constant data (if any). */
if (tp >= BCDUMP_KGC_STR) {
@ -171,7 +170,7 @@ static void bcwrite_knum(BCWriteCtx *ctx, GCproto *pt)
{
MSize i, sizekn = pt->sizekn;
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++) {
int32_t k;
if (tvisint(o)) {
@ -211,7 +210,7 @@ static char *bcwrite_bytecode(BCWriteCtx *ctx, char *p, GCproto *pt)
#if LJ_HASJIT
/* Unpatch modified bytecode containing ILOOP/JLOOP etc. */
if ((pt->flags & PROTO_ILOOP) || pt->trace) {
jit_State *J = L2J(ctx->L);
jit_State *J = L2J(sbufL(&ctx->sb));
MSize i;
for (i = 0; i < nbc; i++, q += sizeof(BCIns)) {
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. */
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);
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. */
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);
setsbufP(&ctx->sb, p);
}
@ -294,7 +293,7 @@ static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt)
char *q = sbufB(&ctx->sb) + (5 - nn);
p = lj_buf_wuleb128(q, n); /* Fill in final size. */
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);
const char *name = strdata(chunkname);
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_HEAD2;
*p++ = BCDUMP_HEAD3;
@ -316,7 +315,7 @@ static void bcwrite_header(BCWriteCtx *ctx)
p = lj_buf_wuleb128(p, 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);
}
@ -325,7 +324,7 @@ static void bcwrite_footer(BCWriteCtx *ctx)
{
if (ctx->status == 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)
{
BCWriteCtx *ctx = (BCWriteCtx *)ud;
UNUSED(dummy);
lj_buf_need(L, &ctx->sb, 1024); /* Avoids resize for most prototypes. */
UNUSED(L); UNUSED(dummy);
lj_buf_need(&ctx->sb, 1024); /* Avoids resize for most prototypes. */
bcwrite_header(ctx);
bcwrite_proto(ctx, ctx->pt);
bcwrite_footer(ctx);
@ -347,16 +346,15 @@ int lj_bcwrite(lua_State *L, GCproto *pt, lua_Writer writer, void *data,
{
BCWriteCtx ctx;
int status;
ctx.L = L;
ctx.pt = pt;
ctx.wfunc = writer;
ctx.wdata = data;
ctx.strip = strip;
ctx.status = 0;
lj_buf_init(&ctx.sb);
lj_buf_init(L, &ctx.sb);
status = lj_vm_cpcall(L, NULL, &ctx, cpwriter);
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;
}

View File

@ -13,8 +13,9 @@
#include "lj_err.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);
MSize sz = (MSize)(en - b);
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);
}
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);
MSize osz = (MSize)(sbufE(sb) - b);
@ -54,14 +57,14 @@ char *lj_buf_wmem(char *p, const void *q, MSize len)
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);
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;
uint32_t v = *p++;
@ -74,7 +77,7 @@ uint32_t lj_buf_ruleb128(const char **pp)
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)
*p++ = (char)((v & 0x7f) | 0x80);

View File

@ -14,21 +14,24 @@
#define sbufB(sb) (mref((sb)->b, char))
#define sbufP(sb) (mref((sb)->p, 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 sbuflen(sb) ((MSize)(sbufP((sb)) - sbufB((sb))))
#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 void lj_buf_grow(lua_State *L, SBuf *sb, char *en);
LJ_FUNC void lj_buf_shrink(lua_State *L, SBuf *sb);
LJ_FUNC char * LJ_FASTCALL lj_buf_tmp(lua_State *L, MSize sz);
LJ_FUNC void LJ_FASTCALL lj_buf_grow(SBuf *sb, char *en);
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 void lj_buf_putmem(lua_State *L, SBuf *sb, const void *q, MSize len);
LJ_FUNC uint32_t lj_buf_ruleb128(const char **pp);
LJ_FUNC char *lj_buf_wuleb128(char *p, uint32_t v);
LJ_FUNC void lj_buf_putmem(SBuf *sb, const void *q, MSize len);
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);
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);
}
@ -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));
}
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;
if (LJ_UNLIKELY(en > sbufE(sb)))
lj_buf_grow(L, sb, en);
lj_buf_grow(sb, en);
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;
if (LJ_UNLIKELY(en > sbufE(sb)))
lj_buf_grow(L, sb, en);
lj_buf_grow(sb, en);
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;
setsbufP(sb, p);
}

View File

@ -89,7 +89,7 @@ static LJ_AINLINE CPChar cp_get(CPState *cp)
/* Save character in buffer. */
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". */
@ -367,7 +367,7 @@ static void cp_init(CPState *cp)
cp->depth = 0;
cp->curpack = 0;
cp->packstack[0] = 255;
lj_buf_init(&cp->sb);
lj_buf_init(cp->L, &cp->sb);
lua_assert(cp->p != NULL);
cp_get(cp); /* Read-ahead first char. */
cp->tok = 0;

View File

@ -61,7 +61,7 @@ static LJ_AINLINE LexChar lex_next(LexState *ls)
/* Save character. */
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. */

View File

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

View File

@ -124,6 +124,7 @@ typedef struct SBuf {
MRef p; /* String buffer pointer. */
MRef e; /* String buffer end pointer. */
MRef b; /* String buffer base. */
MRef L; /* lua_State, used for buffer resizing. */
} SBuf;
/* -- Tags and values ----------------------------------------------------- */
@ -516,7 +517,7 @@ typedef struct global_State {
lua_Alloc allocf; /* Memory allocator. */
void *allocd; /* Memory allocator data. */
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). */
GCstr strempty; /* 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++) {
GCstr *s = strref(vs[fs->uvmap[i]].name);
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);
setsbufP(&ls->sb, p);
}
@ -1454,11 +1454,11 @@ static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar)
BCPos startpc;
char *p;
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;
} else {
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);
}
startpc = vs->startpc;
@ -1468,7 +1468,7 @@ static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar)
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);
}

View File

@ -204,7 +204,7 @@ LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud)
setnilV(&g->nilnode.val);
setnilV(&g->nilnode.key);
setmref(g->nilnode.freetop, &g->nilnode);
lj_buf_init(&g->tmpbuf);
lj_buf_init(NULL, &g->tmpbuf);
g->gc.state = GCSpause;
setgcref(g->gc.root, obj2gco(L));
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)
{
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);
for (;;) {
const char *e = strchr(fmt, '%');
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. */
switch (e[1]) {
case 's': {
const char *s = va_arg(argp, char *);
if (s == NULL) s = "(null)";
lj_buf_putmem(L, sb, s, (MSize)strlen(s));
lj_buf_putmem(sb, s, (MSize)strlen(s));
break;
}
case 'c':
lj_buf_putb(L, sb, va_arg(argp, int));
lj_buf_putb(sb, va_arg(argp, int));
break;
case 'd': {
char buf[LJ_STR_INTBUF];
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;
}
case 'f': {
@ -251,7 +252,7 @@ const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp)
MSize len;
tv.n = (lua_Number)(va_arg(argp, LUAI_UACNUMBER));
len = (MSize)lj_str_bufnum(buf, &tv);
lj_buf_putmem(L, sb, buf, len);
lj_buf_putmem(sb, buf, len);
break;
}
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 i, lasti = 2+FMTP_CHARS;
if (p == 0) {
lj_buf_putmem(L, sb, "NULL", 4);
lj_buf_putmem(sb, "NULL", 4);
break;
}
#if LJ_64
@ -271,20 +272,20 @@ const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp)
buf[1] = 'x';
for (i = lasti-1; i >= 2; i--, p >>= 4)
buf[i] = "0123456789abcdef"[(p & 15)];
lj_buf_putmem(L, sb, buf, (MSize)lasti);
lj_buf_putmem(sb, buf, (MSize)lasti);
break;
}
case '%':
lj_buf_putb(L, sb, '%');
lj_buf_putb(sb, '%');
break;
default:
lj_buf_putb(L, sb, '%');
lj_buf_putb(L, sb, e[1]);
lj_buf_putb(sb, '%');
lj_buf_putb(sb, e[1]);
break;
}
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));
incr_top(L);
return strVdata(L->top - 1);