diff options
Diffstat (limited to 'src/lj_bcwrite.c')
-rw-r--r-- | src/lj_bcwrite.c | 226 |
1 files changed, 95 insertions, 131 deletions
diff --git a/src/lj_bcwrite.c b/src/lj_bcwrite.c index 4805d515..b3289a13 100644 --- a/src/lj_bcwrite.c +++ b/src/lj_bcwrite.c | |||
@@ -8,6 +8,7 @@ | |||
8 | 8 | ||
9 | #include "lj_obj.h" | 9 | #include "lj_obj.h" |
10 | #include "lj_gc.h" | 10 | #include "lj_gc.h" |
11 | #include "lj_buf.h" | ||
11 | #include "lj_str.h" | 12 | #include "lj_str.h" |
12 | #include "lj_bc.h" | 13 | #include "lj_bc.h" |
13 | #if LJ_HASFFI | 14 | #if LJ_HASFFI |
@@ -23,7 +24,6 @@ | |||
23 | /* Context for bytecode writer. */ | 24 | /* Context for bytecode writer. */ |
24 | typedef struct BCWriteCtx { | 25 | typedef struct BCWriteCtx { |
25 | SBuf sb; /* Output buffer. */ | 26 | SBuf sb; /* Output buffer. */ |
26 | lua_State *L; /* Lua state. */ | ||
27 | GCproto *pt; /* Root prototype. */ | 27 | GCproto *pt; /* Root prototype. */ |
28 | lua_Writer wfunc; /* Writer callback. */ | 28 | lua_Writer wfunc; /* Writer callback. */ |
29 | void *wdata; /* Writer callback data. */ | 29 | void *wdata; /* Writer callback data. */ |
@@ -31,85 +31,44 @@ typedef struct BCWriteCtx { | |||
31 | int status; /* Status from writer callback. */ | 31 | int status; /* Status from writer callback. */ |
32 | } BCWriteCtx; | 32 | } BCWriteCtx; |
33 | 33 | ||
34 | /* -- Output buffer handling ---------------------------------------------- */ | ||
35 | |||
36 | /* Resize buffer if needed. */ | ||
37 | static LJ_NOINLINE void bcwrite_resize(BCWriteCtx *ctx, MSize len) | ||
38 | { | ||
39 | MSize sz = ctx->sb.sz * 2; | ||
40 | while (ctx->sb.n + len > sz) sz = sz * 2; | ||
41 | lj_str_resizebuf(ctx->L, &ctx->sb, sz); | ||
42 | } | ||
43 | |||
44 | /* Need a certain amount of buffer space. */ | ||
45 | static LJ_AINLINE void bcwrite_need(BCWriteCtx *ctx, MSize len) | ||
46 | { | ||
47 | if (LJ_UNLIKELY(ctx->sb.n + len > ctx->sb.sz)) | ||
48 | bcwrite_resize(ctx, len); | ||
49 | } | ||
50 | |||
51 | /* Add memory block to buffer. */ | ||
52 | static void bcwrite_block(BCWriteCtx *ctx, const void *p, MSize len) | ||
53 | { | ||
54 | uint8_t *q = (uint8_t *)(ctx->sb.buf + ctx->sb.n); | ||
55 | MSize i; | ||
56 | ctx->sb.n += len; | ||
57 | for (i = 0; i < len; i++) q[i] = ((uint8_t *)p)[i]; | ||
58 | } | ||
59 | |||
60 | /* Add byte to buffer. */ | ||
61 | static LJ_AINLINE void bcwrite_byte(BCWriteCtx *ctx, uint8_t b) | ||
62 | { | ||
63 | ctx->sb.buf[ctx->sb.n++] = b; | ||
64 | } | ||
65 | |||
66 | /* Add ULEB128 value to buffer. */ | ||
67 | static void bcwrite_uleb128(BCWriteCtx *ctx, uint32_t v) | ||
68 | { | ||
69 | MSize n = ctx->sb.n; | ||
70 | uint8_t *p = (uint8_t *)ctx->sb.buf; | ||
71 | for (; v >= 0x80; v >>= 7) | ||
72 | p[n++] = (uint8_t)((v & 0x7f) | 0x80); | ||
73 | p[n++] = (uint8_t)v; | ||
74 | ctx->sb.n = n; | ||
75 | } | ||
76 | |||
77 | /* -- Bytecode writer ----------------------------------------------------- */ | 34 | /* -- Bytecode writer ----------------------------------------------------- */ |
78 | 35 | ||
79 | /* Write a single constant key/value of a template table. */ | 36 | /* Write a single constant key/value of a template table. */ |
80 | static void bcwrite_ktabk(BCWriteCtx *ctx, cTValue *o, int narrow) | 37 | static void bcwrite_ktabk(BCWriteCtx *ctx, cTValue *o, int narrow) |
81 | { | 38 | { |
82 | bcwrite_need(ctx, 1+10); | 39 | char *p = lj_buf_more(&ctx->sb, 1+10); |
83 | if (tvisstr(o)) { | 40 | if (tvisstr(o)) { |
84 | const GCstr *str = strV(o); | 41 | const GCstr *str = strV(o); |
85 | MSize len = str->len; | 42 | MSize len = str->len; |
86 | bcwrite_need(ctx, 5+len); | 43 | p = lj_buf_more(&ctx->sb, 5+len); |
87 | bcwrite_uleb128(ctx, BCDUMP_KTAB_STR+len); | 44 | p = lj_buf_wuleb128(p, BCDUMP_KTAB_STR+len); |
88 | bcwrite_block(ctx, strdata(str), len); | 45 | p = lj_buf_wmem(p, strdata(str), len); |
89 | } else if (tvisint(o)) { | 46 | } else if (tvisint(o)) { |
90 | bcwrite_byte(ctx, BCDUMP_KTAB_INT); | 47 | *p++ = BCDUMP_KTAB_INT; |
91 | bcwrite_uleb128(ctx, intV(o)); | 48 | p = lj_buf_wuleb128(p, intV(o)); |
92 | } else if (tvisnum(o)) { | 49 | } else if (tvisnum(o)) { |
93 | if (!LJ_DUALNUM && narrow) { /* Narrow number constants to integers. */ | 50 | if (!LJ_DUALNUM && narrow) { /* Narrow number constants to integers. */ |
94 | lua_Number num = numV(o); | 51 | lua_Number num = numV(o); |
95 | int32_t k = lj_num2int(num); | 52 | int32_t k = lj_num2int(num); |
96 | if (num == (lua_Number)k) { /* -0 is never a constant. */ | 53 | if (num == (lua_Number)k) { /* -0 is never a constant. */ |
97 | bcwrite_byte(ctx, BCDUMP_KTAB_INT); | 54 | *p++ = BCDUMP_KTAB_INT; |
98 | bcwrite_uleb128(ctx, k); | 55 | p = lj_buf_wuleb128(p, k); |
56 | setsbufP(&ctx->sb, p); | ||
99 | return; | 57 | return; |
100 | } | 58 | } |
101 | } | 59 | } |
102 | bcwrite_byte(ctx, BCDUMP_KTAB_NUM); | 60 | *p++ = BCDUMP_KTAB_NUM; |
103 | bcwrite_uleb128(ctx, o->u32.lo); | 61 | p = lj_buf_wuleb128(p, o->u32.lo); |
104 | bcwrite_uleb128(ctx, o->u32.hi); | 62 | p = lj_buf_wuleb128(p, o->u32.hi); |
105 | } else { | 63 | } else { |
106 | lua_assert(tvispri(o)); | 64 | lua_assert(tvispri(o)); |
107 | bcwrite_byte(ctx, BCDUMP_KTAB_NIL+~itype(o)); | 65 | *p++ = BCDUMP_KTAB_NIL+~itype(o); |
108 | } | 66 | } |
67 | setsbufP(&ctx->sb, p); | ||
109 | } | 68 | } |
110 | 69 | ||
111 | /* Write a template table. */ | 70 | /* Write a template table. */ |
112 | static void bcwrite_ktab(BCWriteCtx *ctx, const GCtab *t) | 71 | static void bcwrite_ktab(BCWriteCtx *ctx, char *p, const GCtab *t) |
113 | { | 72 | { |
114 | MSize narray = 0, nhash = 0; | 73 | MSize narray = 0, nhash = 0; |
115 | if (t->asize > 0) { /* Determine max. length of array part. */ | 74 | if (t->asize > 0) { /* Determine max. length of array part. */ |
@@ -127,8 +86,9 @@ static void bcwrite_ktab(BCWriteCtx *ctx, const GCtab *t) | |||
127 | nhash += !tvisnil(&node[i].val); | 86 | nhash += !tvisnil(&node[i].val); |
128 | } | 87 | } |
129 | /* Write number of array slots and hash slots. */ | 88 | /* Write number of array slots and hash slots. */ |
130 | bcwrite_uleb128(ctx, narray); | 89 | p = lj_buf_wuleb128(p, narray); |
131 | bcwrite_uleb128(ctx, nhash); | 90 | p = lj_buf_wuleb128(p, nhash); |
91 | setsbufP(&ctx->sb, p); | ||
132 | if (narray) { /* Write array entries (may contain nil). */ | 92 | if (narray) { /* Write array entries (may contain nil). */ |
133 | MSize i; | 93 | MSize i; |
134 | TValue *o = tvref(t->array); | 94 | TValue *o = tvref(t->array); |
@@ -155,6 +115,7 @@ static void bcwrite_kgc(BCWriteCtx *ctx, GCproto *pt) | |||
155 | for (i = 0; i < sizekgc; i++, kr++) { | 115 | for (i = 0; i < sizekgc; i++, kr++) { |
156 | GCobj *o = gcref(*kr); | 116 | GCobj *o = gcref(*kr); |
157 | MSize tp, need = 1; | 117 | MSize tp, need = 1; |
118 | char *p; | ||
158 | /* Determine constant type and needed size. */ | 119 | /* Determine constant type and needed size. */ |
159 | if (o->gch.gct == ~LJ_TSTR) { | 120 | if (o->gch.gct == ~LJ_TSTR) { |
160 | tp = BCDUMP_KGC_STR + gco2str(o)->len; | 121 | tp = BCDUMP_KGC_STR + gco2str(o)->len; |
@@ -181,24 +142,26 @@ static void bcwrite_kgc(BCWriteCtx *ctx, GCproto *pt) | |||
181 | need = 1+2*5; | 142 | need = 1+2*5; |
182 | } | 143 | } |
183 | /* Write constant type. */ | 144 | /* Write constant type. */ |
184 | bcwrite_need(ctx, need); | 145 | p = lj_buf_more(&ctx->sb, need); |
185 | bcwrite_uleb128(ctx, tp); | 146 | p = lj_buf_wuleb128(p, tp); |
186 | /* Write constant data (if any). */ | 147 | /* Write constant data (if any). */ |
187 | if (tp >= BCDUMP_KGC_STR) { | 148 | if (tp >= BCDUMP_KGC_STR) { |
188 | bcwrite_block(ctx, strdata(gco2str(o)), gco2str(o)->len); | 149 | p = lj_buf_wmem(p, strdata(gco2str(o)), gco2str(o)->len); |
189 | } else if (tp == BCDUMP_KGC_TAB) { | 150 | } else if (tp == BCDUMP_KGC_TAB) { |
190 | bcwrite_ktab(ctx, gco2tab(o)); | 151 | bcwrite_ktab(ctx, p, gco2tab(o)); |
152 | continue; | ||
191 | #if LJ_HASFFI | 153 | #if LJ_HASFFI |
192 | } else if (tp != BCDUMP_KGC_CHILD) { | 154 | } else if (tp != BCDUMP_KGC_CHILD) { |
193 | cTValue *p = (TValue *)cdataptr(gco2cd(o)); | 155 | cTValue *q = (TValue *)cdataptr(gco2cd(o)); |
194 | bcwrite_uleb128(ctx, p[0].u32.lo); | 156 | p = lj_buf_wuleb128(p, q[0].u32.lo); |
195 | bcwrite_uleb128(ctx, p[0].u32.hi); | 157 | p = lj_buf_wuleb128(p, q[0].u32.hi); |
196 | if (tp == BCDUMP_KGC_COMPLEX) { | 158 | if (tp == BCDUMP_KGC_COMPLEX) { |
197 | bcwrite_uleb128(ctx, p[1].u32.lo); | 159 | p = lj_buf_wuleb128(p, q[1].u32.lo); |
198 | bcwrite_uleb128(ctx, p[1].u32.hi); | 160 | p = lj_buf_wuleb128(p, q[1].u32.hi); |
199 | } | 161 | } |
200 | #endif | 162 | #endif |
201 | } | 163 | } |
164 | setsbufP(&ctx->sb, p); | ||
202 | } | 165 | } |
203 | } | 166 | } |
204 | 167 | ||
@@ -207,7 +170,7 @@ static void bcwrite_knum(BCWriteCtx *ctx, GCproto *pt) | |||
207 | { | 170 | { |
208 | MSize i, sizekn = pt->sizekn; | 171 | MSize i, sizekn = pt->sizekn; |
209 | cTValue *o = mref(pt->k, TValue); | 172 | cTValue *o = mref(pt->k, TValue); |
210 | bcwrite_need(ctx, 10*sizekn); | 173 | char *p = lj_buf_more(&ctx->sb, 10*sizekn); |
211 | for (i = 0; i < sizekn; i++, o++) { | 174 | for (i = 0; i < sizekn; i++, o++) { |
212 | int32_t k; | 175 | int32_t k; |
213 | if (tvisint(o)) { | 176 | if (tvisint(o)) { |
@@ -220,58 +183,58 @@ static void bcwrite_knum(BCWriteCtx *ctx, GCproto *pt) | |||
220 | k = lj_num2int(num); | 183 | k = lj_num2int(num); |
221 | if (num == (lua_Number)k) { /* -0 is never a constant. */ | 184 | if (num == (lua_Number)k) { /* -0 is never a constant. */ |
222 | save_int: | 185 | save_int: |
223 | bcwrite_uleb128(ctx, 2*(uint32_t)k | ((uint32_t)k & 0x80000000u)); | 186 | p = lj_buf_wuleb128(p, 2*(uint32_t)k | ((uint32_t)k & 0x80000000u)); |
224 | if (k < 0) { | 187 | if (k < 0) |
225 | char *p = &ctx->sb.buf[ctx->sb.n-1]; | 188 | p[-1] = (p[-1] & 7) | ((k>>27) & 0x18); |
226 | *p = (*p & 7) | ((k>>27) & 0x18); | ||
227 | } | ||
228 | continue; | 189 | continue; |
229 | } | 190 | } |
230 | } | 191 | } |
231 | bcwrite_uleb128(ctx, 1+(2*o->u32.lo | (o->u32.lo & 0x80000000u))); | 192 | p = lj_buf_wuleb128(p, 1+(2*o->u32.lo | (o->u32.lo & 0x80000000u))); |
232 | if (o->u32.lo >= 0x80000000u) { | 193 | if (o->u32.lo >= 0x80000000u) |
233 | char *p = &ctx->sb.buf[ctx->sb.n-1]; | 194 | p[-1] = (p[-1] & 7) | ((o->u32.lo>>27) & 0x18); |
234 | *p = (*p & 7) | ((o->u32.lo>>27) & 0x18); | 195 | p = lj_buf_wuleb128(p, o->u32.hi); |
235 | } | ||
236 | bcwrite_uleb128(ctx, o->u32.hi); | ||
237 | } | 196 | } |
238 | } | 197 | } |
198 | setsbufP(&ctx->sb, p); | ||
239 | } | 199 | } |
240 | 200 | ||
241 | /* Write bytecode instructions. */ | 201 | /* Write bytecode instructions. */ |
242 | static void bcwrite_bytecode(BCWriteCtx *ctx, GCproto *pt) | 202 | static char *bcwrite_bytecode(BCWriteCtx *ctx, char *p, GCproto *pt) |
243 | { | 203 | { |
244 | MSize nbc = pt->sizebc-1; /* Omit the [JI]FUNC* header. */ | 204 | MSize nbc = pt->sizebc-1; /* Omit the [JI]FUNC* header. */ |
245 | #if LJ_HASJIT | 205 | #if LJ_HASJIT |
246 | uint8_t *p = (uint8_t *)&ctx->sb.buf[ctx->sb.n]; | 206 | uint8_t *q = (uint8_t *)p; |
247 | #endif | 207 | #endif |
248 | bcwrite_block(ctx, proto_bc(pt)+1, nbc*(MSize)sizeof(BCIns)); | 208 | p = lj_buf_wmem(p, proto_bc(pt)+1, nbc*(MSize)sizeof(BCIns)); |
209 | UNUSED(ctx); | ||
249 | #if LJ_HASJIT | 210 | #if LJ_HASJIT |
250 | /* Unpatch modified bytecode containing ILOOP/JLOOP etc. */ | 211 | /* Unpatch modified bytecode containing ILOOP/JLOOP etc. */ |
251 | if ((pt->flags & PROTO_ILOOP) || pt->trace) { | 212 | if ((pt->flags & PROTO_ILOOP) || pt->trace) { |
252 | jit_State *J = L2J(ctx->L); | 213 | jit_State *J = L2J(sbufL(&ctx->sb)); |
253 | MSize i; | 214 | MSize i; |
254 | for (i = 0; i < nbc; i++, p += sizeof(BCIns)) { | 215 | for (i = 0; i < nbc; i++, q += sizeof(BCIns)) { |
255 | BCOp op = (BCOp)p[LJ_ENDIAN_SELECT(0, 3)]; | 216 | BCOp op = (BCOp)q[LJ_ENDIAN_SELECT(0, 3)]; |
256 | if (op == BC_IFORL || op == BC_IITERL || op == BC_ILOOP || | 217 | if (op == BC_IFORL || op == BC_IITERL || op == BC_ILOOP || |
257 | op == BC_JFORI) { | 218 | op == BC_JFORI) { |
258 | p[LJ_ENDIAN_SELECT(0, 3)] = (uint8_t)(op-BC_IFORL+BC_FORL); | 219 | q[LJ_ENDIAN_SELECT(0, 3)] = (uint8_t)(op-BC_IFORL+BC_FORL); |
259 | } else if (op == BC_JFORL || op == BC_JITERL || op == BC_JLOOP) { | 220 | } else if (op == BC_JFORL || op == BC_JITERL || op == BC_JLOOP) { |
260 | BCReg rd = p[LJ_ENDIAN_SELECT(2, 1)] + (p[LJ_ENDIAN_SELECT(3, 0)] << 8); | 221 | BCReg rd = q[LJ_ENDIAN_SELECT(2, 1)] + (q[LJ_ENDIAN_SELECT(3, 0)] << 8); |
261 | BCIns ins = traceref(J, rd)->startins; | 222 | BCIns ins = traceref(J, rd)->startins; |
262 | p[LJ_ENDIAN_SELECT(0, 3)] = (uint8_t)(op-BC_JFORL+BC_FORL); | 223 | q[LJ_ENDIAN_SELECT(0, 3)] = (uint8_t)(op-BC_JFORL+BC_FORL); |
263 | p[LJ_ENDIAN_SELECT(2, 1)] = bc_c(ins); | 224 | q[LJ_ENDIAN_SELECT(2, 1)] = bc_c(ins); |
264 | p[LJ_ENDIAN_SELECT(3, 0)] = bc_b(ins); | 225 | q[LJ_ENDIAN_SELECT(3, 0)] = bc_b(ins); |
265 | } | 226 | } |
266 | } | 227 | } |
267 | } | 228 | } |
268 | #endif | 229 | #endif |
230 | return p; | ||
269 | } | 231 | } |
270 | 232 | ||
271 | /* Write prototype. */ | 233 | /* Write prototype. */ |
272 | static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt) | 234 | static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt) |
273 | { | 235 | { |
274 | MSize sizedbg = 0; | 236 | MSize sizedbg = 0; |
237 | char *p; | ||
275 | 238 | ||
276 | /* Recursively write children of prototype. */ | 239 | /* Recursively write children of prototype. */ |
277 | if ((pt->flags & PROTO_CHILD)) { | 240 | if ((pt->flags & PROTO_CHILD)) { |
@@ -285,31 +248,32 @@ static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt) | |||
285 | } | 248 | } |
286 | 249 | ||
287 | /* Start writing the prototype info to a buffer. */ | 250 | /* Start writing the prototype info to a buffer. */ |
288 | lj_str_resetbuf(&ctx->sb); | 251 | p = lj_buf_need(&ctx->sb, |
289 | ctx->sb.n = 5; /* Leave room for final size. */ | 252 | 5+4+6*5+(pt->sizebc-1)*(MSize)sizeof(BCIns)+pt->sizeuv*2); |
290 | bcwrite_need(ctx, 4+6*5+(pt->sizebc-1)*(MSize)sizeof(BCIns)+pt->sizeuv*2); | 253 | p += 5; /* Leave room for final size. */ |
291 | 254 | ||
292 | /* Write prototype header. */ | 255 | /* Write prototype header. */ |
293 | bcwrite_byte(ctx, (pt->flags & (PROTO_CHILD|PROTO_VARARG|PROTO_FFI))); | 256 | *p++ = (pt->flags & (PROTO_CHILD|PROTO_VARARG|PROTO_FFI)); |
294 | bcwrite_byte(ctx, pt->numparams); | 257 | *p++ = pt->numparams; |
295 | bcwrite_byte(ctx, pt->framesize); | 258 | *p++ = pt->framesize; |
296 | bcwrite_byte(ctx, pt->sizeuv); | 259 | *p++ = pt->sizeuv; |
297 | bcwrite_uleb128(ctx, pt->sizekgc); | 260 | p = lj_buf_wuleb128(p, pt->sizekgc); |
298 | bcwrite_uleb128(ctx, pt->sizekn); | 261 | p = lj_buf_wuleb128(p, pt->sizekn); |
299 | bcwrite_uleb128(ctx, pt->sizebc-1); | 262 | p = lj_buf_wuleb128(p, pt->sizebc-1); |
300 | if (!ctx->strip) { | 263 | if (!ctx->strip) { |
301 | if (proto_lineinfo(pt)) | 264 | if (proto_lineinfo(pt)) |
302 | sizedbg = pt->sizept - (MSize)((char *)proto_lineinfo(pt) - (char *)pt); | 265 | sizedbg = pt->sizept - (MSize)((char *)proto_lineinfo(pt) - (char *)pt); |
303 | bcwrite_uleb128(ctx, sizedbg); | 266 | p = lj_buf_wuleb128(p, sizedbg); |
304 | if (sizedbg) { | 267 | if (sizedbg) { |
305 | bcwrite_uleb128(ctx, pt->firstline); | 268 | p = lj_buf_wuleb128(p, pt->firstline); |
306 | bcwrite_uleb128(ctx, pt->numline); | 269 | p = lj_buf_wuleb128(p, pt->numline); |
307 | } | 270 | } |
308 | } | 271 | } |
309 | 272 | ||
310 | /* Write bytecode instructions and upvalue refs. */ | 273 | /* Write bytecode instructions and upvalue refs. */ |
311 | bcwrite_bytecode(ctx, pt); | 274 | p = bcwrite_bytecode(ctx, p, pt); |
312 | bcwrite_block(ctx, proto_uv(pt), pt->sizeuv*2); | 275 | p = lj_buf_wmem(p, proto_uv(pt), pt->sizeuv*2); |
276 | setsbufP(&ctx->sb, p); | ||
313 | 277 | ||
314 | /* Write constants. */ | 278 | /* Write constants. */ |
315 | bcwrite_kgc(ctx, pt); | 279 | bcwrite_kgc(ctx, pt); |
@@ -317,18 +281,19 @@ static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt) | |||
317 | 281 | ||
318 | /* Write debug info, if not stripped. */ | 282 | /* Write debug info, if not stripped. */ |
319 | if (sizedbg) { | 283 | if (sizedbg) { |
320 | bcwrite_need(ctx, sizedbg); | 284 | p = lj_buf_more(&ctx->sb, sizedbg); |
321 | bcwrite_block(ctx, proto_lineinfo(pt), sizedbg); | 285 | p = lj_buf_wmem(p, proto_lineinfo(pt), sizedbg); |
286 | setsbufP(&ctx->sb, p); | ||
322 | } | 287 | } |
323 | 288 | ||
324 | /* Pass buffer to writer function. */ | 289 | /* Pass buffer to writer function. */ |
325 | if (ctx->status == 0) { | 290 | if (ctx->status == 0) { |
326 | MSize n = ctx->sb.n - 5; | 291 | MSize n = sbuflen(&ctx->sb) - 5; |
327 | MSize nn = (lj_fls(n)+8)*9 >> 6; | 292 | MSize nn = (lj_fls(n)+8)*9 >> 6; |
328 | ctx->sb.n = 5 - nn; | 293 | char *q = sbufB(&ctx->sb) + (5 - nn); |
329 | bcwrite_uleb128(ctx, n); /* Fill in final size. */ | 294 | p = lj_buf_wuleb128(q, n); /* Fill in final size. */ |
330 | lua_assert(ctx->sb.n == 5); | 295 | lua_assert(p == sbufB(&ctx->sb) + 5); |
331 | ctx->status = ctx->wfunc(ctx->L, ctx->sb.buf+5-nn, nn+n, ctx->wdata); | 296 | ctx->status = ctx->wfunc(sbufL(&ctx->sb), q, nn+n, ctx->wdata); |
332 | } | 297 | } |
333 | } | 298 | } |
334 | 299 | ||
@@ -338,20 +303,20 @@ static void bcwrite_header(BCWriteCtx *ctx) | |||
338 | GCstr *chunkname = proto_chunkname(ctx->pt); | 303 | GCstr *chunkname = proto_chunkname(ctx->pt); |
339 | const char *name = strdata(chunkname); | 304 | const char *name = strdata(chunkname); |
340 | MSize len = chunkname->len; | 305 | MSize len = chunkname->len; |
341 | lj_str_resetbuf(&ctx->sb); | 306 | char *p = lj_buf_need(&ctx->sb, 5+5+len); |
342 | bcwrite_need(ctx, 5+5+len); | 307 | *p++ = BCDUMP_HEAD1; |
343 | bcwrite_byte(ctx, BCDUMP_HEAD1); | 308 | *p++ = BCDUMP_HEAD2; |
344 | bcwrite_byte(ctx, BCDUMP_HEAD2); | 309 | *p++ = BCDUMP_HEAD3; |
345 | bcwrite_byte(ctx, BCDUMP_HEAD3); | 310 | *p++ = BCDUMP_VERSION; |
346 | bcwrite_byte(ctx, BCDUMP_VERSION); | 311 | *p++ = (ctx->strip ? BCDUMP_F_STRIP : 0) + |
347 | bcwrite_byte(ctx, (ctx->strip ? BCDUMP_F_STRIP : 0) + | 312 | (LJ_BE ? BCDUMP_F_BE : 0) + |
348 | (LJ_BE ? BCDUMP_F_BE : 0) + | 313 | ((ctx->pt->flags & PROTO_FFI) ? BCDUMP_F_FFI : 0); |
349 | ((ctx->pt->flags & PROTO_FFI) ? BCDUMP_F_FFI : 0)); | ||
350 | if (!ctx->strip) { | 314 | if (!ctx->strip) { |
351 | bcwrite_uleb128(ctx, len); | 315 | p = lj_buf_wuleb128(p, len); |
352 | bcwrite_block(ctx, name, len); | 316 | p = lj_buf_wmem(p, name, len); |
353 | } | 317 | } |
354 | ctx->status = ctx->wfunc(ctx->L, ctx->sb.buf, ctx->sb.n, ctx->wdata); | 318 | ctx->status = ctx->wfunc(sbufL(&ctx->sb), sbufB(&ctx->sb), |
319 | (MSize)(p - sbufB(&ctx->sb)), ctx->wdata); | ||
355 | } | 320 | } |
356 | 321 | ||
357 | /* Write footer of bytecode dump. */ | 322 | /* Write footer of bytecode dump. */ |
@@ -359,7 +324,7 @@ static void bcwrite_footer(BCWriteCtx *ctx) | |||
359 | { | 324 | { |
360 | if (ctx->status == 0) { | 325 | if (ctx->status == 0) { |
361 | uint8_t zero = 0; | 326 | uint8_t zero = 0; |
362 | ctx->status = ctx->wfunc(ctx->L, &zero, 1, ctx->wdata); | 327 | ctx->status = ctx->wfunc(sbufL(&ctx->sb), &zero, 1, ctx->wdata); |
363 | } | 328 | } |
364 | } | 329 | } |
365 | 330 | ||
@@ -367,8 +332,8 @@ static void bcwrite_footer(BCWriteCtx *ctx) | |||
367 | static TValue *cpwriter(lua_State *L, lua_CFunction dummy, void *ud) | 332 | static TValue *cpwriter(lua_State *L, lua_CFunction dummy, void *ud) |
368 | { | 333 | { |
369 | BCWriteCtx *ctx = (BCWriteCtx *)ud; | 334 | BCWriteCtx *ctx = (BCWriteCtx *)ud; |
370 | UNUSED(dummy); | 335 | UNUSED(L); UNUSED(dummy); |
371 | lj_str_resizebuf(L, &ctx->sb, 1024); /* Avoids resize for most prototypes. */ | 336 | lj_buf_need(&ctx->sb, 1024); /* Avoids resize for most prototypes. */ |
372 | bcwrite_header(ctx); | 337 | bcwrite_header(ctx); |
373 | bcwrite_proto(ctx, ctx->pt); | 338 | bcwrite_proto(ctx, ctx->pt); |
374 | bcwrite_footer(ctx); | 339 | bcwrite_footer(ctx); |
@@ -381,16 +346,15 @@ int lj_bcwrite(lua_State *L, GCproto *pt, lua_Writer writer, void *data, | |||
381 | { | 346 | { |
382 | BCWriteCtx ctx; | 347 | BCWriteCtx ctx; |
383 | int status; | 348 | int status; |
384 | ctx.L = L; | ||
385 | ctx.pt = pt; | 349 | ctx.pt = pt; |
386 | ctx.wfunc = writer; | 350 | ctx.wfunc = writer; |
387 | ctx.wdata = data; | 351 | ctx.wdata = data; |
388 | ctx.strip = strip; | 352 | ctx.strip = strip; |
389 | ctx.status = 0; | 353 | ctx.status = 0; |
390 | lj_str_initbuf(&ctx.sb); | 354 | lj_buf_init(L, &ctx.sb); |
391 | status = lj_vm_cpcall(L, NULL, &ctx, cpwriter); | 355 | status = lj_vm_cpcall(L, NULL, &ctx, cpwriter); |
392 | if (status == 0) status = ctx.status; | 356 | if (status == 0) status = ctx.status; |
393 | lj_str_freebuf(G(ctx.L), &ctx.sb); | 357 | lj_buf_free(G(sbufL(&ctx.sb)), &ctx.sb); |
394 | return status; | 358 | return status; |
395 | } | 359 | } |
396 | 360 | ||