diff options
Diffstat (limited to 'src/lj_bcwrite.c')
-rw-r--r-- | src/lj_bcwrite.c | 225 |
1 files changed, 95 insertions, 130 deletions
diff --git a/src/lj_bcwrite.c b/src/lj_bcwrite.c index 171a8d6d..a86d6d00 100644 --- a/src/lj_bcwrite.c +++ b/src/lj_bcwrite.c | |||
@@ -8,7 +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_str.h" | 11 | #include "lj_buf.h" |
12 | #include "lj_bc.h" | 12 | #include "lj_bc.h" |
13 | #if LJ_HASFFI | 13 | #if LJ_HASFFI |
14 | #include "lj_ctype.h" | 14 | #include "lj_ctype.h" |
@@ -17,13 +17,13 @@ | |||
17 | #include "lj_dispatch.h" | 17 | #include "lj_dispatch.h" |
18 | #include "lj_jit.h" | 18 | #include "lj_jit.h" |
19 | #endif | 19 | #endif |
20 | #include "lj_strfmt.h" | ||
20 | #include "lj_bcdump.h" | 21 | #include "lj_bcdump.h" |
21 | #include "lj_vm.h" | 22 | #include "lj_vm.h" |
22 | 23 | ||
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_strfmt_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_strfmt_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_strfmt_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_strfmt_wuleb128(p, o->u32.lo); |
104 | bcwrite_uleb128(ctx, o->u32.hi); | 62 | p = lj_strfmt_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_strfmt_wuleb128(p, narray); |
131 | bcwrite_uleb128(ctx, nhash); | 90 | p = lj_strfmt_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_strfmt_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_strfmt_wuleb128(p, q[0].u32.lo); |
195 | bcwrite_uleb128(ctx, p[0].u32.hi); | 157 | p = lj_strfmt_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_strfmt_wuleb128(p, q[1].u32.lo); |
198 | bcwrite_uleb128(ctx, p[1].u32.hi); | 160 | p = lj_strfmt_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,55 +183,55 @@ 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_strfmt_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_strfmt_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_strfmt_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 | memcpy(p, &traceref(J, rd)->startins, 4); | 222 | memcpy(q, &traceref(J, rd)->startins, 4); |
262 | } | 223 | } |
263 | } | 224 | } |
264 | } | 225 | } |
265 | #endif | 226 | #endif |
227 | return p; | ||
266 | } | 228 | } |
267 | 229 | ||
268 | /* Write prototype. */ | 230 | /* Write prototype. */ |
269 | static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt) | 231 | static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt) |
270 | { | 232 | { |
271 | MSize sizedbg = 0; | 233 | MSize sizedbg = 0; |
234 | char *p; | ||
272 | 235 | ||
273 | /* Recursively write children of prototype. */ | 236 | /* Recursively write children of prototype. */ |
274 | if ((pt->flags & PROTO_CHILD)) { | 237 | if ((pt->flags & PROTO_CHILD)) { |
@@ -282,31 +245,32 @@ static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt) | |||
282 | } | 245 | } |
283 | 246 | ||
284 | /* Start writing the prototype info to a buffer. */ | 247 | /* Start writing the prototype info to a buffer. */ |
285 | lj_str_resetbuf(&ctx->sb); | 248 | p = lj_buf_need(&ctx->sb, |
286 | ctx->sb.n = 5; /* Leave room for final size. */ | 249 | 5+4+6*5+(pt->sizebc-1)*(MSize)sizeof(BCIns)+pt->sizeuv*2); |
287 | bcwrite_need(ctx, 4+6*5+(pt->sizebc-1)*(MSize)sizeof(BCIns)+pt->sizeuv*2); | 250 | p += 5; /* Leave room for final size. */ |
288 | 251 | ||
289 | /* Write prototype header. */ | 252 | /* Write prototype header. */ |
290 | bcwrite_byte(ctx, (pt->flags & (PROTO_CHILD|PROTO_VARARG|PROTO_FFI))); | 253 | *p++ = (pt->flags & (PROTO_CHILD|PROTO_VARARG|PROTO_FFI)); |
291 | bcwrite_byte(ctx, pt->numparams); | 254 | *p++ = pt->numparams; |
292 | bcwrite_byte(ctx, pt->framesize); | 255 | *p++ = pt->framesize; |
293 | bcwrite_byte(ctx, pt->sizeuv); | 256 | *p++ = pt->sizeuv; |
294 | bcwrite_uleb128(ctx, pt->sizekgc); | 257 | p = lj_strfmt_wuleb128(p, pt->sizekgc); |
295 | bcwrite_uleb128(ctx, pt->sizekn); | 258 | p = lj_strfmt_wuleb128(p, pt->sizekn); |
296 | bcwrite_uleb128(ctx, pt->sizebc-1); | 259 | p = lj_strfmt_wuleb128(p, pt->sizebc-1); |
297 | if (!ctx->strip) { | 260 | if (!ctx->strip) { |
298 | if (proto_lineinfo(pt)) | 261 | if (proto_lineinfo(pt)) |
299 | sizedbg = pt->sizept - (MSize)((char *)proto_lineinfo(pt) - (char *)pt); | 262 | sizedbg = pt->sizept - (MSize)((char *)proto_lineinfo(pt) - (char *)pt); |
300 | bcwrite_uleb128(ctx, sizedbg); | 263 | p = lj_strfmt_wuleb128(p, sizedbg); |
301 | if (sizedbg) { | 264 | if (sizedbg) { |
302 | bcwrite_uleb128(ctx, pt->firstline); | 265 | p = lj_strfmt_wuleb128(p, pt->firstline); |
303 | bcwrite_uleb128(ctx, pt->numline); | 266 | p = lj_strfmt_wuleb128(p, pt->numline); |
304 | } | 267 | } |
305 | } | 268 | } |
306 | 269 | ||
307 | /* Write bytecode instructions and upvalue refs. */ | 270 | /* Write bytecode instructions and upvalue refs. */ |
308 | bcwrite_bytecode(ctx, pt); | 271 | p = bcwrite_bytecode(ctx, p, pt); |
309 | bcwrite_block(ctx, proto_uv(pt), pt->sizeuv*2); | 272 | p = lj_buf_wmem(p, proto_uv(pt), pt->sizeuv*2); |
273 | setsbufP(&ctx->sb, p); | ||
310 | 274 | ||
311 | /* Write constants. */ | 275 | /* Write constants. */ |
312 | bcwrite_kgc(ctx, pt); | 276 | bcwrite_kgc(ctx, pt); |
@@ -314,18 +278,19 @@ static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt) | |||
314 | 278 | ||
315 | /* Write debug info, if not stripped. */ | 279 | /* Write debug info, if not stripped. */ |
316 | if (sizedbg) { | 280 | if (sizedbg) { |
317 | bcwrite_need(ctx, sizedbg); | 281 | p = lj_buf_more(&ctx->sb, sizedbg); |
318 | bcwrite_block(ctx, proto_lineinfo(pt), sizedbg); | 282 | p = lj_buf_wmem(p, proto_lineinfo(pt), sizedbg); |
283 | setsbufP(&ctx->sb, p); | ||
319 | } | 284 | } |
320 | 285 | ||
321 | /* Pass buffer to writer function. */ | 286 | /* Pass buffer to writer function. */ |
322 | if (ctx->status == 0) { | 287 | if (ctx->status == 0) { |
323 | MSize n = ctx->sb.n - 5; | 288 | MSize n = sbuflen(&ctx->sb) - 5; |
324 | MSize nn = (lj_fls(n)+8)*9 >> 6; | 289 | MSize nn = (lj_fls(n)+8)*9 >> 6; |
325 | ctx->sb.n = 5 - nn; | 290 | char *q = sbufB(&ctx->sb) + (5 - nn); |
326 | bcwrite_uleb128(ctx, n); /* Fill in final size. */ | 291 | p = lj_strfmt_wuleb128(q, n); /* Fill in final size. */ |
327 | lua_assert(ctx->sb.n == 5); | 292 | lua_assert(p == sbufB(&ctx->sb) + 5); |
328 | ctx->status = ctx->wfunc(ctx->L, ctx->sb.buf+5-nn, nn+n, ctx->wdata); | 293 | ctx->status = ctx->wfunc(sbufL(&ctx->sb), q, nn+n, ctx->wdata); |
329 | } | 294 | } |
330 | } | 295 | } |
331 | 296 | ||
@@ -335,20 +300,21 @@ static void bcwrite_header(BCWriteCtx *ctx) | |||
335 | GCstr *chunkname = proto_chunkname(ctx->pt); | 300 | GCstr *chunkname = proto_chunkname(ctx->pt); |
336 | const char *name = strdata(chunkname); | 301 | const char *name = strdata(chunkname); |
337 | MSize len = chunkname->len; | 302 | MSize len = chunkname->len; |
338 | lj_str_resetbuf(&ctx->sb); | 303 | char *p = lj_buf_need(&ctx->sb, 5+5+len); |
339 | bcwrite_need(ctx, 5+5+len); | 304 | *p++ = BCDUMP_HEAD1; |
340 | bcwrite_byte(ctx, BCDUMP_HEAD1); | 305 | *p++ = BCDUMP_HEAD2; |
341 | bcwrite_byte(ctx, BCDUMP_HEAD2); | 306 | *p++ = BCDUMP_HEAD3; |
342 | bcwrite_byte(ctx, BCDUMP_HEAD3); | 307 | *p++ = BCDUMP_VERSION; |
343 | bcwrite_byte(ctx, BCDUMP_VERSION); | 308 | *p++ = (ctx->strip ? BCDUMP_F_STRIP : 0) + |
344 | bcwrite_byte(ctx, (ctx->strip ? BCDUMP_F_STRIP : 0) + | 309 | LJ_BE*BCDUMP_F_BE + |
345 | (LJ_BE ? BCDUMP_F_BE : 0) + | 310 | ((ctx->pt->flags & PROTO_FFI) ? BCDUMP_F_FFI : 0) + |
346 | ((ctx->pt->flags & PROTO_FFI) ? BCDUMP_F_FFI : 0)); | 311 | LJ_FR2*BCDUMP_F_FR2; |
347 | if (!ctx->strip) { | 312 | if (!ctx->strip) { |
348 | bcwrite_uleb128(ctx, len); | 313 | p = lj_strfmt_wuleb128(p, len); |
349 | bcwrite_block(ctx, name, len); | 314 | p = lj_buf_wmem(p, name, len); |
350 | } | 315 | } |
351 | ctx->status = ctx->wfunc(ctx->L, ctx->sb.buf, ctx->sb.n, ctx->wdata); | 316 | ctx->status = ctx->wfunc(sbufL(&ctx->sb), sbufB(&ctx->sb), |
317 | (MSize)(p - sbufB(&ctx->sb)), ctx->wdata); | ||
352 | } | 318 | } |
353 | 319 | ||
354 | /* Write footer of bytecode dump. */ | 320 | /* Write footer of bytecode dump. */ |
@@ -356,7 +322,7 @@ static void bcwrite_footer(BCWriteCtx *ctx) | |||
356 | { | 322 | { |
357 | if (ctx->status == 0) { | 323 | if (ctx->status == 0) { |
358 | uint8_t zero = 0; | 324 | uint8_t zero = 0; |
359 | ctx->status = ctx->wfunc(ctx->L, &zero, 1, ctx->wdata); | 325 | ctx->status = ctx->wfunc(sbufL(&ctx->sb), &zero, 1, ctx->wdata); |
360 | } | 326 | } |
361 | } | 327 | } |
362 | 328 | ||
@@ -364,8 +330,8 @@ static void bcwrite_footer(BCWriteCtx *ctx) | |||
364 | static TValue *cpwriter(lua_State *L, lua_CFunction dummy, void *ud) | 330 | static TValue *cpwriter(lua_State *L, lua_CFunction dummy, void *ud) |
365 | { | 331 | { |
366 | BCWriteCtx *ctx = (BCWriteCtx *)ud; | 332 | BCWriteCtx *ctx = (BCWriteCtx *)ud; |
367 | UNUSED(dummy); | 333 | UNUSED(L); UNUSED(dummy); |
368 | lj_str_resizebuf(L, &ctx->sb, 1024); /* Avoids resize for most prototypes. */ | 334 | lj_buf_need(&ctx->sb, 1024); /* Avoids resize for most prototypes. */ |
369 | bcwrite_header(ctx); | 335 | bcwrite_header(ctx); |
370 | bcwrite_proto(ctx, ctx->pt); | 336 | bcwrite_proto(ctx, ctx->pt); |
371 | bcwrite_footer(ctx); | 337 | bcwrite_footer(ctx); |
@@ -378,16 +344,15 @@ int lj_bcwrite(lua_State *L, GCproto *pt, lua_Writer writer, void *data, | |||
378 | { | 344 | { |
379 | BCWriteCtx ctx; | 345 | BCWriteCtx ctx; |
380 | int status; | 346 | int status; |
381 | ctx.L = L; | ||
382 | ctx.pt = pt; | 347 | ctx.pt = pt; |
383 | ctx.wfunc = writer; | 348 | ctx.wfunc = writer; |
384 | ctx.wdata = data; | 349 | ctx.wdata = data; |
385 | ctx.strip = strip; | 350 | ctx.strip = strip; |
386 | ctx.status = 0; | 351 | ctx.status = 0; |
387 | lj_str_initbuf(&ctx.sb); | 352 | lj_buf_init(L, &ctx.sb); |
388 | status = lj_vm_cpcall(L, NULL, &ctx, cpwriter); | 353 | status = lj_vm_cpcall(L, NULL, &ctx, cpwriter); |
389 | if (status == 0) status = ctx.status; | 354 | if (status == 0) status = ctx.status; |
390 | lj_str_freebuf(G(ctx.L), &ctx.sb); | 355 | lj_buf_free(G(sbufL(&ctx.sb)), &ctx.sb); |
391 | return status; | 356 | return status; |
392 | } | 357 | } |
393 | 358 | ||