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