aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib_buffer.c23
-rw-r--r--src/lj_buf.c53
-rw-r--r--src/lj_buf.h100
-rw-r--r--src/lj_obj.h4
-rw-r--r--src/lj_serialize.c124
-rw-r--r--src/lj_serialize.h4
6 files changed, 210 insertions, 98 deletions
diff --git a/src/lib_buffer.c b/src/lib_buffer.c
index e21362b8..c9ef9510 100644
--- a/src/lib_buffer.c
+++ b/src/lib_buffer.c
@@ -22,15 +22,13 @@
22 22
23#define LJLIB_MODULE_buffer 23#define LJLIB_MODULE_buffer
24 24
25/* Note: this uses interim structs until the SBuf reorg. */
26
27LJLIB_CF(buffer_encode) 25LJLIB_CF(buffer_encode)
28{ 26{
29 cTValue *o = lj_lib_checkany(L, 1); 27 cTValue *o = lj_lib_checkany(L, 1);
30 StrBuf sbuf; 28 SBufExt sbx;
31 sbuf.sb = lj_buf_tmp_(L); 29 lj_bufx_init_borrow(L, &sbx, &G(L)->tmpbuf);
32 lj_serialize_put(&sbuf, o); 30 lj_serialize_put(&sbx, o);
33 setstrV(L, L->top++, lj_buf_str(L, sbuf.sb)); 31 setstrV(L, L->top++, lj_buf_str(L, (SBuf *)&sbx));
34 lj_gc_check(L); 32 lj_gc_check(L);
35 return 1; 33 return 1;
36} 34}
@@ -38,16 +36,11 @@ LJLIB_CF(buffer_encode)
38LJLIB_CF(buffer_decode) 36LJLIB_CF(buffer_decode)
39{ 37{
40 GCstr *str = lj_lib_checkstr(L, 1); 38 GCstr *str = lj_lib_checkstr(L, 1);
41 char *p = (char *)strdata(str); 39 SBufExt sbx;
42 SBuf sb; 40 lj_bufx_init_cow(L, &sbx, strdata(str), str->len);
43 StrBuf sbuf; 41 /* No need to set sbx.cowref here. */
44 setsbufL(&sb, L);
45 sb.b = p;
46 sb.w = sb.e = p + str->len;
47 sbuf.sb = &sb;
48 sbuf.r = p;
49 setnilV(L->top++); 42 setnilV(L->top++);
50 lj_serialize_get(&sbuf, L->top-1); 43 lj_serialize_get(&sbx, L->top-1);
51 lj_gc_check(L); 44 lj_gc_check(L);
52 return 1; 45 return 1;
53} 46}
diff --git a/src/lj_buf.c b/src/lj_buf.c
index 66a096fb..889ccbca 100644
--- a/src/lj_buf.c
+++ b/src/lj_buf.c
@@ -20,12 +20,32 @@ static void buf_grow(SBuf *sb, MSize sz)
20{ 20{
21 MSize osz = sbufsz(sb), len = sbuflen(sb), nsz = osz; 21 MSize osz = sbufsz(sb), len = sbuflen(sb), nsz = osz;
22 char *b; 22 char *b;
23 GCSize flag;
23 if (nsz < LJ_MIN_SBUF) nsz = LJ_MIN_SBUF; 24 if (nsz < LJ_MIN_SBUF) nsz = LJ_MIN_SBUF;
24 while (nsz < sz) nsz += nsz; 25 while (nsz < sz) nsz += nsz;
25 b = (char *)lj_mem_realloc(sbufL(sb), sb->b, osz, nsz); 26 flag = sbufflag(sb);
27 if ((flag & SBUF_FLAG_COW)) { /* Copy-on-write semantics. */
28 lj_assertG_(G(sbufL(sb)), sb->w == sb->e, "bad SBuf COW");
29 b = (char *)lj_mem_new(sbufL(sb), nsz);
30 setsbufflag(sb, flag & ~(GCSize)SBUF_FLAG_COW);
31 setgcrefnull(sbufX(sb)->cowref);
32 memcpy(b, sb->b, osz);
33 } else {
34 b = (char *)lj_mem_realloc(sbufL(sb), sb->b, osz, nsz);
35 }
36 if ((flag & SBUF_FLAG_EXT)) {
37 sbufX(sb)->r = sbufX(sb)->r - sb->b + b; /* Adjust read pointer, too. */
38 }
39 /* Adjust buffer pointers. */
26 sb->b = b; 40 sb->b = b;
27 sb->w = b + len; 41 sb->w = b + len;
28 sb->e = b + nsz; 42 sb->e = b + nsz;
43 if ((flag & SBUF_FLAG_BORROW)) { /* Adjust borrowed buffer pointers. */
44 SBuf *bsb = mref(sbufX(sb)->bsb, SBuf);
45 bsb->b = b;
46 bsb->w = b + len;
47 bsb->e = b + nsz;
48 }
29} 49}
30 50
31LJ_NOINLINE char *LJ_FASTCALL lj_buf_need2(SBuf *sb, MSize sz) 51LJ_NOINLINE char *LJ_FASTCALL lj_buf_need2(SBuf *sb, MSize sz)
@@ -39,11 +59,31 @@ LJ_NOINLINE char *LJ_FASTCALL lj_buf_need2(SBuf *sb, MSize sz)
39 59
40LJ_NOINLINE char *LJ_FASTCALL lj_buf_more2(SBuf *sb, MSize sz) 60LJ_NOINLINE char *LJ_FASTCALL lj_buf_more2(SBuf *sb, MSize sz)
41{ 61{
42 MSize len = sbuflen(sb); 62 if (sbufisext(sb)) {
43 lj_assertG_(G(sbufL(sb)), sz > sbufleft(sb), "SBuf overflow"); 63 SBufExt *sbx = (SBufExt *)sb;
44 if (LJ_UNLIKELY(sz > LJ_MAX_BUF || len + sz > LJ_MAX_BUF)) 64 MSize len = sbufxlen(sbx);
45 lj_err_mem(sbufL(sb)); 65 if (LJ_UNLIKELY(sz > LJ_MAX_BUF || len + sz > LJ_MAX_BUF))
46 buf_grow(sb, len + sz); 66 lj_err_mem(sbufL(sbx));
67 if (len + sz > sbufsz(sbx)) { /* Must grow. */
68 buf_grow((SBuf *)sbx, len + sz);
69 } else if (sbufxslack(sbx) < (sbufsz(sbx) >> 3)) {
70 /* Also grow to avoid excessive compactions, if slack < size/8. */
71 buf_grow((SBuf *)sbx, sbuflen(sbx) + sz); /* Not sbufxlen! */
72 return sbx->w;
73 }
74 if (sbx->r != sbx->b) { /* Compact by moving down. */
75 memmove(sbx->b, sbx->r, len);
76 sbx->r = sbx->b;
77 sbx->w = sbx->b + len;
78 lj_assertG_(G(sbufL(sbx)), len + sz <= sbufsz(sbx), "bad SBuf compact");
79 }
80 } else {
81 MSize len = sbuflen(sb);
82 lj_assertG_(G(sbufL(sb)), sz > sbufleft(sb), "SBuf overflow");
83 if (LJ_UNLIKELY(sz > LJ_MAX_BUF || len + sz > LJ_MAX_BUF))
84 lj_err_mem(sbufL(sb));
85 buf_grow(sb, len + sz);
86 }
47 return sb->w; 87 return sb->w;
48} 88}
49 89
@@ -58,6 +98,7 @@ void LJ_FASTCALL lj_buf_shrink(lua_State *L, SBuf *sb)
58 sb->w = b + n; 98 sb->w = b + n;
59 sb->e = b + (osz >> 1); 99 sb->e = b + (osz >> 1);
60 } 100 }
101 lj_assertG_(G(sbufL(sb)), !sbufisext(sb), "YAGNI shrink SBufExt");
61} 102}
62 103
63char * LJ_FASTCALL lj_buf_tmp(lua_State *L, MSize sz) 104char * LJ_FASTCALL lj_buf_tmp(lua_State *L, MSize sz)
diff --git a/src/lj_buf.h b/src/lj_buf.h
index 268fce5e..1fb70146 100644
--- a/src/lj_buf.h
+++ b/src/lj_buf.h
@@ -10,13 +10,53 @@
10#include "lj_gc.h" 10#include "lj_gc.h"
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. */
14#define sbufsz(sb) ((MSize)((sb)->e - (sb)->b))
15#define sbuflen(sb) ((MSize)((sb)->w - (sb)->b))
16#define sbufleft(sb) ((MSize)((sb)->e - (sb)->w))
17 14
18#define sbufL(sb) (mref((sb)->L, lua_State)) 15/* The SBuf struct definition is in lj_obj.h:
19#define setsbufL(sb, l) (setmref((sb)->L, (l))) 16** char *w; Write pointer.
17** char *e; End pointer.
18** char *b; Base pointer.
19** MRef L; lua_State, used for buffer resizing. Extension bits in 3 LSB.
20*/
21
22/* Extended string buffer. */
23typedef struct SBufExt {
24 SBufHeader;
25 union {
26 GCRef cowref; /* Copy-on-write object reference. */
27 MRef bsb; /* Borrowed string buffer. */
28 };
29 char *r; /* Read pointer. */
30 int depth; /* Remaining recursion depth. */
31} SBufExt;
32
33#define sbufsz(sb) ((MSize)((sb)->e - (sb)->b))
34#define sbuflen(sb) ((MSize)((sb)->w - (sb)->b))
35#define sbufleft(sb) ((MSize)((sb)->e - (sb)->w))
36#define sbufxlen(sbx) ((MSize)((sbx)->w - (sbx)->r))
37#define sbufxslack(sbx) ((MSize)((sbx)->r - (sbx)->b))
38
39#define SBUF_MASK_FLAG (7)
40#define SBUF_MASK_L (~(GCSize)SBUF_MASK_FLAG)
41#define SBUF_FLAG_EXT 1 /* Extended string buffer. */
42#define SBUF_FLAG_COW 2 /* Copy-on-write buffer. */
43#define SBUF_FLAG_BORROW 4 /* Borrowed string buffer. */
44
45#define sbufL(sb) \
46 ((lua_State *)(void *)(uintptr_t)(mrefu((sb)->L) & SBUF_MASK_L))
47#define setsbufL(sb, l) (setmref((sb)->L, (l)))
48#define setsbufXL(sb, l, flag) \
49 (setmrefu((sb)->L, (GCSize)(uintptr_t)(void *)(l) + (flag)))
50#define setsbufXL_(sb, l) \
51 (setmrefu((sb)->L, (GCSize)(uintptr_t)(void *)(l) | (mrefu((sb)->L) & SBUF_MASK_FLAG)))
52
53#define sbufflag(sb) (mrefu((sb)->L))
54#define sbufisext(sb) (sbufflag((sb)) & SBUF_FLAG_EXT)
55#define sbufiscow(sb) (sbufflag((sb)) & SBUF_FLAG_COW)
56#define sbufisborrow(sb) (sbufflag((sb)) & SBUF_FLAG_BORROW)
57#define sbufX(sb) \
58 (lj_assertG_(G(sbufL(sb)), sbufisext(sb), "not an SBufExt"), (SBufExt *)(sb))
59#define setsbufflag(sb, flag) (setmrefu((sb)->L, (flag)))
20 60
21/* Buffer management */ 61/* Buffer management */
22LJ_FUNC char *LJ_FASTCALL lj_buf_need2(SBuf *sb, MSize sz); 62LJ_FUNC char *LJ_FASTCALL lj_buf_need2(SBuf *sb, MSize sz);
@@ -45,6 +85,7 @@ static LJ_AINLINE SBuf *lj_buf_tmp_(lua_State *L)
45 85
46static LJ_AINLINE void lj_buf_free(global_State *g, SBuf *sb) 86static LJ_AINLINE void lj_buf_free(global_State *g, SBuf *sb)
47{ 87{
88 lj_assertG(!sbufisext(sb), "bad free of SBufExt");
48 lj_mem_free(g, sb->b, sbufsz(sb)); 89 lj_mem_free(g, sb->b, sbufsz(sb));
49} 90}
50 91
@@ -62,6 +103,46 @@ static LJ_AINLINE char *lj_buf_more(SBuf *sb, MSize sz)
62 return sb->w; 103 return sb->w;
63} 104}
64 105
106/* Extended buffer management */
107static LJ_AINLINE void lj_bufx_init(lua_State *L, SBufExt *sbx)
108{
109 memset(sbx, 0, sizeof(SBufExt));
110 setsbufXL(sbx, L, SBUF_FLAG_EXT);
111}
112
113static LJ_AINLINE void lj_bufx_init_borrow(lua_State *L, SBufExt *sbx, SBuf *sb)
114{
115 memset(sbx, 0, sizeof(SBufExt));
116 setsbufXL(sbx, L, SBUF_FLAG_EXT | SBUF_FLAG_BORROW);
117 setmref(sbx->bsb, sb);
118 sbx->r = sbx->w = sbx->b = sb->b;
119 sbx->e = sb->e;
120}
121
122static LJ_AINLINE void lj_bufx_init_cow(lua_State *L, SBufExt *sbx,
123 const char *p, MSize len)
124{
125 memset(sbx, 0, sizeof(SBufExt));
126 setsbufXL(sbx, L, SBUF_FLAG_EXT | SBUF_FLAG_COW);
127 sbx->r = sbx->b = (char *)p;
128 sbx->w = sbx->e = (char *)p + len;
129}
130
131static LJ_AINLINE void lj_bufx_reset(SBufExt *sbx)
132{
133 if (sbufiscow(sbx)) {
134 setmrefu(sbx->L, (mrefu(sbx->L) & ~(GCSize)SBUF_FLAG_COW));
135 setgcrefnull(sbx->cowref);
136 sbx->b = sbx->e = NULL;
137 }
138 sbx->r = sbx->w = sbx->b;
139}
140
141static LJ_AINLINE void lj_bufx_free(global_State *g, SBufExt *sbx)
142{
143 if (!sbufiscow(sbx)) lj_mem_free(g, sbx->b, sbufsz(sbx));
144}
145
65/* Low-level buffer put operations */ 146/* Low-level buffer put operations */
66LJ_FUNC SBuf *lj_buf_putmem(SBuf *sb, const void *q, MSize len); 147LJ_FUNC SBuf *lj_buf_putmem(SBuf *sb, const void *q, MSize len);
67LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putchar(SBuf *sb, int c); 148LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putchar(SBuf *sb, int c);
@@ -97,11 +178,4 @@ static LJ_AINLINE GCstr *lj_buf_str(lua_State *L, SBuf *sb)
97 return lj_str_new(L, sb->b, sbuflen(sb)); 178 return lj_str_new(L, sb->b, sbuflen(sb));
98} 179}
99 180
100/* Interim user-accessible string buffer. */
101typedef struct StrBuf {
102 SBuf *sb; /* Pointer to system buffer. */
103 char *r; /* String buffer read pointer. */
104 int depth; /* Remaining recursion depth. */
105} StrBuf;
106
107#endif 181#endif
diff --git a/src/lj_obj.h b/src/lj_obj.h
index 2150e4e2..9b691e49 100644
--- a/src/lj_obj.h
+++ b/src/lj_obj.h
@@ -34,13 +34,17 @@ typedef struct MRef {
34 34
35#if LJ_GC64 35#if LJ_GC64
36#define mref(r, t) ((t *)(void *)(r).ptr64) 36#define mref(r, t) ((t *)(void *)(r).ptr64)
37#define mrefu(r) ((r).ptr64)
37 38
38#define setmref(r, p) ((r).ptr64 = (uint64_t)(void *)(p)) 39#define setmref(r, p) ((r).ptr64 = (uint64_t)(void *)(p))
40#define setmrefu(r, u) ((r).ptr64 = (uint64_t)(u))
39#define setmrefr(r, v) ((r).ptr64 = (v).ptr64) 41#define setmrefr(r, v) ((r).ptr64 = (v).ptr64)
40#else 42#else
41#define mref(r, t) ((t *)(void *)(uintptr_t)(r).ptr32) 43#define mref(r, t) ((t *)(void *)(uintptr_t)(r).ptr32)
44#define mrefu(r) ((r).ptr32)
42 45
43#define setmref(r, p) ((r).ptr32 = (uint32_t)(uintptr_t)(void *)(p)) 46#define setmref(r, p) ((r).ptr32 = (uint32_t)(uintptr_t)(void *)(p))
47#define setmrefu(r, u) ((r).ptr32 = (uint32_t)(u))
44#define setmrefr(r, v) ((r).ptr32 = (v).ptr32) 48#define setmrefr(r, v) ((r).ptr32 = (v).ptr32)
45#endif 49#endif
46 50
diff --git a/src/lj_serialize.c b/src/lj_serialize.c
index 13220c17..4e76502a 100644
--- a/src/lj_serialize.c
+++ b/src/lj_serialize.c
@@ -55,11 +55,11 @@ LJ_STATIC_ASSERT((SER_TAG_TAB & 7) == 0);
55 55
56/* -- Helper functions ---------------------------------------------------- */ 56/* -- Helper functions ---------------------------------------------------- */
57 57
58static LJ_AINLINE char *serialize_more(char *w, StrBuf *sbuf, MSize sz) 58static LJ_AINLINE char *serialize_more(char *w, SBufExt *sbx, MSize sz)
59{ 59{
60 if (LJ_UNLIKELY(sz > (MSize)(sbuf->sb->e - w))) { 60 if (LJ_UNLIKELY(sz > (MSize)(sbx->e - w))) {
61 sbuf->sb->w = w; 61 sbx->w = w;
62 w = lj_buf_more2(sbuf->sb, sz); 62 w = lj_buf_more2((SBuf *)sbx, sz);
63 } 63 }
64 return w; 64 return w;
65} 65}
@@ -90,14 +90,14 @@ static LJ_AINLINE char *serialize_wu124(char *w, uint32_t v)
90 } 90 }
91} 91}
92 92
93static LJ_NOINLINE char *serialize_ru124_(char *r, char *e, uint32_t *pv) 93static LJ_NOINLINE char *serialize_ru124_(char *r, char *w, uint32_t *pv)
94{ 94{
95 uint32_t v = *pv; 95 uint32_t v = *pv;
96 if (v != 0xff) { 96 if (v != 0xff) {
97 if (r >= e) return NULL; 97 if (r >= w) return NULL;
98 v = ((v & 0x1f) << 8) + *(uint8_t *)r + 0xe0; r++; 98 v = ((v & 0x1f) << 8) + *(uint8_t *)r + 0xe0; r++;
99 } else { 99 } else {
100 if (r + 4 > e) return NULL; 100 if (r + 4 > w) return NULL;
101 v = lj_getu32(r); r += 4; 101 v = lj_getu32(r); r += 4;
102#if LJ_BE 102#if LJ_BE
103 v = lj_bswap(v); 103 v = lj_bswap(v);
@@ -107,13 +107,13 @@ static LJ_NOINLINE char *serialize_ru124_(char *r, char *e, uint32_t *pv)
107 return r; 107 return r;
108} 108}
109 109
110static LJ_AINLINE char *serialize_ru124(char *r, char *e, uint32_t *pv) 110static LJ_AINLINE char *serialize_ru124(char *r, char *w, uint32_t *pv)
111{ 111{
112 if (LJ_LIKELY(r < e)) { 112 if (LJ_LIKELY(r < w)) {
113 uint32_t v = *(uint8_t *)r; r++; 113 uint32_t v = *(uint8_t *)r; r++;
114 *pv = v; 114 *pv = v;
115 if (LJ_UNLIKELY(v >= 0xe0)) { 115 if (LJ_UNLIKELY(v >= 0xe0)) {
116 r = serialize_ru124_(r, e, pv); 116 r = serialize_ru124_(r, w, pv);
117 } 117 }
118 return r; 118 return r;
119 } 119 }
@@ -123,30 +123,30 @@ static LJ_AINLINE char *serialize_ru124(char *r, char *e, uint32_t *pv)
123/* -- Internal serializer ------------------------------------------------- */ 123/* -- Internal serializer ------------------------------------------------- */
124 124
125/* Put serialized object into buffer. */ 125/* Put serialized object into buffer. */
126static char *serialize_put(char *w, StrBuf *sbuf, cTValue *o) 126static char *serialize_put(char *w, SBufExt *sbx, cTValue *o)
127{ 127{
128 if (LJ_LIKELY(tvisstr(o))) { 128 if (LJ_LIKELY(tvisstr(o))) {
129 const GCstr *str = strV(o); 129 const GCstr *str = strV(o);
130 MSize len = str->len; 130 MSize len = str->len;
131 w = serialize_more(w, sbuf, 5+len); 131 w = serialize_more(w, sbx, 5+len);
132 w = serialize_wu124(w, SER_TAG_STR + len); 132 w = serialize_wu124(w, SER_TAG_STR + len);
133 w = lj_buf_wmem(w, strdata(str), len); 133 w = lj_buf_wmem(w, strdata(str), len);
134 } else if (tvisint(o)) { 134 } else if (tvisint(o)) {
135 uint32_t x = LJ_BE ? lj_bswap((uint32_t)intV(o)) : (uint32_t)intV(o); 135 uint32_t x = LJ_BE ? lj_bswap((uint32_t)intV(o)) : (uint32_t)intV(o);
136 w = serialize_more(w, sbuf, 1+4); 136 w = serialize_more(w, sbx, 1+4);
137 *w++ = SER_TAG_INT; memcpy(w, &x, 4); w += 4; 137 *w++ = SER_TAG_INT; memcpy(w, &x, 4); w += 4;
138 } else if (tvisnum(o)) { 138 } else if (tvisnum(o)) {
139 uint64_t x = LJ_BE ? lj_bswap64(o->u64) : o->u64; 139 uint64_t x = LJ_BE ? lj_bswap64(o->u64) : o->u64;
140 w = serialize_more(w, sbuf, 1+sizeof(lua_Number)); 140 w = serialize_more(w, sbx, 1+sizeof(lua_Number));
141 *w++ = SER_TAG_NUM; memcpy(w, &x, 8); w += 8; 141 *w++ = SER_TAG_NUM; memcpy(w, &x, 8); w += 8;
142 } else if (tvispri(o)) { 142 } else if (tvispri(o)) {
143 w = serialize_more(w, sbuf, 1); 143 w = serialize_more(w, sbx, 1);
144 *w++ = (char)(SER_TAG_NIL + ~itype(o)); 144 *w++ = (char)(SER_TAG_NIL + ~itype(o));
145 } else if (tvistab(o)) { 145 } else if (tvistab(o)) {
146 const GCtab *t = tabV(o); 146 const GCtab *t = tabV(o);
147 uint32_t narray = 0, nhash = 0, one = 2; 147 uint32_t narray = 0, nhash = 0, one = 2;
148 if (sbuf->depth <= 0) lj_err_caller(sbufL(sbuf->sb), LJ_ERR_BUFFER_DEPTH); 148 if (sbx->depth <= 0) lj_err_caller(sbufL(sbx), LJ_ERR_BUFFER_DEPTH);
149 sbuf->depth--; 149 sbx->depth--;
150 if (t->asize > 0) { /* Determine max. length of array part. */ 150 if (t->asize > 0) { /* Determine max. length of array part. */
151 ptrdiff_t i; 151 ptrdiff_t i;
152 TValue *array = tvref(t->array); 152 TValue *array = tvref(t->array);
@@ -163,32 +163,32 @@ static char *serialize_put(char *w, StrBuf *sbuf, cTValue *o)
163 nhash += !tvisnil(&node[i].val); 163 nhash += !tvisnil(&node[i].val);
164 } 164 }
165 /* Write number of array slots and hash slots. */ 165 /* Write number of array slots and hash slots. */
166 w = serialize_more(w, sbuf, 1+2*5); 166 w = serialize_more(w, sbx, 1+2*5);
167 *w++ = (char)(SER_TAG_TAB + (nhash ? 1 : 0) + (narray ? one : 0)); 167 *w++ = (char)(SER_TAG_TAB + (nhash ? 1 : 0) + (narray ? one : 0));
168 if (narray) w = serialize_wu124(w, narray); 168 if (narray) w = serialize_wu124(w, narray);
169 if (nhash) w = serialize_wu124(w, nhash); 169 if (nhash) w = serialize_wu124(w, nhash);
170 if (narray) { /* Write array entries. */ 170 if (narray) { /* Write array entries. */
171 cTValue *oa = tvref(t->array) + (one >> 2); 171 cTValue *oa = tvref(t->array) + (one >> 2);
172 cTValue *oe = tvref(t->array) + narray; 172 cTValue *oe = tvref(t->array) + narray;
173 while (oa < oe) w = serialize_put(w, sbuf, oa++); 173 while (oa < oe) w = serialize_put(w, sbx, oa++);
174 } 174 }
175 if (nhash) { /* Write hash entries. */ 175 if (nhash) { /* Write hash entries. */
176 const Node *node = noderef(t->node) + t->hmask; 176 const Node *node = noderef(t->node) + t->hmask;
177 for (;; node--) 177 for (;; node--)
178 if (!tvisnil(&node->val)) { 178 if (!tvisnil(&node->val)) {
179 w = serialize_put(w, sbuf, &node->key); 179 w = serialize_put(w, sbx, &node->key);
180 w = serialize_put(w, sbuf, &node->val); 180 w = serialize_put(w, sbx, &node->val);
181 if (--nhash == 0) break; 181 if (--nhash == 0) break;
182 } 182 }
183 } 183 }
184 sbuf->depth++; 184 sbx->depth++;
185#if LJ_HASFFI 185#if LJ_HASFFI
186 } else if (tviscdata(o)) { 186 } else if (tviscdata(o)) {
187 CTState *cts = ctype_cts(sbufL(sbuf->sb)); 187 CTState *cts = ctype_cts(sbufL(sbx));
188 CType *s = ctype_raw(cts, cdataV(o)->ctypeid); 188 CType *s = ctype_raw(cts, cdataV(o)->ctypeid);
189 uint8_t *sp = cdataptr(cdataV(o)); 189 uint8_t *sp = cdataptr(cdataV(o));
190 if (ctype_isinteger(s->info) && s->size == 8) { 190 if (ctype_isinteger(s->info) && s->size == 8) {
191 w = serialize_more(w, sbuf, 1+8); 191 w = serialize_more(w, sbx, 1+8);
192 *w++ = (s->info & CTF_UNSIGNED) ? SER_TAG_UINT64 : SER_TAG_INT64; 192 *w++ = (s->info & CTF_UNSIGNED) ? SER_TAG_UINT64 : SER_TAG_INT64;
193#if LJ_BE 193#if LJ_BE
194 { uint64_t u = lj_bswap64(*(uint64_t *)sp); memcpy(w, &u, 8); } 194 { uint64_t u = lj_bswap64(*(uint64_t *)sp); memcpy(w, &u, 8); }
@@ -197,7 +197,7 @@ static char *serialize_put(char *w, StrBuf *sbuf, cTValue *o)
197#endif 197#endif
198 w += 8; 198 w += 8;
199 } else if (ctype_iscomplex(s->info) && s->size == 16) { 199 } else if (ctype_iscomplex(s->info) && s->size == 16) {
200 w = serialize_more(w, sbuf, 1+16); 200 w = serialize_more(w, sbx, 1+16);
201 *w++ = SER_TAG_COMPLEX; 201 *w++ = SER_TAG_COMPLEX;
202#if LJ_BE 202#if LJ_BE
203 { /* Only swap the doubles. The re/im order stays the same. */ 203 { /* Only swap the doubles. The re/im order stays the same. */
@@ -213,8 +213,8 @@ static char *serialize_put(char *w, StrBuf *sbuf, cTValue *o)
213 } 213 }
214#endif 214#endif
215 } else if (tvislightud(o)) { 215 } else if (tvislightud(o)) {
216 uintptr_t ud = (uintptr_t)lightudV(G(sbufL(sbuf->sb)), o); 216 uintptr_t ud = (uintptr_t)lightudV(G(sbufL(sbx)), o);
217 w = serialize_more(w, sbuf, 1+sizeof(ud)); 217 w = serialize_more(w, sbx, 1+sizeof(ud));
218 if (ud == 0) { 218 if (ud == 0) {
219 *w++ = SER_TAG_NULL; 219 *w++ = SER_TAG_NULL;
220 } else if (LJ_32 || checku32(ud)) { 220 } else if (LJ_32 || checku32(ud)) {
@@ -237,28 +237,28 @@ static char *serialize_put(char *w, StrBuf *sbuf, cTValue *o)
237#if LJ_HASFFI 237#if LJ_HASFFI
238 badenc: 238 badenc:
239#endif 239#endif
240 lj_err_callerv(sbufL(sbuf->sb), LJ_ERR_BUFFER_BADENC, lj_typename(o)); 240 lj_err_callerv(sbufL(sbx), LJ_ERR_BUFFER_BADENC, lj_typename(o));
241 } 241 }
242 return w; 242 return w;
243} 243}
244 244
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, SBufExt *sbx, TValue *o)
247{ 247{
248 char *e = sbuf->sb->e; 248 char *w = sbx->w;
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, w, &tp); if (LJ_UNLIKELY(!r)) goto eob;
251 if (LJ_LIKELY(tp >= SER_TAG_STR)) { 251 if (LJ_LIKELY(tp >= SER_TAG_STR)) {
252 uint32_t len = tp - SER_TAG_STR; 252 uint32_t len = tp - SER_TAG_STR;
253 if (LJ_UNLIKELY(len > (uint32_t)(e - r))) goto eob; 253 if (LJ_UNLIKELY(len > (uint32_t)(w - r))) goto eob;
254 setstrV(sbufL(sbuf->sb), o, lj_str_new(sbufL(sbuf->sb), r, len)); 254 setstrV(sbufL(sbx), o, lj_str_new(sbufL(sbx), r, len));
255 r += len; 255 r += len;
256 } else if (tp == SER_TAG_INT) { 256 } else if (tp == SER_TAG_INT) {
257 if (LJ_UNLIKELY(r + 4 > e)) goto eob; 257 if (LJ_UNLIKELY(r + 4 > w)) goto eob;
258 setintV(o, (int32_t)(LJ_BE ? lj_bswap(lj_getu32(r)) : lj_getu32(r))); 258 setintV(o, (int32_t)(LJ_BE ? lj_bswap(lj_getu32(r)) : lj_getu32(r)));
259 r += 4; 259 r += 4;
260 } else if (tp == SER_TAG_NUM) { 260 } else if (tp == SER_TAG_NUM) {
261 if (LJ_UNLIKELY(r + 8 > e)) goto eob; 261 if (LJ_UNLIKELY(r + 8 > w)) goto eob;
262 memcpy(o, r, 8); r += 8; 262 memcpy(o, r, 8); r += 8;
263#if LJ_BE 263#if LJ_BE
264 o->u64 = lj_bswap64(o->u64); 264 o->u64 = lj_bswap64(o->u64);
@@ -270,34 +270,34 @@ static char *serialize_get(char *r, StrBuf *sbuf, TValue *o)
270 uint32_t narray = 0, nhash = 0; 270 uint32_t narray = 0, nhash = 0;
271 GCtab *t; 271 GCtab *t;
272 if (tp >= SER_TAG_TAB+2) { 272 if (tp >= SER_TAG_TAB+2) {
273 r = serialize_ru124(r, e, &narray); if (LJ_UNLIKELY(!r)) goto eob; 273 r = serialize_ru124(r, w, &narray); if (LJ_UNLIKELY(!r)) goto eob;
274 } 274 }
275 if ((tp & 1)) { 275 if ((tp & 1)) {
276 r = serialize_ru124(r, e, &nhash); if (LJ_UNLIKELY(!r)) goto eob; 276 r = serialize_ru124(r, w, &nhash); if (LJ_UNLIKELY(!r)) goto eob;
277 } 277 }
278 t = lj_tab_new(sbufL(sbuf->sb), narray, hsize2hbits(nhash)); 278 t = lj_tab_new(sbufL(sbx), narray, hsize2hbits(nhash));
279 settabV(sbufL(sbuf->sb), o, t); 279 settabV(sbufL(sbx), o, t);
280 if (narray) { 280 if (narray) {
281 TValue *oa = tvref(t->array) + (tp >= SER_TAG_TAB+4); 281 TValue *oa = tvref(t->array) + (tp >= SER_TAG_TAB+4);
282 TValue *oe = tvref(t->array) + narray; 282 TValue *oe = tvref(t->array) + narray;
283 while (oa < oe) r = serialize_get(r, sbuf, oa++); 283 while (oa < oe) r = serialize_get(r, sbx, oa++);
284 } 284 }
285 if (nhash) { 285 if (nhash) {
286 do { 286 do {
287 TValue k, *v; 287 TValue k, *v;
288 r = serialize_get(r, sbuf, &k); 288 r = serialize_get(r, sbx, &k);
289 v = lj_tab_set(sbufL(sbuf->sb), t, &k); 289 v = lj_tab_set(sbufL(sbx), t, &k);
290 if (LJ_UNLIKELY(!tvisnil(v))) 290 if (LJ_UNLIKELY(!tvisnil(v)))
291 lj_err_caller(sbufL(sbuf->sb), LJ_ERR_BUFFER_DUPKEY); 291 lj_err_caller(sbufL(sbx), LJ_ERR_BUFFER_DUPKEY);
292 r = serialize_get(r, sbuf, v); 292 r = serialize_get(r, sbx, v);
293 } while (--nhash); 293 } while (--nhash);
294 } 294 }
295#if LJ_HASFFI 295#if LJ_HASFFI
296 } else if (tp >= SER_TAG_INT64 && tp <= SER_TAG_COMPLEX) { 296 } else if (tp >= SER_TAG_INT64 && tp <= SER_TAG_COMPLEX) {
297 uint32_t sz = tp == SER_TAG_COMPLEX ? 16 : 8; 297 uint32_t sz = tp == SER_TAG_COMPLEX ? 16 : 8;
298 GCcdata *cd; 298 GCcdata *cd;
299 if (LJ_UNLIKELY(r + sz > e)) goto eob; 299 if (LJ_UNLIKELY(r + sz > w)) goto eob;
300 cd = lj_cdata_new_(sbufL(sbuf->sb), 300 cd = lj_cdata_new_(sbufL(sbx),
301 tp == SER_TAG_INT64 ? CTID_INT64 : 301 tp == SER_TAG_INT64 ? CTID_INT64 :
302 tp == SER_TAG_UINT64 ? CTID_UINT64 : CTID_COMPLEX_DOUBLE, 302 tp == SER_TAG_UINT64 ? CTID_UINT64 : CTID_COMPLEX_DOUBLE,
303 sz); 303 sz);
@@ -307,50 +307,50 @@ static char *serialize_get(char *r, StrBuf *sbuf, TValue *o)
307 if (sz == 16) 307 if (sz == 16)
308 ((uint64_t *)cdataptr(cd))[1] = lj_bswap64(((uint64_t *)cdataptr(cd))[1]); 308 ((uint64_t *)cdataptr(cd))[1] = lj_bswap64(((uint64_t *)cdataptr(cd))[1]);
309#endif 309#endif
310 setcdataV(sbufL(sbuf->sb), o, cd); 310 setcdataV(sbufL(sbx), o, cd);
311#endif 311#endif
312 } else if (tp <= (LJ_64 ? SER_TAG_LIGHTUD64 : SER_TAG_LIGHTUD32)) { 312 } else if (tp <= (LJ_64 ? SER_TAG_LIGHTUD64 : SER_TAG_LIGHTUD32)) {
313 uintptr_t ud = 0; 313 uintptr_t ud = 0;
314 if (tp == SER_TAG_LIGHTUD32) { 314 if (tp == SER_TAG_LIGHTUD32) {
315 if (LJ_UNLIKELY(r + 4 > e)) goto eob; 315 if (LJ_UNLIKELY(r + 4 > w)) goto eob;
316 ud = (uintptr_t)(LJ_BE ? lj_bswap(lj_getu32(r)) : lj_getu32(r)); 316 ud = (uintptr_t)(LJ_BE ? lj_bswap(lj_getu32(r)) : lj_getu32(r));
317 r += 4; 317 r += 4;
318 } 318 }
319#if LJ_64 319#if LJ_64
320 else if (tp == SER_TAG_LIGHTUD64) { 320 else if (tp == SER_TAG_LIGHTUD64) {
321 if (LJ_UNLIKELY(r + 8 > e)) goto eob; 321 if (LJ_UNLIKELY(r + 8 > w)) goto eob;
322 memcpy(&ud, r, 8); r += 8; 322 memcpy(&ud, r, 8); r += 8;
323#if LJ_BE 323#if LJ_BE
324 ud = lj_bswap64(ud); 324 ud = lj_bswap64(ud);
325#endif 325#endif
326 } 326 }
327 setrawlightudV(o, lj_lightud_intern(sbufL(sbuf->sb), (void *)ud)); 327 setrawlightudV(o, lj_lightud_intern(sbufL(sbx), (void *)ud));
328#else 328#else
329 setrawlightudV(o, (void *)ud); 329 setrawlightudV(o, (void *)ud);
330#endif 330#endif
331 } else { 331 } else {
332 lj_err_callerv(sbufL(sbuf->sb), LJ_ERR_BUFFER_BADDEC, tp); 332 lj_err_callerv(sbufL(sbx), LJ_ERR_BUFFER_BADDEC, tp);
333 } 333 }
334 return r; 334 return r;
335eob: 335eob:
336 lj_err_caller(sbufL(sbuf->sb), LJ_ERR_BUFFER_EOB); 336 lj_err_caller(sbufL(sbx), LJ_ERR_BUFFER_EOB);
337 return NULL; 337 return NULL;
338} 338}
339 339
340StrBuf * LJ_FASTCALL lj_serialize_put(StrBuf *sbuf, cTValue *o) 340SBufExt * LJ_FASTCALL lj_serialize_put(SBufExt *sbx, cTValue *o)
341{ 341{
342 sbuf->depth = LJ_SERIALIZE_DEPTH; 342 sbx->depth = LJ_SERIALIZE_DEPTH;
343 sbuf->sb->w = serialize_put(sbuf->sb->w, sbuf, o); 343 sbx->w = serialize_put(sbx->w, sbx, o);
344 return sbuf; 344 return sbx;
345} 345}
346 346
347StrBuf * LJ_FASTCALL lj_serialize_get(StrBuf *sbuf, TValue *o) 347SBufExt * LJ_FASTCALL lj_serialize_get(SBufExt *sbx, TValue *o)
348{ 348{
349 char *r = serialize_get(sbuf->r, sbuf, o); 349 char *r = serialize_get(sbx->r, sbx, o);
350 if (r != sbuf->sb->w) 350 if (r != sbx->w)
351 lj_err_caller(sbufL(sbuf->sb), LJ_ERR_BUFFER_LEFTOV); 351 lj_err_caller(sbufL(sbx), LJ_ERR_BUFFER_LEFTOV);
352 sbuf->r = r; 352 sbx->r = r;
353 return sbuf; 353 return sbx;
354} 354}
355 355
356#endif 356#endif
diff --git a/src/lj_serialize.h b/src/lj_serialize.h
index 95d62f4e..f5617790 100644
--- a/src/lj_serialize.h
+++ b/src/lj_serialize.h
@@ -13,8 +13,8 @@
13 13
14#define LJ_SERIALIZE_DEPTH 100 /* Default depth. */ 14#define LJ_SERIALIZE_DEPTH 100 /* Default depth. */
15 15
16LJ_FUNC StrBuf * LJ_FASTCALL lj_serialize_put(StrBuf *sb, cTValue *o); 16LJ_FUNC SBufExt * LJ_FASTCALL lj_serialize_put(SBufExt *sbx, cTValue *o);
17LJ_FUNC StrBuf * LJ_FASTCALL lj_serialize_get(StrBuf *sb, TValue *o); 17LJ_FUNC SBufExt * LJ_FASTCALL lj_serialize_get(SBufExt *sbx, TValue *o);
18 18
19#endif 19#endif
20 20