ljx

FORK: LuaJIT with native 5.2 and 5.3 support
git clone https://git.neptards.moe/neptards/ljx.git
Log | Files | Refs | README

lj_bcread.c (12998B)


      1 /*
      2 ** Bytecode reader.
      3 ** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
      4 */
      5 
      6 #define lj_bcread_c
      7 #define LUA_CORE
      8 
      9 #include "lj_obj.h"
     10 #include "lj_gc.h"
     11 #include "lj_err.h"
     12 #include "lj_buf.h"
     13 #include "lj_str.h"
     14 #include "lj_tab.h"
     15 #include "lj_bc.h"
     16 #if LJ_HASFFI
     17 #include "lj_ctype.h"
     18 #include "lj_cdata.h"
     19 #include "lualib.h"
     20 #endif
     21 #include "lj_lex.h"
     22 #include "lj_bcdump.h"
     23 #include "lj_state.h"
     24 #include "lj_strfmt.h"
     25 
     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))
     33 
     34 /* -- Input buffer handling ----------------------------------------------- */
     35 
     36 /* Throw reader error. */
     37 static LJ_NOINLINE void bcread_error(LexState *ls, ErrMsg em)
     38 {
     39   lua_State *L = ls->L;
     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);
     45 }
     46 
     47 /* Refill buffer. */
     48 static LJ_NOINLINE void bcread_fill(LexState *ls, MSize len, int need)
     49 {
     50   lua_assert(len != 0);
     51   if (len > LJ_MAX_BUF || ls->c < 0)
     52     bcread_error(ls, LJ_ERR_BCBAD);
     53   do {
     54     const char *buf;
     55     size_t sz;
     56     char *p = sbufB(&ls->sb);
     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 	lua_assert(ls->pe == sbufP(&ls->sb));
     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);
     64 	memcpy(p, ls->p, n);
     65       }
     66       ls->p = p;
     67       ls->pe = p + n;
     68     }
     69     setsbufP(&ls->sb, p + n);
     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. */
     74       break;
     75     }
     76     if (n) {  /* Append to buffer. */
     77       n += (MSize)sz;
     78       p = lj_buf_need(&ls->sb, n < len ? len : n);
     79       memcpy(sbufP(&ls->sb), buf, sz);
     80       setsbufP(&ls->sb, p + n);
     81       ls->p = p;
     82       ls->pe = p + n;
     83     } else {  /* Return buffer provided by reader. */
     84       ls->p = buf;
     85       ls->pe = buf + sz;
     86     }
     87   } while (ls->p + len > ls->pe);
     88 }
     89 
     90 /* Need a certain number of bytes. */
     91 static LJ_AINLINE void bcread_need(LexState *ls, MSize len)
     92 {
     93   if (LJ_UNLIKELY(ls->p + len > ls->pe))
     94     bcread_fill(ls, len, 1);
     95 }
     96 
     97 /* Want to read up to a certain number of bytes, but may need less. */
     98 static LJ_AINLINE void bcread_want(LexState *ls, MSize len)
     99 {
    100   if (LJ_UNLIKELY(ls->p + len > ls->pe))
    101     bcread_fill(ls, len, 0);
    102 }
    103 
    104 /* Return memory block from buffer. */
    105 static LJ_AINLINE uint8_t *bcread_mem(LexState *ls, MSize len)
    106 {
    107   uint8_t *p = (uint8_t *)ls->p;
    108   ls->p += len;
    109   lua_assert(ls->p <= ls->pe);
    110   return p;
    111 }
    112 
    113 /* Copy memory block from buffer. */
    114 static void bcread_block(LexState *ls, void *q, MSize len)
    115 {
    116   memcpy(q, bcread_mem(ls, len), len);
    117 }
    118 
    119 /* Read byte from buffer. */
    120 static LJ_AINLINE uint32_t bcread_byte(LexState *ls)
    121 {
    122   lua_assert(ls->p < ls->pe);
    123   return (uint32_t)(uint8_t)*ls->p++;
    124 }
    125 
    126 /* Read ULEB128 value from buffer. */
    127 static LJ_AINLINE uint32_t bcread_uleb128(LexState *ls)
    128 {
    129   uint32_t v = lj_buf_ruleb128(&ls->p);
    130   lua_assert(ls->p <= ls->pe);
    131   return v;
    132 }
    133 
    134 /* Read top 32 bits of 33 bit ULEB128 value from buffer. */
    135 static uint32_t bcread_uleb128_33(LexState *ls)
    136 {
    137   const uint8_t *p = (const uint8_t *)ls->p;
    138   uint32_t v = (*p++ >> 1);
    139   if (LJ_UNLIKELY(v >= 0x40)) {
    140     int sh = -1;
    141     v &= 0x3f;
    142     do {
    143      v |= ((*p & 0x7f) << (sh += 7));
    144    } while (*p++ >= 0x80);
    145   }
    146   ls->p = (char *)p;
    147   lua_assert(ls->p <= ls->pe);
    148   return v;
    149 }
    150 
    151 /* -- Bytecode reader ----------------------------------------------------- */
    152 
    153 /* Read debug info of a prototype. */
    154 static void bcread_dbg(LexState *ls, GCproto *pt, MSize sizedbg)
    155 {
    156   void *lineinfo = (void *)proto_lineinfo(pt);
    157   bcread_block(ls, lineinfo, sizedbg);
    158   /* Swap lineinfo if the endianess differs. */
    159   if (bcread_swap(ls) && pt->numline >= 256) {
    160     MSize i, n = pt->sizebc-1;
    161     if (pt->numline < 65536) {
    162       uint16_t *p = (uint16_t *)lineinfo;
    163       for (i = 0; i < n; i++) p[i] = (uint16_t)((p[i] >> 8)|(p[i] << 8));
    164     } else {
    165       uint32_t *p = (uint32_t *)lineinfo;
    166       for (i = 0; i < n; i++) p[i] = lj_bswap(p[i]);
    167     }
    168   }
    169 }
    170 
    171 /* Find pointer to varinfo. */
    172 static const void *bcread_varinfo(GCproto *pt)
    173 {
    174   const uint8_t *p = proto_uvinfo(pt);
    175   MSize n = pt->sizeuv;
    176   if (n) while (*p++ || --n) ;
    177   return p;
    178 }
    179 
    180 /* Read a single constant key/value of a template table. */
    181 static void bcread_ktabk(LexState *ls, TValue *o)
    182 {
    183   MSize tp = bcread_uleb128(ls);
    184   if (tp >= BCDUMP_KTAB_STR) {
    185     MSize len = tp - BCDUMP_KTAB_STR;
    186     const char *p = (const char *)bcread_mem(ls, len);
    187     setstrV(ls->L, o, lj_str_new(ls->L, p, len));
    188   } else if (tp == BCDUMP_KTAB_INT) {
    189     setintV(o, (int32_t)bcread_uleb128(ls));
    190   } else if (tp == BCDUMP_KTAB_NUM) {
    191     o->u32.lo = bcread_uleb128(ls);
    192     o->u32.hi = bcread_uleb128(ls);
    193   } else {
    194     lua_assert(tp <= BCDUMP_KTAB_TRUE);
    195     setpriV(o, ~tp);
    196   }
    197 }
    198 
    199 /* Read a template table. */
    200 static GCtab *bcread_ktab(LexState *ls)
    201 {
    202   MSize narray = bcread_uleb128(ls);
    203   MSize nhash = bcread_uleb128(ls);
    204   GCtab *t = lj_tab_new(ls->L, narray, hsize2hbits(nhash));
    205   if (narray) {  /* Read array entries. */
    206     MSize i;
    207     TValue *o = tvref(t->array);
    208     for (i = 0; i < narray; i++, o++)
    209       bcread_ktabk(ls, o);
    210   }
    211   if (nhash) {  /* Read hash entries. */
    212     MSize i;
    213     for (i = 0; i < nhash; i++) {
    214       TValue key;
    215       bcread_ktabk(ls, &key);
    216       lua_assert(!tvisnil(&key));
    217       bcread_ktabk(ls, lj_tab_set(ls->L, t, &key));
    218     }
    219   }
    220   return t;
    221 }
    222 
    223 /* Read GC constants of a prototype. */
    224 static void bcread_kgc(LexState *ls, GCproto *pt, MSize sizekgc)
    225 {
    226   MSize i;
    227   GCRef *kr = mref(pt->k, GCRef) - (ptrdiff_t)sizekgc;
    228   for (i = 0; i < sizekgc; i++, kr++) {
    229     MSize tp = bcread_uleb128(ls);
    230     if (tp >= BCDUMP_KGC_STR) {
    231       MSize len = tp - BCDUMP_KGC_STR;
    232       const char *p = (const char *)bcread_mem(ls, len);
    233       setgcref(*kr, obj2gco(lj_str_new(ls->L, p, len)));
    234     } else if (tp == BCDUMP_KGC_TAB) {
    235       setgcref(*kr, obj2gco(bcread_ktab(ls)));
    236 #if LJ_HASFFI
    237     } else if (tp != BCDUMP_KGC_CHILD) {
    238       CTypeID id = tp == BCDUMP_KGC_COMPLEX ? CTID_COMPLEX_DOUBLE :
    239 		   tp == BCDUMP_KGC_I64 ? CTID_INT64 : CTID_UINT64;
    240       CTSize sz = tp == BCDUMP_KGC_COMPLEX ? 16 : 8;
    241       GCcdata *cd = lj_cdata_new_(ls->L, id, sz);
    242       TValue *p = (TValue *)cdataptr(cd);
    243       setgcref(*kr, obj2gco(cd));
    244       p[0].u32.lo = bcread_uleb128(ls);
    245       p[0].u32.hi = bcread_uleb128(ls);
    246       if (tp == BCDUMP_KGC_COMPLEX) {
    247 	p[1].u32.lo = bcread_uleb128(ls);
    248 	p[1].u32.hi = bcread_uleb128(ls);
    249       }
    250 #endif
    251     } else {
    252       lua_State *L = ls->L;
    253       lua_assert(tp == BCDUMP_KGC_CHILD);
    254       if (L->top <= bcread_oldtop(L, ls))  /* Stack underflow? */
    255 	bcread_error(ls, LJ_ERR_BCBAD);
    256       L->top--;
    257       setgcref(*kr, obj2gco(protoV(L->top)));
    258     }
    259   }
    260 }
    261 
    262 /* Read number constants of a prototype. */
    263 static void bcread_knum(LexState *ls, GCproto *pt, MSize sizekn)
    264 {
    265   MSize i;
    266   TValue *o = mref(pt->k, TValue);
    267   for (i = 0; i < sizekn; i++, o++) {
    268     int isnum = (ls->p[0] & 1);
    269     uint32_t lo = bcread_uleb128_33(ls);
    270     if (isnum) {
    271       o->u32.lo = lo;
    272       o->u32.hi = bcread_uleb128(ls);
    273     } else {
    274       setintV(o, lo);
    275     }
    276   }
    277 }
    278 
    279 /* Read bytecode instructions. */
    280 static void bcread_bytecode(LexState *ls, GCproto *pt, MSize sizebc)
    281 {
    282   BCIns *bc = proto_bc(pt);
    283   bc[0] = BCINS_AD((pt->flags & PROTO_VARARG) ? BC_FUNCV : BC_FUNCF,
    284 		   pt->framesize, 0);
    285   bcread_block(ls, bc+1, (sizebc-1)*(MSize)sizeof(BCIns));
    286   /* Swap bytecode instructions if the endianess differs. */
    287   if (bcread_swap(ls)) {
    288     MSize i;
    289     for (i = 1; i < sizebc; i++) bc[i] = lj_bswap(bc[i]);
    290   }
    291 }
    292 
    293 /* Read upvalue refs. */
    294 static void bcread_uv(LexState *ls, GCproto *pt, MSize sizeuv)
    295 {
    296   if (sizeuv) {
    297     uint16_t *uv = proto_uv(pt);
    298     bcread_block(ls, uv, sizeuv*2);
    299     /* Swap upvalue refs if the endianess differs. */
    300     if (bcread_swap(ls)) {
    301       MSize i;
    302       for (i = 0; i < sizeuv; i++)
    303 	uv[i] = (uint16_t)((uv[i] >> 8)|(uv[i] << 8));
    304     }
    305   }
    306 }
    307 
    308 /* Read a prototype. */
    309 GCproto *lj_bcread_proto(LexState *ls)
    310 {
    311   GCproto *pt;
    312   MSize framesize, numparams, flags, sizeuv, sizekgc, sizekn, sizebc, sizept;
    313   MSize ofsk, ofsuv, ofsdbg;
    314   MSize sizedbg = 0;
    315   BCLine firstline = 0, numline = 0;
    316 
    317   /* Read prototype header. */
    318   flags = bcread_byte(ls);
    319   numparams = bcread_byte(ls);
    320   framesize = bcread_byte(ls);
    321   sizeuv = bcread_byte(ls);
    322   sizekgc = bcread_uleb128(ls);
    323   sizekn = bcread_uleb128(ls);
    324   sizebc = bcread_uleb128(ls) + 1;
    325   if (!(bcread_flags(ls) & BCDUMP_F_STRIP)) {
    326     sizedbg = bcread_uleb128(ls);
    327     if (sizedbg) {
    328       firstline = bcread_uleb128(ls);
    329       numline = bcread_uleb128(ls);
    330     }
    331   }
    332 
    333   /* Calculate total size of prototype including all colocated arrays. */
    334   sizept = (MSize)sizeof(GCproto) +
    335 	   sizebc*(MSize)sizeof(BCIns) +
    336 	   sizekgc*(MSize)sizeof(GCRef);
    337   sizept = (sizept + (MSize)sizeof(TValue)-1) & ~((MSize)sizeof(TValue)-1);
    338   ofsk = sizept; sizept += sizekn*(MSize)sizeof(TValue);
    339   ofsuv = sizept; sizept += ((sizeuv+1)&~1)*2;
    340   ofsdbg = sizept; sizept += sizedbg;
    341 
    342   /* Allocate prototype object and initialize its fields. */
    343   pt = (GCproto *)lj_mem_newgco(ls->L, (MSize)sizept);
    344   pt->gct = ~LJ_TPROTO;
    345   pt->numparams = (uint8_t)numparams;
    346   pt->framesize = (uint8_t)framesize;
    347   pt->sizebc = sizebc;
    348   setmref(pt->k, (char *)pt + ofsk);
    349   setmref(pt->uv, (char *)pt + ofsuv);
    350   pt->sizekgc = 0;  /* Set to zero until fully initialized. */
    351   pt->sizekn = sizekn;
    352   pt->sizept = sizept;
    353   pt->sizeuv = (uint8_t)sizeuv;
    354   pt->flags = (uint8_t)flags;
    355   pt->trace = 0;
    356   setgcref(pt->chunkname, obj2gco(ls->chunkname));
    357 
    358   /* Close potentially uninitialized gap between bc and kgc. */
    359   *(uint32_t *)((char *)pt + ofsk - sizeof(GCRef)*(sizekgc+1)) = 0;
    360 
    361   /* Read bytecode instructions and upvalue refs. */
    362   bcread_bytecode(ls, pt, sizebc);
    363   bcread_uv(ls, pt, sizeuv);
    364 
    365   /* Read constants. */
    366   bcread_kgc(ls, pt, sizekgc);
    367   pt->sizekgc = sizekgc;
    368   bcread_knum(ls, pt, sizekn);
    369 
    370   /* Read and initialize debug info. */
    371   pt->firstline = firstline;
    372   pt->numline = numline;
    373   if (sizedbg) {
    374     MSize sizeli = (sizebc-1) << (numline < 256 ? 0 : numline < 65536 ? 1 : 2);
    375     setmref(pt->lineinfo, (char *)pt + ofsdbg);
    376     setmref(pt->uvinfo, (char *)pt + ofsdbg + sizeli);
    377     bcread_dbg(ls, pt, sizedbg);
    378     setmref(pt->varinfo, bcread_varinfo(pt));
    379   } else {
    380     setmref(pt->lineinfo, NULL);
    381     setmref(pt->uvinfo, NULL);
    382     setmref(pt->varinfo, NULL);
    383   }
    384   return pt;
    385 }
    386 
    387 /* Read and check header of bytecode dump. */
    388 static int bcread_header(LexState *ls)
    389 {
    390   uint32_t flags;
    391   bcread_want(ls, 3+5+5);
    392   if (bcread_byte(ls) != BCDUMP_HEAD2 ||
    393       bcread_byte(ls) != BCDUMP_HEAD3 ||
    394       bcread_byte(ls) != BCDUMP_VERSION) return 0;
    395   bcread_flags(ls) = flags = bcread_uleb128(ls);
    396   if ((flags & ~(BCDUMP_F_KNOWN)) != 0) return 0;
    397   if ((flags & BCDUMP_F_FR2) != LJ_FR2*BCDUMP_F_FR2) return 0;
    398   if ((flags & BCDUMP_F_FFI)) {
    399 #if LJ_HASFFI
    400     lua_State *L = ls->L;
    401     if (!ctype_ctsG(G(L))) {
    402       ptrdiff_t oldtop = savestack(L, L->top);
    403       luaopen_ffi(L);  /* Load FFI library on-demand. */
    404       L->top = restorestack(L, oldtop);
    405     }
    406 #else
    407     return 0;
    408 #endif
    409   }
    410   if ((flags & BCDUMP_F_STRIP)) {
    411     ls->chunkname = lj_str_newz(ls->L, ls->chunkarg);
    412   } else {
    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);
    416   }
    417   return 1;  /* Ok. */
    418 }
    419 
    420 /* Read a bytecode dump. */
    421 GCproto *lj_bcread(LexState *ls)
    422 {
    423   lua_State *L = ls->L;
    424   lua_assert(ls->c == BCDUMP_HEAD1);
    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. */
    431     GCproto *pt;
    432     MSize len;
    433     const char *startp;
    434     /* Read length. */
    435     if (ls->p < ls->pe && ls->p[0] == 0) {  /* Shortcut EOF. */
    436       ls->p++;
    437       break;
    438     }
    439     bcread_want(ls, 5);
    440     len = bcread_uleb128(ls);
    441     if (!len) break;  /* EOF */
    442     bcread_need(ls, len);
    443     startp = ls->p;
    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);
    448     incr_top(L);
    449   }
    450   if ((int32_t)(2*(uint32_t)(ls->pe - ls->p)) > 0 ||
    451       L->top-1 != bcread_oldtop(L, ls))
    452     bcread_error(ls, LJ_ERR_BCBAD);
    453   /* Pop off last prototype. */
    454   L->top--;
    455   return protoV(L->top);
    456 }
    457