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_crecord.c (60289B)


      1 /*
      2 ** Trace recorder for C data operations.
      3 ** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h
      4 **
      5 ** Minor FFI API extensions
      6 ** Copyright (C) 2014 Karel Tuma
      7 */
      8 
      9 #define lj_ffrecord_c
     10 #define LUA_CORE
     11 
     12 #include "lj_obj.h"
     13 
     14 #if LJ_HASJIT && LJ_HASFFI
     15 
     16 #include "lj_err.h"
     17 #include "lj_tab.h"
     18 #include "lj_frame.h"
     19 #include "lj_ctype.h"
     20 #include "lj_cdata.h"
     21 #include "lj_cparse.h"
     22 #include "lj_cconv.h"
     23 #include "lj_carith.h"
     24 #include "lj_clib.h"
     25 #include "lj_ccall.h"
     26 #include "lj_ff.h"
     27 #include "lj_ir.h"
     28 #include "lj_jit.h"
     29 #include "lj_ircall.h"
     30 #include "lj_iropt.h"
     31 #include "lj_trace.h"
     32 #include "lj_record.h"
     33 #include "lj_ffrecord.h"
     34 #include "lj_snap.h"
     35 #include "lj_crecord.h"
     36 #include "lj_dispatch.h"
     37 #include "lj_strfmt.h"
     38 
     39 /* Some local macros to save typing. Undef'd at the end. */
     40 #define IR(ref)			(&J->cur.ir[(ref)])
     41 
     42 /* Pass IR on to next optimization in chain (FOLD). */
     43 #define emitir(ot, a, b)	(lj_ir_set(J, (ot), (a), (b)), lj_opt_fold(J))
     44 
     45 #define emitconv(a, dt, st, flags) \
     46   emitir(IRT(IR_CONV, (dt)), (a), (st)|((dt) << 5)|(flags))
     47 
     48 /* -- C type checks ------------------------------------------------------- */
     49 
     50 static GCcdata *argv2cdata(jit_State *J, TRef tr, cTValue *o)
     51 {
     52   GCcdata *cd;
     53   TRef trtypeid;
     54   if (!tref_iscdata(tr))
     55     lj_trace_err(J, LJ_TRERR_BADTYPE);
     56   cd = cdataV(o);
     57   /* Specialize to the CTypeID. */
     58   trtypeid = emitir(IRT(IR_FLOAD, IRT_U16), tr, IRFL_CDATA_CTYPEID);
     59   emitir(IRTG(IR_EQ, IRT_INT), trtypeid, lj_ir_kint(J, (int32_t)cd->ctypeid));
     60   return cd;
     61 }
     62 
     63 /* Specialize to the CTypeID held by a cdata constructor. */
     64 static CTypeID crec_constructor(jit_State *J, GCcdata *cd, TRef tr)
     65 {
     66   CTypeID id;
     67   lua_assert(tref_iscdata(tr) && cd->ctypeid == CTID_CTYPEID);
     68   id = *(CTypeID *)cdataptr(cd);
     69   tr = emitir(IRT(IR_FLOAD, IRT_INT), tr, IRFL_CDATA_INT);
     70   emitir(IRTG(IR_EQ, IRT_INT), tr, lj_ir_kint(J, (int32_t)id));
     71   return id;
     72 }
     73 
     74 static CTypeID argv2ctype(jit_State *J, TRef tr, cTValue *o)
     75 {
     76   if (tref_isstr(tr)) {
     77     GCstr *s = strV(o);
     78     CPState cp;
     79     CTypeID oldtop;
     80     /* Specialize to the string containing the C type declaration. */
     81     emitir(IRTG(IR_EQ, IRT_STR), tr, lj_ir_kstr(J, s));
     82     cp.L = J->L;
     83     cp.cts = ctype_ctsG(J2G(J));
     84     oldtop = cp.cts->top;
     85     cp.srcname = strdata(s);
     86     cp.p = strdata(s);
     87     cp.param = NULL;
     88     cp.mode = CPARSE_MODE_ABSTRACT|CPARSE_MODE_NOIMPLICIT;
     89     if (lj_cparse(&cp) || cp.cts->top > oldtop)  /* Avoid new struct defs. */
     90       lj_trace_err(J, LJ_TRERR_BADTYPE);
     91     return cp.val.id;
     92   } else {
     93     GCcdata *cd = argv2cdata(J, tr, o);
     94     return cd->ctypeid == CTID_CTYPEID ? crec_constructor(J, cd, tr) :
     95 					cd->ctypeid;
     96   }
     97 }
     98 
     99 /* Convert CType to IRType (if possible). */
    100 static IRType crec_ct2irt(CTState *cts, CType *ct)
    101 {
    102   if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
    103   if (LJ_LIKELY(ctype_isnum(ct->info))) {
    104     if ((ct->info & CTF_FP)) {
    105       if (ct->size == sizeof(double))
    106 	return IRT_NUM;
    107       else if (ct->size == sizeof(float))
    108 	return IRT_FLOAT;
    109     } else {
    110       uint32_t b = lj_fls(ct->size);
    111       if (b <= 3)
    112 	return IRT_I8 + 2*b + ((ct->info & CTF_UNSIGNED) ? 1 : 0);
    113     }
    114   } else if (ctype_isptr(ct->info)) {
    115     return (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32;
    116   } else if (ctype_iscomplex(ct->info)) {
    117     if (ct->size == 2*sizeof(double))
    118       return IRT_NUM;
    119     else if (ct->size == 2*sizeof(float))
    120       return IRT_FLOAT;
    121   }
    122   return IRT_CDATA;
    123 }
    124 
    125 /* -- Optimized memory fill and copy -------------------------------------- */
    126 
    127 /* Maximum length and unroll of inlined copy/fill. */
    128 #define CREC_COPY_MAXUNROLL		16
    129 #define CREC_COPY_MAXLEN		128
    130 
    131 #define CREC_FILL_MAXUNROLL		16
    132 
    133 /* Number of windowed registers used for optimized memory copy. */
    134 #if LJ_TARGET_X86
    135 #define CREC_COPY_REGWIN		2
    136 #elif LJ_TARGET_PPC || LJ_TARGET_MIPS
    137 #define CREC_COPY_REGWIN		8
    138 #else
    139 #define CREC_COPY_REGWIN		4
    140 #endif
    141 
    142 /* List of memory offsets for copy/fill. */
    143 typedef struct CRecMemList {
    144   CTSize ofs;		/* Offset in bytes. */
    145   IRType tp;		/* Type of load/store. */
    146   TRef trofs;		/* TRef of interned offset. */
    147   TRef trval;		/* TRef of load value. */
    148 } CRecMemList;
    149 
    150 /* Generate copy list for element-wise struct copy. */
    151 static MSize crec_copy_struct(CRecMemList *ml, CTState *cts, CType *ct)
    152 {
    153   CTypeID fid = ct->sib;
    154   MSize mlp = 0;
    155   while (fid) {
    156     CType *df = ctype_get(cts, fid);
    157     fid = df->sib;
    158     if (ctype_isfield(df->info)) {
    159       CType *cct;
    160       IRType tp;
    161       if (!gcref(df->name)) continue;  /* Ignore unnamed fields. */
    162       cct = ctype_rawchild(cts, df);  /* Field type. */
    163       tp = crec_ct2irt(cts, cct);
    164       if (tp == IRT_CDATA) return 0;  /* NYI: aggregates. */
    165       if (mlp >= CREC_COPY_MAXUNROLL) return 0;
    166       ml[mlp].ofs = df->size;
    167       ml[mlp].tp = tp;
    168       mlp++;
    169       if (ctype_iscomplex(cct->info)) {
    170 	if (mlp >= CREC_COPY_MAXUNROLL) return 0;
    171 	ml[mlp].ofs = df->size + (cct->size >> 1);
    172 	ml[mlp].tp = tp;
    173 	mlp++;
    174       }
    175     } else if (!ctype_isconstval(df->info)) {
    176       /* NYI: bitfields and sub-structures. */
    177       return 0;
    178     }
    179   }
    180   return mlp;
    181 }
    182 
    183 /* Generate unrolled copy list, from highest to lowest step size/alignment. */
    184 static MSize crec_copy_unroll(CRecMemList *ml, CTSize len, CTSize step,
    185 			      IRType tp)
    186 {
    187   CTSize ofs = 0;
    188   MSize mlp = 0;
    189   if (tp == IRT_CDATA) tp = IRT_U8 + 2*lj_fls(step);
    190   do {
    191     while (ofs + step <= len) {
    192       if (mlp >= CREC_COPY_MAXUNROLL) return 0;
    193       ml[mlp].ofs = ofs;
    194       ml[mlp].tp = tp;
    195       mlp++;
    196       ofs += step;
    197     }
    198     step >>= 1;
    199     tp -= 2;
    200   } while (ofs < len);
    201   return mlp;
    202 }
    203 
    204 /*
    205 ** Emit copy list with windowed loads/stores.
    206 ** LJ_TARGET_UNALIGNED: may emit unaligned loads/stores (not marked as such).
    207 */
    208 static void crec_copy_emit(jit_State *J, CRecMemList *ml, MSize mlp,
    209 			   TRef trdst, TRef trsrc)
    210 {
    211   MSize i, j, rwin = 0;
    212   for (i = 0, j = 0; i < mlp; ) {
    213     TRef trofs = lj_ir_kintp(J, ml[i].ofs);
    214     TRef trsptr = emitir(IRT(IR_ADD, IRT_PTR), trsrc, trofs);
    215     ml[i].trval = emitir(IRT(IR_XLOAD, ml[i].tp), trsptr, 0);
    216     ml[i].trofs = trofs;
    217     i++;
    218     rwin += (LJ_SOFTFP && ml[i].tp == IRT_NUM) ? 2 : 1;
    219     if (rwin >= CREC_COPY_REGWIN || i >= mlp) {  /* Flush buffered stores. */
    220       rwin = 0;
    221       for ( ; j < i; j++) {
    222 	TRef trdptr = emitir(IRT(IR_ADD, IRT_PTR), trdst, ml[j].trofs);
    223 	emitir(IRT(IR_XSTORE, ml[j].tp), trdptr, ml[j].trval);
    224       }
    225     }
    226   }
    227 }
    228 
    229 /* Optimized memory copy. */
    230 static void crec_copy(jit_State *J, TRef trdst, TRef trsrc, TRef trlen,
    231 		      CType *ct)
    232 {
    233   if (tref_isk(trlen)) {  /* Length must be constant. */
    234     CRecMemList ml[CREC_COPY_MAXUNROLL];
    235     MSize mlp = 0;
    236     CTSize step = 1, len = (CTSize)IR(tref_ref(trlen))->i;
    237     IRType tp = IRT_CDATA;
    238     int needxbar = 0;
    239     if (len == 0) return;  /* Shortcut. */
    240     if (len > CREC_COPY_MAXLEN) goto fallback;
    241     if (ct) {
    242       CTState *cts = ctype_ctsG(J2G(J));
    243       lua_assert(ctype_isarray(ct->info) || ctype_isstruct(ct->info));
    244       if (ctype_isarray(ct->info)) {
    245 	CType *cct = ctype_rawchild(cts, ct);
    246 	tp = crec_ct2irt(cts, cct);
    247 	if (tp == IRT_CDATA) goto rawcopy;
    248 	step = lj_ir_type_size[tp];
    249 	lua_assert((len & (step-1)) == 0);
    250       } else if ((ct->info & CTF_UNION)) {
    251 	step = (1u << ctype_align(ct->info));
    252 	goto rawcopy;
    253       } else {
    254 	mlp = crec_copy_struct(ml, cts, ct);
    255 	goto emitcopy;
    256       }
    257     } else {
    258     rawcopy:
    259       needxbar = 1;
    260       if (LJ_TARGET_UNALIGNED || step >= CTSIZE_PTR)
    261 	step = CTSIZE_PTR;
    262     }
    263     mlp = crec_copy_unroll(ml, len, step, tp);
    264   emitcopy:
    265     if (mlp) {
    266       crec_copy_emit(J, ml, mlp, trdst, trsrc);
    267       if (needxbar)
    268 	emitir(IRT(IR_XBAR, IRT_NIL), 0, 0);
    269       return;
    270     }
    271   }
    272 fallback:
    273   /* Call memcpy. Always needs a barrier to disable alias analysis. */
    274   lj_ir_call(J, IRCALL_memcpy, trdst, trsrc, trlen);
    275   emitir(IRT(IR_XBAR, IRT_NIL), 0, 0);
    276 }
    277 
    278 /* Generate unrolled fill list, from highest to lowest step size/alignment. */
    279 static MSize crec_fill_unroll(CRecMemList *ml, CTSize len, CTSize step)
    280 {
    281   CTSize ofs = 0;
    282   MSize mlp = 0;
    283   IRType tp = IRT_U8 + 2*lj_fls(step);
    284   do {
    285     while (ofs + step <= len) {
    286       if (mlp >= CREC_COPY_MAXUNROLL) return 0;
    287       ml[mlp].ofs = ofs;
    288       ml[mlp].tp = tp;
    289       mlp++;
    290       ofs += step;
    291     }
    292     step >>= 1;
    293     tp -= 2;
    294   } while (ofs < len);
    295   return mlp;
    296 }
    297 
    298 /*
    299 ** Emit stores for fill list.
    300 ** LJ_TARGET_UNALIGNED: may emit unaligned stores (not marked as such).
    301 */
    302 static void crec_fill_emit(jit_State *J, CRecMemList *ml, MSize mlp,
    303 			   TRef trdst, TRef trfill)
    304 {
    305   MSize i;
    306   for (i = 0; i < mlp; i++) {
    307     TRef trofs = lj_ir_kintp(J, ml[i].ofs);
    308     TRef trdptr = emitir(IRT(IR_ADD, IRT_PTR), trdst, trofs);
    309     emitir(IRT(IR_XSTORE, ml[i].tp), trdptr, trfill);
    310   }
    311 }
    312 
    313 /* Optimized memory fill. */
    314 static void crec_fill(jit_State *J, TRef trdst, TRef trlen, TRef trfill,
    315 		      CTSize step)
    316 {
    317   if (tref_isk(trlen)) {  /* Length must be constant. */
    318     CRecMemList ml[CREC_FILL_MAXUNROLL];
    319     MSize mlp;
    320     CTSize len = (CTSize)IR(tref_ref(trlen))->i;
    321     if (len == 0) return;  /* Shortcut. */
    322     if (LJ_TARGET_UNALIGNED || step >= CTSIZE_PTR)
    323       step = CTSIZE_PTR;
    324     if (step * CREC_FILL_MAXUNROLL < len) goto fallback;
    325     mlp = crec_fill_unroll(ml, len, step);
    326     if (!mlp) goto fallback;
    327     if (tref_isk(trfill) || ml[0].tp != IRT_U8)
    328       trfill = emitconv(trfill, IRT_INT, IRT_U8, 0);
    329     if (ml[0].tp != IRT_U8) {  /* Scatter U8 to U16/U32/U64. */
    330       if (CTSIZE_PTR == 8 && ml[0].tp == IRT_U64) {
    331 	if (tref_isk(trfill))  /* Pointless on x64 with zero-extended regs. */
    332 	  trfill = emitconv(trfill, IRT_U64, IRT_U32, 0);
    333 	trfill = emitir(IRT(IR_MUL, IRT_U64), trfill,
    334 			lj_ir_kint64(J, U64x(01010101,01010101)));
    335       } else {
    336 	trfill = emitir(IRTI(IR_MUL), trfill,
    337 		   lj_ir_kint(J, ml[0].tp == IRT_U16 ? 0x0101 : 0x01010101));
    338       }
    339     }
    340     crec_fill_emit(J, ml, mlp, trdst, trfill);
    341   } else {
    342 fallback:
    343     /* Call memset. Always needs a barrier to disable alias analysis. */
    344     lj_ir_call(J, IRCALL_memset, trdst, trfill, trlen);  /* Note: arg order! */
    345   }
    346   emitir(IRT(IR_XBAR, IRT_NIL), 0, 0);
    347 }
    348 
    349 /* -- Convert C type to C type -------------------------------------------- */
    350 
    351 /*
    352 ** This code mirrors the code in lj_cconv.c. It performs the same steps
    353 ** for the trace recorder that lj_cconv.c does for the interpreter.
    354 **
    355 ** One major difference is that we can get away with much fewer checks
    356 ** here. E.g. checks for casts, constness or correct types can often be
    357 ** omitted, even if they might fail. The interpreter subsequently throws
    358 ** an error, which aborts the trace.
    359 **
    360 ** All operations are specialized to their C types, so the on-trace
    361 ** outcome must be the same as the outcome in the interpreter. If the
    362 ** interpreter doesn't throw an error, then the trace is correct, too.
    363 ** Care must be taken not to generate invalid (temporary) IR or to
    364 ** trigger asserts.
    365 */
    366 
    367 /* Determine whether a passed number or cdata number is non-zero. */
    368 static int crec_isnonzero(CType *s, void *p)
    369 {
    370   if (p == (void *)0)
    371     return 0;
    372   if (p == (void *)1)
    373     return 1;
    374   if ((s->info & CTF_FP)) {
    375     if (s->size == sizeof(float))
    376       return (*(float *)p != 0);
    377     else
    378       return (*(double *)p != 0);
    379   } else {
    380     if (s->size == 1)
    381       return (*(uint8_t *)p != 0);
    382     else if (s->size == 2)
    383       return (*(uint16_t *)p != 0);
    384     else if (s->size == 4)
    385       return (*(uint32_t *)p != 0);
    386     else
    387       return (*(uint64_t *)p != 0);
    388   }
    389 }
    390 
    391 static TRef crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp,
    392 		       void *svisnz)
    393 {
    394   IRType dt = crec_ct2irt(ctype_ctsG(J2G(J)), d);
    395   IRType st = crec_ct2irt(ctype_ctsG(J2G(J)), s);
    396   CTSize dsize = d->size, ssize = s->size;
    397   CTInfo dinfo = d->info, sinfo = s->info;
    398 
    399   if (ctype_type(dinfo) > CT_MAYCONVERT || ctype_type(sinfo) > CT_MAYCONVERT)
    400     goto err_conv;
    401 
    402   /*
    403   ** Note: Unlike lj_cconv_ct_ct(), sp holds the _value_ of pointers and
    404   ** numbers up to 8 bytes. Otherwise sp holds a pointer.
    405   */
    406 
    407   switch (cconv_idx2(dinfo, sinfo)) {
    408   /* Destination is a bool. */
    409   case CCX(B, B):
    410     goto xstore;  /* Source operand is already normalized. */
    411   case CCX(B, I):
    412   case CCX(B, F):
    413     if (st != IRT_CDATA) {
    414       /* Specialize to the result of a comparison against 0. */
    415       TRef zero = (st == IRT_NUM  || st == IRT_FLOAT) ? lj_ir_knum(J, 0) :
    416 		  (st == IRT_I64 || st == IRT_U64) ? lj_ir_kint64(J, 0) :
    417 		  lj_ir_kint(J, 0);
    418       int isnz = crec_isnonzero(s, svisnz);
    419       emitir(IRTG(isnz ? IR_NE : IR_EQ, st), sp, zero);
    420       sp = lj_ir_kint(J, isnz);
    421       goto xstore;
    422     }
    423     goto err_nyi;
    424 
    425   /* Destination is an integer. */
    426   case CCX(I, B):
    427   case CCX(I, I):
    428   conv_I_I:
    429     if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi;
    430     /* Extend 32 to 64 bit integer. */
    431     if (dsize == 8 && ssize < 8 && !(LJ_64 && (sinfo & CTF_UNSIGNED)))
    432       sp = emitconv(sp, dt, ssize < 4 ? IRT_INT : st,
    433 		    (sinfo & CTF_UNSIGNED) ? 0 : IRCONV_SEXT);
    434     else if (dsize < 8 && ssize == 8)  /* Truncate from 64 bit integer. */
    435       sp = emitconv(sp, dsize < 4 ? IRT_INT : dt, st, 0);
    436     else if (st == IRT_INT)
    437       sp = lj_opt_narrow_toint(J, sp);
    438   xstore:
    439     if (dt == IRT_I64 || dt == IRT_U64) lj_needsplit(J);
    440     if (dp == 0) return sp;
    441     emitir(IRT(IR_XSTORE, dt), dp, sp);
    442     break;
    443   case CCX(I, C):
    444     sp = emitir(IRT(IR_XLOAD, st), sp, 0);  /* Load re. */
    445     /* fallthrough */
    446   case CCX(I, F):
    447     if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi;
    448     sp = emitconv(sp, dsize < 4 ? IRT_INT : dt, st, IRCONV_ANY);
    449     goto xstore;
    450   case CCX(I, P):
    451   case CCX(I, A):
    452     sinfo = CTINFO(CT_NUM, CTF_UNSIGNED);
    453     ssize = CTSIZE_PTR;
    454     st = IRT_UINTP;
    455     if (((dsize ^ ssize) & 8) == 0) {  /* Must insert no-op type conversion. */
    456       sp = emitconv(sp, dsize < 4 ? IRT_INT : dt, IRT_PTR, 0);
    457       goto xstore;
    458     }
    459     goto conv_I_I;
    460 
    461   /* Destination is a floating-point number. */
    462   case CCX(F, B):
    463   case CCX(F, I):
    464   conv_F_I:
    465     if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi;
    466     sp = emitconv(sp, dt, ssize < 4 ? IRT_INT : st, 0);
    467     goto xstore;
    468   case CCX(F, C):
    469     sp = emitir(IRT(IR_XLOAD, st), sp, 0);  /* Load re. */
    470     /* fallthrough */
    471   case CCX(F, F):
    472   conv_F_F:
    473     if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi;
    474     if (dt != st) sp = emitconv(sp, dt, st, 0);
    475     goto xstore;
    476 
    477   /* Destination is a complex number. */
    478   case CCX(C, I):
    479   case CCX(C, F):
    480     {  /* Clear im. */
    481       TRef ptr = emitir(IRT(IR_ADD, IRT_PTR), dp, lj_ir_kintp(J, (dsize >> 1)));
    482       emitir(IRT(IR_XSTORE, dt), ptr, lj_ir_knum(J, 0));
    483     }
    484     /* Convert to re. */
    485     if ((sinfo & CTF_FP)) goto conv_F_F; else goto conv_F_I;
    486 
    487   case CCX(C, C):
    488     if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi;
    489     {
    490       TRef re, im, ptr;
    491       re = emitir(IRT(IR_XLOAD, st), sp, 0);
    492       ptr = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, (ssize >> 1)));
    493       im = emitir(IRT(IR_XLOAD, st), ptr, 0);
    494       if (dt != st) {
    495 	re = emitconv(re, dt, st, 0);
    496 	im = emitconv(im, dt, st, 0);
    497       }
    498       emitir(IRT(IR_XSTORE, dt), dp, re);
    499       ptr = emitir(IRT(IR_ADD, IRT_PTR), dp, lj_ir_kintp(J, (dsize >> 1)));
    500       emitir(IRT(IR_XSTORE, dt), ptr, im);
    501     }
    502     break;
    503 
    504   /* Destination is a vector. */
    505   case CCX(V, I):
    506   case CCX(V, F):
    507   case CCX(V, C):
    508   case CCX(V, V):
    509     goto err_nyi;
    510 
    511   /* Destination is a pointer. */
    512   case CCX(P, P):
    513   case CCX(P, A):
    514   case CCX(P, S):
    515     /* There are only 32 bit pointers/addresses on 32 bit machines.
    516     ** Also ok on x64, since all 32 bit ops clear the upper part of the reg.
    517     */
    518     goto xstore;
    519   case CCX(P, I):
    520     if (st == IRT_CDATA) goto err_nyi;
    521     if (!LJ_64 && ssize == 8)  /* Truncate from 64 bit integer. */
    522       sp = emitconv(sp, IRT_U32, st, 0);
    523     goto xstore;
    524   case CCX(P, F):
    525     if (st == IRT_CDATA) goto err_nyi;
    526     /* The signed conversion is cheaper. x64 really has 47 bit pointers. */
    527     sp = emitconv(sp, (LJ_64 && dsize == 8) ? IRT_I64 : IRT_U32,
    528 		  st, IRCONV_ANY);
    529     goto xstore;
    530 
    531   /* Destination is an array. */
    532   case CCX(A, A):
    533   /* Destination is a struct/union. */
    534   case CCX(S, S):
    535     if (dp == 0) goto err_conv;
    536     crec_copy(J, dp, sp, lj_ir_kint(J, dsize), d);
    537     break;
    538 
    539   default:
    540   err_conv:
    541   err_nyi:
    542     lj_trace_err(J, LJ_TRERR_NYICONV);
    543     break;
    544   }
    545   return 0;
    546 }
    547 
    548 /* -- Convert C type to TValue (load) ------------------------------------- */
    549 
    550 static TRef crec_tv_ct(jit_State *J, CType *s, CTypeID sid, TRef sp)
    551 {
    552   CTState *cts = ctype_ctsG(J2G(J));
    553   IRType t = crec_ct2irt(cts, s);
    554   CTInfo sinfo = s->info;
    555   if (ctype_isnum(sinfo)) {
    556     TRef tr;
    557     if (t == IRT_CDATA)
    558       goto err_nyi;  /* NYI: copyval of >64 bit integers. */
    559     tr = emitir(IRT(IR_XLOAD, t), sp, 0);
    560     if (t == IRT_FLOAT || t == IRT_U32) {  /* Keep uint32_t/float as numbers. */
    561       return emitconv(tr, IRT_NUM, t, 0);
    562     } else if (t == IRT_I64 || t == IRT_U64) {  /* Box 64 bit integer. */
    563       sp = tr;
    564       lj_needsplit(J);
    565     } else if ((sinfo & CTF_BOOL)) {
    566       /* Assume not equal to zero. Fixup and emit pending guard later. */
    567       lj_ir_set(J, IRTGI(IR_NE), tr, lj_ir_kint(J, 0));
    568       J->postproc = LJ_POST_FIXGUARD;
    569       return TREF_TRUE;
    570     } else {
    571       return tr;
    572     }
    573   } else if (ctype_isptr(sinfo) || ctype_isenum(sinfo)) {
    574     sp = emitir(IRT(IR_XLOAD, t), sp, 0);  /* Box pointers and enums. */
    575   } else if (ctype_isrefarray(sinfo) || ctype_isstruct(sinfo)) {
    576     cts->L = J->L;
    577     sid = lj_ctype_intern(cts, CTINFO_REF(sid), CTSIZE_PTR);  /* Create ref. */
    578   } else if (ctype_iscomplex(sinfo)) {  /* Unbox/box complex. */
    579     ptrdiff_t esz = (ptrdiff_t)(s->size >> 1);
    580     TRef ptr, tr1, tr2, dp;
    581     dp = emitir(IRTG(IR_CNEW, IRT_CDATA), lj_ir_kint(J, sid), TREF_NIL);
    582     tr1 = emitir(IRT(IR_XLOAD, t), sp, 0);
    583     ptr = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, esz));
    584     tr2 = emitir(IRT(IR_XLOAD, t), ptr, 0);
    585     ptr = emitir(IRT(IR_ADD, IRT_PTR), dp, lj_ir_kintp(J, sizeof(GCcdata)));
    586     emitir(IRT(IR_XSTORE, t), ptr, tr1);
    587     ptr = emitir(IRT(IR_ADD, IRT_PTR), dp, lj_ir_kintp(J, sizeof(GCcdata)+esz));
    588     emitir(IRT(IR_XSTORE, t), ptr, tr2);
    589     return dp;
    590   } else {
    591     /* NYI: copyval of vectors. */
    592   err_nyi:
    593     lj_trace_err(J, LJ_TRERR_NYICONV);
    594   }
    595   /* Box pointer, ref, enum or 64 bit integer. */
    596   return emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, sid), sp);
    597 }
    598 
    599 /* -- Convert TValue to C type (store) ------------------------------------ */
    600 
    601 TRef lj_crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, cTValue *sval)
    602 {
    603   CTState *cts = ctype_ctsG(J2G(J));
    604   CTypeID sid = CTID_P_VOID;
    605   void *svisnz = 0;
    606   CType *s;
    607   if (LJ_LIKELY(tref_isinteger(sp))) {
    608     sid = CTID_INT32;
    609     svisnz = (void *)(intptr_t)(tvisint(sval)?(intV(sval)!=0):!tviszero(sval));
    610   } else if (tref_isnum(sp)) {
    611     sid = CTID_DOUBLE;
    612     svisnz = (void *)(intptr_t)(tvisint(sval)?(intV(sval)!=0):!tviszero(sval));
    613   } else if (tref_isbool(sp)) {
    614     sp = lj_ir_kint(J, tref_istrue(sp) ? 1 : 0);
    615     sid = CTID_BOOL;
    616   } else if (tref_isnil(sp)) {
    617     sp = lj_ir_kptr(J, NULL);
    618   } else if (tref_isudata(sp)) {
    619     GCudata *ud = udataV(sval);
    620     if (ud->udtype == UDTYPE_IO_FILE) {
    621       TRef tr = emitir(IRT(IR_FLOAD, IRT_U8), sp, IRFL_UDATA_UDTYPE);
    622       emitir(IRTGI(IR_EQ), tr, lj_ir_kint(J, UDTYPE_IO_FILE));
    623       sp = emitir(IRT(IR_FLOAD, IRT_PTR), sp, IRFL_UDATA_FILE);
    624     } else {
    625       sp = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, sizeof(GCudata)));
    626     }
    627   } else if (tref_isstr(sp)) {
    628     if (ctype_isenum(d->info)) {  /* Match string against enum constant. */
    629       GCstr *str = strV(sval);
    630       CTSize ofs;
    631       CType *cct = lj_ctype_getfield(cts, d, str, &ofs);
    632       /* Specialize to the name of the enum constant. */
    633       emitir(IRTG(IR_EQ, IRT_STR), sp, lj_ir_kstr(J, str));
    634       if (cct && ctype_isconstval(cct->info)) {
    635 	lua_assert(ctype_child(cts, cct)->size == 4);
    636 	svisnz = (void *)(intptr_t)(ofs != 0);
    637 	sp = lj_ir_kint(J, (int32_t)ofs);
    638 	sid = ctype_cid(cct->info);
    639       }  /* else: interpreter will throw. */
    640     } else if (ctype_isrefarray(d->info)) {  /* Copy string to array. */
    641       lj_trace_err(J, LJ_TRERR_BADTYPE);  /* NYI */
    642     } else {  /* Otherwise pass the string data as a const char[]. */
    643       /* Don't use STRREF. It folds with SNEW, which loses the trailing NUL. */
    644       sp = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, sizeof(GCstr)));
    645       sid = CTID_A_CCHAR;
    646     }
    647   } else if (tref_islightud(sp)) {
    648 #if LJ_64
    649     sp = emitir(IRT(IR_BAND, IRT_P64), sp,
    650 		lj_ir_kint64(J, U64x(00007fff,ffffffff)));
    651 #endif
    652   } else {  /* NYI: tref_istab(sp). */
    653     IRType t;
    654     sid = argv2cdata(J, sp, sval)->ctypeid;
    655     s = ctype_raw(cts, sid);
    656     svisnz = cdataptr(cdataV(sval));
    657     if (ctype_isfunc(s->info)) {
    658       sid = lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|sid), CTSIZE_PTR);
    659       s = ctype_get(cts, sid);
    660       t = IRT_PTR;
    661     } else {
    662       t = crec_ct2irt(cts, s);
    663     }
    664     if (ctype_isptr(s->info)) {
    665       sp = emitir(IRT(IR_FLOAD, t), sp, IRFL_CDATA_PTR);
    666       if (ctype_isref(s->info)) {
    667 	svisnz = *(void **)svisnz;
    668 	s = ctype_rawchild(cts, s);
    669 	if (ctype_isenum(s->info)) s = ctype_child(cts, s);
    670 	t = crec_ct2irt(cts, s);
    671       } else {
    672 	goto doconv;
    673       }
    674     } else if (t == IRT_I64 || t == IRT_U64) {
    675       sp = emitir(IRT(IR_FLOAD, t), sp, IRFL_CDATA_INT64);
    676       lj_needsplit(J);
    677       goto doconv;
    678     } else if (t == IRT_INT || t == IRT_U32) {
    679       if (ctype_isenum(s->info)) s = ctype_child(cts, s);
    680       sp = emitir(IRT(IR_FLOAD, t), sp, IRFL_CDATA_INT);
    681       goto doconv;
    682     } else {
    683       sp = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, sizeof(GCcdata)));
    684     }
    685     if (ctype_isnum(s->info) && t != IRT_CDATA)
    686       sp = emitir(IRT(IR_XLOAD, t), sp, 0);  /* Load number value. */
    687     goto doconv;
    688   }
    689   s = ctype_get(cts, sid);
    690 doconv:
    691   if (ctype_isenum(d->info)) d = ctype_child(cts, d);
    692   return crec_ct_ct(J, d, s, dp, sp, svisnz);
    693 }
    694 
    695 /* -- C data metamethods -------------------------------------------------- */
    696 
    697 /* This would be rather difficult in FOLD, so do it here:
    698 ** (base+k)+(idx*sz)+ofs ==> (base+idx*sz)+(ofs+k)
    699 ** (base+(idx+k)*sz)+ofs ==> (base+idx*sz)+(ofs+k*sz)
    700 */
    701 static TRef crec_reassoc_ofs(jit_State *J, TRef tr, ptrdiff_t *ofsp, MSize sz)
    702 {
    703   IRIns *ir = IR(tref_ref(tr));
    704   if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD) && irref_isk(ir->op2) &&
    705       (ir->o == IR_ADD || ir->o == IR_ADDOV || ir->o == IR_SUBOV)) {
    706     IRIns *irk = IR(ir->op2);
    707     ptrdiff_t k;
    708     if (LJ_64 && irk->o == IR_KINT64)
    709       k = (ptrdiff_t)ir_kint64(irk)->u64 * sz;
    710     else
    711       k = (ptrdiff_t)irk->i * sz;
    712     if (ir->o == IR_SUBOV) *ofsp -= k; else *ofsp += k;
    713     tr = ir->op1;  /* Not a TRef, but the caller doesn't care. */
    714   }
    715   return tr;
    716 }
    717 
    718 /* Tailcall to function. */
    719 static void crec_tailcall(jit_State *J, RecordFFData *rd, cTValue *tv)
    720 {
    721   TRef kfunc = lj_ir_kfunc(J, funcV(tv));
    722 #if LJ_FR2
    723   J->base[-2] = kfunc;
    724   J->base[-1] = TREF_FRAME;
    725 #else
    726   J->base[-1] = kfunc | TREF_FRAME;
    727 #endif
    728   rd->nres = -1;  /* Pending tailcall. */
    729 }
    730 
    731 /* Record ctype __index/__newindex metamethods. */
    732 static void crec_index_meta(jit_State *J, CTState *cts, CType *ct,
    733 			    RecordFFData *rd)
    734 {
    735   CTypeID id = ctype_typeid(cts, ct);
    736   cTValue *tv = lj_ctype_meta(cts, id, rd->data ? MM_newindex : MM_index);
    737   if (!tv)
    738     lj_trace_err(J, LJ_TRERR_BADTYPE);
    739   if (tvisfunc(tv)) {
    740     crec_tailcall(J, rd, tv);
    741   } else if (rd->data == 0 && tvistab(tv) && tref_isstr(J->base[1])) {
    742     /* Specialize to result of __index lookup. */
    743     cTValue *o = lj_tab_get(J->L, tabV(tv), &rd->argv[1]);
    744     J->base[0] = lj_record_constify(J, o);
    745     if (!J->base[0])
    746       lj_trace_err(J, LJ_TRERR_BADTYPE);
    747     /* Always specialize to the key. */
    748     emitir(IRTG(IR_EQ, IRT_STR), J->base[1], lj_ir_kstr(J, strV(&rd->argv[1])));
    749   } else {
    750     /* NYI: resolving of non-function metamethods. */
    751     /* NYI: non-string keys for __index table. */
    752     /* NYI: stores to __newindex table. */
    753     lj_trace_err(J, LJ_TRERR_BADTYPE);
    754   }
    755 }
    756 
    757 void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd)
    758 {
    759   TRef idx, ptr = J->base[0];
    760   ptrdiff_t ofs = sizeof(GCcdata);
    761   GCcdata *cd = argv2cdata(J, ptr, &rd->argv[0]);
    762   CTState *cts = ctype_ctsG(J2G(J));
    763   CType *ct = ctype_raw(cts, cd->ctypeid);
    764   CTypeID sid = 0;
    765 
    766   /* Resolve pointer or reference for cdata object. */
    767   if (ctype_isptr(ct->info)) {
    768     IRType t = (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32;
    769     if (ctype_isref(ct->info)) ct = ctype_rawchild(cts, ct);
    770     ptr = emitir(IRT(IR_FLOAD, t), ptr, IRFL_CDATA_PTR);
    771     ofs = 0;
    772     ptr = crec_reassoc_ofs(J, ptr, &ofs, 1);
    773   }
    774 
    775 again:
    776   idx = J->base[1];
    777   if (tref_isnumber(idx)) {
    778     idx = lj_opt_narrow_cindex(J, idx);
    779     if (ctype_ispointer(ct->info)) {
    780       CTSize sz;
    781   integer_key:
    782       if ((ct->info & CTF_COMPLEX))
    783 	idx = emitir(IRT(IR_BAND, IRT_INTP), idx, lj_ir_kintp(J, 1));
    784       sz = lj_ctype_size(cts, (sid = ctype_cid(ct->info)));
    785       idx = crec_reassoc_ofs(J, idx, &ofs, sz);
    786 #if LJ_TARGET_ARM || LJ_TARGET_PPC
    787       /* Hoist base add to allow fusion of index/shift into operands. */
    788       if (LJ_LIKELY(J->flags & JIT_F_OPT_LOOP) && ofs
    789 #if LJ_TARGET_ARM
    790 	  && (sz == 1 || sz == 4)
    791 #endif
    792 	  ) {
    793 	ptr = emitir(IRT(IR_ADD, IRT_PTR), ptr, lj_ir_kintp(J, ofs));
    794 	ofs = 0;
    795       }
    796 #endif
    797       idx = emitir(IRT(IR_MUL, IRT_INTP), idx, lj_ir_kintp(J, sz));
    798       ptr = emitir(IRT(IR_ADD, IRT_PTR), idx, ptr);
    799     }
    800   } else if (tref_iscdata(idx)) {
    801     GCcdata *cdk = cdataV(&rd->argv[1]);
    802     CType *ctk = ctype_raw(cts, cdk->ctypeid);
    803     IRType t = crec_ct2irt(cts, ctk);
    804     if (ctype_ispointer(ct->info) && t >= IRT_I8 && t <= IRT_U64) {
    805       if (ctk->size == 8) {
    806 	idx = emitir(IRT(IR_FLOAD, t), idx, IRFL_CDATA_INT64);
    807       } else if (ctk->size == 4) {
    808 	idx = emitir(IRT(IR_FLOAD, t), idx, IRFL_CDATA_INT);
    809       } else {
    810 	idx = emitir(IRT(IR_ADD, IRT_PTR), idx,
    811 		     lj_ir_kintp(J, sizeof(GCcdata)));
    812 	idx = emitir(IRT(IR_XLOAD, t), idx, 0);
    813       }
    814       if (LJ_64 && ctk->size < sizeof(intptr_t) && !(ctk->info & CTF_UNSIGNED))
    815 	idx = emitconv(idx, IRT_INTP, IRT_INT, IRCONV_SEXT);
    816       if (!LJ_64 && ctk->size > sizeof(intptr_t)) {
    817 	idx = emitconv(idx, IRT_INTP, t, 0);
    818 	lj_needsplit(J);
    819       }
    820       goto integer_key;
    821     }
    822   } else if (tref_isstr(idx)) {
    823     GCstr *name = strV(&rd->argv[1]);
    824     if (cd && cd->ctypeid == CTID_CTYPEID)
    825       ct = ctype_raw(cts, crec_constructor(J, cd, ptr));
    826     if (ctype_isstruct(ct->info)) {
    827       CTSize fofs;
    828       CType *fct;
    829       fct = lj_ctype_getfield(cts, ct, name, &fofs);
    830       if (fct) {
    831 	/* Always specialize to the field name. */
    832 	emitir(IRTG(IR_EQ, IRT_STR), idx, lj_ir_kstr(J, name));
    833 	if (ctype_isconstval(fct->info)) {
    834 	  if (fct->size >= 0x80000000u &&
    835 	      (ctype_child(cts, fct)->info & CTF_UNSIGNED)) {
    836 	    J->base[0] = lj_ir_knum(J, (lua_Number)(uint32_t)fct->size);
    837 	    return;
    838 	  }
    839 	  J->base[0] = lj_ir_kint(J, (int32_t)fct->size);
    840 	  return;  /* Interpreter will throw for newindex. */
    841 	} else if (ctype_isbitfield(fct->info)) {
    842 	  lj_trace_err(J, LJ_TRERR_NYICONV);
    843 	} else {
    844 	  lua_assert(ctype_isfield(fct->info));
    845 	  sid = ctype_cid(fct->info);
    846 	}
    847 	ofs += (ptrdiff_t)fofs;
    848       }
    849     } else if (ctype_iscomplex(ct->info)) {
    850       if (name->len == 2 &&
    851 	  ((strdata(name)[0] == 'r' && strdata(name)[1] == 'e') ||
    852 	   (strdata(name)[0] == 'i' && strdata(name)[1] == 'm'))) {
    853 	/* Always specialize to the field name. */
    854 	emitir(IRTG(IR_EQ, IRT_STR), idx, lj_ir_kstr(J, name));
    855 	if (strdata(name)[0] == 'i') ofs += (ct->size >> 1);
    856 	sid = ctype_cid(ct->info);
    857       }
    858     }
    859   }
    860   if (!sid) {
    861     if (ctype_isptr(ct->info)) {  /* Automatically perform '->'. */
    862       CType *cct = ctype_rawchild(cts, ct);
    863       if (ctype_isstruct(cct->info)) {
    864 	ct = cct;
    865 	cd = NULL;
    866 	if (tref_isstr(idx)) goto again;
    867       }
    868     }
    869     crec_index_meta(J, cts, ct, rd);
    870     return;
    871   }
    872 
    873   if (ofs)
    874     ptr = emitir(IRT(IR_ADD, IRT_PTR), ptr, lj_ir_kintp(J, ofs));
    875 
    876   /* Resolve reference for field. */
    877   ct = ctype_get(cts, sid);
    878   if (ctype_isref(ct->info)) {
    879     ptr = emitir(IRT(IR_XLOAD, IRT_PTR), ptr, 0);
    880     sid = ctype_cid(ct->info);
    881     ct = ctype_get(cts, sid);
    882   }
    883 
    884   while (ctype_isattrib(ct->info))
    885     ct = ctype_child(cts, ct);  /* Skip attributes. */
    886 
    887   if (rd->data == 0) {  /* __index metamethod. */
    888     J->base[0] = crec_tv_ct(J, ct, sid, ptr);
    889   } else {  /* __newindex metamethod. */
    890     rd->nres = 0;
    891     J->needsnap = 1;
    892     lj_crec_ct_tv(J, ct, ptr, J->base[2], &rd->argv[2]);
    893   }
    894 }
    895 
    896 /* Record setting a finalizer. */
    897 static void crec_finalizer(jit_State *J, TRef trcd, TRef trfin, cTValue *fin)
    898 {
    899   if (tvisgcv(fin)) {
    900     if (!trfin) trfin = lj_ir_kptr(J, gcval(fin));
    901   } else if (tvisnil(fin)) {
    902     trfin = lj_ir_kptr(J, NULL);
    903   } else {
    904     lj_trace_err(J, LJ_TRERR_BADTYPE);
    905   }
    906   lj_ir_call(J, IRCALL_lj_cdata_setfin, trcd,
    907 	     trfin, lj_ir_kint(J, (int32_t)itype(fin)));
    908   J->needsnap = 1;
    909 }
    910 
    911 /* Record cdata allocation. */
    912 static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id)
    913 {
    914   CTState *cts = ctype_ctsG(J2G(J));
    915   CTSize sz;
    916   CTInfo info = lj_ctype_info(cts, id, &sz);
    917   CType *d = ctype_raw(cts, id);
    918   TRef trcd, trid = lj_ir_kint(J, id);
    919   cTValue *fin;
    920   /* Use special instruction to box pointer or 32/64 bit integer. */
    921   if (ctype_isptr(info) || (ctype_isinteger(info) && (sz == 4 || sz == 8))) {
    922     TRef sp = J->base[1] ? lj_crec_ct_tv(J, d, 0, J->base[1], &rd->argv[1]) :
    923 	      ctype_isptr(info) ? lj_ir_kptr(J, NULL) :
    924 	      sz == 4 ? lj_ir_kint(J, 0) :
    925 	      (lj_needsplit(J), lj_ir_kint64(J, 0));
    926     J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, sp);
    927     return;
    928   } else {
    929     TRef trsz = TREF_NIL;
    930     if ((info & CTF_VLA)) {  /* Calculate VLA/VLS size at runtime. */
    931       CTSize sz0, sz1;
    932       if (!J->base[1] || J->base[2])
    933 	lj_trace_err(J, LJ_TRERR_NYICONV);  /* NYI: init VLA/VLS. */
    934       trsz = lj_crec_ct_tv(J, ctype_get(cts, CTID_INT32), 0,
    935 			J->base[1], &rd->argv[1]);
    936       sz0 = lj_ctype_vlsize(cts, d, 0);
    937       sz1 = lj_ctype_vlsize(cts, d, 1);
    938       trsz = emitir(IRTGI(IR_MULOV), trsz, lj_ir_kint(J, (int32_t)(sz1-sz0)));
    939       trsz = emitir(IRTGI(IR_ADDOV), trsz, lj_ir_kint(J, (int32_t)sz0));
    940       J->base[1] = 0;  /* Simplify logic below. */
    941     } else if (ctype_align(info) > CT_MEMALIGN) {
    942       trsz = lj_ir_kint(J, sz);
    943     }
    944     trcd = emitir(IRTG(IR_CNEW, IRT_CDATA), trid, trsz);
    945     if (sz > 128 || (info & CTF_VLA)) {
    946       TRef dp;
    947       CTSize align;
    948     special:  /* Only handle bulk zero-fill for large/VLA/VLS types. */
    949       if (J->base[1])
    950 	lj_trace_err(J, LJ_TRERR_NYICONV);  /* NYI: init large/VLA/VLS types. */
    951       dp = emitir(IRT(IR_ADD, IRT_PTR), trcd, lj_ir_kintp(J, sizeof(GCcdata)));
    952       if (trsz == TREF_NIL) trsz = lj_ir_kint(J, sz);
    953       align = ctype_align(info);
    954       if (align < CT_MEMALIGN) align = CT_MEMALIGN;
    955       crec_fill(J, dp, trsz, lj_ir_kint(J, 0), (1u << align));
    956     } else if (J->base[1] && !J->base[2] &&
    957 	!lj_cconv_multi_init(cts, d, &rd->argv[1])) {
    958       goto single_init;
    959     } else if (ctype_isarray(d->info)) {
    960       CType *dc = ctype_rawchild(cts, d);  /* Array element type. */
    961       CTSize ofs, esize = dc->size;
    962       TRef sp = 0;
    963       TValue tv;
    964       TValue *sval = &tv;
    965       MSize i;
    966       tv.u64 = 0;
    967       if (!(ctype_isnum(dc->info) || ctype_isptr(dc->info)) ||
    968 	  esize * CREC_FILL_MAXUNROLL < sz)
    969 	goto special;
    970       for (i = 1, ofs = 0; ofs < sz; ofs += esize) {
    971 	TRef dp = emitir(IRT(IR_ADD, IRT_PTR), trcd,
    972 			 lj_ir_kintp(J, ofs + sizeof(GCcdata)));
    973 	if (J->base[i]) {
    974 	  sp = J->base[i];
    975 	  sval = &rd->argv[i];
    976 	  i++;
    977 	} else if (i != 2) {
    978 	  sp = ctype_isnum(dc->info) ? lj_ir_kint(J, 0) : TREF_NIL;
    979 	}
    980 	lj_crec_ct_tv(J, dc, dp, sp, sval);
    981       }
    982     } else if (ctype_isstruct(d->info)) {
    983       CTypeID fid = d->sib;
    984       MSize i = 1;
    985       while (fid) {
    986 	CType *df = ctype_get(cts, fid);
    987 	fid = df->sib;
    988 	if (ctype_isfield(df->info)) {
    989 	  CType *dc;
    990 	  TRef sp, dp;
    991 	  TValue tv;
    992 	  TValue *sval = &tv;
    993 	  setintV(&tv, 0);
    994 	  if (!gcref(df->name)) continue;  /* Ignore unnamed fields. */
    995 	  dc = ctype_rawchild(cts, df);  /* Field type. */
    996 	  if (!(ctype_isnum(dc->info) || ctype_isptr(dc->info) ||
    997 		ctype_isenum(dc->info)))
    998 	    lj_trace_err(J, LJ_TRERR_NYICONV);  /* NYI: init aggregates. */
    999 	  if (J->base[i]) {
   1000 	    sp = J->base[i];
   1001 	    sval = &rd->argv[i];
   1002 	    i++;
   1003 	  } else {
   1004 	    sp = ctype_isptr(dc->info) ? TREF_NIL : lj_ir_kint(J, 0);
   1005 	  }
   1006 	  dp = emitir(IRT(IR_ADD, IRT_PTR), trcd,
   1007 		      lj_ir_kintp(J, df->size + sizeof(GCcdata)));
   1008 	  lj_crec_ct_tv(J, dc, dp, sp, sval);
   1009 	} else if (!ctype_isconstval(df->info)) {
   1010 	  /* NYI: init bitfields and sub-structures. */
   1011 	  lj_trace_err(J, LJ_TRERR_NYICONV);
   1012 	}
   1013       }
   1014     } else {
   1015       TRef dp;
   1016     single_init:
   1017       dp = emitir(IRT(IR_ADD, IRT_PTR), trcd, lj_ir_kintp(J, sizeof(GCcdata)));
   1018       if (J->base[1]) {
   1019 	lj_crec_ct_tv(J, d, dp, J->base[1], &rd->argv[1]);
   1020       } else {
   1021 	TValue tv;
   1022 	tv.u64 = 0;
   1023 	lj_crec_ct_tv(J, d, dp, lj_ir_kint(J, 0), &tv);
   1024       }
   1025     }
   1026   }
   1027   J->base[0] = trcd;
   1028   /* Handle __gc metamethod. */
   1029   fin = lj_ctype_meta(cts, id, MM_gc);
   1030   if (fin)
   1031     crec_finalizer(J, trcd, 0, fin);
   1032 }
   1033 
   1034 /* Record argument conversions. */
   1035 static TRef crec_call_args(jit_State *J, RecordFFData *rd,
   1036 			   CTState *cts, CType *ct)
   1037 {
   1038   TRef args[CCI_NARGS_MAX];
   1039   CTypeID fid;
   1040   MSize i, n;
   1041   TRef tr, *base;
   1042   cTValue *o;
   1043 #if LJ_TARGET_X86
   1044 #if LJ_ABI_WIN
   1045   TRef *arg0 = NULL, *arg1 = NULL;
   1046 #endif
   1047   int ngpr = 0;
   1048   if (ctype_cconv(ct->info) == CTCC_THISCALL)
   1049     ngpr = 1;
   1050   else if (ctype_cconv(ct->info) == CTCC_FASTCALL)
   1051     ngpr = 2;
   1052 #endif
   1053 
   1054   /* Skip initial attributes. */
   1055   fid = ct->sib;
   1056   while (fid) {
   1057     CType *ctf = ctype_get(cts, fid);
   1058     if (!ctype_isattrib(ctf->info)) break;
   1059     fid = ctf->sib;
   1060   }
   1061   args[0] = TREF_NIL;
   1062   for (n = 0, base = J->base+1, o = rd->argv+1; *base; n++, base++, o++) {
   1063     CTypeID did;
   1064     CType *d;
   1065 
   1066     if (n >= CCI_NARGS_MAX)
   1067       lj_trace_err(J, LJ_TRERR_NYICALL);
   1068 
   1069     if (fid) {  /* Get argument type from field. */
   1070       CType *ctf = ctype_get(cts, fid);
   1071       fid = ctf->sib;
   1072       lua_assert(ctype_isfield(ctf->info));
   1073       did = ctype_cid(ctf->info);
   1074     } else {
   1075       if (!(ct->info & CTF_VARARG))
   1076 	lj_trace_err(J, LJ_TRERR_NYICALL);  /* Too many arguments. */
   1077       did = lj_ccall_ctid_vararg(cts, o);  /* Infer vararg type. */
   1078     }
   1079     d = ctype_raw(cts, did);
   1080     if (!(ctype_isnum(d->info) || ctype_isptr(d->info) ||
   1081 	  ctype_isenum(d->info)))
   1082       lj_trace_err(J, LJ_TRERR_NYICALL);
   1083     tr = lj_crec_ct_tv(J, d, 0, *base, o);
   1084     if (ctype_isinteger_or_bool(d->info)) {
   1085       if (d->size < 4) {
   1086 	if ((d->info & CTF_UNSIGNED))
   1087 	  tr = emitconv(tr, IRT_INT, d->size==1 ? IRT_U8 : IRT_U16, 0);
   1088 	else
   1089 	  tr = emitconv(tr, IRT_INT, d->size==1 ? IRT_I8 : IRT_I16,IRCONV_SEXT);
   1090       }
   1091     } else if (LJ_SOFTFP && ctype_isfp(d->info) && d->size > 4) {
   1092       lj_needsplit(J);
   1093     }
   1094 #if LJ_TARGET_X86
   1095     /* 64 bit args must not end up in registers for fastcall/thiscall. */
   1096 #if LJ_ABI_WIN
   1097     if (!ctype_isfp(d->info)) {
   1098       /* Sigh, the Windows/x86 ABI allows reordering across 64 bit args. */
   1099       if (tref_typerange(tr, IRT_I64, IRT_U64)) {
   1100 	if (ngpr) {
   1101 	  arg0 = &args[n]; args[n++] = TREF_NIL; ngpr--;
   1102 	  if (ngpr) {
   1103 	    arg1 = &args[n]; args[n++] = TREF_NIL; ngpr--;
   1104 	  }
   1105 	}
   1106       } else {
   1107 	if (arg0) { *arg0 = tr; arg0 = NULL; n--; continue; }
   1108 	if (arg1) { *arg1 = tr; arg1 = NULL; n--; continue; }
   1109 	if (ngpr) ngpr--;
   1110       }
   1111     }
   1112 #else
   1113     if (!ctype_isfp(d->info) && ngpr) {
   1114       if (tref_typerange(tr, IRT_I64, IRT_U64)) {
   1115 	/* No reordering for other x86 ABIs. Simply add alignment args. */
   1116 	do { args[n++] = TREF_NIL; } while (--ngpr);
   1117       } else {
   1118 	ngpr--;
   1119       }
   1120     }
   1121 #endif
   1122 #endif
   1123     args[n] = tr;
   1124   }
   1125   tr = args[0];
   1126   for (i = 1; i < n; i++)
   1127     tr = emitir(IRT(IR_CARG, IRT_NIL), tr, args[i]);
   1128   return tr;
   1129 }
   1130 
   1131 /* Create a snapshot for the caller, simulating a 'false' return value. */
   1132 static void crec_snap_caller(jit_State *J)
   1133 {
   1134   lua_State *L = J->L;
   1135   TValue *base = L->base, *top = L->top;
   1136   const BCIns *pc = J->pc;
   1137   TRef ftr = J->base[-1-LJ_FR2];
   1138   ptrdiff_t delta;
   1139   if (!frame_islua(base-1) || J->framedepth <= 0)
   1140     lj_trace_err(J, LJ_TRERR_NYICALL);
   1141   J->pc = frame_pc(base-1); delta = 1+LJ_FR2+bc_a(J->pc[-1]);
   1142   L->top = base; L->base = base - delta;
   1143   J->base[-1-LJ_FR2] = TREF_FALSE;
   1144   J->base -= delta; J->baseslot -= (BCReg)delta;
   1145   J->maxslot = (BCReg)delta-LJ_FR2; J->framedepth--;
   1146   lj_snap_add(J);
   1147   L->base = base; L->top = top;
   1148   J->framedepth++; J->maxslot = 1;
   1149   J->base += delta; J->baseslot += (BCReg)delta;
   1150   J->base[-1-LJ_FR2] = ftr; J->pc = pc;
   1151 }
   1152 
   1153 /* Record function call. */
   1154 static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd)
   1155 {
   1156   CTState *cts = ctype_ctsG(J2G(J));
   1157   CType *ct = ctype_raw(cts, cd->ctypeid);
   1158   IRType tp = IRT_PTR;
   1159   if (ctype_isptr(ct->info)) {
   1160     tp = (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32;
   1161     ct = ctype_rawchild(cts, ct);
   1162   }
   1163   if (ctype_isfunc(ct->info)) {
   1164     TRef func = emitir(IRT(IR_FLOAD, tp), J->base[0], IRFL_CDATA_PTR);
   1165     CType *ctr = ctype_rawchild(cts, ct);
   1166     IRType t = crec_ct2irt(cts, ctr);
   1167     TRef tr;
   1168     TValue tv;
   1169     /* Check for blacklisted C functions that might call a callback. */
   1170     setlightudV(&tv,
   1171 		cdata_getptr(cdataptr(cd), (LJ_64 && tp == IRT_P64) ? 8 : 4));
   1172     if (tvistrue(lj_tab_get(J->L, cts->miscmap, &tv)))
   1173       lj_trace_err(J, LJ_TRERR_BLACKL);
   1174     if (ctype_isvoid(ctr->info)) {
   1175       t = IRT_NIL;
   1176       rd->nres = 0;
   1177     } else if (!(ctype_isnum(ctr->info) || ctype_isptr(ctr->info) ||
   1178 		 ctype_isenum(ctr->info)) || t == IRT_CDATA) {
   1179       lj_trace_err(J, LJ_TRERR_NYICALL);
   1180     }
   1181     if ((ct->info & CTF_VARARG)
   1182 #if LJ_TARGET_X86
   1183 	|| ctype_cconv(ct->info) != CTCC_CDECL
   1184 #endif
   1185 	)
   1186       func = emitir(IRT(IR_CARG, IRT_NIL), func,
   1187 		    lj_ir_kint(J, ctype_typeid(cts, ct)));
   1188     tr = emitir(IRT(IR_CALLXS, t), crec_call_args(J, rd, cts, ct), func);
   1189     if (ctype_isbool(ctr->info)) {
   1190       if (frame_islua(J->L->base-1) && bc_b(frame_pc(J->L->base-1)[-1]) == 1) {
   1191 	/* Don't check result if ignored. */
   1192 	tr = TREF_NIL;
   1193       } else {
   1194 	crec_snap_caller(J);
   1195 #if LJ_TARGET_X86ORX64
   1196 	/* Note: only the x86/x64 backend supports U8 and only for EQ(tr, 0). */
   1197 	lj_ir_set(J, IRTG(IR_NE, IRT_U8), tr, lj_ir_kint(J, 0));
   1198 #else
   1199 	lj_ir_set(J, IRTGI(IR_NE), tr, lj_ir_kint(J, 0));
   1200 #endif
   1201 	J->postproc = LJ_POST_FIXGUARDSNAP;
   1202 	tr = TREF_TRUE;
   1203       }
   1204     } else if (t == IRT_PTR || (LJ_64 && t == IRT_P32) ||
   1205 	       t == IRT_I64 || t == IRT_U64 || ctype_isenum(ctr->info)) {
   1206       TRef trid = lj_ir_kint(J, ctype_cid(ct->info));
   1207       tr = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, tr);
   1208       if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J);
   1209     } else if (t == IRT_FLOAT || t == IRT_U32) {
   1210       tr = emitconv(tr, IRT_NUM, t, 0);
   1211     } else if (t == IRT_I8 || t == IRT_I16) {
   1212       tr = emitconv(tr, IRT_INT, t, IRCONV_SEXT);
   1213     } else if (t == IRT_U8 || t == IRT_U16) {
   1214       tr = emitconv(tr, IRT_INT, t, 0);
   1215     }
   1216     J->base[0] = tr;
   1217     J->needsnap = 1;
   1218     return 1;
   1219   }
   1220   return 0;
   1221 }
   1222 
   1223 void LJ_FASTCALL recff_cdata_call(jit_State *J, RecordFFData *rd)
   1224 {
   1225   CTState *cts = ctype_ctsG(J2G(J));
   1226   GCcdata *cd = argv2cdata(J, J->base[0], &rd->argv[0]);
   1227   CTypeID id = cd->ctypeid;
   1228   CType *ct;
   1229   cTValue *tv;
   1230   MMS mm = MM_call;
   1231   if (id == CTID_CTYPEID) {
   1232     id = crec_constructor(J, cd, J->base[0]);
   1233     mm = MM_new;
   1234   } else if (crec_call(J, rd, cd)) {
   1235     return;
   1236   }
   1237   /* Record ctype __call/__new metamethod. */
   1238   ct = ctype_raw(cts, id);
   1239   tv = lj_ctype_meta(cts, ctype_isptr(ct->info) ? ctype_cid(ct->info) : id, mm);
   1240   if (tv) {
   1241     if (tvisfunc(tv)) {
   1242       crec_tailcall(J, rd, tv);
   1243       return;
   1244     }
   1245   } else if (mm == MM_new) {
   1246     crec_alloc(J, rd, id);
   1247     return;
   1248   }
   1249   /* No metamethod or NYI: non-function metamethods. */
   1250   lj_trace_err(J, LJ_TRERR_BADTYPE);
   1251 }
   1252 
   1253 static TRef crec_arith_int64(jit_State *J, TRef *sp, CType **s, MMS mm)
   1254 {
   1255   if (ctype_isnum(s[0]->info) && ctype_isnum(s[1]->info)) {
   1256     IRType dt;
   1257     CTypeID id;
   1258     TRef tr;
   1259     MSize i;
   1260     IROp op;
   1261     lj_needsplit(J);
   1262     if (((s[0]->info & CTF_UNSIGNED) && s[0]->size == 8) ||
   1263 	((s[1]->info & CTF_UNSIGNED) && s[1]->size == 8)) {
   1264       dt = IRT_U64; id = CTID_UINT64;
   1265     } else {
   1266       dt = IRT_I64; id = CTID_INT64;
   1267       if (mm < MM_add &&
   1268 	  !((s[0]->info | s[1]->info) & CTF_FP) &&
   1269 	  s[0]->size == 4 && s[1]->size == 4) {  /* Try to narrow comparison. */
   1270 	if (!((s[0]->info ^ s[1]->info) & CTF_UNSIGNED) ||
   1271 	    (tref_isk(sp[1]) && IR(tref_ref(sp[1]))->i >= 0)) {
   1272 	  dt = (s[0]->info & CTF_UNSIGNED) ? IRT_U32 : IRT_INT;
   1273 	  goto comp;
   1274 	} else if (tref_isk(sp[0]) && IR(tref_ref(sp[0]))->i >= 0) {
   1275 	  dt = (s[1]->info & CTF_UNSIGNED) ? IRT_U32 : IRT_INT;
   1276 	  goto comp;
   1277 	}
   1278       }
   1279     }
   1280     for (i = 0; i < 2; i++) {
   1281       IRType st = tref_type(sp[i]);
   1282       if (st == IRT_NUM || st == IRT_FLOAT)
   1283 	sp[i] = emitconv(sp[i], dt, st, IRCONV_ANY);
   1284       else if (!(st == IRT_I64 || st == IRT_U64))
   1285 	sp[i] = emitconv(sp[i], dt, IRT_INT,
   1286 			 (s[i]->info & CTF_UNSIGNED) ? 0 : IRCONV_SEXT);
   1287     }
   1288     if (mm < MM_add) {
   1289     comp:
   1290       /* Assume true comparison. Fixup and emit pending guard later. */
   1291       if (mm == MM_eq) {
   1292 	op = IR_EQ;
   1293       } else {
   1294 	op = mm == MM_lt ? IR_LT : IR_LE;
   1295 	if (dt == IRT_U32 || dt == IRT_U64)
   1296 	  op += (IR_ULT-IR_LT);
   1297       }
   1298       lj_ir_set(J, IRTG(op, dt), sp[0], sp[1]);
   1299       J->postproc = LJ_POST_FIXGUARD;
   1300       return TREF_TRUE;
   1301     } else {
   1302       tr = emitir(IRT(mm+(int)IR_ADD-(int)MM_add, dt), sp[0], sp[1]);
   1303     }
   1304     return emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
   1305   }
   1306   return 0;
   1307 }
   1308 
   1309 static TRef crec_arith_ptr(jit_State *J, TRef *sp, CType **s, MMS mm)
   1310 {
   1311   CTState *cts = ctype_ctsG(J2G(J));
   1312   CType *ctp = s[0];
   1313   if (ctype_isptr(ctp->info) || ctype_isrefarray(ctp->info)) {
   1314     if ((mm == MM_sub || mm == MM_eq || mm == MM_lt || mm == MM_le) &&
   1315 	(ctype_isptr(s[1]->info) || ctype_isrefarray(s[1]->info))) {
   1316       if (mm == MM_sub) {  /* Pointer difference. */
   1317 	TRef tr;
   1318 	CTSize sz = lj_ctype_size(cts, ctype_cid(ctp->info));
   1319 	if (sz == 0 || (sz & (sz-1)) != 0)
   1320 	  return 0;  /* NYI: integer division. */
   1321 	tr = emitir(IRT(IR_SUB, IRT_INTP), sp[0], sp[1]);
   1322 	tr = emitir(IRT(IR_BSAR, IRT_INTP), tr, lj_ir_kint(J, lj_fls(sz)));
   1323 #if LJ_64
   1324 	tr = emitconv(tr, IRT_NUM, IRT_INTP, 0);
   1325 #endif
   1326 	return tr;
   1327       } else {  /* Pointer comparison (unsigned). */
   1328 	/* Assume true comparison. Fixup and emit pending guard later. */
   1329 	IROp op = mm == MM_eq ? IR_EQ : mm == MM_lt ? IR_ULT : IR_ULE;
   1330 	lj_ir_set(J, IRTG(op, IRT_PTR), sp[0], sp[1]);
   1331 	J->postproc = LJ_POST_FIXGUARD;
   1332 	return TREF_TRUE;
   1333       }
   1334     }
   1335     if (!((mm == MM_add || mm == MM_sub) && ctype_isnum(s[1]->info)))
   1336       return 0;
   1337   } else if (mm == MM_add && ctype_isnum(ctp->info) &&
   1338 	     (ctype_isptr(s[1]->info) || ctype_isrefarray(s[1]->info))) {
   1339     TRef tr = sp[0]; sp[0] = sp[1]; sp[1] = tr;  /* Swap pointer and index. */
   1340     ctp = s[1];
   1341   } else {
   1342     return 0;
   1343   }
   1344   {
   1345     TRef tr = sp[1];
   1346     IRType t = tref_type(tr);
   1347     CTSize sz = lj_ctype_size(cts, ctype_cid(ctp->info));
   1348     CTypeID id;
   1349 #if LJ_64
   1350     if (t == IRT_NUM || t == IRT_FLOAT)
   1351       tr = emitconv(tr, IRT_INTP, t, IRCONV_ANY);
   1352     else if (!(t == IRT_I64 || t == IRT_U64))
   1353       tr = emitconv(tr, IRT_INTP, IRT_INT,
   1354 		    ((t - IRT_I8) & 1) ? 0 : IRCONV_SEXT);
   1355 #else
   1356     if (!tref_typerange(sp[1], IRT_I8, IRT_U32)) {
   1357       tr = emitconv(tr, IRT_INTP, t,
   1358 		    (t == IRT_NUM || t == IRT_FLOAT) ? IRCONV_ANY : 0);
   1359     }
   1360 #endif
   1361     tr = emitir(IRT(IR_MUL, IRT_INTP), tr, lj_ir_kintp(J, sz));
   1362     tr = emitir(IRT(mm+(int)IR_ADD-(int)MM_add, IRT_PTR), sp[0], tr);
   1363     id = lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|ctype_cid(ctp->info)),
   1364 			 CTSIZE_PTR);
   1365     return emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
   1366   }
   1367 }
   1368 
   1369 /* Record ctype arithmetic metamethods. */
   1370 static TRef crec_arith_meta(jit_State *J, TRef *sp, CType **s, CTState *cts,
   1371 			    RecordFFData *rd)
   1372 {
   1373   cTValue *tv = NULL;
   1374   if (J->base[0]) {
   1375     if (tviscdata(&rd->argv[0])) {
   1376       CTypeID id = argv2cdata(J, J->base[0], &rd->argv[0])->ctypeid;
   1377       CType *ct = ctype_raw(cts, id);
   1378       if (ctype_isptr(ct->info)) id = ctype_cid(ct->info);
   1379       tv = lj_ctype_meta(cts, id, (MMS)rd->data);
   1380     }
   1381     if (!tv && J->base[1] && tviscdata(&rd->argv[1])) {
   1382       CTypeID id = argv2cdata(J, J->base[1], &rd->argv[1])->ctypeid;
   1383       CType *ct = ctype_raw(cts, id);
   1384       if (ctype_isptr(ct->info)) id = ctype_cid(ct->info);
   1385       tv = lj_ctype_meta(cts, id, (MMS)rd->data);
   1386     }
   1387   }
   1388   if (tv) {
   1389     if (tvisfunc(tv)) {
   1390       crec_tailcall(J, rd, tv);
   1391       return 0;
   1392     }  /* NYI: non-function metamethods. */
   1393   } else if ((MMS)rd->data == MM_eq) {  /* Fallback cdata pointer comparison. */
   1394     if (sp[0] && sp[1] && ctype_isnum(s[0]->info) == ctype_isnum(s[1]->info)) {
   1395       /* Assume true comparison. Fixup and emit pending guard later. */
   1396       lj_ir_set(J, IRTG(IR_EQ, IRT_PTR), sp[0], sp[1]);
   1397       J->postproc = LJ_POST_FIXGUARD;
   1398       return TREF_TRUE;
   1399     } else {
   1400       return TREF_FALSE;
   1401     }
   1402   }
   1403   lj_trace_err(J, LJ_TRERR_BADTYPE);
   1404   return 0;
   1405 }
   1406 
   1407 void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd)
   1408 {
   1409   CTState *cts = ctype_ctsG(J2G(J));
   1410   TRef sp[2];
   1411   CType *s[2];
   1412   MSize i;
   1413   for (i = 0; i < 2; i++) {
   1414     TRef tr = J->base[i];
   1415     CType *ct = ctype_get(cts, CTID_DOUBLE);
   1416     if (!tr) {
   1417       lj_trace_err(J, LJ_TRERR_BADTYPE);
   1418     } else if (tref_iscdata(tr)) {
   1419       CTypeID id = argv2cdata(J, tr, &rd->argv[i])->ctypeid;
   1420       IRType t;
   1421       ct = ctype_raw(cts, id);
   1422       t = crec_ct2irt(cts, ct);
   1423       if (ctype_isptr(ct->info)) {  /* Resolve pointer or reference. */
   1424 	tr = emitir(IRT(IR_FLOAD, t), tr, IRFL_CDATA_PTR);
   1425 	if (ctype_isref(ct->info)) {
   1426 	  ct = ctype_rawchild(cts, ct);
   1427 	  t = crec_ct2irt(cts, ct);
   1428 	}
   1429       } else if (t == IRT_I64 || t == IRT_U64) {
   1430 	tr = emitir(IRT(IR_FLOAD, t), tr, IRFL_CDATA_INT64);
   1431 	lj_needsplit(J);
   1432 	goto ok;
   1433       } else if (t == IRT_INT || t == IRT_U32) {
   1434 	tr = emitir(IRT(IR_FLOAD, t), tr, IRFL_CDATA_INT);
   1435 	if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
   1436 	goto ok;
   1437       } else if (ctype_isfunc(ct->info)) {
   1438 	tr = emitir(IRT(IR_FLOAD, IRT_PTR), tr, IRFL_CDATA_PTR);
   1439 	ct = ctype_get(cts,
   1440 	  lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|id), CTSIZE_PTR));
   1441 	goto ok;
   1442       } else {
   1443 	tr = emitir(IRT(IR_ADD, IRT_PTR), tr, lj_ir_kintp(J, sizeof(GCcdata)));
   1444       }
   1445       if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
   1446       if (ctype_isnum(ct->info)) {
   1447 	if (t == IRT_CDATA) {
   1448 	  tr = 0;
   1449 	} else {
   1450 	  if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J);
   1451 	  tr = emitir(IRT(IR_XLOAD, t), tr, 0);
   1452 	}
   1453       }
   1454     } else if (tref_isnil(tr)) {
   1455       tr = lj_ir_kptr(J, NULL);
   1456       ct = ctype_get(cts, CTID_P_VOID);
   1457     } else if (tref_isinteger(tr)) {
   1458       ct = ctype_get(cts, CTID_INT32);
   1459     } else if (tref_isstr(tr)) {
   1460       TRef tr2 = J->base[1-i];
   1461       CTypeID id = argv2cdata(J, tr2, &rd->argv[1-i])->ctypeid;
   1462       ct = ctype_raw(cts, id);
   1463       if (ctype_isenum(ct->info)) {  /* Match string against enum constant. */
   1464 	GCstr *str = strV(&rd->argv[i]);
   1465 	CTSize ofs;
   1466 	CType *cct = lj_ctype_getfield(cts, ct, str, &ofs);
   1467 	if (cct && ctype_isconstval(cct->info)) {
   1468 	  /* Specialize to the name of the enum constant. */
   1469 	  emitir(IRTG(IR_EQ, IRT_STR), tr, lj_ir_kstr(J, str));
   1470 	  ct = ctype_child(cts, cct);
   1471 	  tr = lj_ir_kint(J, (int32_t)ofs);
   1472 	} else {  /* Interpreter will throw or return false. */
   1473 	  ct = ctype_get(cts, CTID_P_VOID);
   1474 	}
   1475       } else if (ctype_isptr(ct->info)) {
   1476 	tr = emitir(IRT(IR_ADD, IRT_PTR), tr, lj_ir_kintp(J, sizeof(GCstr)));
   1477       } else {
   1478 	ct = ctype_get(cts, CTID_P_VOID);
   1479       }
   1480     } else if (!tref_isnum(tr)) {
   1481       tr = 0;
   1482       ct = ctype_get(cts, CTID_P_VOID);
   1483     }
   1484   ok:
   1485     s[i] = ct;
   1486     sp[i] = tr;
   1487   }
   1488   {
   1489     TRef tr;
   1490     if (!(tr = crec_arith_int64(J, sp, s, (MMS)rd->data)) &&
   1491 	!(tr = crec_arith_ptr(J, sp, s, (MMS)rd->data)) &&
   1492 	!(tr = crec_arith_meta(J, sp, s, cts, rd)))
   1493       return;
   1494     J->base[0] = tr;
   1495     /* Fixup cdata comparisons, too. Avoids some cdata escapes. */
   1496     if (J->postproc == LJ_POST_FIXGUARD && frame_iscont(J->L->base-1) &&
   1497 	!irt_isguard(J->guardemit)) {
   1498       const BCIns *pc = frame_contpc(J->L->base-1) - 1;
   1499       if (bc_op(*pc) <= BC_ISNEP) {
   1500 	J2G(J)->tmptv.u64 = (uint64_t)(uintptr_t)pc;
   1501 	J->postproc = LJ_POST_FIXCOMP;
   1502       }
   1503     }
   1504   }
   1505 }
   1506 
   1507 /* -- C library namespace metamethods ------------------------------------- */
   1508 
   1509 void LJ_FASTCALL recff_clib_index(jit_State *J, RecordFFData *rd)
   1510 {
   1511   CTState *cts = ctype_ctsG(J2G(J));
   1512   if (tref_isudata(J->base[0]) && tref_isstr(J->base[1]) &&
   1513       udataV(&rd->argv[0])->udtype == UDTYPE_FFI_CLIB) {
   1514     CLibrary *cl = (CLibrary *)uddata(udataV(&rd->argv[0]));
   1515     GCstr *name = strV(&rd->argv[1]);
   1516     CType *ct;
   1517     CTypeID id = lj_ctype_getname(cts, &ct, name, CLNS_INDEX);
   1518     cTValue *tv = lj_tab_getstr(cl->cache, name);
   1519     rd->nres = rd->data;
   1520     if (id && tv && !tvisnil(tv)) {
   1521       /* Specialize to the symbol name and make the result a constant. */
   1522       emitir(IRTG(IR_EQ, IRT_STR), J->base[1], lj_ir_kstr(J, name));
   1523       if (ctype_isconstval(ct->info)) {
   1524 	if (ct->size >= 0x80000000u &&
   1525 	    (ctype_child(cts, ct)->info & CTF_UNSIGNED))
   1526 	  J->base[0] = lj_ir_knum(J, (lua_Number)(uint32_t)ct->size);
   1527 	else
   1528 	  J->base[0] = lj_ir_kint(J, (int32_t)ct->size);
   1529       } else if (ctype_isextern(ct->info)) {
   1530 	CTypeID sid = ctype_cid(ct->info);
   1531 	void *sp = *(void **)cdataptr(cdataV(tv));
   1532 	TRef ptr;
   1533 	ct = ctype_raw(cts, sid);
   1534 	if (LJ_64 && !checkptr32(sp))
   1535 	  ptr = lj_ir_kintp(J, (uintptr_t)sp);
   1536 	else
   1537 	  ptr = lj_ir_kptr(J, sp);
   1538 	if (rd->data) {
   1539 	  J->base[0] = crec_tv_ct(J, ct, sid, ptr);
   1540 	} else {
   1541 	  J->needsnap = 1;
   1542 	  lj_crec_ct_tv(J, ct, ptr, J->base[2], &rd->argv[2]);
   1543 	}
   1544       } else {
   1545 	J->base[0] = lj_ir_kgc(J, obj2gco(cdataV(tv)), IRT_CDATA);
   1546       }
   1547     } else {
   1548       lj_trace_err(J, LJ_TRERR_NOCACHE);
   1549     }
   1550   }  /* else: interpreter will throw. */
   1551 }
   1552 
   1553 /* -- FFI library functions ----------------------------------------------- */
   1554 
   1555 static TRef crec_toint(jit_State *J, CTState *cts, TRef sp, TValue *sval)
   1556 {
   1557   return lj_crec_ct_tv(J, ctype_get(cts, CTID_INT32), 0, sp, sval);
   1558 }
   1559 
   1560 void LJ_FASTCALL recff_ffi_new(jit_State *J, RecordFFData *rd)
   1561 {
   1562   crec_alloc(J, rd, argv2ctype(J, J->base[0], &rd->argv[0]));
   1563 }
   1564 
   1565 void LJ_FASTCALL recff_ffi_errno(jit_State *J, RecordFFData *rd)
   1566 {
   1567   UNUSED(rd);
   1568   if (J->base[0])
   1569     lj_trace_err(J, LJ_TRERR_NYICALL);
   1570   J->base[0] = lj_ir_call(J, IRCALL_lj_vm_errno);
   1571 }
   1572 
   1573 void LJ_FASTCALL recff_ffi_string(jit_State *J, RecordFFData *rd)
   1574 {
   1575   CTState *cts = ctype_ctsG(J2G(J));
   1576   TRef tr = J->base[0];
   1577   if (tr) {
   1578     TRef trlen = J->base[1];
   1579     if (!tref_isnil(trlen)) {
   1580       trlen = crec_toint(J, cts, trlen, &rd->argv[1]);
   1581       tr = lj_crec_ct_tv(J, ctype_get(cts, CTID_P_CVOID), 0, tr, &rd->argv[0]);
   1582     } else {
   1583       tr = lj_crec_ct_tv(J, ctype_get(cts, CTID_P_CCHAR), 0, tr, &rd->argv[0]);
   1584       trlen = lj_ir_call(J, IRCALL_strlen, tr);
   1585     }
   1586     J->base[0] = emitir(IRT(IR_XSNEW, IRT_STR), tr, trlen);
   1587   }  /* else: interpreter will throw. */
   1588 }
   1589 
   1590 void LJ_FASTCALL recff_ffi_strbuf(jit_State *J, RecordFFData *rd)
   1591 {
   1592   CTState *cts = ctype_ctsG(J2G(J));
   1593   TRef dst, tr = J->base[0];
   1594   if (tr) {
   1595     dst = lj_crec_ct_tv(J, ctype_get(cts, CTID_P_VOID), 0, tr, &rd->argv[0]);
   1596     /* TBD: big endian */
   1597     TRef hdr = lj_ir_kint64(J, ((0L|LJ_GC_SFIXED|LJ_GC_FIXED)<<32) +
   1598         ((0L+(~LJ_TSTR))<<40));
   1599     emitir(IRT(IR_XSTORE, IRT_U64), dst, hdr);
   1600     J->base[0] = emitconv(dst, IRT_STR, IRT_PTR, 0);
   1601     emitir(IRT(IR_XBAR, IRT_NIL), 0, 0);
   1602   }
   1603 }
   1604 
   1605 void LJ_FASTCALL recff_ffi_copy(jit_State *J, RecordFFData *rd)
   1606 {
   1607   CTState *cts = ctype_ctsG(J2G(J));
   1608   TRef trdst = J->base[0], trsrc = J->base[1], trlen = J->base[2];
   1609   if (trdst && trsrc && (trlen || tref_isstr(trsrc))) {
   1610     trdst = lj_crec_ct_tv(J, ctype_get(cts, CTID_P_VOID), 0, trdst, &rd->argv[0]);
   1611     trsrc = lj_crec_ct_tv(J, ctype_get(cts, CTID_P_CVOID), 0, trsrc, &rd->argv[1]);
   1612     if (trlen) {
   1613       trlen = crec_toint(J, cts, trlen, &rd->argv[2]);
   1614     } else {
   1615       trlen = emitir(IRTI(IR_FLOAD), J->base[1], IRFL_STR_LEN);
   1616       trlen = emitir(IRTI(IR_ADD), trlen, lj_ir_kint(J, 1));
   1617     }
   1618     rd->nres = 0;
   1619     crec_copy(J, trdst, trsrc, trlen, NULL);
   1620   }  /* else: interpreter will throw. */
   1621 }
   1622 
   1623 void LJ_FASTCALL recff_ffi_fill(jit_State *J, RecordFFData *rd)
   1624 {
   1625   CTState *cts = ctype_ctsG(J2G(J));
   1626   TRef trdst = J->base[0], trlen = J->base[1], trfill = J->base[2];
   1627   if (trdst && trlen) {
   1628     CTSize step = 1;
   1629     if (tviscdata(&rd->argv[0])) {  /* Get alignment of original destination. */
   1630       CTSize sz;
   1631       CType *ct = ctype_raw(cts, cdataV(&rd->argv[0])->ctypeid);
   1632       if (ctype_isptr(ct->info))
   1633 	ct = ctype_rawchild(cts, ct);
   1634       step = (1u<<ctype_align(lj_ctype_info(cts, ctype_typeid(cts, ct), &sz)));
   1635     }
   1636     trdst = lj_crec_ct_tv(J, ctype_get(cts, CTID_P_VOID), 0, trdst, &rd->argv[0]);
   1637     trlen = crec_toint(J, cts, trlen, &rd->argv[1]);
   1638     if (trfill)
   1639       trfill = crec_toint(J, cts, trfill, &rd->argv[2]);
   1640     else
   1641       trfill = lj_ir_kint(J, 0);
   1642     rd->nres = 0;
   1643     crec_fill(J, trdst, trlen, trfill, step);
   1644   }  /* else: interpreter will throw. */
   1645 }
   1646 
   1647 void LJ_FASTCALL recff_ffi_typeof(jit_State *J, RecordFFData *rd)
   1648 {
   1649   if (tref_iscdata(J->base[0])) {
   1650     TRef trid = lj_ir_kint(J, argv2ctype(J, J->base[0], &rd->argv[0]));
   1651     J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA),
   1652 			lj_ir_kint(J, CTID_CTYPEID), trid);
   1653   } else {
   1654     setfuncV(J->L, &J->errinfo, J->fn);
   1655     lj_trace_err_info(J, LJ_TRERR_NYIFFU);
   1656   }
   1657 }
   1658 
   1659 void LJ_FASTCALL recff_ffi_istype(jit_State *J, RecordFFData *rd)
   1660 {
   1661   argv2ctype(J, J->base[0], &rd->argv[0]);
   1662   if (tref_iscdata(J->base[1])) {
   1663     argv2ctype(J, J->base[1], &rd->argv[1]);
   1664     J->postproc = LJ_POST_FIXBOOL;
   1665     J->base[0] = TREF_TRUE;
   1666   } else {
   1667     J->base[0] = TREF_FALSE;
   1668   }
   1669 }
   1670 
   1671 void LJ_FASTCALL recff_ffi_abi(jit_State *J, RecordFFData *rd)
   1672 {
   1673   if (tref_isstr(J->base[0])) {
   1674     /* Specialize to the ABI string to make the boolean result a constant. */
   1675     emitir(IRTG(IR_EQ, IRT_STR), J->base[0], lj_ir_kstr(J, strV(&rd->argv[0])));
   1676     J->postproc = LJ_POST_FIXBOOL;
   1677     J->base[0] = TREF_TRUE;
   1678   } else {
   1679     lj_trace_err(J, LJ_TRERR_BADTYPE);
   1680   }
   1681 }
   1682 
   1683 /* Record ffi.sizeof(), ffi.alignof(), ffi.offsetof(). */
   1684 void LJ_FASTCALL recff_ffi_xof(jit_State *J, RecordFFData *rd)
   1685 {
   1686   CTypeID id = argv2ctype(J, J->base[0], &rd->argv[0]);
   1687   if (rd->data == FF_ffi_sizeof) {
   1688     CType *ct = lj_ctype_rawref(ctype_ctsG(J2G(J)), id);
   1689     if (ctype_isvltype(ct->info))
   1690       lj_trace_err(J, LJ_TRERR_BADTYPE);
   1691   } else if (rd->data == FF_ffi_offsetof) {  /* Specialize to the field name. */
   1692     if (!tref_isstr(J->base[1]))
   1693       lj_trace_err(J, LJ_TRERR_BADTYPE);
   1694     emitir(IRTG(IR_EQ, IRT_STR), J->base[1], lj_ir_kstr(J, strV(&rd->argv[1])));
   1695     rd->nres = 3;  /* Just in case. */
   1696   }
   1697   J->postproc = LJ_POST_FIXCONST;
   1698   J->base[0] = J->base[1] = J->base[2] = TREF_NIL;
   1699 }
   1700 
   1701 void LJ_FASTCALL recff_ffi_gc(jit_State *J, RecordFFData *rd)
   1702 {
   1703   argv2cdata(J, J->base[0], &rd->argv[0]);
   1704   if (!J->base[1])
   1705     lj_trace_err(J, LJ_TRERR_BADTYPE);
   1706   crec_finalizer(J, J->base[0], J->base[1], &rd->argv[1]);
   1707 }
   1708 
   1709 /* -- 64 bit bit.* library functions -------------------------------------- */
   1710 
   1711 /* Determine bit operation type from argument type. */
   1712 CTypeID LJ_FASTCALL lj_crec_bit64_type(CTState *cts, cTValue *tv)
   1713 {
   1714   if (tviscdata(tv)) {
   1715     CType *ct = lj_ctype_rawref(cts, cdataV(tv)->ctypeid);
   1716     if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
   1717     if ((ct->info & (CTMASK_NUM|CTF_BOOL|CTF_FP|CTF_UNSIGNED)) ==
   1718 	CTINFO(CT_NUM, CTF_UNSIGNED) && ct->size == 8)
   1719       return CTID_UINT64;  /* Use uint64_t, since it has the highest rank. */
   1720     return CTID_INT64;  /* Otherwise use int64_t. */
   1721   }
   1722   return 0;  /* Use regular 32 bit ops. */
   1723 }
   1724 
   1725 void LJ_FASTCALL recff_bit64_tobit(jit_State *J, RecordFFData *rd)
   1726 {
   1727   CTState *cts = ctype_ctsG(J2G(J));
   1728   TRef tr = lj_crec_ct_tv(J, ctype_get(cts, CTID_INT64), 0,
   1729 		       J->base[0], &rd->argv[0]);
   1730   if (!tref_isinteger(tr))
   1731     tr = emitconv(tr, IRT_INT, tref_type(tr), 0);
   1732   J->base[0] = tr;
   1733 }
   1734 
   1735 int LJ_FASTCALL recff_bit64_unary(jit_State *J, RecordFFData *rd)
   1736 {
   1737   CTState *cts = ctype_ctsG(J2G(J));
   1738   CTypeID id = lj_crec_bit64_type(cts, &rd->argv[0]);
   1739   if (id) {
   1740     TRef tr = lj_crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]);
   1741     tr = emitir(IRT(rd->data, id-CTID_INT64+IRT_I64), tr, 0);
   1742     J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
   1743     return 1;
   1744   }
   1745   return 0;
   1746 }
   1747 
   1748 int LJ_FASTCALL recff_bit64_nary(jit_State *J, RecordFFData *rd)
   1749 {
   1750   CTState *cts = ctype_ctsG(J2G(J));
   1751   CTypeID id = 0;
   1752   MSize i;
   1753   for (i = 0; J->base[i] != 0; i++) {
   1754     CTypeID aid = lj_crec_bit64_type(cts, &rd->argv[i]);
   1755     if (id < aid) id = aid;  /* Determine highest type rank of all arguments. */
   1756   }
   1757   if (id) {
   1758     CType *ct = ctype_get(cts, id);
   1759     uint32_t ot = IRT(rd->data, id-CTID_INT64+IRT_I64);
   1760     TRef tr = lj_crec_ct_tv(J, ct, 0, J->base[0], &rd->argv[0]);
   1761     for (i = 1; J->base[i] != 0; i++) {
   1762       TRef tr2 = lj_crec_ct_tv(J, ct, 0, J->base[i], &rd->argv[i]);
   1763       tr = emitir(ot, tr, tr2);
   1764     }
   1765     J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
   1766     return 1;
   1767   }
   1768   return 0;
   1769 }
   1770 
   1771 int LJ_FASTCALL recff_bit64_shift(jit_State *J, RecordFFData *rd)
   1772 {
   1773   CTState *cts = ctype_ctsG(J2G(J));
   1774   CTypeID id;
   1775   TRef tsh = 0;
   1776   if (J->base[0] && tref_iscdata(J->base[1])) {
   1777     tsh = lj_crec_ct_tv(J, ctype_get(cts, CTID_INT64), 0,
   1778 		     J->base[1], &rd->argv[1]);
   1779     if (!tref_isinteger(tsh))
   1780       tsh = emitconv(tsh, IRT_INT, tref_type(tsh), 0);
   1781     J->base[1] = tsh;
   1782   }
   1783   id = lj_crec_bit64_type(cts, &rd->argv[0]);
   1784   if (id) {
   1785     TRef tr = lj_crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]);
   1786     uint32_t op = rd->data;
   1787     if (!tsh) tsh = lj_opt_narrow_tobit(J, J->base[1]);
   1788     if (!(op < IR_BROL ? LJ_TARGET_MASKSHIFT : LJ_TARGET_MASKROT) &&
   1789 	!tref_isk(tsh))
   1790       tsh = emitir(IRTI(IR_BAND), tsh, lj_ir_kint(J, 63));
   1791 #ifdef LJ_TARGET_UNIFYROT
   1792       if (op == (LJ_TARGET_UNIFYROT == 1 ? IR_BROR : IR_BROL)) {
   1793 	op = LJ_TARGET_UNIFYROT == 1 ? IR_BROL : IR_BROR;
   1794 	tsh = emitir(IRTI(IR_NEG), tsh, tsh);
   1795       }
   1796 #endif
   1797     tr = emitir(IRT(op, id-CTID_INT64+IRT_I64), tr, tsh);
   1798     J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
   1799     return 1;
   1800   }
   1801   return 0;
   1802 }
   1803 
   1804 TRef recff_bit64_tohex(jit_State *J, RecordFFData *rd, TRef hdr)
   1805 {
   1806   CTState *cts = ctype_ctsG(J2G(J));
   1807   CTypeID id = lj_crec_bit64_type(cts, &rd->argv[0]);
   1808   TRef tr, trsf = J->base[1];
   1809   SFormat sf = (STRFMT_UINT|STRFMT_T_HEX);
   1810   int32_t n;
   1811   if (trsf) {
   1812     CTypeID id2 = 0;
   1813     n = (int32_t)lj_carith_check64(J->L, 2, &id2);
   1814     if (id2)
   1815       trsf = lj_crec_ct_tv(J, ctype_get(cts, CTID_INT32), 0, trsf, &rd->argv[1]);
   1816     else
   1817       trsf = lj_opt_narrow_tobit(J, trsf);
   1818     emitir(IRTGI(IR_EQ), trsf, lj_ir_kint(J, n));  /* Specialize to n. */
   1819   } else {
   1820     n = id ? 16 : 8;
   1821   }
   1822   if (n < 0) { n = -n; sf |= STRFMT_F_UPPER; }
   1823   sf |= ((SFormat)((n+1)&255) << STRFMT_SH_PREC);
   1824   if (id) {
   1825     tr = lj_crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]);
   1826     if (n < 16)
   1827       tr = emitir(IRT(IR_BAND, IRT_U64), tr,
   1828 		  lj_ir_kint64(J, ((uint64_t)1 << 4*n)-1));
   1829   } else {
   1830     tr = lj_opt_narrow_tobit(J, J->base[0]);
   1831     if (n < 8)
   1832       tr = emitir(IRTI(IR_BAND), tr, lj_ir_kint(J, (int32_t)((1u << 4*n)-1)));
   1833     tr = emitconv(tr, IRT_U64, IRT_INT, 0);  /* No sign-extension. */
   1834     lj_needsplit(J);
   1835   }
   1836   return lj_ir_call(J, IRCALL_lj_strfmt_putfxint, hdr, lj_ir_kint(J, sf), tr);
   1837 }
   1838 
   1839 /* -- Miscellaneous library functions ------------------------------------- */
   1840 
   1841 void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd)
   1842 {
   1843   CTState *cts = ctype_ctsG(J2G(J));
   1844   CType *d, *ct = lj_ctype_rawref(cts, cdataV(&rd->argv[0])->ctypeid);
   1845   if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
   1846   if (ctype_isnum(ct->info) || ctype_iscomplex(ct->info)) {
   1847     if (ctype_isinteger_or_bool(ct->info) && ct->size <= 4 &&
   1848 	!(ct->size == 4 && (ct->info & CTF_UNSIGNED)))
   1849       d = ctype_get(cts, CTID_INT32);
   1850     else
   1851       d = ctype_get(cts, CTID_DOUBLE);
   1852     J->base[0] = lj_crec_ct_tv(J, d, 0, J->base[0], &rd->argv[0]);
   1853   } else {
   1854     J->base[0] = TREF_NIL;
   1855   }
   1856 }
   1857 
   1858 #undef IR
   1859 #undef emitir
   1860 #undef emitconv
   1861 
   1862 #endif