aboutsummaryrefslogtreecommitdiff
path: root/src/lj_buf.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_buf.h')
-rw-r--r--src/lj_buf.h100
1 files changed, 87 insertions, 13 deletions
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