aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2021-06-01 00:45:06 +0200
committerMike Pall <mike>2021-06-01 00:45:06 +0200
commit394fb6267acba72ee984edcd331ad1bbde72056a (patch)
tree9c79314df37e41fd15fb30f148e96cb9ab1be3a9 /src
parentb5dafe58912a70a7b5780ebbea06fac744e08b3a (diff)
downloadluajit-394fb6267acba72ee984edcd331ad1bbde72056a.tar.gz
luajit-394fb6267acba72ee984edcd331ad1bbde72056a.tar.bz2
luajit-394fb6267acba72ee984edcd331ad1bbde72056a.zip
String buffers, part 2a: internal SBuf reorg. Use full pointers.
Sponsored by fmad.io.
Diffstat (limited to 'src')
-rw-r--r--src/lib_buffer.c9
-rw-r--r--src/lib_table.c2
-rw-r--r--src/lj_asm.c2
-rw-r--r--src/lj_bcread.c10
-rw-r--r--src/lj_bcwrite.c22
-rw-r--r--src/lj_buf.c106
-rw-r--r--src/lj_buf.h29
-rw-r--r--src/lj_cparse.c8
-rw-r--r--src/lj_ctype.c2
-rw-r--r--src/lj_debug.c2
-rw-r--r--src/lj_lex.c10
-rw-r--r--src/lj_obj.h6
-rw-r--r--src/lj_parse.c6
-rw-r--r--src/lj_profile.c5
-rw-r--r--src/lj_serialize.c10
-rw-r--r--src/lj_strfmt.c66
-rw-r--r--src/lj_strfmt_num.c2
-rw-r--r--src/vm_arm.dasc2
-rw-r--r--src/vm_arm64.dasc2
-rw-r--r--src/vm_mips.dasc2
-rw-r--r--src/vm_mips64.dasc2
-rw-r--r--src/vm_ppc.dasc2
-rw-r--r--src/vm_x64.dasc2
-rw-r--r--src/vm_x86.dasc4
24 files changed, 153 insertions, 160 deletions
diff --git a/src/lib_buffer.c b/src/lib_buffer.c
index e4555596..e21362b8 100644
--- a/src/lib_buffer.c
+++ b/src/lib_buffer.c
@@ -38,15 +38,14 @@ LJLIB_CF(buffer_encode)
38LJLIB_CF(buffer_decode) 38LJLIB_CF(buffer_decode)
39{ 39{
40 GCstr *str = lj_lib_checkstr(L, 1); 40 GCstr *str = lj_lib_checkstr(L, 1);
41 const char *p = strdata(str); 41 char *p = (char *)strdata(str);
42 SBuf sb; 42 SBuf sb;
43 StrBuf sbuf; 43 StrBuf sbuf;
44 setsbufL(&sb, L); 44 setsbufL(&sb, L);
45 setmref(sb.b, p); 45 sb.b = p;
46 setmref(sb.p, p + str->len); 46 sb.w = sb.e = p + str->len;
47 setmref(sb.e, p + str->len);
48 sbuf.sb = &sb; 47 sbuf.sb = &sb;
49 sbuf.r = (char *)p; 48 sbuf.r = p;
50 setnilV(L->top++); 49 setnilV(L->top++);
51 lj_serialize_get(&sbuf, L->top-1); 50 lj_serialize_get(&sbuf, L->top-1);
52 lj_gc_check(L); 51 lj_gc_check(L);
diff --git a/src/lib_table.c b/src/lib_table.c
index 63a6a4c6..0214bb40 100644
--- a/src/lib_table.c
+++ b/src/lib_table.c
@@ -159,7 +159,7 @@ LJLIB_CF(table_concat) LJLIB_REC(.)
159 SBuf *sb = lj_buf_tmp_(L); 159 SBuf *sb = lj_buf_tmp_(L);
160 SBuf *sbx = lj_buf_puttab(sb, t, sep, i, e); 160 SBuf *sbx = lj_buf_puttab(sb, t, sep, i, e);
161 if (LJ_UNLIKELY(!sbx)) { /* Error: bad element type. */ 161 if (LJ_UNLIKELY(!sbx)) { /* Error: bad element type. */
162 int32_t idx = (int32_t)(intptr_t)sbufP(sb); 162 int32_t idx = (int32_t)(intptr_t)sb->w;
163 cTValue *o = lj_tab_getint(t, idx); 163 cTValue *o = lj_tab_getint(t, idx);
164 lj_err_callerv(L, LJ_ERR_TABCAT, 164 lj_err_callerv(L, LJ_ERR_TABCAT,
165 lj_obj_itypename[o ? itypemap(o) : ~LJ_TNIL], idx); 165 lj_obj_itypename[o ? itypemap(o) : ~LJ_TNIL], idx);
diff --git a/src/lj_asm.c b/src/lj_asm.c
index 8dfe4dd0..286756c6 100644
--- a/src/lj_asm.c
+++ b/src/lj_asm.c
@@ -1163,7 +1163,7 @@ static void asm_bufhdr(ASMState *as, IRIns *ir)
1163 } else { 1163 } else {
1164 Reg tmp = ra_scratch(as, rset_exclude(RSET_GPR, sb)); 1164 Reg tmp = ra_scratch(as, rset_exclude(RSET_GPR, sb));
1165 /* Passing ir isn't strictly correct, but it's an IRT_PGC, too. */ 1165 /* Passing ir isn't strictly correct, but it's an IRT_PGC, too. */
1166 emit_storeofs(as, ir, tmp, sb, offsetof(SBuf, p)); 1166 emit_storeofs(as, ir, tmp, sb, offsetof(SBuf, w));
1167 emit_loadofs(as, ir, tmp, sb, offsetof(SBuf, b)); 1167 emit_loadofs(as, ir, tmp, sb, offsetof(SBuf, b));
1168 } 1168 }
1169#if LJ_TARGET_X86ORX64 1169#if LJ_TARGET_X86ORX64
diff --git a/src/lj_bcread.c b/src/lj_bcread.c
index 047f98df..28795e3c 100644
--- a/src/lj_bcread.c
+++ b/src/lj_bcread.c
@@ -53,11 +53,11 @@ static LJ_NOINLINE void bcread_fill(LexState *ls, MSize len, int need)
53 do { 53 do {
54 const char *buf; 54 const char *buf;
55 size_t sz; 55 size_t sz;
56 char *p = sbufB(&ls->sb); 56 char *p = ls->sb.b;
57 MSize n = (MSize)(ls->pe - ls->p); 57 MSize n = (MSize)(ls->pe - ls->p);
58 if (n) { /* Copy remainder to buffer. */ 58 if (n) { /* Copy remainder to buffer. */
59 if (sbuflen(&ls->sb)) { /* Move down in buffer. */ 59 if (sbuflen(&ls->sb)) { /* Move down in buffer. */
60 lj_assertLS(ls->pe == sbufP(&ls->sb), "bad buffer pointer"); 60 lj_assertLS(ls->pe == ls->sb.w, "bad buffer pointer");
61 if (ls->p != p) memmove(p, ls->p, n); 61 if (ls->p != p) memmove(p, ls->p, n);
62 } else { /* Copy from buffer provided by reader. */ 62 } else { /* Copy from buffer provided by reader. */
63 p = lj_buf_need(&ls->sb, len); 63 p = lj_buf_need(&ls->sb, len);
@@ -66,7 +66,7 @@ static LJ_NOINLINE void bcread_fill(LexState *ls, MSize len, int need)
66 ls->p = p; 66 ls->p = p;
67 ls->pe = p + n; 67 ls->pe = p + n;
68 } 68 }
69 setsbufP(&ls->sb, p + n); 69 ls->sb.w = p + n;
70 buf = ls->rfunc(ls->L, ls->rdata, &sz); /* Get more data from reader. */ 70 buf = ls->rfunc(ls->L, ls->rdata, &sz); /* Get more data from reader. */
71 if (buf == NULL || sz == 0) { /* EOF? */ 71 if (buf == NULL || sz == 0) { /* EOF? */
72 if (need) bcread_error(ls, LJ_ERR_BCBAD); 72 if (need) bcread_error(ls, LJ_ERR_BCBAD);
@@ -77,8 +77,8 @@ static LJ_NOINLINE void bcread_fill(LexState *ls, MSize len, int need)
77 if (n) { /* Append to buffer. */ 77 if (n) { /* Append to buffer. */
78 n += (MSize)sz; 78 n += (MSize)sz;
79 p = lj_buf_need(&ls->sb, n < len ? len : n); 79 p = lj_buf_need(&ls->sb, n < len ? len : n);
80 memcpy(sbufP(&ls->sb), buf, sz); 80 memcpy(ls->sb.w, buf, sz);
81 setsbufP(&ls->sb, p + n); 81 ls->sb.w = p + n;
82 ls->p = p; 82 ls->p = p;
83 ls->pe = p + n; 83 ls->pe = p + n;
84 } else { /* Return buffer provided by reader. */ 84 } else { /* Return buffer provided by reader. */
diff --git a/src/lj_bcwrite.c b/src/lj_bcwrite.c
index 7580a8ea..c5c042e0 100644
--- a/src/lj_bcwrite.c
+++ b/src/lj_bcwrite.c
@@ -62,7 +62,7 @@ static void bcwrite_ktabk(BCWriteCtx *ctx, cTValue *o, int narrow)
62 if (num == (lua_Number)k) { /* -0 is never a constant. */ 62 if (num == (lua_Number)k) { /* -0 is never a constant. */
63 *p++ = BCDUMP_KTAB_INT; 63 *p++ = BCDUMP_KTAB_INT;
64 p = lj_strfmt_wuleb128(p, k); 64 p = lj_strfmt_wuleb128(p, k);
65 setsbufP(&ctx->sb, p); 65 ctx->sb.w = p;
66 return; 66 return;
67 } 67 }
68 } 68 }
@@ -73,7 +73,7 @@ static void bcwrite_ktabk(BCWriteCtx *ctx, cTValue *o, int narrow)
73 lj_assertBCW(tvispri(o), "unhandled type %d", itype(o)); 73 lj_assertBCW(tvispri(o), "unhandled type %d", itype(o));
74 *p++ = BCDUMP_KTAB_NIL+~itype(o); 74 *p++ = BCDUMP_KTAB_NIL+~itype(o);
75 } 75 }
76 setsbufP(&ctx->sb, p); 76 ctx->sb.w = p;
77} 77}
78 78
79/* Write a template table. */ 79/* Write a template table. */
@@ -97,7 +97,7 @@ static void bcwrite_ktab(BCWriteCtx *ctx, char *p, const GCtab *t)
97 /* Write number of array slots and hash slots. */ 97 /* Write number of array slots and hash slots. */
98 p = lj_strfmt_wuleb128(p, narray); 98 p = lj_strfmt_wuleb128(p, narray);
99 p = lj_strfmt_wuleb128(p, nhash); 99 p = lj_strfmt_wuleb128(p, nhash);
100 setsbufP(&ctx->sb, p); 100 ctx->sb.w = p;
101 if (narray) { /* Write array entries (may contain nil). */ 101 if (narray) { /* Write array entries (may contain nil). */
102 MSize i; 102 MSize i;
103 TValue *o = tvref(t->array); 103 TValue *o = tvref(t->array);
@@ -172,7 +172,7 @@ static void bcwrite_kgc(BCWriteCtx *ctx, GCproto *pt)
172 } 172 }
173#endif 173#endif
174 } 174 }
175 setsbufP(&ctx->sb, p); 175 ctx->sb.w = p;
176 } 176 }
177} 177}
178 178
@@ -206,7 +206,7 @@ static void bcwrite_knum(BCWriteCtx *ctx, GCproto *pt)
206 p = lj_strfmt_wuleb128(p, o->u32.hi); 206 p = lj_strfmt_wuleb128(p, o->u32.hi);
207 } 207 }
208 } 208 }
209 setsbufP(&ctx->sb, p); 209 ctx->sb.w = p;
210} 210}
211 211
212/* Write bytecode instructions. */ 212/* Write bytecode instructions. */
@@ -281,7 +281,7 @@ static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt)
281 /* Write bytecode instructions and upvalue refs. */ 281 /* Write bytecode instructions and upvalue refs. */
282 p = bcwrite_bytecode(ctx, p, pt); 282 p = bcwrite_bytecode(ctx, p, pt);
283 p = lj_buf_wmem(p, proto_uv(pt), pt->sizeuv*2); 283 p = lj_buf_wmem(p, proto_uv(pt), pt->sizeuv*2);
284 setsbufP(&ctx->sb, p); 284 ctx->sb.w = p;
285 285
286 /* Write constants. */ 286 /* Write constants. */
287 bcwrite_kgc(ctx, pt); 287 bcwrite_kgc(ctx, pt);
@@ -291,16 +291,16 @@ static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt)
291 if (sizedbg) { 291 if (sizedbg) {
292 p = lj_buf_more(&ctx->sb, sizedbg); 292 p = lj_buf_more(&ctx->sb, sizedbg);
293 p = lj_buf_wmem(p, proto_lineinfo(pt), sizedbg); 293 p = lj_buf_wmem(p, proto_lineinfo(pt), sizedbg);
294 setsbufP(&ctx->sb, p); 294 ctx->sb.w = p;
295 } 295 }
296 296
297 /* Pass buffer to writer function. */ 297 /* Pass buffer to writer function. */
298 if (ctx->status == 0) { 298 if (ctx->status == 0) {
299 MSize n = sbuflen(&ctx->sb) - 5; 299 MSize n = sbuflen(&ctx->sb) - 5;
300 MSize nn = (lj_fls(n)+8)*9 >> 6; 300 MSize nn = (lj_fls(n)+8)*9 >> 6;
301 char *q = sbufB(&ctx->sb) + (5 - nn); 301 char *q = ctx->sb.b + (5 - nn);
302 p = lj_strfmt_wuleb128(q, n); /* Fill in final size. */ 302 p = lj_strfmt_wuleb128(q, n); /* Fill in final size. */
303 lj_assertBCW(p == sbufB(&ctx->sb) + 5, "bad ULEB128 write"); 303 lj_assertBCW(p == ctx->sb.b + 5, "bad ULEB128 write");
304 ctx->status = ctx->wfunc(sbufL(&ctx->sb), q, nn+n, ctx->wdata); 304 ctx->status = ctx->wfunc(sbufL(&ctx->sb), q, nn+n, ctx->wdata);
305 } 305 }
306} 306}
@@ -324,8 +324,8 @@ static void bcwrite_header(BCWriteCtx *ctx)
324 p = lj_strfmt_wuleb128(p, len); 324 p = lj_strfmt_wuleb128(p, len);
325 p = lj_buf_wmem(p, name, len); 325 p = lj_buf_wmem(p, name, len);
326 } 326 }
327 ctx->status = ctx->wfunc(sbufL(&ctx->sb), sbufB(&ctx->sb), 327 ctx->status = ctx->wfunc(sbufL(&ctx->sb), ctx->sb.b,
328 (MSize)(p - sbufB(&ctx->sb)), ctx->wdata); 328 (MSize)(p - ctx->sb.b), ctx->wdata);
329} 329}
330 330
331/* Write footer of bytecode dump. */ 331/* Write footer of bytecode dump. */
diff --git a/src/lj_buf.c b/src/lj_buf.c
index 731470f4..66a096fb 100644
--- a/src/lj_buf.c
+++ b/src/lj_buf.c
@@ -22,10 +22,10 @@ static void buf_grow(SBuf *sb, MSize sz)
22 char *b; 22 char *b;
23 if (nsz < LJ_MIN_SBUF) nsz = LJ_MIN_SBUF; 23 if (nsz < LJ_MIN_SBUF) nsz = LJ_MIN_SBUF;
24 while (nsz < sz) nsz += nsz; 24 while (nsz < sz) nsz += nsz;
25 b = (char *)lj_mem_realloc(sbufL(sb), sbufB(sb), osz, nsz); 25 b = (char *)lj_mem_realloc(sbufL(sb), sb->b, osz, nsz);
26 setmref(sb->b, b); 26 sb->b = b;
27 setmref(sb->p, b + len); 27 sb->w = b + len;
28 setmref(sb->e, b + nsz); 28 sb->e = b + nsz;
29} 29}
30 30
31LJ_NOINLINE char *LJ_FASTCALL lj_buf_need2(SBuf *sb, MSize sz) 31LJ_NOINLINE char *LJ_FASTCALL lj_buf_need2(SBuf *sb, MSize sz)
@@ -34,7 +34,7 @@ LJ_NOINLINE char *LJ_FASTCALL lj_buf_need2(SBuf *sb, MSize sz)
34 if (LJ_UNLIKELY(sz > LJ_MAX_BUF)) 34 if (LJ_UNLIKELY(sz > LJ_MAX_BUF))
35 lj_err_mem(sbufL(sb)); 35 lj_err_mem(sbufL(sb));
36 buf_grow(sb, sz); 36 buf_grow(sb, sz);
37 return sbufB(sb); 37 return sb->b;
38} 38}
39 39
40LJ_NOINLINE char *LJ_FASTCALL lj_buf_more2(SBuf *sb, MSize sz) 40LJ_NOINLINE char *LJ_FASTCALL lj_buf_more2(SBuf *sb, MSize sz)
@@ -44,19 +44,19 @@ LJ_NOINLINE char *LJ_FASTCALL lj_buf_more2(SBuf *sb, MSize sz)
44 if (LJ_UNLIKELY(sz > LJ_MAX_BUF || len + sz > LJ_MAX_BUF)) 44 if (LJ_UNLIKELY(sz > LJ_MAX_BUF || len + sz > LJ_MAX_BUF))
45 lj_err_mem(sbufL(sb)); 45 lj_err_mem(sbufL(sb));
46 buf_grow(sb, len + sz); 46 buf_grow(sb, len + sz);
47 return sbufP(sb); 47 return sb->w;
48} 48}
49 49
50void LJ_FASTCALL lj_buf_shrink(lua_State *L, SBuf *sb) 50void LJ_FASTCALL lj_buf_shrink(lua_State *L, SBuf *sb)
51{ 51{
52 char *b = sbufB(sb); 52 char *b = sb->b;
53 MSize osz = (MSize)(sbufE(sb) - b); 53 MSize osz = (MSize)(sb->e - b);
54 if (osz > 2*LJ_MIN_SBUF) { 54 if (osz > 2*LJ_MIN_SBUF) {
55 MSize n = (MSize)(sbufP(sb) - b); 55 MSize n = (MSize)(sb->w - b);
56 b = lj_mem_realloc(L, b, osz, (osz >> 1)); 56 b = lj_mem_realloc(L, b, osz, (osz >> 1));
57 setmref(sb->b, b); 57 sb->b = b;
58 setmref(sb->p, b + n); 58 sb->w = b + n;
59 setmref(sb->e, b + (osz >> 1)); 59 sb->e = b + (osz >> 1);
60 } 60 }
61} 61}
62 62
@@ -71,26 +71,26 @@ char * LJ_FASTCALL lj_buf_tmp(lua_State *L, MSize sz)
71 71
72SBuf *lj_buf_putmem(SBuf *sb, const void *q, MSize len) 72SBuf *lj_buf_putmem(SBuf *sb, const void *q, MSize len)
73{ 73{
74 char *p = lj_buf_more(sb, len); 74 char *w = lj_buf_more(sb, len);
75 p = lj_buf_wmem(p, q, len); 75 w = lj_buf_wmem(w, q, len);
76 setsbufP(sb, p); 76 sb->w = w;
77 return sb; 77 return sb;
78} 78}
79 79
80SBuf * LJ_FASTCALL lj_buf_putchar(SBuf *sb, int c) 80SBuf * LJ_FASTCALL lj_buf_putchar(SBuf *sb, int c)
81{ 81{
82 char *p = lj_buf_more(sb, 1); 82 char *w = lj_buf_more(sb, 1);
83 *p++ = (char)c; 83 *w++ = (char)c;
84 setsbufP(sb, p); 84 sb->w = w;
85 return sb; 85 return sb;
86} 86}
87 87
88SBuf * LJ_FASTCALL lj_buf_putstr(SBuf *sb, GCstr *s) 88SBuf * LJ_FASTCALL lj_buf_putstr(SBuf *sb, GCstr *s)
89{ 89{
90 MSize len = s->len; 90 MSize len = s->len;
91 char *p = lj_buf_more(sb, len); 91 char *w = lj_buf_more(sb, len);
92 p = lj_buf_wmem(p, strdata(s), len); 92 w = lj_buf_wmem(w, strdata(s), len);
93 setsbufP(sb, p); 93 sb->w = w;
94 return sb; 94 return sb;
95} 95}
96 96
@@ -99,47 +99,47 @@ SBuf * LJ_FASTCALL lj_buf_putstr(SBuf *sb, GCstr *s)
99SBuf * LJ_FASTCALL lj_buf_putstr_reverse(SBuf *sb, GCstr *s) 99SBuf * LJ_FASTCALL lj_buf_putstr_reverse(SBuf *sb, GCstr *s)
100{ 100{
101 MSize len = s->len; 101 MSize len = s->len;
102 char *p = lj_buf_more(sb, len), *e = p+len; 102 char *w = lj_buf_more(sb, len), *e = w+len;
103 const char *q = strdata(s)+len-1; 103 const char *q = strdata(s)+len-1;
104 while (p < e) 104 while (w < e)
105 *p++ = *q--; 105 *w++ = *q--;
106 setsbufP(sb, p); 106 sb->w = w;
107 return sb; 107 return sb;
108} 108}
109 109
110SBuf * LJ_FASTCALL lj_buf_putstr_lower(SBuf *sb, GCstr *s) 110SBuf * LJ_FASTCALL lj_buf_putstr_lower(SBuf *sb, GCstr *s)
111{ 111{
112 MSize len = s->len; 112 MSize len = s->len;
113 char *p = lj_buf_more(sb, len), *e = p+len; 113 char *w = lj_buf_more(sb, len), *e = w+len;
114 const char *q = strdata(s); 114 const char *q = strdata(s);
115 for (; p < e; p++, q++) { 115 for (; w < e; w++, q++) {
116 uint32_t c = *(unsigned char *)q; 116 uint32_t c = *(unsigned char *)q;
117#if LJ_TARGET_PPC 117#if LJ_TARGET_PPC
118 *p = c + ((c >= 'A' && c <= 'Z') << 5); 118 *w = c + ((c >= 'A' && c <= 'Z') << 5);
119#else 119#else
120 if (c >= 'A' && c <= 'Z') c += 0x20; 120 if (c >= 'A' && c <= 'Z') c += 0x20;
121 *p = c; 121 *w = c;
122#endif 122#endif
123 } 123 }
124 setsbufP(sb, p); 124 sb->w = w;
125 return sb; 125 return sb;
126} 126}
127 127
128SBuf * LJ_FASTCALL lj_buf_putstr_upper(SBuf *sb, GCstr *s) 128SBuf * LJ_FASTCALL lj_buf_putstr_upper(SBuf *sb, GCstr *s)
129{ 129{
130 MSize len = s->len; 130 MSize len = s->len;
131 char *p = lj_buf_more(sb, len), *e = p+len; 131 char *w = lj_buf_more(sb, len), *e = w+len;
132 const char *q = strdata(s); 132 const char *q = strdata(s);
133 for (; p < e; p++, q++) { 133 for (; w < e; w++, q++) {
134 uint32_t c = *(unsigned char *)q; 134 uint32_t c = *(unsigned char *)q;
135#if LJ_TARGET_PPC 135#if LJ_TARGET_PPC
136 *p = c - ((c >= 'a' && c <= 'z') << 5); 136 *w = c - ((c >= 'a' && c <= 'z') << 5);
137#else 137#else
138 if (c >= 'a' && c <= 'z') c -= 0x20; 138 if (c >= 'a' && c <= 'z') c -= 0x20;
139 *p = c; 139 *w = c;
140#endif 140#endif
141 } 141 }
142 setsbufP(sb, p); 142 sb->w = w;
143 return sb; 143 return sb;
144} 144}
145 145
@@ -148,21 +148,21 @@ SBuf *lj_buf_putstr_rep(SBuf *sb, GCstr *s, int32_t rep)
148 MSize len = s->len; 148 MSize len = s->len;
149 if (rep > 0 && len) { 149 if (rep > 0 && len) {
150 uint64_t tlen = (uint64_t)rep * len; 150 uint64_t tlen = (uint64_t)rep * len;
151 char *p; 151 char *w;
152 if (LJ_UNLIKELY(tlen > LJ_MAX_STR)) 152 if (LJ_UNLIKELY(tlen > LJ_MAX_STR))
153 lj_err_mem(sbufL(sb)); 153 lj_err_mem(sbufL(sb));
154 p = lj_buf_more(sb, (MSize)tlen); 154 w = lj_buf_more(sb, (MSize)tlen);
155 if (len == 1) { /* Optimize a common case. */ 155 if (len == 1) { /* Optimize a common case. */
156 uint32_t c = strdata(s)[0]; 156 uint32_t c = strdata(s)[0];
157 do { *p++ = c; } while (--rep > 0); 157 do { *w++ = c; } while (--rep > 0);
158 } else { 158 } else {
159 const char *e = strdata(s) + len; 159 const char *e = strdata(s) + len;
160 do { 160 do {
161 const char *q = strdata(s); 161 const char *q = strdata(s);
162 do { *p++ = *q++; } while (q < e); 162 do { *w++ = *q++; } while (q < e);
163 } while (--rep > 0); 163 } while (--rep > 0);
164 } 164 }
165 setsbufP(sb, p); 165 sb->w = w;
166 } 166 }
167 return sb; 167 return sb;
168} 168}
@@ -173,27 +173,27 @@ SBuf *lj_buf_puttab(SBuf *sb, GCtab *t, GCstr *sep, int32_t i, int32_t e)
173 if (i <= e) { 173 if (i <= e) {
174 for (;;) { 174 for (;;) {
175 cTValue *o = lj_tab_getint(t, i); 175 cTValue *o = lj_tab_getint(t, i);
176 char *p; 176 char *w;
177 if (!o) { 177 if (!o) {
178 badtype: /* Error: bad element type. */ 178 badtype: /* Error: bad element type. */
179 setsbufP(sb, (void *)(intptr_t)i); /* Store failing index. */ 179 sb->w = (char *)(intptr_t)i; /* Store failing index. */
180 return NULL; 180 return NULL;
181 } else if (tvisstr(o)) { 181 } else if (tvisstr(o)) {
182 MSize len = strV(o)->len; 182 MSize len = strV(o)->len;
183 p = lj_buf_wmem(lj_buf_more(sb, len + seplen), strVdata(o), len); 183 w = lj_buf_wmem(lj_buf_more(sb, len + seplen), strVdata(o), len);
184 } else if (tvisint(o)) { 184 } else if (tvisint(o)) {
185 p = lj_strfmt_wint(lj_buf_more(sb, STRFMT_MAXBUF_INT+seplen), intV(o)); 185 w = lj_strfmt_wint(lj_buf_more(sb, STRFMT_MAXBUF_INT+seplen), intV(o));
186 } else if (tvisnum(o)) { 186 } else if (tvisnum(o)) {
187 p = lj_buf_more(lj_strfmt_putfnum(sb, STRFMT_G14, numV(o)), seplen); 187 w = lj_buf_more(lj_strfmt_putfnum(sb, STRFMT_G14, numV(o)), seplen);
188 } else { 188 } else {
189 goto badtype; 189 goto badtype;
190 } 190 }
191 if (i++ == e) { 191 if (i++ == e) {
192 setsbufP(sb, p); 192 sb->w = w;
193 break; 193 break;
194 } 194 }
195 if (seplen) p = lj_buf_wmem(p, strdata(sep), seplen); 195 if (seplen) w = lj_buf_wmem(w, strdata(sep), seplen);
196 setsbufP(sb, p); 196 sb->w = w;
197 } 197 }
198 } 198 }
199 return sb; 199 return sb;
@@ -203,7 +203,7 @@ SBuf *lj_buf_puttab(SBuf *sb, GCtab *t, GCstr *sep, int32_t i, int32_t e)
203 203
204GCstr * LJ_FASTCALL lj_buf_tostr(SBuf *sb) 204GCstr * LJ_FASTCALL lj_buf_tostr(SBuf *sb)
205{ 205{
206 return lj_str_new(sbufL(sb), sbufB(sb), sbuflen(sb)); 206 return lj_str_new(sbufL(sb), sb->b, sbuflen(sb));
207} 207}
208 208
209/* Concatenate two strings. */ 209/* Concatenate two strings. */
@@ -219,14 +219,14 @@ GCstr *lj_buf_cat2str(lua_State *L, GCstr *s1, GCstr *s2)
219/* Read ULEB128 from buffer. */ 219/* Read ULEB128 from buffer. */
220uint32_t LJ_FASTCALL lj_buf_ruleb128(const char **pp) 220uint32_t LJ_FASTCALL lj_buf_ruleb128(const char **pp)
221{ 221{
222 const uint8_t *p = (const uint8_t *)*pp; 222 const uint8_t *w = (const uint8_t *)*pp;
223 uint32_t v = *p++; 223 uint32_t v = *w++;
224 if (LJ_UNLIKELY(v >= 0x80)) { 224 if (LJ_UNLIKELY(v >= 0x80)) {
225 int sh = 0; 225 int sh = 0;
226 v &= 0x7f; 226 v &= 0x7f;
227 do { v |= ((*p & 0x7f) << (sh += 7)); } while (*p++ >= 0x80); 227 do { v |= ((*w & 0x7f) << (sh += 7)); } while (*w++ >= 0x80);
228 } 228 }
229 *pp = (const char *)p; 229 *pp = (const char *)w;
230 return v; 230 return v;
231} 231}
232 232
diff --git a/src/lj_buf.h b/src/lj_buf.h
index a720f83b..268fce5e 100644
--- a/src/lj_buf.h
+++ b/src/lj_buf.h
@@ -11,14 +11,11 @@
11#include "lj_str.h" 11#include "lj_str.h"
12 12
13/* Resizable string buffers. SBuf struct definition in lj_obj.h. */ 13/* Resizable string buffers. SBuf struct definition in lj_obj.h. */
14#define sbufB(sb) (mref((sb)->b, char)) 14#define sbufsz(sb) ((MSize)((sb)->e - (sb)->b))
15#define sbufP(sb) (mref((sb)->p, char)) 15#define sbuflen(sb) ((MSize)((sb)->w - (sb)->b))
16#define sbufE(sb) (mref((sb)->e, char)) 16#define sbufleft(sb) ((MSize)((sb)->e - (sb)->w))
17
17#define sbufL(sb) (mref((sb)->L, lua_State)) 18#define sbufL(sb) (mref((sb)->L, lua_State))
18#define sbufsz(sb) ((MSize)(sbufE((sb)) - sbufB((sb))))
19#define sbuflen(sb) ((MSize)(sbufP((sb)) - sbufB((sb))))
20#define sbufleft(sb) ((MSize)(sbufE((sb)) - sbufP((sb))))
21#define setsbufP(sb, q) (setmref((sb)->p, (q)))
22#define setsbufL(sb, l) (setmref((sb)->L, (l))) 19#define setsbufL(sb, l) (setmref((sb)->L, (l)))
23 20
24/* Buffer management */ 21/* Buffer management */
@@ -30,12 +27,12 @@ LJ_FUNC char * LJ_FASTCALL lj_buf_tmp(lua_State *L, MSize sz);
30static LJ_AINLINE void lj_buf_init(lua_State *L, SBuf *sb) 27static LJ_AINLINE void lj_buf_init(lua_State *L, SBuf *sb)
31{ 28{
32 setsbufL(sb, L); 29 setsbufL(sb, L);
33 setmref(sb->p, NULL); setmref(sb->e, NULL); setmref(sb->b, NULL); 30 sb->w = sb->e = sb->b = NULL;
34} 31}
35 32
36static LJ_AINLINE void lj_buf_reset(SBuf *sb) 33static LJ_AINLINE void lj_buf_reset(SBuf *sb)
37{ 34{
38 setmrefr(sb->p, sb->b); 35 sb->w = sb->b;
39} 36}
40 37
41static LJ_AINLINE SBuf *lj_buf_tmp_(lua_State *L) 38static LJ_AINLINE SBuf *lj_buf_tmp_(lua_State *L)
@@ -48,21 +45,21 @@ static LJ_AINLINE SBuf *lj_buf_tmp_(lua_State *L)
48 45
49static LJ_AINLINE void lj_buf_free(global_State *g, SBuf *sb) 46static LJ_AINLINE void lj_buf_free(global_State *g, SBuf *sb)
50{ 47{
51 lj_mem_free(g, sbufB(sb), sbufsz(sb)); 48 lj_mem_free(g, sb->b, sbufsz(sb));
52} 49}
53 50
54static LJ_AINLINE char *lj_buf_need(SBuf *sb, MSize sz) 51static LJ_AINLINE char *lj_buf_need(SBuf *sb, MSize sz)
55{ 52{
56 if (LJ_UNLIKELY(sz > sbufsz(sb))) 53 if (LJ_UNLIKELY(sz > sbufsz(sb)))
57 return lj_buf_need2(sb, sz); 54 return lj_buf_need2(sb, sz);
58 return sbufB(sb); 55 return sb->b;
59} 56}
60 57
61static LJ_AINLINE char *lj_buf_more(SBuf *sb, MSize sz) 58static LJ_AINLINE char *lj_buf_more(SBuf *sb, MSize sz)
62{ 59{
63 if (LJ_UNLIKELY(sz > sbufleft(sb))) 60 if (LJ_UNLIKELY(sz > sbufleft(sb)))
64 return lj_buf_more2(sb, sz); 61 return lj_buf_more2(sb, sz);
65 return sbufP(sb); 62 return sb->w;
66} 63}
67 64
68/* Low-level buffer put operations */ 65/* Low-level buffer put operations */
@@ -77,9 +74,9 @@ static LJ_AINLINE char *lj_buf_wmem(char *p, const void *q, MSize len)
77 74
78static LJ_AINLINE void lj_buf_putb(SBuf *sb, int c) 75static LJ_AINLINE void lj_buf_putb(SBuf *sb, int c)
79{ 76{
80 char *p = lj_buf_more(sb, 1); 77 char *w = lj_buf_more(sb, 1);
81 *p++ = (char)c; 78 *w++ = (char)c;
82 setsbufP(sb, p); 79 sb->w = w;
83} 80}
84 81
85/* High-level buffer put operations */ 82/* High-level buffer put operations */
@@ -97,7 +94,7 @@ LJ_FUNC uint32_t LJ_FASTCALL lj_buf_ruleb128(const char **pp);
97 94
98static LJ_AINLINE GCstr *lj_buf_str(lua_State *L, SBuf *sb) 95static LJ_AINLINE GCstr *lj_buf_str(lua_State *L, SBuf *sb)
99{ 96{
100 return lj_str_new(L, sbufB(sb), sbuflen(sb)); 97 return lj_str_new(L, sb->b, sbuflen(sb));
101} 98}
102 99
103/* Interim user-accessible string buffer. */ 100/* Interim user-accessible string buffer. */
diff --git a/src/lj_cparse.c b/src/lj_cparse.c
index 16a1d7b7..efe80759 100644
--- a/src/lj_cparse.c
+++ b/src/lj_cparse.c
@@ -133,9 +133,9 @@ LJ_NORET static void cp_errmsg(CPState *cp, CPToken tok, ErrMsg em, ...)
133 tokstr = NULL; 133 tokstr = NULL;
134 } else if (tok == CTOK_IDENT || tok == CTOK_INTEGER || tok == CTOK_STRING || 134 } else if (tok == CTOK_IDENT || tok == CTOK_INTEGER || tok == CTOK_STRING ||
135 tok >= CTOK_FIRSTDECL) { 135 tok >= CTOK_FIRSTDECL) {
136 if (sbufP(&cp->sb) == sbufB(&cp->sb)) cp_save(cp, '$'); 136 if (cp->sb.w == cp->sb.b) cp_save(cp, '$');
137 cp_save(cp, '\0'); 137 cp_save(cp, '\0');
138 tokstr = sbufB(&cp->sb); 138 tokstr = cp->sb.b;
139 } else { 139 } else {
140 tokstr = cp_tok2str(cp, tok); 140 tokstr = cp_tok2str(cp, tok);
141 } 141 }
@@ -175,7 +175,7 @@ static CPToken cp_number(CPState *cp)
175 TValue o; 175 TValue o;
176 do { cp_save(cp, cp->c); } while (lj_char_isident(cp_get(cp))); 176 do { cp_save(cp, cp->c); } while (lj_char_isident(cp_get(cp)));
177 cp_save(cp, '\0'); 177 cp_save(cp, '\0');
178 fmt = lj_strscan_scan((const uint8_t *)sbufB(&cp->sb), sbuflen(&cp->sb)-1, 178 fmt = lj_strscan_scan((const uint8_t *)(cp->sb.b), sbuflen(&cp->sb)-1,
179 &o, STRSCAN_OPT_C); 179 &o, STRSCAN_OPT_C);
180 if (fmt == STRSCAN_INT) cp->val.id = CTID_INT32; 180 if (fmt == STRSCAN_INT) cp->val.id = CTID_INT32;
181 else if (fmt == STRSCAN_U32) cp->val.id = CTID_UINT32; 181 else if (fmt == STRSCAN_U32) cp->val.id = CTID_UINT32;
@@ -279,7 +279,7 @@ static CPToken cp_string(CPState *cp)
279 return CTOK_STRING; 279 return CTOK_STRING;
280 } else { 280 } else {
281 if (sbuflen(&cp->sb) != 1) cp_err_token(cp, '\''); 281 if (sbuflen(&cp->sb) != 1) cp_err_token(cp, '\'');
282 cp->val.i32 = (int32_t)(char)*sbufB(&cp->sb); 282 cp->val.i32 = (int32_t)(char)*cp->sb.b;
283 cp->val.id = CTID_INT32; 283 cp->val.id = CTID_INT32;
284 return CTOK_INTEGER; 284 return CTOK_INTEGER;
285 } 285 }
diff --git a/src/lj_ctype.c b/src/lj_ctype.c
index 4e913556..6741437c 100644
--- a/src/lj_ctype.c
+++ b/src/lj_ctype.c
@@ -583,7 +583,7 @@ GCstr *lj_ctype_repr_complex(lua_State *L, void *sp, CTSize size)
583 lj_strfmt_putfnum(sb, STRFMT_G14, re.n); 583 lj_strfmt_putfnum(sb, STRFMT_G14, re.n);
584 if (!(im.u32.hi & 0x80000000u) || im.n != im.n) lj_buf_putchar(sb, '+'); 584 if (!(im.u32.hi & 0x80000000u) || im.n != im.n) lj_buf_putchar(sb, '+');
585 lj_strfmt_putfnum(sb, STRFMT_G14, im.n); 585 lj_strfmt_putfnum(sb, STRFMT_G14, im.n);
586 lj_buf_putchar(sb, sbufP(sb)[-1] >= 'a' ? 'I' : 'i'); 586 lj_buf_putchar(sb, sb->w[-1] >= 'a' ? 'I' : 'i');
587 return lj_buf_str(L, sb); 587 return lj_buf_str(L, sb);
588} 588}
589 589
diff --git a/src/lj_debug.c b/src/lj_debug.c
index 0b4e2c87..3dffad90 100644
--- a/src/lj_debug.c
+++ b/src/lj_debug.c
@@ -648,7 +648,7 @@ void lj_debug_dumpstack(lua_State *L, SBuf *sb, const char *fmt, int depth)
648 level += dir; 648 level += dir;
649 } 649 }
650 if (lastlen) 650 if (lastlen)
651 setsbufP(sb, sbufB(sb) + lastlen); /* Zap trailing separator. */ 651 sb->w = sb->b + lastlen; /* Zap trailing separator. */
652} 652}
653#endif 653#endif
654 654
diff --git a/src/lj_lex.c b/src/lj_lex.c
index 44ff306c..f954b428 100644
--- a/src/lj_lex.c
+++ b/src/lj_lex.c
@@ -105,7 +105,7 @@ static void lex_number(LexState *ls, TValue *tv)
105 lex_savenext(ls); 105 lex_savenext(ls);
106 } 106 }
107 lex_save(ls, '\0'); 107 lex_save(ls, '\0');
108 fmt = lj_strscan_scan((const uint8_t *)sbufB(&ls->sb), sbuflen(&ls->sb)-1, tv, 108 fmt = lj_strscan_scan((const uint8_t *)ls->sb.b, sbuflen(&ls->sb)-1, tv,
109 (LJ_DUALNUM ? STRSCAN_OPT_TOINT : STRSCAN_OPT_TONUM) | 109 (LJ_DUALNUM ? STRSCAN_OPT_TOINT : STRSCAN_OPT_TONUM) |
110 (LJ_HASFFI ? (STRSCAN_OPT_LL|STRSCAN_OPT_IMAG) : 0)); 110 (LJ_HASFFI ? (STRSCAN_OPT_LL|STRSCAN_OPT_IMAG) : 0));
111 if (LJ_DUALNUM && fmt == STRSCAN_INT) { 111 if (LJ_DUALNUM && fmt == STRSCAN_INT) {
@@ -180,7 +180,7 @@ static void lex_longstring(LexState *ls, TValue *tv, int sep)
180 } 180 }
181 } endloop: 181 } endloop:
182 if (tv) { 182 if (tv) {
183 GCstr *str = lj_parse_keepstr(ls, sbufB(&ls->sb) + (2 + (MSize)sep), 183 GCstr *str = lj_parse_keepstr(ls, ls->sb.b + (2 + (MSize)sep),
184 sbuflen(&ls->sb) - 2*(2 + (MSize)sep)); 184 sbuflen(&ls->sb) - 2*(2 + (MSize)sep));
185 setstrV(ls->L, tv, str); 185 setstrV(ls->L, tv, str);
186 } 186 }
@@ -286,7 +286,7 @@ static void lex_string(LexState *ls, TValue *tv)
286 } 286 }
287 lex_savenext(ls); /* Skip trailing delimiter. */ 287 lex_savenext(ls); /* Skip trailing delimiter. */
288 setstrV(ls->L, tv, 288 setstrV(ls->L, tv,
289 lj_parse_keepstr(ls, sbufB(&ls->sb)+1, sbuflen(&ls->sb)-2)); 289 lj_parse_keepstr(ls, ls->sb.b+1, sbuflen(&ls->sb)-2));
290} 290}
291 291
292/* -- Main lexical scanner ------------------------------------------------ */ 292/* -- Main lexical scanner ------------------------------------------------ */
@@ -306,7 +306,7 @@ static LexToken lex_scan(LexState *ls, TValue *tv)
306 do { 306 do {
307 lex_savenext(ls); 307 lex_savenext(ls);
308 } while (lj_char_isident(ls->c)); 308 } while (lj_char_isident(ls->c));
309 s = lj_parse_keepstr(ls, sbufB(&ls->sb), sbuflen(&ls->sb)); 309 s = lj_parse_keepstr(ls, ls->sb.b, sbuflen(&ls->sb));
310 setstrV(ls->L, tv, s); 310 setstrV(ls->L, tv, s);
311 if (s->reserved > 0) /* Reserved word? */ 311 if (s->reserved > 0) /* Reserved word? */
312 return TK_OFS + s->reserved; 312 return TK_OFS + s->reserved;
@@ -496,7 +496,7 @@ void lj_lex_error(LexState *ls, LexToken tok, ErrMsg em, ...)
496 tokstr = NULL; 496 tokstr = NULL;
497 } else if (tok == TK_name || tok == TK_string || tok == TK_number) { 497 } else if (tok == TK_name || tok == TK_string || tok == TK_number) {
498 lex_save(ls, '\0'); 498 lex_save(ls, '\0');
499 tokstr = sbufB(&ls->sb); 499 tokstr = ls->sb.b;
500 } else { 500 } else {
501 tokstr = lj_lex_token2str(ls, tok); 501 tokstr = lj_lex_token2str(ls, tok);
502 } 502 }
diff --git a/src/lj_obj.h b/src/lj_obj.h
index 11434ce2..2150e4e2 100644
--- a/src/lj_obj.h
+++ b/src/lj_obj.h
@@ -153,11 +153,9 @@ typedef int32_t BCLine; /* Bytecode line number. */
153typedef void (*ASMFunction)(void); 153typedef void (*ASMFunction)(void);
154 154
155/* Resizable string buffer. Need this here, details in lj_buf.h. */ 155/* Resizable string buffer. Need this here, details in lj_buf.h. */
156#define SBufHeader char *w, *e, *b; MRef L
156typedef struct SBuf { 157typedef struct SBuf {
157 MRef p; /* String buffer pointer. */ 158 SBufHeader;
158 MRef e; /* String buffer end pointer. */
159 MRef b; /* String buffer base. */
160 MRef L; /* lua_State, used for buffer resizing. */
161} SBuf; 159} SBuf;
162 160
163/* -- Tags and values ----------------------------------------------------- */ 161/* -- Tags and values ----------------------------------------------------- */
diff --git a/src/lj_parse.c b/src/lj_parse.c
index 27fcf53c..ea64677f 100644
--- a/src/lj_parse.c
+++ b/src/lj_parse.c
@@ -1465,7 +1465,7 @@ static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar)
1465 MSize len = s->len+1; 1465 MSize len = s->len+1;
1466 char *p = lj_buf_more(&ls->sb, len); 1466 char *p = lj_buf_more(&ls->sb, len);
1467 p = lj_buf_wmem(p, strdata(s), len); 1467 p = lj_buf_wmem(p, strdata(s), len);
1468 setsbufP(&ls->sb, p); 1468 ls->sb.w = p;
1469 } 1469 }
1470 *ofsvar = sbuflen(&ls->sb); 1470 *ofsvar = sbuflen(&ls->sb);
1471 lastpc = 0; 1471 lastpc = 0;
@@ -1486,7 +1486,7 @@ static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar)
1486 startpc = vs->startpc; 1486 startpc = vs->startpc;
1487 p = lj_strfmt_wuleb128(p, startpc-lastpc); 1487 p = lj_strfmt_wuleb128(p, startpc-lastpc);
1488 p = lj_strfmt_wuleb128(p, vs->endpc-startpc); 1488 p = lj_strfmt_wuleb128(p, vs->endpc-startpc);
1489 setsbufP(&ls->sb, p); 1489 ls->sb.w = p;
1490 lastpc = startpc; 1490 lastpc = startpc;
1491 } 1491 }
1492 } 1492 }
@@ -1499,7 +1499,7 @@ static void fs_fixup_var(LexState *ls, GCproto *pt, uint8_t *p, size_t ofsvar)
1499{ 1499{
1500 setmref(pt->uvinfo, p); 1500 setmref(pt->uvinfo, p);
1501 setmref(pt->varinfo, (char *)p + ofsvar); 1501 setmref(pt->varinfo, (char *)p + ofsvar);
1502 memcpy(p, sbufB(&ls->sb), sbuflen(&ls->sb)); /* Copy from temp. buffer. */ 1502 memcpy(p, ls->sb.b, sbuflen(&ls->sb)); /* Copy from temp. buffer. */
1503} 1503}
1504#else 1504#else
1505 1505
diff --git a/src/lj_profile.c b/src/lj_profile.c
index 00fdd6da..fbcb9878 100644
--- a/src/lj_profile.c
+++ b/src/lj_profile.c
@@ -346,8 +346,7 @@ LUA_API void luaJIT_profile_stop(lua_State *L)
346 lj_trace_flushall(L); 346 lj_trace_flushall(L);
347#endif 347#endif
348 lj_buf_free(g, &ps->sb); 348 lj_buf_free(g, &ps->sb);
349 setmref(ps->sb.b, NULL); 349 ps->sb.w = ps->sb.e = NULL;
350 setmref(ps->sb.e, NULL);
351 ps->g = NULL; 350 ps->g = NULL;
352 } 351 }
353} 352}
@@ -362,7 +361,7 @@ LUA_API const char *luaJIT_profile_dumpstack(lua_State *L, const char *fmt,
362 lj_buf_reset(sb); 361 lj_buf_reset(sb);
363 lj_debug_dumpstack(L, sb, fmt, depth); 362 lj_debug_dumpstack(L, sb, fmt, depth);
364 *len = (size_t)sbuflen(sb); 363 *len = (size_t)sbuflen(sb);
365 return sbufB(sb); 364 return sb->b;
366} 365}
367 366
368#endif 367#endif
diff --git a/src/lj_serialize.c b/src/lj_serialize.c
index be09d670..13220c17 100644
--- a/src/lj_serialize.c
+++ b/src/lj_serialize.c
@@ -57,8 +57,8 @@ LJ_STATIC_ASSERT((SER_TAG_TAB & 7) == 0);
57 57
58static LJ_AINLINE char *serialize_more(char *w, StrBuf *sbuf, MSize sz) 58static LJ_AINLINE char *serialize_more(char *w, StrBuf *sbuf, MSize sz)
59{ 59{
60 if (LJ_UNLIKELY(sz > (MSize)(sbufE(sbuf->sb) - w))) { 60 if (LJ_UNLIKELY(sz > (MSize)(sbuf->sb->e - w))) {
61 setsbufP(sbuf->sb, w); 61 sbuf->sb->w = w;
62 w = lj_buf_more2(sbuf->sb, sz); 62 w = lj_buf_more2(sbuf->sb, sz);
63 } 63 }
64 return w; 64 return w;
@@ -245,7 +245,7 @@ static char *serialize_put(char *w, StrBuf *sbuf, cTValue *o)
245/* Get serialized object from buffer. */ 245/* Get serialized object from buffer. */
246static char *serialize_get(char *r, StrBuf *sbuf, TValue *o) 246static char *serialize_get(char *r, StrBuf *sbuf, TValue *o)
247{ 247{
248 char *e = sbufE(sbuf->sb); 248 char *e = sbuf->sb->e;
249 uint32_t tp; 249 uint32_t tp;
250 r = serialize_ru124(r, e, &tp); if (LJ_UNLIKELY(!r)) goto eob; 250 r = serialize_ru124(r, e, &tp); if (LJ_UNLIKELY(!r)) goto eob;
251 if (LJ_LIKELY(tp >= SER_TAG_STR)) { 251 if (LJ_LIKELY(tp >= SER_TAG_STR)) {
@@ -340,14 +340,14 @@ eob:
340StrBuf * LJ_FASTCALL lj_serialize_put(StrBuf *sbuf, cTValue *o) 340StrBuf * LJ_FASTCALL lj_serialize_put(StrBuf *sbuf, cTValue *o)
341{ 341{
342 sbuf->depth = LJ_SERIALIZE_DEPTH; 342 sbuf->depth = LJ_SERIALIZE_DEPTH;
343 setsbufP(sbuf->sb, serialize_put(sbufP(sbuf->sb), sbuf, o)); 343 sbuf->sb->w = serialize_put(sbuf->sb->w, sbuf, o);
344 return sbuf; 344 return sbuf;
345} 345}
346 346
347StrBuf * LJ_FASTCALL lj_serialize_get(StrBuf *sbuf, TValue *o) 347StrBuf * LJ_FASTCALL lj_serialize_get(StrBuf *sbuf, TValue *o)
348{ 348{
349 char *r = serialize_get(sbuf->r, sbuf, o); 349 char *r = serialize_get(sbuf->r, sbuf, o);
350 if (r != sbufP(sbuf->sb)) 350 if (r != sbuf->sb->w)
351 lj_err_caller(sbufL(sbuf->sb), LJ_ERR_BUFFER_LEFTOV); 351 lj_err_caller(sbufL(sbuf->sb), LJ_ERR_BUFFER_LEFTOV);
352 sbuf->r = r; 352 sbuf->r = r;
353 return sbuf; 353 return sbuf;
diff --git a/src/lj_strfmt.c b/src/lj_strfmt.c
index b1c74f88..bde3ec0e 100644
--- a/src/lj_strfmt.c
+++ b/src/lj_strfmt.c
@@ -169,7 +169,7 @@ const char *lj_strfmt_wstrnum(lua_State *L, cTValue *o, MSize *lenp)
169 return NULL; 169 return NULL;
170 } 170 }
171 *lenp = sbuflen(sb); 171 *lenp = sbuflen(sb);
172 return sbufB(sb); 172 return sb->b;
173} 173}
174 174
175/* -- Unformatted conversions to buffer ----------------------------------- */ 175/* -- Unformatted conversions to buffer ----------------------------------- */
@@ -177,7 +177,7 @@ const char *lj_strfmt_wstrnum(lua_State *L, cTValue *o, MSize *lenp)
177/* Add integer to buffer. */ 177/* Add integer to buffer. */
178SBuf * LJ_FASTCALL lj_strfmt_putint(SBuf *sb, int32_t k) 178SBuf * LJ_FASTCALL lj_strfmt_putint(SBuf *sb, int32_t k)
179{ 179{
180 setsbufP(sb, lj_strfmt_wint(lj_buf_more(sb, STRFMT_MAXBUF_INT), k)); 180 sb->w = lj_strfmt_wint(lj_buf_more(sb, STRFMT_MAXBUF_INT), k);
181 return sb; 181 return sb;
182} 182}
183 183
@@ -191,7 +191,7 @@ SBuf * LJ_FASTCALL lj_strfmt_putnum(SBuf *sb, cTValue *o)
191 191
192SBuf * LJ_FASTCALL lj_strfmt_putptr(SBuf *sb, const void *v) 192SBuf * LJ_FASTCALL lj_strfmt_putptr(SBuf *sb, const void *v)
193{ 193{
194 setsbufP(sb, lj_strfmt_wptr(lj_buf_more(sb, STRFMT_MAXBUF_PTR), v)); 194 sb->w = lj_strfmt_wptr(lj_buf_more(sb, STRFMT_MAXBUF_PTR), v);
195 return sb; 195 return sb;
196} 196}
197 197
@@ -203,23 +203,23 @@ SBuf * LJ_FASTCALL lj_strfmt_putquoted(SBuf *sb, GCstr *str)
203 lj_buf_putb(sb, '"'); 203 lj_buf_putb(sb, '"');
204 while (len--) { 204 while (len--) {
205 uint32_t c = (uint32_t)(uint8_t)*s++; 205 uint32_t c = (uint32_t)(uint8_t)*s++;
206 char *p = lj_buf_more(sb, 4); 206 char *w = lj_buf_more(sb, 4);
207 if (c == '"' || c == '\\' || c == '\n') { 207 if (c == '"' || c == '\\' || c == '\n') {
208 *p++ = '\\'; 208 *w++ = '\\';
209 } else if (lj_char_iscntrl(c)) { /* This can only be 0-31 or 127. */ 209 } else if (lj_char_iscntrl(c)) { /* This can only be 0-31 or 127. */
210 uint32_t d; 210 uint32_t d;
211 *p++ = '\\'; 211 *w++ = '\\';
212 if (c >= 100 || lj_char_isdigit((uint8_t)*s)) { 212 if (c >= 100 || lj_char_isdigit((uint8_t)*s)) {
213 *p++ = (char)('0'+(c >= 100)); if (c >= 100) c -= 100; 213 *w++ = (char)('0'+(c >= 100)); if (c >= 100) c -= 100;
214 goto tens; 214 goto tens;
215 } else if (c >= 10) { 215 } else if (c >= 10) {
216 tens: 216 tens:
217 d = (c * 205) >> 11; c -= d * 10; *p++ = (char)('0'+d); 217 d = (c * 205) >> 11; c -= d * 10; *w++ = (char)('0'+d);
218 } 218 }
219 c += '0'; 219 c += '0';
220 } 220 }
221 *p++ = (char)c; 221 *w++ = (char)c;
222 setsbufP(sb, p); 222 sb->w = w;
223 } 223 }
224 lj_buf_putb(sb, '"'); 224 lj_buf_putb(sb, '"');
225 return sb; 225 return sb;
@@ -231,11 +231,11 @@ SBuf * LJ_FASTCALL lj_strfmt_putquoted(SBuf *sb, GCstr *str)
231SBuf *lj_strfmt_putfchar(SBuf *sb, SFormat sf, int32_t c) 231SBuf *lj_strfmt_putfchar(SBuf *sb, SFormat sf, int32_t c)
232{ 232{
233 MSize width = STRFMT_WIDTH(sf); 233 MSize width = STRFMT_WIDTH(sf);
234 char *p = lj_buf_more(sb, width > 1 ? width : 1); 234 char *w = lj_buf_more(sb, width > 1 ? width : 1);
235 if ((sf & STRFMT_F_LEFT)) *p++ = (char)c; 235 if ((sf & STRFMT_F_LEFT)) *w++ = (char)c;
236 while (width-- > 1) *p++ = ' '; 236 while (width-- > 1) *w++ = ' ';
237 if (!(sf & STRFMT_F_LEFT)) *p++ = (char)c; 237 if (!(sf & STRFMT_F_LEFT)) *w++ = (char)c;
238 setsbufP(sb, p); 238 sb->w = w;
239 return sb; 239 return sb;
240} 240}
241 241
@@ -244,20 +244,20 @@ SBuf *lj_strfmt_putfstr(SBuf *sb, SFormat sf, GCstr *str)
244{ 244{
245 MSize len = str->len <= STRFMT_PREC(sf) ? str->len : STRFMT_PREC(sf); 245 MSize len = str->len <= STRFMT_PREC(sf) ? str->len : STRFMT_PREC(sf);
246 MSize width = STRFMT_WIDTH(sf); 246 MSize width = STRFMT_WIDTH(sf);
247 char *p = lj_buf_more(sb, width > len ? width : len); 247 char *w = lj_buf_more(sb, width > len ? width : len);
248 if ((sf & STRFMT_F_LEFT)) p = lj_buf_wmem(p, strdata(str), len); 248 if ((sf & STRFMT_F_LEFT)) w = lj_buf_wmem(w, strdata(str), len);
249 while (width-- > len) *p++ = ' '; 249 while (width-- > len) *w++ = ' ';
250 if (!(sf & STRFMT_F_LEFT)) p = lj_buf_wmem(p, strdata(str), len); 250 if (!(sf & STRFMT_F_LEFT)) w = lj_buf_wmem(w, strdata(str), len);
251 setsbufP(sb, p); 251 sb->w = w;
252 return sb; 252 return sb;
253} 253}
254 254
255/* Add formatted signed/unsigned integer to buffer. */ 255/* Add formatted signed/unsigned integer to buffer. */
256SBuf *lj_strfmt_putfxint(SBuf *sb, SFormat sf, uint64_t k) 256SBuf *lj_strfmt_putfxint(SBuf *sb, SFormat sf, uint64_t k)
257{ 257{
258 char buf[STRFMT_MAXBUF_XINT], *q = buf + sizeof(buf), *p; 258 char buf[STRFMT_MAXBUF_XINT], *q = buf + sizeof(buf), *w;
259#ifdef LUA_USE_ASSERT 259#ifdef LUA_USE_ASSERT
260 char *ps; 260 char *ws;
261#endif 261#endif
262 MSize prefix = 0, len, prec, pprec, width, need; 262 MSize prefix = 0, len, prec, pprec, width, need;
263 263
@@ -301,27 +301,27 @@ SBuf *lj_strfmt_putfxint(SBuf *sb, SFormat sf, uint64_t k)
301 width = STRFMT_WIDTH(sf); 301 width = STRFMT_WIDTH(sf);
302 pprec = prec + (prefix >> 8); 302 pprec = prec + (prefix >> 8);
303 need = width > pprec ? width : pprec; 303 need = width > pprec ? width : pprec;
304 p = lj_buf_more(sb, need); 304 w = lj_buf_more(sb, need);
305#ifdef LUA_USE_ASSERT 305#ifdef LUA_USE_ASSERT
306 ps = p; 306 ws = w;
307#endif 307#endif
308 308
309 /* Format number with leading/trailing whitespace and zeros. */ 309 /* Format number with leading/trailing whitespace and zeros. */
310 if ((sf & (STRFMT_F_LEFT|STRFMT_F_ZERO)) == 0) 310 if ((sf & (STRFMT_F_LEFT|STRFMT_F_ZERO)) == 0)
311 while (width-- > pprec) *p++ = ' '; 311 while (width-- > pprec) *w++ = ' ';
312 if (prefix) { 312 if (prefix) {
313 if ((char)prefix >= 'X') *p++ = '0'; 313 if ((char)prefix >= 'X') *w++ = '0';
314 *p++ = (char)prefix; 314 *w++ = (char)prefix;
315 } 315 }
316 if ((sf & (STRFMT_F_LEFT|STRFMT_F_ZERO)) == STRFMT_F_ZERO) 316 if ((sf & (STRFMT_F_LEFT|STRFMT_F_ZERO)) == STRFMT_F_ZERO)
317 while (width-- > pprec) *p++ = '0'; 317 while (width-- > pprec) *w++ = '0';
318 while (prec-- > len) *p++ = '0'; 318 while (prec-- > len) *w++ = '0';
319 while (q < buf + sizeof(buf)) *p++ = *q++; /* Add number itself. */ 319 while (q < buf + sizeof(buf)) *w++ = *q++; /* Add number itself. */
320 if ((sf & STRFMT_F_LEFT)) 320 if ((sf & STRFMT_F_LEFT))
321 while (width-- > pprec) *p++ = ' '; 321 while (width-- > pprec) *w++ = ' ';
322 322
323 lj_assertX(need == (MSize)(p - ps), "miscalculated format size"); 323 lj_assertX(need == (MSize)(w - ws), "miscalculated format size");
324 setsbufP(sb, p); 324 sb->w = w;
325 return sb; 325 return sb;
326} 326}
327 327
diff --git a/src/lj_strfmt_num.c b/src/lj_strfmt_num.c
index 66f83af3..dfd56bd4 100644
--- a/src/lj_strfmt_num.c
+++ b/src/lj_strfmt_num.c
@@ -576,7 +576,7 @@ static char *lj_strfmt_wfnum(SBuf *sb, SFormat sf, lua_Number n, char *p)
576/* Add formatted floating-point number to buffer. */ 576/* Add formatted floating-point number to buffer. */
577SBuf *lj_strfmt_putfnum(SBuf *sb, SFormat sf, lua_Number n) 577SBuf *lj_strfmt_putfnum(SBuf *sb, SFormat sf, lua_Number n)
578{ 578{
579 setsbufP(sb, lj_strfmt_wfnum(sb, sf, n, NULL)); 579 sb->w = lj_strfmt_wfnum(sb, sf, n, NULL);
580 return sb; 580 return sb;
581} 581}
582 582
diff --git a/src/vm_arm.dasc b/src/vm_arm.dasc
index c0934ac8..35ba0e36 100644
--- a/src/vm_arm.dasc
+++ b/src/vm_arm.dasc
@@ -1810,7 +1810,7 @@ static void build_subroutines(BuildCtx *ctx)
1810 | str BASE, L->base 1810 | str BASE, L->base
1811 | str PC, SAVE_PC 1811 | str PC, SAVE_PC
1812 | str L, SBUF:CARG1->L 1812 | str L, SBUF:CARG1->L
1813 | str CARG4, SBUF:CARG1->p 1813 | str CARG4, SBUF:CARG1->w
1814 | bl extern lj_buf_putstr_ .. name 1814 | bl extern lj_buf_putstr_ .. name
1815 | bl extern lj_buf_tostr 1815 | bl extern lj_buf_tostr
1816 | b ->fff_resstr 1816 | b ->fff_resstr
diff --git a/src/vm_arm64.dasc b/src/vm_arm64.dasc
index 3a63d23b..92f89cd6 100644
--- a/src/vm_arm64.dasc
+++ b/src/vm_arm64.dasc
@@ -1589,7 +1589,7 @@ static void build_subroutines(BuildCtx *ctx)
1589 | str BASE, L->base 1589 | str BASE, L->base
1590 | str PC, SAVE_PC 1590 | str PC, SAVE_PC
1591 | str L, GL->tmpbuf.L 1591 | str L, GL->tmpbuf.L
1592 | str TMP0, GL->tmpbuf.p 1592 | str TMP0, GL->tmpbuf.w
1593 | bl extern lj_buf_putstr_ .. name 1593 | bl extern lj_buf_putstr_ .. name
1594 | bl extern lj_buf_tostr 1594 | bl extern lj_buf_tostr
1595 | b ->fff_resstr 1595 | b ->fff_resstr
diff --git a/src/vm_mips.dasc b/src/vm_mips.dasc
index e16066d7..7bd86514 100644
--- a/src/vm_mips.dasc
+++ b/src/vm_mips.dasc
@@ -1971,7 +1971,7 @@ static void build_subroutines(BuildCtx *ctx)
1971 | lw TMP0, SBUF:CARG1->b 1971 | lw TMP0, SBUF:CARG1->b
1972 | sw L, SBUF:CARG1->L 1972 | sw L, SBUF:CARG1->L
1973 | sw BASE, L->base 1973 | sw BASE, L->base
1974 | sw TMP0, SBUF:CARG1->p 1974 | sw TMP0, SBUF:CARG1->w
1975 | call_intern extern lj_buf_putstr_ .. name 1975 | call_intern extern lj_buf_putstr_ .. name
1976 |. sw PC, SAVE_PC 1976 |. sw PC, SAVE_PC
1977 | load_got lj_buf_tostr 1977 | load_got lj_buf_tostr
diff --git a/src/vm_mips64.dasc b/src/vm_mips64.dasc
index 877d9885..05395ffd 100644
--- a/src/vm_mips64.dasc
+++ b/src/vm_mips64.dasc
@@ -2041,7 +2041,7 @@ static void build_subroutines(BuildCtx *ctx)
2041 | ld TMP0, SBUF:CARG1->b 2041 | ld TMP0, SBUF:CARG1->b
2042 | sd L, SBUF:CARG1->L 2042 | sd L, SBUF:CARG1->L
2043 | sd BASE, L->base 2043 | sd BASE, L->base
2044 | sd TMP0, SBUF:CARG1->p 2044 | sd TMP0, SBUF:CARG1->w
2045 | call_intern extern lj_buf_putstr_ .. name 2045 | call_intern extern lj_buf_putstr_ .. name
2046 |. sd PC, SAVE_PC 2046 |. sd PC, SAVE_PC
2047 | load_got lj_buf_tostr 2047 | load_got lj_buf_tostr
diff --git a/src/vm_ppc.dasc b/src/vm_ppc.dasc
index 25898f94..6aa00c5b 100644
--- a/src/vm_ppc.dasc
+++ b/src/vm_ppc.dasc
@@ -2516,7 +2516,7 @@ static void build_subroutines(BuildCtx *ctx)
2516 | stw L, SBUF:CARG1->L 2516 | stw L, SBUF:CARG1->L
2517 | stp BASE, L->base 2517 | stp BASE, L->base
2518 | stw PC, SAVE_PC 2518 | stw PC, SAVE_PC
2519 | stw TMP0, SBUF:CARG1->p 2519 | stw TMP0, SBUF:CARG1->w
2520 | bl extern lj_buf_putstr_ .. name 2520 | bl extern lj_buf_putstr_ .. name
2521 | bl extern lj_buf_tostr 2521 | bl extern lj_buf_tostr
2522 | b ->fff_resstr 2522 | b ->fff_resstr
diff --git a/src/vm_x64.dasc b/src/vm_x64.dasc
index 05bfa649..76ce071d 100644
--- a/src/vm_x64.dasc
+++ b/src/vm_x64.dasc
@@ -2011,7 +2011,7 @@ static void build_subroutines(BuildCtx *ctx)
2011 |.endif 2011 |.endif
2012 | mov RC, SBUF:CARG1->b 2012 | mov RC, SBUF:CARG1->b
2013 | mov SBUF:CARG1->L, L:RB 2013 | mov SBUF:CARG1->L, L:RB
2014 | mov SBUF:CARG1->p, RC 2014 | mov SBUF:CARG1->w, RC
2015 | mov SAVE_PC, PC 2015 | mov SAVE_PC, PC
2016 | call extern lj_buf_putstr_ .. name 2016 | call extern lj_buf_putstr_ .. name
2017 | mov CARG1, rax 2017 | mov CARG1, rax
diff --git a/src/vm_x86.dasc b/src/vm_x86.dasc
index 1e376e45..81b899fa 100644
--- a/src/vm_x86.dasc
+++ b/src/vm_x86.dasc
@@ -2423,9 +2423,9 @@ static void build_subroutines(BuildCtx *ctx)
2423 | lea SBUF:FCARG1, [DISPATCH+DISPATCH_GL(tmpbuf)] 2423 | lea SBUF:FCARG1, [DISPATCH+DISPATCH_GL(tmpbuf)]
2424 | mov L:RB->base, BASE 2424 | mov L:RB->base, BASE
2425 | mov STR:FCARG2, [BASE] // Caveat: FCARG2 == BASE 2425 | mov STR:FCARG2, [BASE] // Caveat: FCARG2 == BASE
2426 | mov RC, SBUF:FCARG1->b 2426 | mov RCa, SBUF:FCARG1->b
2427 | mov SBUF:FCARG1->L, L:RB 2427 | mov SBUF:FCARG1->L, L:RB
2428 | mov SBUF:FCARG1->p, RC 2428 | mov SBUF:FCARG1->w, RCa
2429 | mov SAVE_PC, PC 2429 | mov SAVE_PC, PC
2430 | call extern lj_buf_putstr_ .. name .. @8 2430 | call extern lj_buf_putstr_ .. name .. @8
2431 | mov FCARG1, eax 2431 | mov FCARG1, eax