aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lj_bcread.c4
-rw-r--r--src/lj_bcwrite.c32
-rw-r--r--src/lj_buf.c19
-rw-r--r--src/lj_buf.h29
-rw-r--r--src/lj_cparse.c4
-rw-r--r--src/lj_lex.c2
-rw-r--r--src/lj_load.c2
-rw-r--r--src/lj_obj.h3
-rw-r--r--src/lj_parse.c8
-rw-r--r--src/lj_state.c2
-rw-r--r--src/lj_str.c25
11 files changed, 68 insertions, 62 deletions
diff --git a/src/lj_bcread.c b/src/lj_bcread.c
index fcc2aa1d..7bb16a60 100644
--- a/src/lj_bcread.c
+++ b/src/lj_bcread.c
@@ -59,7 +59,7 @@ static LJ_NOINLINE void bcread_fill(LexState *ls, MSize len, int need)
59 lua_assert(ls->pe == sbufP(&ls->sb)); 59 lua_assert(ls->pe == sbufP(&ls->sb));
60 if (ls->p != p) memmove(p, ls->p, n); 60 if (ls->p != p) memmove(p, ls->p, n);
61 } else { /* Copy from buffer provided by reader. */ 61 } else { /* Copy from buffer provided by reader. */
62 p = lj_buf_need(ls->L, &ls->sb, len); 62 p = lj_buf_need(&ls->sb, len);
63 memcpy(p, ls->p, n); 63 memcpy(p, ls->p, n);
64 } 64 }
65 ls->p = p; 65 ls->p = p;
@@ -74,7 +74,7 @@ static LJ_NOINLINE void bcread_fill(LexState *ls, MSize len, int need)
74 } 74 }
75 if (n) { /* Append to buffer. */ 75 if (n) { /* Append to buffer. */
76 n += (MSize)sz; 76 n += (MSize)sz;
77 p = lj_buf_need(ls->L, &ls->sb, n < len ? len : n); 77 p = lj_buf_need(&ls->sb, n < len ? len : n);
78 memcpy(sbufP(&ls->sb), buf, sz); 78 memcpy(sbufP(&ls->sb), buf, sz);
79 setsbufP(&ls->sb, p + n); 79 setsbufP(&ls->sb, p + n);
80 ls->p = p; 80 ls->p = p;
diff --git a/src/lj_bcwrite.c b/src/lj_bcwrite.c
index 71c86581..b3289a13 100644
--- a/src/lj_bcwrite.c
+++ b/src/lj_bcwrite.c
@@ -24,7 +24,6 @@
24/* Context for bytecode writer. */ 24/* Context for bytecode writer. */
25typedef struct BCWriteCtx { 25typedef struct BCWriteCtx {
26 SBuf sb; /* Output buffer. */ 26 SBuf sb; /* Output buffer. */
27 lua_State *L; /* Lua state. */
28 GCproto *pt; /* Root prototype. */ 27 GCproto *pt; /* Root prototype. */
29 lua_Writer wfunc; /* Writer callback. */ 28 lua_Writer wfunc; /* Writer callback. */
30 void *wdata; /* Writer callback data. */ 29 void *wdata; /* Writer callback data. */
@@ -37,11 +36,11 @@ typedef struct BCWriteCtx {
37/* Write a single constant key/value of a template table. */ 36/* Write a single constant key/value of a template table. */
38static void bcwrite_ktabk(BCWriteCtx *ctx, cTValue *o, int narrow) 37static void bcwrite_ktabk(BCWriteCtx *ctx, cTValue *o, int narrow)
39{ 38{
40 char *p = lj_buf_more(ctx->L, &ctx->sb, 1+10); 39 char *p = lj_buf_more(&ctx->sb, 1+10);
41 if (tvisstr(o)) { 40 if (tvisstr(o)) {
42 const GCstr *str = strV(o); 41 const GCstr *str = strV(o);
43 MSize len = str->len; 42 MSize len = str->len;
44 p = lj_buf_more(ctx->L, &ctx->sb, 5+len); 43 p = lj_buf_more(&ctx->sb, 5+len);
45 p = lj_buf_wuleb128(p, BCDUMP_KTAB_STR+len); 44 p = lj_buf_wuleb128(p, BCDUMP_KTAB_STR+len);
46 p = lj_buf_wmem(p, strdata(str), len); 45 p = lj_buf_wmem(p, strdata(str), len);
47 } else if (tvisint(o)) { 46 } else if (tvisint(o)) {
@@ -143,7 +142,7 @@ static void bcwrite_kgc(BCWriteCtx *ctx, GCproto *pt)
143 need = 1+2*5; 142 need = 1+2*5;
144 } 143 }
145 /* Write constant type. */ 144 /* Write constant type. */
146 p = lj_buf_more(ctx->L, &ctx->sb, need); 145 p = lj_buf_more(&ctx->sb, need);
147 p = lj_buf_wuleb128(p, tp); 146 p = lj_buf_wuleb128(p, tp);
148 /* Write constant data (if any). */ 147 /* Write constant data (if any). */
149 if (tp >= BCDUMP_KGC_STR) { 148 if (tp >= BCDUMP_KGC_STR) {
@@ -171,7 +170,7 @@ static void bcwrite_knum(BCWriteCtx *ctx, GCproto *pt)
171{ 170{
172 MSize i, sizekn = pt->sizekn; 171 MSize i, sizekn = pt->sizekn;
173 cTValue *o = mref(pt->k, TValue); 172 cTValue *o = mref(pt->k, TValue);
174 char *p = lj_buf_more(ctx->L, &ctx->sb, 10*sizekn); 173 char *p = lj_buf_more(&ctx->sb, 10*sizekn);
175 for (i = 0; i < sizekn; i++, o++) { 174 for (i = 0; i < sizekn; i++, o++) {
176 int32_t k; 175 int32_t k;
177 if (tvisint(o)) { 176 if (tvisint(o)) {
@@ -211,7 +210,7 @@ static char *bcwrite_bytecode(BCWriteCtx *ctx, char *p, GCproto *pt)
211#if LJ_HASJIT 210#if LJ_HASJIT
212 /* Unpatch modified bytecode containing ILOOP/JLOOP etc. */ 211 /* Unpatch modified bytecode containing ILOOP/JLOOP etc. */
213 if ((pt->flags & PROTO_ILOOP) || pt->trace) { 212 if ((pt->flags & PROTO_ILOOP) || pt->trace) {
214 jit_State *J = L2J(ctx->L); 213 jit_State *J = L2J(sbufL(&ctx->sb));
215 MSize i; 214 MSize i;
216 for (i = 0; i < nbc; i++, q += sizeof(BCIns)) { 215 for (i = 0; i < nbc; i++, q += sizeof(BCIns)) {
217 BCOp op = (BCOp)q[LJ_ENDIAN_SELECT(0, 3)]; 216 BCOp op = (BCOp)q[LJ_ENDIAN_SELECT(0, 3)];
@@ -249,7 +248,7 @@ static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt)
249 } 248 }
250 249
251 /* Start writing the prototype info to a buffer. */ 250 /* Start writing the prototype info to a buffer. */
252 p = lj_buf_need(ctx->L, &ctx->sb, 251 p = lj_buf_need(&ctx->sb,
253 5+4+6*5+(pt->sizebc-1)*(MSize)sizeof(BCIns)+pt->sizeuv*2); 252 5+4+6*5+(pt->sizebc-1)*(MSize)sizeof(BCIns)+pt->sizeuv*2);
254 p += 5; /* Leave room for final size. */ 253 p += 5; /* Leave room for final size. */
255 254
@@ -282,7 +281,7 @@ static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt)
282 281
283 /* Write debug info, if not stripped. */ 282 /* Write debug info, if not stripped. */
284 if (sizedbg) { 283 if (sizedbg) {
285 p = lj_buf_more(ctx->L, &ctx->sb, sizedbg); 284 p = lj_buf_more(&ctx->sb, sizedbg);
286 p = lj_buf_wmem(p, proto_lineinfo(pt), sizedbg); 285 p = lj_buf_wmem(p, proto_lineinfo(pt), sizedbg);
287 setsbufP(&ctx->sb, p); 286 setsbufP(&ctx->sb, p);
288 } 287 }
@@ -294,7 +293,7 @@ static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt)
294 char *q = sbufB(&ctx->sb) + (5 - nn); 293 char *q = sbufB(&ctx->sb) + (5 - nn);
295 p = lj_buf_wuleb128(q, n); /* Fill in final size. */ 294 p = lj_buf_wuleb128(q, n); /* Fill in final size. */
296 lua_assert(p == sbufB(&ctx->sb) + 5); 295 lua_assert(p == sbufB(&ctx->sb) + 5);
297 ctx->status = ctx->wfunc(ctx->L, q, nn+n, ctx->wdata); 296 ctx->status = ctx->wfunc(sbufL(&ctx->sb), q, nn+n, ctx->wdata);
298 } 297 }
299} 298}
300 299
@@ -304,7 +303,7 @@ static void bcwrite_header(BCWriteCtx *ctx)
304 GCstr *chunkname = proto_chunkname(ctx->pt); 303 GCstr *chunkname = proto_chunkname(ctx->pt);
305 const char *name = strdata(chunkname); 304 const char *name = strdata(chunkname);
306 MSize len = chunkname->len; 305 MSize len = chunkname->len;
307 char *p = lj_buf_need(ctx->L, &ctx->sb, 5+5+len); 306 char *p = lj_buf_need(&ctx->sb, 5+5+len);
308 *p++ = BCDUMP_HEAD1; 307 *p++ = BCDUMP_HEAD1;
309 *p++ = BCDUMP_HEAD2; 308 *p++ = BCDUMP_HEAD2;
310 *p++ = BCDUMP_HEAD3; 309 *p++ = BCDUMP_HEAD3;
@@ -316,7 +315,7 @@ static void bcwrite_header(BCWriteCtx *ctx)
316 p = lj_buf_wuleb128(p, len); 315 p = lj_buf_wuleb128(p, len);
317 p = lj_buf_wmem(p, name, len); 316 p = lj_buf_wmem(p, name, len);
318 } 317 }
319 ctx->status = ctx->wfunc(ctx->L, sbufB(&ctx->sb), 318 ctx->status = ctx->wfunc(sbufL(&ctx->sb), sbufB(&ctx->sb),
320 (MSize)(p - sbufB(&ctx->sb)), ctx->wdata); 319 (MSize)(p - sbufB(&ctx->sb)), ctx->wdata);
321} 320}
322 321
@@ -325,7 +324,7 @@ static void bcwrite_footer(BCWriteCtx *ctx)
325{ 324{
326 if (ctx->status == 0) { 325 if (ctx->status == 0) {
327 uint8_t zero = 0; 326 uint8_t zero = 0;
328 ctx->status = ctx->wfunc(ctx->L, &zero, 1, ctx->wdata); 327 ctx->status = ctx->wfunc(sbufL(&ctx->sb), &zero, 1, ctx->wdata);
329 } 328 }
330} 329}
331 330
@@ -333,8 +332,8 @@ static void bcwrite_footer(BCWriteCtx *ctx)
333static TValue *cpwriter(lua_State *L, lua_CFunction dummy, void *ud) 332static TValue *cpwriter(lua_State *L, lua_CFunction dummy, void *ud)
334{ 333{
335 BCWriteCtx *ctx = (BCWriteCtx *)ud; 334 BCWriteCtx *ctx = (BCWriteCtx *)ud;
336 UNUSED(dummy); 335 UNUSED(L); UNUSED(dummy);
337 lj_buf_need(L, &ctx->sb, 1024); /* Avoids resize for most prototypes. */ 336 lj_buf_need(&ctx->sb, 1024); /* Avoids resize for most prototypes. */
338 bcwrite_header(ctx); 337 bcwrite_header(ctx);
339 bcwrite_proto(ctx, ctx->pt); 338 bcwrite_proto(ctx, ctx->pt);
340 bcwrite_footer(ctx); 339 bcwrite_footer(ctx);
@@ -347,16 +346,15 @@ int lj_bcwrite(lua_State *L, GCproto *pt, lua_Writer writer, void *data,
347{ 346{
348 BCWriteCtx ctx; 347 BCWriteCtx ctx;
349 int status; 348 int status;
350 ctx.L = L;
351 ctx.pt = pt; 349 ctx.pt = pt;
352 ctx.wfunc = writer; 350 ctx.wfunc = writer;
353 ctx.wdata = data; 351 ctx.wdata = data;
354 ctx.strip = strip; 352 ctx.strip = strip;
355 ctx.status = 0; 353 ctx.status = 0;
356 lj_buf_init(&ctx.sb); 354 lj_buf_init(L, &ctx.sb);
357 status = lj_vm_cpcall(L, NULL, &ctx, cpwriter); 355 status = lj_vm_cpcall(L, NULL, &ctx, cpwriter);
358 if (status == 0) status = ctx.status; 356 if (status == 0) status = ctx.status;
359 lj_buf_free(G(ctx.L), &ctx.sb); 357 lj_buf_free(G(sbufL(&ctx.sb)), &ctx.sb);
360 return status; 358 return status;
361} 359}
362 360
diff --git a/src/lj_buf.c b/src/lj_buf.c
index a05dc22e..c08d23c9 100644
--- a/src/lj_buf.c
+++ b/src/lj_buf.c
@@ -13,8 +13,9 @@
13#include "lj_err.h" 13#include "lj_err.h"
14#include "lj_buf.h" 14#include "lj_buf.h"
15 15
16LJ_NOINLINE void lj_buf_grow(lua_State *L, SBuf *sb, char *en) 16LJ_NOINLINE void LJ_FASTCALL lj_buf_grow(SBuf *sb, char *en)
17{ 17{
18 lua_State *L = sbufL(sb);
18 char *b = sbufB(sb); 19 char *b = sbufB(sb);
19 MSize sz = (MSize)(en - b); 20 MSize sz = (MSize)(en - b);
20 MSize osz = (MSize)(sbufE(sb) - b), nsz = osz; 21 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)
29 setmref(sb->e, b + nsz); 30 setmref(sb->e, b + nsz);
30} 31}
31 32
32char *lj_buf_tmp(lua_State *L, MSize sz) 33char * LJ_FASTCALL lj_buf_tmp(lua_State *L, MSize sz)
33{ 34{
34 return lj_buf_need(L, &G(L)->tmpbuf, sz); 35 SBuf *sb = &G(L)->tmpbuf;
36 setmref(sb->L, L);
37 return lj_buf_need(sb, sz);
35} 38}
36 39
37void lj_buf_shrink(lua_State *L, SBuf *sb) 40void LJ_FASTCALL lj_buf_shrink(lua_State *L, SBuf *sb)
38{ 41{
39 char *b = sbufB(sb); 42 char *b = sbufB(sb);
40 MSize osz = (MSize)(sbufE(sb) - b); 43 MSize osz = (MSize)(sbufE(sb) - b);
@@ -54,14 +57,14 @@ char *lj_buf_wmem(char *p, const void *q, MSize len)
54 return p; 57 return p;
55} 58}
56 59
57void lj_buf_putmem(lua_State *L, SBuf *sb, const void *q, MSize len) 60void lj_buf_putmem(SBuf *sb, const void *q, MSize len)
58{ 61{
59 char *p = lj_buf_more(L, sb, len); 62 char *p = lj_buf_more(sb, len);
60 p = lj_buf_wmem(p, q, len); 63 p = lj_buf_wmem(p, q, len);
61 setsbufP(sb, p); 64 setsbufP(sb, p);
62} 65}
63 66
64uint32_t lj_buf_ruleb128(const char **pp) 67uint32_t LJ_FASTCALL lj_buf_ruleb128(const char **pp)
65{ 68{
66 const uint8_t *p = (const uint8_t *)*pp; 69 const uint8_t *p = (const uint8_t *)*pp;
67 uint32_t v = *p++; 70 uint32_t v = *p++;
@@ -74,7 +77,7 @@ uint32_t lj_buf_ruleb128(const char **pp)
74 return v; 77 return v;
75} 78}
76 79
77char *lj_buf_wuleb128(char *p, uint32_t v) 80char * LJ_FASTCALL lj_buf_wuleb128(char *p, uint32_t v)
78{ 81{
79 for (; v >= 0x80; v >>= 7) 82 for (; v >= 0x80; v >>= 7)
80 *p++ = (char)((v & 0x7f) | 0x80); 83 *p++ = (char)((v & 0x7f) | 0x80);
diff --git a/src/lj_buf.h b/src/lj_buf.h
index 5a7eae31..289eb01d 100644
--- a/src/lj_buf.h
+++ b/src/lj_buf.h
@@ -14,21 +14,24 @@
14#define sbufB(sb) (mref((sb)->b, char)) 14#define sbufB(sb) (mref((sb)->b, char))
15#define sbufP(sb) (mref((sb)->p, char)) 15#define sbufP(sb) (mref((sb)->p, char))
16#define sbufE(sb) (mref((sb)->e, char)) 16#define sbufE(sb) (mref((sb)->e, char))
17#define sbufL(sb) (mref((sb)->L, lua_State))
17#define sbufsz(sb) ((MSize)(sbufE((sb)) - sbufB((sb)))) 18#define sbufsz(sb) ((MSize)(sbufE((sb)) - sbufB((sb))))
18#define sbuflen(sb) ((MSize)(sbufP((sb)) - sbufB((sb)))) 19#define sbuflen(sb) ((MSize)(sbufP((sb)) - sbufB((sb))))
19#define setsbufP(sb, q) (setmref((sb)->p, (q))) 20#define setsbufP(sb, q) (setmref((sb)->p, (q)))
21#define setsbufL(sb, l) (setmref((sb)->L, (l)))
20 22
21LJ_FUNC char *lj_buf_tmp(lua_State *L, MSize sz); 23LJ_FUNC char * LJ_FASTCALL lj_buf_tmp(lua_State *L, MSize sz);
22LJ_FUNC void lj_buf_grow(lua_State *L, SBuf *sb, char *en); 24LJ_FUNC void LJ_FASTCALL lj_buf_grow(SBuf *sb, char *en);
23LJ_FUNC void lj_buf_shrink(lua_State *L, SBuf *sb); 25LJ_FUNC void LJ_FASTCALL lj_buf_shrink(lua_State *L, SBuf *sb);
24 26
25LJ_FUNC char *lj_buf_wmem(char *p, const void *q, MSize len); 27LJ_FUNC char *lj_buf_wmem(char *p, const void *q, MSize len);
26LJ_FUNC void lj_buf_putmem(lua_State *L, SBuf *sb, const void *q, MSize len); 28LJ_FUNC void lj_buf_putmem(SBuf *sb, const void *q, MSize len);
27LJ_FUNC uint32_t lj_buf_ruleb128(const char **pp); 29LJ_FUNC uint32_t LJ_FASTCALL lj_buf_ruleb128(const char **pp);
28LJ_FUNC char *lj_buf_wuleb128(char *p, uint32_t v); 30LJ_FUNC char * LJ_FASTCALL lj_buf_wuleb128(char *p, uint32_t v);
29 31
30static LJ_AINLINE void lj_buf_init(SBuf *sb) 32static LJ_AINLINE void lj_buf_init(lua_State *L, SBuf *sb)
31{ 33{
34 setsbufL(sb, L);
32 setmref(sb->p, NULL); setmref(sb->e, NULL); setmref(sb->b, NULL); 35 setmref(sb->p, NULL); setmref(sb->e, NULL); setmref(sb->b, NULL);
33} 36}
34 37
@@ -47,25 +50,25 @@ static LJ_AINLINE GCstr *lj_buf_str(lua_State *L, SBuf *sb)
47 return lj_str_new(L, sbufB(sb), sbuflen(sb)); 50 return lj_str_new(L, sbufB(sb), sbuflen(sb));
48} 51}
49 52
50static LJ_AINLINE char *lj_buf_need(lua_State *L, SBuf *sb, MSize sz) 53static LJ_AINLINE char *lj_buf_need(SBuf *sb, MSize sz)
51{ 54{
52 char *en = sbufB(sb) + sz; 55 char *en = sbufB(sb) + sz;
53 if (LJ_UNLIKELY(en > sbufE(sb))) 56 if (LJ_UNLIKELY(en > sbufE(sb)))
54 lj_buf_grow(L, sb, en); 57 lj_buf_grow(sb, en);
55 return sbufB(sb); 58 return sbufB(sb);
56} 59}
57 60
58static LJ_AINLINE char *lj_buf_more(lua_State *L, SBuf *sb, MSize sz) 61static LJ_AINLINE char *lj_buf_more(SBuf *sb, MSize sz)
59{ 62{
60 char *en = sbufP(sb) + sz; 63 char *en = sbufP(sb) + sz;
61 if (LJ_UNLIKELY(en > sbufE(sb))) 64 if (LJ_UNLIKELY(en > sbufE(sb)))
62 lj_buf_grow(L, sb, en); 65 lj_buf_grow(sb, en);
63 return sbufP(sb); 66 return sbufP(sb);
64} 67}
65 68
66static LJ_AINLINE void lj_buf_putb(lua_State *L, SBuf *sb, int c) 69static LJ_AINLINE void lj_buf_putb(SBuf *sb, int c)
67{ 70{
68 char *p = lj_buf_more(L, sb, 1); 71 char *p = lj_buf_more(sb, 1);
69 *p++ = (char)c; 72 *p++ = (char)c;
70 setsbufP(sb, p); 73 setsbufP(sb, p);
71} 74}
diff --git a/src/lj_cparse.c b/src/lj_cparse.c
index b8e31820..b8c95bd3 100644
--- a/src/lj_cparse.c
+++ b/src/lj_cparse.c
@@ -89,7 +89,7 @@ static LJ_AINLINE CPChar cp_get(CPState *cp)
89/* Save character in buffer. */ 89/* Save character in buffer. */
90static LJ_AINLINE void cp_save(CPState *cp, CPChar c) 90static LJ_AINLINE void cp_save(CPState *cp, CPChar c)
91{ 91{
92 lj_buf_putb(cp->L, &cp->sb, c); 92 lj_buf_putb(&cp->sb, c);
93} 93}
94 94
95/* Skip line break. Handles "\n", "\r", "\r\n" or "\n\r". */ 95/* Skip line break. Handles "\n", "\r", "\r\n" or "\n\r". */
@@ -367,7 +367,7 @@ static void cp_init(CPState *cp)
367 cp->depth = 0; 367 cp->depth = 0;
368 cp->curpack = 0; 368 cp->curpack = 0;
369 cp->packstack[0] = 255; 369 cp->packstack[0] = 255;
370 lj_buf_init(&cp->sb); 370 lj_buf_init(cp->L, &cp->sb);
371 lua_assert(cp->p != NULL); 371 lua_assert(cp->p != NULL);
372 cp_get(cp); /* Read-ahead first char. */ 372 cp_get(cp); /* Read-ahead first char. */
373 cp->tok = 0; 373 cp->tok = 0;
diff --git a/src/lj_lex.c b/src/lj_lex.c
index 5a8f1003..c988a6c1 100644
--- a/src/lj_lex.c
+++ b/src/lj_lex.c
@@ -61,7 +61,7 @@ static LJ_AINLINE LexChar lex_next(LexState *ls)
61/* Save character. */ 61/* Save character. */
62static LJ_AINLINE void lex_save(LexState *ls, LexChar c) 62static LJ_AINLINE void lex_save(LexState *ls, LexChar c)
63{ 63{
64 lj_buf_putb(ls->L, &ls->sb, c); 64 lj_buf_putb(&ls->sb, c);
65} 65}
66 66
67/* Save previous character and get next character. */ 67/* Save previous character and get next character. */
diff --git a/src/lj_load.c b/src/lj_load.c
index 2572e79b..b5cbb3ba 100644
--- a/src/lj_load.c
+++ b/src/lj_load.c
@@ -55,7 +55,7 @@ LUA_API int lua_loadx(lua_State *L, lua_Reader reader, void *data,
55 ls.rdata = data; 55 ls.rdata = data;
56 ls.chunkarg = chunkname ? chunkname : "?"; 56 ls.chunkarg = chunkname ? chunkname : "?";
57 ls.mode = mode; 57 ls.mode = mode;
58 lj_buf_init(&ls.sb); 58 lj_buf_init(L, &ls.sb);
59 status = lj_vm_cpcall(L, NULL, &ls, cpparser); 59 status = lj_vm_cpcall(L, NULL, &ls, cpparser);
60 lj_lex_cleanup(L, &ls); 60 lj_lex_cleanup(L, &ls);
61 lj_gc_check(L); 61 lj_gc_check(L);
diff --git a/src/lj_obj.h b/src/lj_obj.h
index 4d7b9262..33237119 100644
--- a/src/lj_obj.h
+++ b/src/lj_obj.h
@@ -124,6 +124,7 @@ typedef struct SBuf {
124 MRef p; /* String buffer pointer. */ 124 MRef p; /* String buffer pointer. */
125 MRef e; /* String buffer end pointer. */ 125 MRef e; /* String buffer end pointer. */
126 MRef b; /* String buffer base. */ 126 MRef b; /* String buffer base. */
127 MRef L; /* lua_State, used for buffer resizing. */
127} SBuf; 128} SBuf;
128 129
129/* -- Tags and values ----------------------------------------------------- */ 130/* -- Tags and values ----------------------------------------------------- */
@@ -516,7 +517,7 @@ typedef struct global_State {
516 lua_Alloc allocf; /* Memory allocator. */ 517 lua_Alloc allocf; /* Memory allocator. */
517 void *allocd; /* Memory allocator data. */ 518 void *allocd; /* Memory allocator data. */
518 GCState gc; /* Garbage collector. */ 519 GCState gc; /* Garbage collector. */
519 SBuf tmpbuf; /* Temporary buffer for string concatenation. */ 520 SBuf tmpbuf; /* Temporary string buffer. */
520 Node nilnode; /* Fallback 1-element hash part (nil key and value). */ 521 Node nilnode; /* Fallback 1-element hash part (nil key and value). */
521 GCstr strempty; /* Empty string. */ 522 GCstr strempty; /* Empty string. */
522 uint8_t stremptyz; /* Zero terminator of empty string. */ 523 uint8_t stremptyz; /* Zero terminator of empty string. */
diff --git a/src/lj_parse.c b/src/lj_parse.c
index 39a01e6f..c1ef2593 100644
--- a/src/lj_parse.c
+++ b/src/lj_parse.c
@@ -1441,7 +1441,7 @@ static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar)
1441 for (i = 0, n = fs->nuv; i < n; i++) { 1441 for (i = 0, n = fs->nuv; i < n; i++) {
1442 GCstr *s = strref(vs[fs->uvmap[i]].name); 1442 GCstr *s = strref(vs[fs->uvmap[i]].name);
1443 MSize len = s->len+1; 1443 MSize len = s->len+1;
1444 char *p = lj_buf_more(ls->L, &ls->sb, len); 1444 char *p = lj_buf_more(&ls->sb, len);
1445 p = lj_buf_wmem(p, strdata(s), len); 1445 p = lj_buf_wmem(p, strdata(s), len);
1446 setsbufP(&ls->sb, p); 1446 setsbufP(&ls->sb, p);
1447 } 1447 }
@@ -1454,11 +1454,11 @@ static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar)
1454 BCPos startpc; 1454 BCPos startpc;
1455 char *p; 1455 char *p;
1456 if ((uintptr_t)s < VARNAME__MAX) { 1456 if ((uintptr_t)s < VARNAME__MAX) {
1457 p = lj_buf_more(ls->L, &ls->sb, 1 + 2*5); 1457 p = lj_buf_more(&ls->sb, 1 + 2*5);
1458 *p++ = (char)(uintptr_t)s; 1458 *p++ = (char)(uintptr_t)s;
1459 } else { 1459 } else {
1460 MSize len = s->len+1; 1460 MSize len = s->len+1;
1461 p = lj_buf_more(ls->L, &ls->sb, len + 2*5); 1461 p = lj_buf_more(&ls->sb, len + 2*5);
1462 p = lj_buf_wmem(p, strdata(s), len); 1462 p = lj_buf_wmem(p, strdata(s), len);
1463 } 1463 }
1464 startpc = vs->startpc; 1464 startpc = vs->startpc;
@@ -1468,7 +1468,7 @@ static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar)
1468 lastpc = startpc; 1468 lastpc = startpc;
1469 } 1469 }
1470 } 1470 }
1471 lj_buf_putb(ls->L, &ls->sb, '\0'); /* Terminator for varinfo. */ 1471 lj_buf_putb(&ls->sb, '\0'); /* Terminator for varinfo. */
1472 return sbuflen(&ls->sb); 1472 return sbuflen(&ls->sb);
1473} 1473}
1474 1474
diff --git a/src/lj_state.c b/src/lj_state.c
index 6c3e97b1..604ff886 100644
--- a/src/lj_state.c
+++ b/src/lj_state.c
@@ -204,7 +204,7 @@ LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud)
204 setnilV(&g->nilnode.val); 204 setnilV(&g->nilnode.val);
205 setnilV(&g->nilnode.key); 205 setnilV(&g->nilnode.key);
206 setmref(g->nilnode.freetop, &g->nilnode); 206 setmref(g->nilnode.freetop, &g->nilnode);
207 lj_buf_init(&g->tmpbuf); 207 lj_buf_init(NULL, &g->tmpbuf);
208 g->gc.state = GCSpause; 208 g->gc.state = GCSpause;
209 setgcref(g->gc.root, obj2gco(L)); 209 setgcref(g->gc.root, obj2gco(L));
210 setmref(g->gc.sweep, &g->gc.root); 210 setmref(g->gc.sweep, &g->gc.root);
diff --git a/src/lj_str.c b/src/lj_str.c
index 84bab864..67353154 100644
--- a/src/lj_str.c
+++ b/src/lj_str.c
@@ -222,27 +222,28 @@ GCstr * LJ_FASTCALL lj_str_fromnumber(lua_State *L, cTValue *o)
222const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp) 222const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp)
223{ 223{
224 SBuf *sb = &G(L)->tmpbuf; 224 SBuf *sb = &G(L)->tmpbuf;
225 lj_buf_need(L, sb, (MSize)strlen(fmt)); 225 setsbufL(sb, L);
226 lj_buf_need(sb, (MSize)strlen(fmt));
226 lj_buf_reset(sb); 227 lj_buf_reset(sb);
227 for (;;) { 228 for (;;) {
228 const char *e = strchr(fmt, '%'); 229 const char *e = strchr(fmt, '%');
229 if (e == NULL) break; 230 if (e == NULL) break;
230 lj_buf_putmem(L, sb, fmt, (MSize)(e-fmt)); 231 lj_buf_putmem(sb, fmt, (MSize)(e-fmt));
231 /* This function only handles %s, %c, %d, %f and %p formats. */ 232 /* This function only handles %s, %c, %d, %f and %p formats. */
232 switch (e[1]) { 233 switch (e[1]) {
233 case 's': { 234 case 's': {
234 const char *s = va_arg(argp, char *); 235 const char *s = va_arg(argp, char *);
235 if (s == NULL) s = "(null)"; 236 if (s == NULL) s = "(null)";
236 lj_buf_putmem(L, sb, s, (MSize)strlen(s)); 237 lj_buf_putmem(sb, s, (MSize)strlen(s));
237 break; 238 break;
238 } 239 }
239 case 'c': 240 case 'c':
240 lj_buf_putb(L, sb, va_arg(argp, int)); 241 lj_buf_putb(sb, va_arg(argp, int));
241 break; 242 break;
242 case 'd': { 243 case 'd': {
243 char buf[LJ_STR_INTBUF]; 244 char buf[LJ_STR_INTBUF];
244 char *p = lj_str_bufint(buf, va_arg(argp, int32_t)); 245 char *p = lj_str_bufint(buf, va_arg(argp, int32_t));
245 lj_buf_putmem(L, sb, p, (MSize)(buf+LJ_STR_INTBUF-p)); 246 lj_buf_putmem(sb, p, (MSize)(buf+LJ_STR_INTBUF-p));
246 break; 247 break;
247 } 248 }
248 case 'f': { 249 case 'f': {
@@ -251,7 +252,7 @@ const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp)
251 MSize len; 252 MSize len;
252 tv.n = (lua_Number)(va_arg(argp, LUAI_UACNUMBER)); 253 tv.n = (lua_Number)(va_arg(argp, LUAI_UACNUMBER));
253 len = (MSize)lj_str_bufnum(buf, &tv); 254 len = (MSize)lj_str_bufnum(buf, &tv);
254 lj_buf_putmem(L, sb, buf, len); 255 lj_buf_putmem(sb, buf, len);
255 break; 256 break;
256 } 257 }
257 case 'p': { 258 case 'p': {
@@ -260,7 +261,7 @@ const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp)
260 ptrdiff_t p = (ptrdiff_t)(va_arg(argp, void *)); 261 ptrdiff_t p = (ptrdiff_t)(va_arg(argp, void *));
261 ptrdiff_t i, lasti = 2+FMTP_CHARS; 262 ptrdiff_t i, lasti = 2+FMTP_CHARS;
262 if (p == 0) { 263 if (p == 0) {
263 lj_buf_putmem(L, sb, "NULL", 4); 264 lj_buf_putmem(sb, "NULL", 4);
264 break; 265 break;
265 } 266 }
266#if LJ_64 267#if LJ_64
@@ -271,20 +272,20 @@ const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp)
271 buf[1] = 'x'; 272 buf[1] = 'x';
272 for (i = lasti-1; i >= 2; i--, p >>= 4) 273 for (i = lasti-1; i >= 2; i--, p >>= 4)
273 buf[i] = "0123456789abcdef"[(p & 15)]; 274 buf[i] = "0123456789abcdef"[(p & 15)];
274 lj_buf_putmem(L, sb, buf, (MSize)lasti); 275 lj_buf_putmem(sb, buf, (MSize)lasti);
275 break; 276 break;
276 } 277 }
277 case '%': 278 case '%':
278 lj_buf_putb(L, sb, '%'); 279 lj_buf_putb(sb, '%');
279 break; 280 break;
280 default: 281 default:
281 lj_buf_putb(L, sb, '%'); 282 lj_buf_putb(sb, '%');
282 lj_buf_putb(L, sb, e[1]); 283 lj_buf_putb(sb, e[1]);
283 break; 284 break;
284 } 285 }
285 fmt = e+2; 286 fmt = e+2;
286 } 287 }
287 lj_buf_putmem(L, sb, fmt, (MSize)strlen(fmt)); 288 lj_buf_putmem(sb, fmt, (MSize)strlen(fmt));
288 setstrV(L, L->top, lj_buf_str(L, sb)); 289 setstrV(L, L->top, lj_buf_str(L, sb));
289 incr_top(L); 290 incr_top(L);
290 return strVdata(L->top - 1); 291 return strVdata(L->top - 1);