3 ** Copyright (C) 2005-2022 Mike Pall. See Copyright Notice in luajit.h
21 #include "lj_bcdump.h"
24 /* Reuse some lexer fields for our own purposes. */
25 #define bcread_flags(ls) ls->level
26 #define bcread_swap(ls) \
27 ((bcread_flags(ls) & BCDUMP_F_BE) != LJ_BE*BCDUMP_F_BE)
28 #define bcread_oldtop(L, ls) restorestack(L, ls->lastline)
29 #define bcread_savetop(L, ls, top) \
30 ls->lastline = (BCLine)savestack(L, (top))
32 /* -- Input buffer handling ----------------------------------------------- */
34 /* Throw reader error. */
35 static LJ_NOINLINE
void bcread_error(LexState
*ls
, ErrMsg em
)
38 const char *name
= ls
->chunkarg
;
39 if (*name
== BCDUMP_HEAD1
) name
= "(binary)";
40 else if (*name
== '@' || *name
== '=') name
++;
41 lj_str_pushf(L
, "%s: %s", name
, err2msg(em
));
42 lj_err_throw(L
, LUA_ERRSYNTAX
);
45 /* Resize input buffer. */
46 static void bcread_resize(LexState
*ls
, MSize len
)
48 if (ls
->sb
.sz
< len
) {
49 MSize sz
= ls
->sb
.sz
* 2;
50 while (len
> sz
) sz
= sz
* 2;
51 lj_str_resizebuf(ls
->L
, &ls
->sb
, sz
);
52 /* Caveat: this may change ls->sb.buf which may affect ls->p. */
56 /* Refill buffer if needed. */
57 static LJ_NOINLINE
void bcread_fill(LexState
*ls
, MSize len
, int need
)
60 if (len
> LJ_MAX_MEM
|| ls
->current
< 0)
61 bcread_error(ls
, LJ_ERR_BCBAD
);
65 if (ls
->n
) { /* Copy remainder to buffer. */
66 if (ls
->sb
.n
) { /* Move down in buffer. */
67 lua_assert(ls
->p
+ ls
->n
== ls
->sb
.buf
+ ls
->sb
.n
);
68 if (ls
->n
!= ls
->sb
.n
)
69 memmove(ls
->sb
.buf
, ls
->p
, ls
->n
);
70 } else { /* Copy from buffer provided by reader. */
71 bcread_resize(ls
, len
);
72 memcpy(ls
->sb
.buf
, ls
->p
, ls
->n
);
77 buf
= ls
->rfunc(ls
->L
, ls
->rdata
, &size
); /* Get more data from reader. */
78 if (buf
== NULL
|| size
== 0) { /* EOF? */
79 if (need
) bcread_error(ls
, LJ_ERR_BCBAD
);
80 ls
->current
= -1; /* Only bad if we get called again. */
83 if (size
>= LJ_MAX_MEM
- ls
->sb
.n
) lj_err_mem(ls
->L
);
84 if (ls
->sb
.n
) { /* Append to buffer. */
85 MSize n
= ls
->sb
.n
+ (MSize
)size
;
86 bcread_resize(ls
, n
< len
? len
: n
);
87 memcpy(ls
->sb
.buf
+ ls
->sb
.n
, buf
, size
);
90 } else { /* Return buffer provided by reader. */
94 } while (ls
->n
< len
);
97 /* Need a certain number of bytes. */
98 static LJ_AINLINE
void bcread_need(LexState
*ls
, MSize len
)
100 if (LJ_UNLIKELY(ls
->n
< len
))
101 bcread_fill(ls
, len
, 1);
104 /* Want to read up to a certain number of bytes, but may need less. */
105 static LJ_AINLINE
void bcread_want(LexState
*ls
, MSize len
)
107 if (LJ_UNLIKELY(ls
->n
< len
))
108 bcread_fill(ls
, len
, 0);
111 #define bcread_dec(ls) check_exp(ls->n > 0, ls->n--)
112 #define bcread_consume(ls, len) check_exp(ls->n >= (len), ls->n -= (len))
114 /* Return memory block from buffer. */
115 static uint8_t *bcread_mem(LexState
*ls
, MSize len
)
117 uint8_t *p
= (uint8_t *)ls
->p
;
118 bcread_consume(ls
, len
);
119 ls
->p
= (char *)p
+ len
;
123 /* Copy memory block from buffer. */
124 static void bcread_block(LexState
*ls
, void *q
, MSize len
)
126 memcpy(q
, bcread_mem(ls
, len
), len
);
129 /* Read byte from buffer. */
130 static LJ_AINLINE
uint32_t bcread_byte(LexState
*ls
)
133 return (uint32_t)(uint8_t)*ls
->p
++;
136 /* Read ULEB128 value from buffer. */
137 static uint32_t bcread_uleb128(LexState
*ls
)
139 const uint8_t *p
= (const uint8_t *)ls
->p
;
141 if (LJ_UNLIKELY(v
>= 0x80)) {
145 v
|= ((*p
& 0x7f) << (sh
+= 7));
147 } while (*p
++ >= 0x80);
154 /* Read top 32 bits of 33 bit ULEB128 value from buffer. */
155 static uint32_t bcread_uleb128_33(LexState
*ls
)
157 const uint8_t *p
= (const uint8_t *)ls
->p
;
158 uint32_t v
= (*p
++ >> 1);
159 if (LJ_UNLIKELY(v
>= 0x40)) {
163 v
|= ((*p
& 0x7f) << (sh
+= 7));
165 } while (*p
++ >= 0x80);
172 /* -- Bytecode reader ----------------------------------------------------- */
174 /* Read debug info of a prototype. */
175 static void bcread_dbg(LexState
*ls
, GCproto
*pt
, MSize sizedbg
)
177 void *lineinfo
= (void *)proto_lineinfo(pt
);
178 bcread_block(ls
, lineinfo
, sizedbg
);
179 /* Swap lineinfo if the endianess differs. */
180 if (bcread_swap(ls
) && pt
->numline
>= 256) {
181 MSize i
, n
= pt
->sizebc
-1;
182 if (pt
->numline
< 65536) {
183 uint16_t *p
= (uint16_t *)lineinfo
;
184 for (i
= 0; i
< n
; i
++) p
[i
] = (uint16_t)((p
[i
] >> 8)|(p
[i
] << 8));
186 uint32_t *p
= (uint32_t *)lineinfo
;
187 for (i
= 0; i
< n
; i
++) p
[i
] = lj_bswap(p
[i
]);
192 /* Find pointer to varinfo. */
193 static const void *bcread_varinfo(GCproto
*pt
)
195 const uint8_t *p
= proto_uvinfo(pt
);
196 MSize n
= pt
->sizeuv
;
197 if (n
) while (*p
++ || --n
) ;
201 /* Read a single constant key/value of a template table. */
202 static void bcread_ktabk(LexState
*ls
, TValue
*o
)
204 MSize tp
= bcread_uleb128(ls
);
205 if (tp
>= BCDUMP_KTAB_STR
) {
206 MSize len
= tp
- BCDUMP_KTAB_STR
;
207 const char *p
= (const char *)bcread_mem(ls
, len
);
208 setstrV(ls
->L
, o
, lj_str_new(ls
->L
, p
, len
));
209 } else if (tp
== BCDUMP_KTAB_INT
) {
210 setintV(o
, (int32_t)bcread_uleb128(ls
));
211 } else if (tp
== BCDUMP_KTAB_NUM
) {
212 o
->u32
.lo
= bcread_uleb128(ls
);
213 o
->u32
.hi
= bcread_uleb128(ls
);
215 lua_assert(tp
<= BCDUMP_KTAB_TRUE
);
220 /* Read a template table. */
221 static GCtab
*bcread_ktab(LexState
*ls
)
223 MSize narray
= bcread_uleb128(ls
);
224 MSize nhash
= bcread_uleb128(ls
);
225 GCtab
*t
= lj_tab_new(ls
->L
, narray
, hsize2hbits(nhash
));
226 if (narray
) { /* Read array entries. */
228 TValue
*o
= tvref(t
->array
);
229 for (i
= 0; i
< narray
; i
++, o
++)
232 if (nhash
) { /* Read hash entries. */
234 for (i
= 0; i
< nhash
; i
++) {
236 bcread_ktabk(ls
, &key
);
237 lua_assert(!tvisnil(&key
));
238 bcread_ktabk(ls
, lj_tab_set(ls
->L
, t
, &key
));
244 /* Read GC constants of a prototype. */
245 static void bcread_kgc(LexState
*ls
, GCproto
*pt
, MSize sizekgc
)
248 GCRef
*kr
= mref(pt
->k
, GCRef
) - (ptrdiff_t)sizekgc
;
249 for (i
= 0; i
< sizekgc
; i
++, kr
++) {
250 MSize tp
= bcread_uleb128(ls
);
251 if (tp
>= BCDUMP_KGC_STR
) {
252 MSize len
= tp
- BCDUMP_KGC_STR
;
253 const char *p
= (const char *)bcread_mem(ls
, len
);
254 setgcref(*kr
, obj2gco(lj_str_new(ls
->L
, p
, len
)));
255 } else if (tp
== BCDUMP_KGC_TAB
) {
256 setgcref(*kr
, obj2gco(bcread_ktab(ls
)));
258 } else if (tp
!= BCDUMP_KGC_CHILD
) {
259 CTypeID id
= tp
== BCDUMP_KGC_COMPLEX
? CTID_COMPLEX_DOUBLE
:
260 tp
== BCDUMP_KGC_I64
? CTID_INT64
: CTID_UINT64
;
261 CTSize sz
= tp
== BCDUMP_KGC_COMPLEX
? 16 : 8;
262 GCcdata
*cd
= lj_cdata_new_(ls
->L
, id
, sz
);
263 TValue
*p
= (TValue
*)cdataptr(cd
);
264 setgcref(*kr
, obj2gco(cd
));
265 p
[0].u32
.lo
= bcread_uleb128(ls
);
266 p
[0].u32
.hi
= bcread_uleb128(ls
);
267 if (tp
== BCDUMP_KGC_COMPLEX
) {
268 p
[1].u32
.lo
= bcread_uleb128(ls
);
269 p
[1].u32
.hi
= bcread_uleb128(ls
);
273 lua_State
*L
= ls
->L
;
274 lua_assert(tp
== BCDUMP_KGC_CHILD
);
275 if (L
->top
<= bcread_oldtop(L
, ls
)) /* Stack underflow? */
276 bcread_error(ls
, LJ_ERR_BCBAD
);
278 setgcref(*kr
, obj2gco(protoV(L
->top
)));
283 /* Read number constants of a prototype. */
284 static void bcread_knum(LexState
*ls
, GCproto
*pt
, MSize sizekn
)
287 TValue
*o
= mref(pt
->k
, TValue
);
288 for (i
= 0; i
< sizekn
; i
++, o
++) {
289 int isnum
= (ls
->p
[0] & 1);
290 uint32_t lo
= bcread_uleb128_33(ls
);
293 o
->u32
.hi
= bcread_uleb128(ls
);
300 /* Read bytecode instructions. */
301 static void bcread_bytecode(LexState
*ls
, GCproto
*pt
, MSize sizebc
)
303 BCIns
*bc
= proto_bc(pt
);
304 bc
[0] = BCINS_AD((pt
->flags
& PROTO_VARARG
) ? BC_FUNCV
: BC_FUNCF
,
306 bcread_block(ls
, bc
+1, (sizebc
-1)*(MSize
)sizeof(BCIns
));
307 /* Swap bytecode instructions if the endianess differs. */
308 if (bcread_swap(ls
)) {
310 for (i
= 1; i
< sizebc
; i
++) bc
[i
] = lj_bswap(bc
[i
]);
314 /* Read upvalue refs. */
315 static void bcread_uv(LexState
*ls
, GCproto
*pt
, MSize sizeuv
)
318 uint16_t *uv
= proto_uv(pt
);
319 bcread_block(ls
, uv
, sizeuv
*2);
320 /* Swap upvalue refs if the endianess differs. */
321 if (bcread_swap(ls
)) {
323 for (i
= 0; i
< sizeuv
; i
++)
324 uv
[i
] = (uint16_t)((uv
[i
] >> 8)|(uv
[i
] << 8));
329 /* Read a prototype. */
330 static GCproto
*bcread_proto(LexState
*ls
)
333 MSize framesize
, numparams
, flags
, sizeuv
, sizekgc
, sizekn
, sizebc
, sizept
;
334 MSize ofsk
, ofsuv
, ofsdbg
;
336 BCLine firstline
= 0, numline
= 0;
340 if (ls
->n
> 0 && ls
->p
[0] == 0) { /* Shortcut EOF. */
345 len
= bcread_uleb128(ls
);
346 if (!len
) return NULL
; /* EOF */
347 bcread_need(ls
, len
);
350 /* Read prototype header. */
351 flags
= bcread_byte(ls
);
352 numparams
= bcread_byte(ls
);
353 framesize
= bcread_byte(ls
);
354 sizeuv
= bcread_byte(ls
);
355 sizekgc
= bcread_uleb128(ls
);
356 sizekn
= bcread_uleb128(ls
);
357 sizebc
= bcread_uleb128(ls
) + 1;
358 if (!(bcread_flags(ls
) & BCDUMP_F_STRIP
)) {
359 sizedbg
= bcread_uleb128(ls
);
361 firstline
= bcread_uleb128(ls
);
362 numline
= bcread_uleb128(ls
);
366 /* Calculate total size of prototype including all colocated arrays. */
367 sizept
= (MSize
)sizeof(GCproto
) +
368 sizebc
*(MSize
)sizeof(BCIns
) +
369 sizekgc
*(MSize
)sizeof(GCRef
);
370 sizept
= (sizept
+ (MSize
)sizeof(TValue
)-1) & ~((MSize
)sizeof(TValue
)-1);
371 ofsk
= sizept
; sizept
+= sizekn
*(MSize
)sizeof(TValue
);
372 ofsuv
= sizept
; sizept
+= ((sizeuv
+1)&~1)*2;
373 ofsdbg
= sizept
; sizept
+= sizedbg
;
375 /* Allocate prototype object and initialize its fields. */
376 pt
= (GCproto
*)lj_mem_newgco(ls
->L
, (MSize
)sizept
);
377 pt
->gct
= ~LJ_TPROTO
;
378 pt
->numparams
= (uint8_t)numparams
;
379 pt
->framesize
= (uint8_t)framesize
;
381 setmref(pt
->k
, (char *)pt
+ ofsk
);
382 setmref(pt
->uv
, (char *)pt
+ ofsuv
);
383 pt
->sizekgc
= 0; /* Set to zero until fully initialized. */
386 pt
->sizeuv
= (uint8_t)sizeuv
;
387 pt
->flags
= (uint8_t)flags
;
389 setgcref(pt
->chunkname
, obj2gco(ls
->chunkname
));
391 /* Close potentially uninitialized gap between bc and kgc. */
392 *(uint32_t *)((char *)pt
+ ofsk
- sizeof(GCRef
)*(sizekgc
+1)) = 0;
394 /* Read bytecode instructions and upvalue refs. */
395 bcread_bytecode(ls
, pt
, sizebc
);
396 bcread_uv(ls
, pt
, sizeuv
);
398 /* Read constants. */
399 bcread_kgc(ls
, pt
, sizekgc
);
400 pt
->sizekgc
= sizekgc
;
401 bcread_knum(ls
, pt
, sizekn
);
403 /* Read and initialize debug info. */
404 pt
->firstline
= firstline
;
405 pt
->numline
= numline
;
407 MSize sizeli
= (sizebc
-1) << (numline
< 256 ? 0 : numline
< 65536 ? 1 : 2);
408 setmref(pt
->lineinfo
, (char *)pt
+ ofsdbg
);
409 setmref(pt
->uvinfo
, (char *)pt
+ ofsdbg
+ sizeli
);
410 bcread_dbg(ls
, pt
, sizedbg
);
411 setmref(pt
->varinfo
, bcread_varinfo(pt
));
413 setmref(pt
->lineinfo
, NULL
);
414 setmref(pt
->uvinfo
, NULL
);
415 setmref(pt
->varinfo
, NULL
);
418 if (len
!= startn
- ls
->n
)
419 bcread_error(ls
, LJ_ERR_BCBAD
);
423 /* Read and check header of bytecode dump. */
424 static int bcread_header(LexState
*ls
)
427 bcread_want(ls
, 3+5+5);
428 if (bcread_byte(ls
) != BCDUMP_HEAD2
||
429 bcread_byte(ls
) != BCDUMP_HEAD3
||
430 bcread_byte(ls
) != BCDUMP_VERSION
) return 0;
431 bcread_flags(ls
) = flags
= bcread_uleb128(ls
);
432 if ((flags
& ~(BCDUMP_F_KNOWN
)) != 0) return 0;
433 if ((flags
& BCDUMP_F_FFI
)) {
435 lua_State
*L
= ls
->L
;
436 if (!ctype_ctsG(G(L
))) {
437 ptrdiff_t oldtop
= savestack(L
, L
->top
);
438 luaopen_ffi(L
); /* Load FFI library on-demand. */
439 L
->top
= restorestack(L
, oldtop
);
445 if ((flags
& BCDUMP_F_STRIP
)) {
446 ls
->chunkname
= lj_str_newz(ls
->L
, ls
->chunkarg
);
448 MSize len
= bcread_uleb128(ls
);
449 bcread_need(ls
, len
);
450 ls
->chunkname
= lj_str_new(ls
->L
, (const char *)bcread_mem(ls
, len
), len
);
455 /* Read a bytecode dump. */
456 GCproto
*lj_bcread(LexState
*ls
)
458 lua_State
*L
= ls
->L
;
459 lua_assert(ls
->current
== BCDUMP_HEAD1
);
460 bcread_savetop(L
, ls
, L
->top
);
461 lj_str_resetbuf(&ls
->sb
);
462 /* Check for a valid bytecode dump header. */
463 if (!bcread_header(ls
))
464 bcread_error(ls
, LJ_ERR_BCFMT
);
465 for (;;) { /* Process all prototypes in the bytecode dump. */
466 GCproto
*pt
= bcread_proto(ls
);
468 setprotoV(L
, L
->top
, pt
);
471 if ((ls
->n
&& !ls
->endmark
) || L
->top
-1 != bcread_oldtop(L
, ls
))
472 bcread_error(ls
, LJ_ERR_BCBAD
);
473 /* Pop off last prototype. */
475 return protoV(L
->top
);