3 ** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
22 #include "lj_bcdump.h"
24 #include "lj_strfmt.h"
26 /* Reuse some lexer fields for our own purposes. */
27 #define bcread_flags(ls) ls->level
28 #define bcread_swap(ls) \
29 ((bcread_flags(ls) & BCDUMP_F_BE) != LJ_BE*BCDUMP_F_BE)
30 #define bcread_oldtop(L, ls) restorestack(L, ls->lastline)
31 #define bcread_savetop(L, ls, top) \
32 ls->lastline = (BCLine)savestack(L, (top))
34 /* -- Input buffer handling ----------------------------------------------- */
36 /* Throw reader error. */
37 static LJ_NOINLINE
void bcread_error(LexState
*ls
, ErrMsg em
)
40 const char *name
= ls
->chunkarg
;
41 if (*name
== BCDUMP_HEAD1
) name
= "(binary)";
42 else if (*name
== '@' || *name
== '=') name
++;
43 lj_strfmt_pushf(L
, "%s: %s", name
, err2msg(em
));
44 lj_err_throw(L
, LUA_ERRSYNTAX
);
48 static LJ_NOINLINE
void bcread_fill(LexState
*ls
, MSize len
, int need
)
50 lj_assertLS(len
!= 0, "empty refill");
51 if (len
> LJ_MAX_BUF
|| ls
->c
< 0)
52 bcread_error(ls
, LJ_ERR_BCBAD
);
57 MSize n
= (MSize
)(ls
->pe
- ls
->p
);
58 if (n
) { /* Copy remainder to buffer. */
59 if (sbuflen(&ls
->sb
)) { /* Move down in buffer. */
60 lj_assertLS(ls
->pe
== ls
->sb
.w
, "bad buffer pointer");
61 if (ls
->p
!= p
) memmove(p
, ls
->p
, n
);
62 } else { /* Copy from buffer provided by reader. */
63 p
= lj_buf_need(&ls
->sb
, len
);
70 buf
= ls
->rfunc(ls
->L
, ls
->rdata
, &sz
); /* Get more data from reader. */
71 if (buf
== NULL
|| sz
== 0) { /* EOF? */
72 if (need
) bcread_error(ls
, LJ_ERR_BCBAD
);
73 ls
->c
= -1; /* Only bad if we get called again. */
76 if (sz
>= LJ_MAX_BUF
- n
) lj_err_mem(ls
->L
);
77 if (n
) { /* Append to buffer. */
79 p
= lj_buf_need(&ls
->sb
, n
< len
? len
: n
);
80 memcpy(ls
->sb
.w
, buf
, sz
);
84 } else { /* Return buffer provided by reader. */
88 } while ((MSize
)(ls
->pe
- ls
->p
) < len
);
91 /* Need a certain number of bytes. */
92 static LJ_AINLINE
void bcread_need(LexState
*ls
, MSize len
)
94 if (LJ_UNLIKELY((MSize
)(ls
->pe
- ls
->p
) < len
))
95 bcread_fill(ls
, len
, 1);
98 /* Want to read up to a certain number of bytes, but may need less. */
99 static LJ_AINLINE
void bcread_want(LexState
*ls
, MSize len
)
101 if (LJ_UNLIKELY((MSize
)(ls
->pe
- ls
->p
) < len
))
102 bcread_fill(ls
, len
, 0);
105 /* Return memory block from buffer. */
106 static LJ_AINLINE
uint8_t *bcread_mem(LexState
*ls
, MSize len
)
108 uint8_t *p
= (uint8_t *)ls
->p
;
110 lj_assertLS(ls
->p
<= ls
->pe
, "buffer read overflow");
114 /* Copy memory block from buffer. */
115 static void bcread_block(LexState
*ls
, void *q
, MSize len
)
117 memcpy(q
, bcread_mem(ls
, len
), len
);
120 /* Read byte from buffer. */
121 static LJ_AINLINE
uint32_t bcread_byte(LexState
*ls
)
123 lj_assertLS(ls
->p
< ls
->pe
, "buffer read overflow");
124 return (uint32_t)(uint8_t)*ls
->p
++;
127 /* Read ULEB128 value from buffer. */
128 static LJ_AINLINE
uint32_t bcread_uleb128(LexState
*ls
)
130 uint32_t v
= lj_buf_ruleb128(&ls
->p
);
131 lj_assertLS(ls
->p
<= ls
->pe
, "buffer read overflow");
135 /* Read top 32 bits of 33 bit ULEB128 value from buffer. */
136 static uint32_t bcread_uleb128_33(LexState
*ls
)
138 const uint8_t *p
= (const uint8_t *)ls
->p
;
139 uint32_t v
= (*p
++ >> 1);
140 if (LJ_UNLIKELY(v
>= 0x40)) {
144 v
|= ((*p
& 0x7f) << (sh
+= 7));
145 } while (*p
++ >= 0x80);
148 lj_assertLS(ls
->p
<= ls
->pe
, "buffer read overflow");
152 /* -- Bytecode reader ----------------------------------------------------- */
154 /* Read debug info of a prototype. */
155 static void bcread_dbg(LexState
*ls
, GCproto
*pt
, MSize sizedbg
)
157 void *lineinfo
= (void *)proto_lineinfo(pt
);
158 bcread_block(ls
, lineinfo
, sizedbg
);
159 /* Swap lineinfo if the endianess differs. */
160 if (bcread_swap(ls
) && pt
->numline
>= 256) {
161 MSize i
, n
= pt
->sizebc
-1;
162 if (pt
->numline
< 65536) {
163 uint16_t *p
= (uint16_t *)lineinfo
;
164 for (i
= 0; i
< n
; i
++) p
[i
] = (uint16_t)((p
[i
] >> 8)|(p
[i
] << 8));
166 uint32_t *p
= (uint32_t *)lineinfo
;
167 for (i
= 0; i
< n
; i
++) p
[i
] = lj_bswap(p
[i
]);
172 /* Find pointer to varinfo. */
173 static const void *bcread_varinfo(GCproto
*pt
)
175 const uint8_t *p
= proto_uvinfo(pt
);
176 MSize n
= pt
->sizeuv
;
177 if (n
) while (*p
++ || --n
) ;
181 /* Read a single constant key/value of a template table. */
182 static void bcread_ktabk(LexState
*ls
, TValue
*o
)
184 MSize tp
= bcread_uleb128(ls
);
185 if (tp
>= BCDUMP_KTAB_STR
) {
186 MSize len
= tp
- BCDUMP_KTAB_STR
;
187 const char *p
= (const char *)bcread_mem(ls
, len
);
188 setstrV(ls
->L
, o
, lj_str_new(ls
->L
, p
, len
));
189 } else if (tp
== BCDUMP_KTAB_INT
) {
190 setintV(o
, (int32_t)bcread_uleb128(ls
));
191 } else if (tp
== BCDUMP_KTAB_NUM
) {
192 o
->u32
.lo
= bcread_uleb128(ls
);
193 o
->u32
.hi
= bcread_uleb128(ls
);
195 lj_assertLS(tp
<= BCDUMP_KTAB_TRUE
, "bad constant type %d", tp
);
200 /* Read a template table. */
201 static GCtab
*bcread_ktab(LexState
*ls
)
203 MSize narray
= bcread_uleb128(ls
);
204 MSize nhash
= bcread_uleb128(ls
);
205 GCtab
*t
= lj_tab_new(ls
->L
, narray
, hsize2hbits(nhash
));
206 if (narray
) { /* Read array entries. */
208 TValue
*o
= tvref(t
->array
);
209 for (i
= 0; i
< narray
; i
++, o
++)
212 if (nhash
) { /* Read hash entries. */
214 for (i
= 0; i
< nhash
; i
++) {
216 bcread_ktabk(ls
, &key
);
217 lj_assertLS(!tvisnil(&key
), "nil key");
218 bcread_ktabk(ls
, lj_tab_set(ls
->L
, t
, &key
));
224 /* Read GC constants of a prototype. */
225 static void bcread_kgc(LexState
*ls
, GCproto
*pt
, MSize sizekgc
)
228 GCRef
*kr
= mref(pt
->k
, GCRef
) - (ptrdiff_t)sizekgc
;
229 for (i
= 0; i
< sizekgc
; i
++, kr
++) {
230 MSize tp
= bcread_uleb128(ls
);
231 if (tp
>= BCDUMP_KGC_STR
) {
232 MSize len
= tp
- BCDUMP_KGC_STR
;
233 const char *p
= (const char *)bcread_mem(ls
, len
);
234 setgcref(*kr
, obj2gco(lj_str_new(ls
->L
, p
, len
)));
235 } else if (tp
== BCDUMP_KGC_TAB
) {
236 setgcref(*kr
, obj2gco(bcread_ktab(ls
)));
238 } else if (tp
!= BCDUMP_KGC_CHILD
) {
239 CTypeID id
= tp
== BCDUMP_KGC_COMPLEX
? CTID_COMPLEX_DOUBLE
:
240 tp
== BCDUMP_KGC_I64
? CTID_INT64
: CTID_UINT64
;
241 CTSize sz
= tp
== BCDUMP_KGC_COMPLEX
? 16 : 8;
242 GCcdata
*cd
= lj_cdata_new_(ls
->L
, id
, sz
);
243 TValue
*p
= (TValue
*)cdataptr(cd
);
244 setgcref(*kr
, obj2gco(cd
));
245 p
[0].u32
.lo
= bcread_uleb128(ls
);
246 p
[0].u32
.hi
= bcread_uleb128(ls
);
247 if (tp
== BCDUMP_KGC_COMPLEX
) {
248 p
[1].u32
.lo
= bcread_uleb128(ls
);
249 p
[1].u32
.hi
= bcread_uleb128(ls
);
253 lua_State
*L
= ls
->L
;
254 lj_assertLS(tp
== BCDUMP_KGC_CHILD
, "bad constant type %d", tp
);
255 if (L
->top
<= bcread_oldtop(L
, ls
)) /* Stack underflow? */
256 bcread_error(ls
, LJ_ERR_BCBAD
);
258 setgcref(*kr
, obj2gco(protoV(L
->top
)));
263 /* Read number constants of a prototype. */
264 static void bcread_knum(LexState
*ls
, GCproto
*pt
, MSize sizekn
)
267 TValue
*o
= mref(pt
->k
, TValue
);
268 for (i
= 0; i
< sizekn
; i
++, o
++) {
269 int isnum
= (ls
->p
[0] & 1);
270 uint32_t lo
= bcread_uleb128_33(ls
);
273 o
->u32
.hi
= bcread_uleb128(ls
);
280 /* Read bytecode instructions. */
281 static void bcread_bytecode(LexState
*ls
, GCproto
*pt
, MSize sizebc
)
283 BCIns
*bc
= proto_bc(pt
);
285 if (ls
->fr2
!= LJ_FR2
) op
= BC_NOT
; /* Mark non-native prototype. */
286 else if ((pt
->flags
& PROTO_VARARG
)) op
= BC_FUNCV
;
288 bc
[0] = BCINS_AD(op
, pt
->framesize
, 0);
289 bcread_block(ls
, bc
+1, (sizebc
-1)*(MSize
)sizeof(BCIns
));
290 /* Swap bytecode instructions if the endianess differs. */
291 if (bcread_swap(ls
)) {
293 for (i
= 1; i
< sizebc
; i
++) bc
[i
] = lj_bswap(bc
[i
]);
297 /* Read upvalue refs. */
298 static void bcread_uv(LexState
*ls
, GCproto
*pt
, MSize sizeuv
)
301 uint16_t *uv
= proto_uv(pt
);
302 bcread_block(ls
, uv
, sizeuv
*2);
303 /* Swap upvalue refs if the endianess differs. */
304 if (bcread_swap(ls
)) {
306 for (i
= 0; i
< sizeuv
; i
++)
307 uv
[i
] = (uint16_t)((uv
[i
] >> 8)|(uv
[i
] << 8));
312 /* Read a prototype. */
313 GCproto
*lj_bcread_proto(LexState
*ls
)
316 MSize framesize
, numparams
, flags
, sizeuv
, sizekgc
, sizekn
, sizebc
, sizept
;
317 MSize ofsk
, ofsuv
, ofsdbg
;
319 BCLine firstline
= 0, numline
= 0;
321 /* Read prototype header. */
322 flags
= bcread_byte(ls
);
323 numparams
= bcread_byte(ls
);
324 framesize
= bcread_byte(ls
);
325 sizeuv
= bcread_byte(ls
);
326 sizekgc
= bcread_uleb128(ls
);
327 sizekn
= bcread_uleb128(ls
);
328 sizebc
= bcread_uleb128(ls
) + 1;
329 if (!(bcread_flags(ls
) & BCDUMP_F_STRIP
)) {
330 sizedbg
= bcread_uleb128(ls
);
332 firstline
= bcread_uleb128(ls
);
333 numline
= bcread_uleb128(ls
);
337 /* Calculate total size of prototype including all colocated arrays. */
338 sizept
= (MSize
)sizeof(GCproto
) +
339 sizebc
*(MSize
)sizeof(BCIns
) +
340 sizekgc
*(MSize
)sizeof(GCRef
);
341 sizept
= (sizept
+ (MSize
)sizeof(TValue
)-1) & ~((MSize
)sizeof(TValue
)-1);
342 ofsk
= sizept
; sizept
+= sizekn
*(MSize
)sizeof(TValue
);
343 ofsuv
= sizept
; sizept
+= ((sizeuv
+1)&~1)*2;
344 ofsdbg
= sizept
; sizept
+= sizedbg
;
346 /* Allocate prototype object and initialize its fields. */
347 pt
= (GCproto
*)lj_mem_newgco(ls
->L
, (MSize
)sizept
);
348 pt
->gct
= ~LJ_TPROTO
;
349 pt
->numparams
= (uint8_t)numparams
;
350 pt
->framesize
= (uint8_t)framesize
;
352 setmref(pt
->k
, (char *)pt
+ ofsk
);
353 setmref(pt
->uv
, (char *)pt
+ ofsuv
);
354 pt
->sizekgc
= 0; /* Set to zero until fully initialized. */
357 pt
->sizeuv
= (uint8_t)sizeuv
;
358 pt
->flags
= (uint8_t)flags
;
360 setgcref(pt
->chunkname
, obj2gco(ls
->chunkname
));
362 /* Close potentially uninitialized gap between bc and kgc. */
363 *(uint32_t *)((char *)pt
+ ofsk
- sizeof(GCRef
)*(sizekgc
+1)) = 0;
365 /* Read bytecode instructions and upvalue refs. */
366 bcread_bytecode(ls
, pt
, sizebc
);
367 bcread_uv(ls
, pt
, sizeuv
);
369 /* Read constants. */
370 bcread_kgc(ls
, pt
, sizekgc
);
371 pt
->sizekgc
= sizekgc
;
372 bcread_knum(ls
, pt
, sizekn
);
374 /* Read and initialize debug info. */
375 pt
->firstline
= firstline
;
376 pt
->numline
= numline
;
378 MSize sizeli
= (sizebc
-1) << (numline
< 256 ? 0 : numline
< 65536 ? 1 : 2);
379 setmref(pt
->lineinfo
, (char *)pt
+ ofsdbg
);
380 setmref(pt
->uvinfo
, (char *)pt
+ ofsdbg
+ sizeli
);
381 bcread_dbg(ls
, pt
, sizedbg
);
382 setmref(pt
->varinfo
, bcread_varinfo(pt
));
384 setmref(pt
->lineinfo
, NULL
);
385 setmref(pt
->uvinfo
, NULL
);
386 setmref(pt
->varinfo
, NULL
);
391 /* Read and check header of bytecode dump. */
392 static int bcread_header(LexState
*ls
)
395 bcread_want(ls
, 3+5+5);
396 if (bcread_byte(ls
) != BCDUMP_HEAD2
||
397 bcread_byte(ls
) != BCDUMP_HEAD3
||
398 bcread_byte(ls
) != BCDUMP_VERSION
) return 0;
399 bcread_flags(ls
) = flags
= bcread_uleb128(ls
);
400 if ((flags
& ~(BCDUMP_F_KNOWN
)) != 0) return 0;
401 if ((flags
& BCDUMP_F_FR2
) != (uint32_t)ls
->fr2
*BCDUMP_F_FR2
) return 0;
402 if ((flags
& BCDUMP_F_FFI
)) {
404 lua_State
*L
= ls
->L
;
410 if ((flags
& BCDUMP_F_STRIP
)) {
411 ls
->chunkname
= lj_str_newz(ls
->L
, ls
->chunkarg
);
413 MSize len
= bcread_uleb128(ls
);
414 bcread_need(ls
, len
);
415 ls
->chunkname
= lj_str_new(ls
->L
, (const char *)bcread_mem(ls
, len
), len
);
420 /* Read a bytecode dump. */
421 GCproto
*lj_bcread(LexState
*ls
)
423 lua_State
*L
= ls
->L
;
424 lj_assertLS(ls
->c
== BCDUMP_HEAD1
, "bad bytecode header");
425 bcread_savetop(L
, ls
, L
->top
);
426 lj_buf_reset(&ls
->sb
);
427 /* Check for a valid bytecode dump header. */
428 if (!bcread_header(ls
))
429 bcread_error(ls
, LJ_ERR_BCFMT
);
430 for (;;) { /* Process all prototypes in the bytecode dump. */
435 if (ls
->p
< ls
->pe
&& ls
->p
[0] == 0) { /* Shortcut EOF. */
440 len
= bcread_uleb128(ls
);
441 if (!len
) break; /* EOF */
442 bcread_need(ls
, len
);
444 pt
= lj_bcread_proto(ls
);
445 if (ls
->p
!= startp
+ len
)
446 bcread_error(ls
, LJ_ERR_BCBAD
);
447 setprotoV(L
, L
->top
, pt
);
450 if ((ls
->pe
!= ls
->p
&& !ls
->endmark
) || L
->top
-1 != bcread_oldtop(L
, ls
))
451 bcread_error(ls
, LJ_ERR_BCBAD
);
452 /* Pop off last prototype. */
454 return protoV(L
->top
);