795
795
} else if (tref_isstr(idx)) {
796
796
GCstr *name = strV(&rd->argv[1]);
797
if (cd->ctypeid == CTID_CTYPEID)
797
if (cd && cd->ctypeid == CTID_CTYPEID)
798
798
ct = ctype_raw(cts, crec_constructor(J, cd, ptr));
799
799
if (ctype_isstruct(ct->info)) {
848
849
/* Resolve reference for field. */
849
850
ct = ctype_get(cts, sid);
850
if (ctype_isref(ct->info))
851
if (ctype_isref(ct->info)) {
851
852
ptr = emitir(IRT(IR_XLOAD, IRT_PTR), ptr, 0);
853
sid = ctype_cid(ct->info);
854
ct = ctype_get(cts, sid);
853
857
while (ctype_isattrib(ct->info))
854
858
ct = ctype_child(cts, ct); /* Skip attributes. */
1319
1323
/* Record ctype arithmetic metamethods. */
1320
static void crec_arith_meta(jit_State *J, CTState *cts, RecordFFData *rd)
1324
static TRef crec_arith_meta(jit_State *J, TRef *sp, CType **s, CTState *cts,
1322
1327
cTValue *tv = NULL;
1323
1328
if (J->base[0]) {
1338
1343
if (tvisfunc(tv)) {
1339
1344
J->base[-1] = lj_ir_kfunc(J, funcV(tv)) | TREF_FRAME;
1340
1345
rd->nres = -1; /* Pending tailcall. */
1342
1347
} /* NYI: non-function metamethods. */
1343
} else if ((MMS)rd->data == MM_eq) {
1344
J->base[0] = TREF_FALSE;
1348
} else if ((MMS)rd->data == MM_eq) { /* Fallback cdata pointer comparison. */
1349
if (sp[0] && sp[1] && ctype_isnum(s[0]->info) == ctype_isnum(s[1]->info)) {
1350
/* Assume true comparison. Fixup and emit pending guard later. */
1351
lj_ir_set(J, IRTG(IR_EQ, IRT_PTR), sp[0], sp[1]);
1352
J->postproc = LJ_POST_FIXGUARD;
1347
1358
lj_trace_err(J, LJ_TRERR_BADTYPE);
1350
1362
void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd)
1357
1369
TRef tr = J->base[i];
1358
1370
CType *ct = ctype_get(cts, CTID_DOUBLE);
1372
lj_trace_err(J, LJ_TRERR_BADTYPE);
1361
1373
} else if (tref_iscdata(tr)) {
1362
1374
CTypeID id = argv2cdata(J, tr, &rd->argv[i])->ctypeid;
1388
1400
if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
1389
1401
if (ctype_isnum(ct->info)) {
1390
if (t == IRT_CDATA) goto trymeta;
1391
if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J);
1392
tr = emitir(IRT(IR_XLOAD, t), tr, 0);
1393
} else if (!(ctype_isptr(ct->info) || ctype_isrefarray(ct->info))) {
1402
if (t == IRT_CDATA) {
1405
if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J);
1406
tr = emitir(IRT(IR_XLOAD, t), tr, 0);
1396
1409
} else if (tref_isnil(tr)) {
1397
1410
tr = lj_ir_kptr(J, NULL);
1411
1424
emitir(IRTG(IR_EQ, IRT_STR), tr, lj_ir_kstr(J, str));
1412
1425
ct = ctype_child(cts, cct);
1413
1426
tr = lj_ir_kint(J, (int32_t)ofs);
1414
} /* else: interpreter will throw. */
1415
} /* else: interpreter will throw. */
1427
} else { /* Interpreter will throw or return false. */
1428
ct = ctype_get(cts, CTID_P_VOID);
1430
} else if (ctype_isptr(ct->info)) {
1431
tr = emitir(IRT(IR_ADD, IRT_PTR), tr, lj_ir_kintp(J, sizeof(GCstr)));
1433
ct = ctype_get(cts, CTID_P_VOID);
1416
1435
} else if (!tref_isnum(tr)) {
1437
ct = ctype_get(cts, CTID_P_VOID);
1425
if ((tr = crec_arith_int64(J, sp, s, (MMS)rd->data)) ||
1426
(tr = crec_arith_ptr(J, sp, s, (MMS)rd->data))) {
1428
/* Fixup cdata comparisons, too. Avoids some cdata escapes. */
1429
if (J->postproc == LJ_POST_FIXGUARD && frame_iscont(J->L->base-1) &&
1430
!irt_isguard(J->guardemit)) {
1431
const BCIns *pc = frame_contpc(J->L->base-1) - 1;
1432
if (bc_op(*pc) <= BC_ISNEP) {
1433
setframe_pc(&J2G(J)->tmptv, pc);
1434
J2G(J)->tmptv.u32.lo = ((tref_istrue(tr) ^ bc_op(*pc)) & 1);
1435
J->postproc = LJ_POST_FIXCOMP;
1445
if (!(tr = crec_arith_int64(J, sp, s, (MMS)rd->data)) &&
1446
!(tr = crec_arith_ptr(J, sp, s, (MMS)rd->data)) &&
1447
!(tr = crec_arith_meta(J, sp, s, cts, rd)))
1450
/* Fixup cdata comparisons, too. Avoids some cdata escapes. */
1451
if (J->postproc == LJ_POST_FIXGUARD && frame_iscont(J->L->base-1) &&
1452
!irt_isguard(J->guardemit)) {
1453
const BCIns *pc = frame_contpc(J->L->base-1) - 1;
1454
if (bc_op(*pc) <= BC_ISNEP) {
1455
setframe_pc(&J2G(J)->tmptv, pc);
1456
J2G(J)->tmptv.u32.lo = ((tref_istrue(tr) ^ bc_op(*pc)) & 1);
1457
J->postproc = LJ_POST_FIXCOMP;
1440
crec_arith_meta(J, cts, rd);