|
@@ -111,8 +111,9 @@ static CTypeID argv2ctype(jit_State *J, TRef tr, cTValue *o)
|
|
*/
|
|
*/
|
|
|
|
|
|
/* Convert CType to IRType. */
|
|
/* Convert CType to IRType. */
|
|
-static IRType crec_ct2irt(CType *ct)
|
|
|
|
|
|
+static IRType crec_ct2irt(CTState *cts, CType *ct)
|
|
{
|
|
{
|
|
|
|
+ if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
|
|
if (LJ_LIKELY(ctype_isnum(ct->info))) {
|
|
if (LJ_LIKELY(ctype_isnum(ct->info))) {
|
|
if ((ct->info & CTF_FP)) {
|
|
if ((ct->info & CTF_FP)) {
|
|
if (ct->size == sizeof(double))
|
|
if (ct->size == sizeof(double))
|
|
@@ -162,10 +163,10 @@ static int crec_isnonzero(CType *s, void *p)
|
|
static TRef crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp,
|
|
static TRef crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp,
|
|
void *svisnz)
|
|
void *svisnz)
|
|
{
|
|
{
|
|
|
|
+ IRType dt = crec_ct2irt(ctype_ctsG(J2G(J)), d);
|
|
|
|
+ IRType st = crec_ct2irt(ctype_ctsG(J2G(J)), s);
|
|
CTSize dsize = d->size, ssize = s->size;
|
|
CTSize dsize = d->size, ssize = s->size;
|
|
CTInfo dinfo = d->info, sinfo = s->info;
|
|
CTInfo dinfo = d->info, sinfo = s->info;
|
|
- IRType dt = crec_ct2irt(d);
|
|
|
|
- IRType st = crec_ct2irt(s);
|
|
|
|
|
|
|
|
if (ctype_type(dinfo) > CT_MAYCONVERT || ctype_type(sinfo) > CT_MAYCONVERT)
|
|
if (ctype_type(dinfo) > CT_MAYCONVERT || ctype_type(sinfo) > CT_MAYCONVERT)
|
|
goto err_conv;
|
|
goto err_conv;
|
|
@@ -317,10 +318,9 @@ static TRef crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp,
|
|
static TRef crec_tv_ct(jit_State *J, CType *s, CTypeID sid, TRef sp)
|
|
static TRef crec_tv_ct(jit_State *J, CType *s, CTypeID sid, TRef sp)
|
|
{
|
|
{
|
|
CTState *cts = ctype_ctsG(J2G(J));
|
|
CTState *cts = ctype_ctsG(J2G(J));
|
|
|
|
+ IRType t = crec_ct2irt(cts, s);
|
|
CTInfo sinfo = s->info;
|
|
CTInfo sinfo = s->info;
|
|
- lua_assert(!ctype_isenum(sinfo));
|
|
|
|
if (ctype_isnum(sinfo)) {
|
|
if (ctype_isnum(sinfo)) {
|
|
- IRType t = crec_ct2irt(s);
|
|
|
|
TRef tr;
|
|
TRef tr;
|
|
if (t == IRT_CDATA)
|
|
if (t == IRT_CDATA)
|
|
goto err_nyi; /* NYI: copyval of >64 bit integers. */
|
|
goto err_nyi; /* NYI: copyval of >64 bit integers. */
|
|
@@ -338,14 +338,12 @@ static TRef crec_tv_ct(jit_State *J, CType *s, CTypeID sid, TRef sp)
|
|
} else {
|
|
} else {
|
|
return tr;
|
|
return tr;
|
|
}
|
|
}
|
|
- } else if (ctype_isptr(sinfo)) {
|
|
|
|
- IRType t = (LJ_64 && s->size == 8) ? IRT_P64 : IRT_P32;
|
|
|
|
- sp = emitir(IRT(IR_XLOAD, t), sp, 0);
|
|
|
|
|
|
+ } else if (ctype_isptr(sinfo) || ctype_isenum(sinfo)) {
|
|
|
|
+ sp = emitir(IRT(IR_XLOAD, t), sp, 0); /* Box pointers and enums. */
|
|
} else if (ctype_isrefarray(sinfo) || ctype_isstruct(sinfo)) {
|
|
} else if (ctype_isrefarray(sinfo) || ctype_isstruct(sinfo)) {
|
|
cts->L = J->L;
|
|
cts->L = J->L;
|
|
sid = lj_ctype_intern(cts, CTINFO_REF(sid), CTSIZE_PTR); /* Create ref. */
|
|
sid = lj_ctype_intern(cts, CTINFO_REF(sid), CTSIZE_PTR); /* Create ref. */
|
|
} else if (ctype_iscomplex(sinfo)) { /* Unbox/box complex. */
|
|
} else if (ctype_iscomplex(sinfo)) { /* Unbox/box complex. */
|
|
- IRType t = s->size == 2*sizeof(double) ? IRT_NUM : IRT_FLOAT;
|
|
|
|
ptrdiff_t esz = (ptrdiff_t)(s->size >> 1);
|
|
ptrdiff_t esz = (ptrdiff_t)(s->size >> 1);
|
|
TRef ptr, tr1, tr2, dp;
|
|
TRef ptr, tr1, tr2, dp;
|
|
dp = emitir(IRTG(IR_CNEW, IRT_CDATA), lj_ir_kint(J, sid), TREF_NIL);
|
|
dp = emitir(IRTG(IR_CNEW, IRT_CDATA), lj_ir_kint(J, sid), TREF_NIL);
|
|
@@ -362,7 +360,7 @@ static TRef crec_tv_ct(jit_State *J, CType *s, CTypeID sid, TRef sp)
|
|
err_nyi:
|
|
err_nyi:
|
|
lj_trace_err(J, LJ_TRERR_NYICONV);
|
|
lj_trace_err(J, LJ_TRERR_NYICONV);
|
|
}
|
|
}
|
|
- /* Box pointer, ref or 64 bit integer. */
|
|
|
|
|
|
+ /* Box pointer, ref, enum or 64 bit integer. */
|
|
return emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, sid), sp);
|
|
return emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, sid), sp);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -403,8 +401,8 @@ static TRef crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, cTValue *sval)
|
|
emitir(IRTG(IR_EQ, IRT_STR), sp, lj_ir_kstr(J, str));
|
|
emitir(IRTG(IR_EQ, IRT_STR), sp, lj_ir_kstr(J, str));
|
|
if (cct && ctype_isconstval(cct->info)) {
|
|
if (cct && ctype_isconstval(cct->info)) {
|
|
lua_assert(ctype_child(cts, cct)->size == 4);
|
|
lua_assert(ctype_child(cts, cct)->size == 4);
|
|
- svisnz = (void *)(intptr_t)(cct->size != 0);
|
|
|
|
- sp = lj_ir_kint(J, (int32_t)cct->size);
|
|
|
|
|
|
+ svisnz = (void *)(intptr_t)(ofs != 0);
|
|
|
|
+ sp = lj_ir_kint(J, (int32_t)ofs);
|
|
sid = ctype_cid(cct->info);
|
|
sid = ctype_cid(cct->info);
|
|
} /* else: interpreter will throw. */
|
|
} /* else: interpreter will throw. */
|
|
} else if (ctype_isrefarray(d->info)) { /* Copy string to array. */
|
|
} else if (ctype_isrefarray(d->info)) { /* Copy string to array. */
|
|
@@ -418,15 +416,13 @@ static TRef crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, cTValue *sval)
|
|
sid = argv2cdata(J, sp, sval)->ctypeid;
|
|
sid = argv2cdata(J, sp, sval)->ctypeid;
|
|
s = ctype_raw(cts, sid);
|
|
s = ctype_raw(cts, sid);
|
|
svisnz = cdataptr(cdataV(sval));
|
|
svisnz = cdataptr(cdataV(sval));
|
|
- if (ctype_isenum(s->info)) s = ctype_child(cts, s);
|
|
|
|
- t = crec_ct2irt(s);
|
|
|
|
|
|
+ t = crec_ct2irt(cts, s);
|
|
if (ctype_isptr(s->info)) {
|
|
if (ctype_isptr(s->info)) {
|
|
sp = emitir(IRT(IR_FLOAD, t), sp, IRFL_CDATA_PTR);
|
|
sp = emitir(IRT(IR_FLOAD, t), sp, IRFL_CDATA_PTR);
|
|
if (ctype_isref(s->info)) {
|
|
if (ctype_isref(s->info)) {
|
|
svisnz = *(void **)svisnz;
|
|
svisnz = *(void **)svisnz;
|
|
s = ctype_rawchild(cts, s);
|
|
s = ctype_rawchild(cts, s);
|
|
- if (ctype_isenum(s->info)) s = ctype_child(cts, s);
|
|
|
|
- t = crec_ct2irt(s);
|
|
|
|
|
|
+ t = crec_ct2irt(cts, s);
|
|
} else {
|
|
} else {
|
|
goto doconv;
|
|
goto doconv;
|
|
}
|
|
}
|
|
@@ -554,10 +550,8 @@ again:
|
|
} else if (tref_iscdata(idx)) {
|
|
} else if (tref_iscdata(idx)) {
|
|
GCcdata *cdk = cdataV(&rd->argv[1]);
|
|
GCcdata *cdk = cdataV(&rd->argv[1]);
|
|
CType *ctk = ctype_raw(cts, cdk->ctypeid);
|
|
CType *ctk = ctype_raw(cts, cdk->ctypeid);
|
|
- IRType t;
|
|
|
|
- if (ctype_isenum(ctk->info)) ctk = ctype_child(cts, ctk);
|
|
|
|
- if (ctype_ispointer(ct->info) &&
|
|
|
|
- ctype_isinteger(ctk->info) && (t = crec_ct2irt(ctk)) != IRT_CDATA) {
|
|
|
|
|
|
+ IRType t = crec_ct2irt(cts, ctk);
|
|
|
|
+ if (ctype_ispointer(ct->info) && t >= IRT_I8 && t <= IRT_U64) {
|
|
if (ctk->size == 8) {
|
|
if (ctk->size == 8) {
|
|
idx = emitir(IRT(IR_FLOAD, t), idx, IRFL_CDATA_INT64);
|
|
idx = emitir(IRT(IR_FLOAD, t), idx, IRFL_CDATA_INT64);
|
|
} else if (ctk->size == 4) {
|
|
} else if (ctk->size == 4) {
|
|
@@ -637,7 +631,6 @@ again:
|
|
ct = ctype_child(cts, ct); /* Skip attributes. */
|
|
ct = ctype_child(cts, ct); /* Skip attributes. */
|
|
|
|
|
|
if (rd->data == 0) { /* __index metamethod. */
|
|
if (rd->data == 0) { /* __index metamethod. */
|
|
- if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct); /* Skip enums. */
|
|
|
|
J->base[0] = crec_tv_ct(J, ct, sid, ptr);
|
|
J->base[0] = crec_tv_ct(J, ct, sid, ptr);
|
|
} else { /* __newindex metamethod. */
|
|
} else { /* __newindex metamethod. */
|
|
rd->nres = 0;
|
|
rd->nres = 0;
|
|
@@ -888,7 +881,7 @@ static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd)
|
|
if (ctype_isfunc(ct->info)) {
|
|
if (ctype_isfunc(ct->info)) {
|
|
TRef func = emitir(IRT(IR_FLOAD, tp), J->base[0], IRFL_CDATA_PTR);
|
|
TRef func = emitir(IRT(IR_FLOAD, tp), J->base[0], IRFL_CDATA_PTR);
|
|
CType *ctr = ctype_rawchild(cts, ct);
|
|
CType *ctr = ctype_rawchild(cts, ct);
|
|
- IRType t = crec_ct2irt(ctr);
|
|
|
|
|
|
+ IRType t = crec_ct2irt(cts, ctr);
|
|
TRef tr;
|
|
TRef tr;
|
|
TValue tv;
|
|
TValue tv;
|
|
/* Check for blacklisted C functions that might call a callback. */
|
|
/* Check for blacklisted C functions that might call a callback. */
|
|
@@ -899,12 +892,10 @@ static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd)
|
|
if (ctype_isvoid(ctr->info)) {
|
|
if (ctype_isvoid(ctr->info)) {
|
|
t = IRT_NIL;
|
|
t = IRT_NIL;
|
|
rd->nres = 0;
|
|
rd->nres = 0;
|
|
- } else if (ctype_isenum(ctr->info)) {
|
|
|
|
- ctr = ctype_child(cts, ctr);
|
|
|
|
- }
|
|
|
|
- if (!(ctype_isnum(ctr->info) || ctype_isptr(ctr->info) ||
|
|
|
|
- ctype_isvoid(ctr->info)) || t == IRT_CDATA)
|
|
|
|
|
|
+ } else if (!(ctype_isnum(ctr->info) || ctype_isptr(ctr->info) ||
|
|
|
|
+ ctype_isenum(ctr->info)) || t == IRT_CDATA) {
|
|
lj_trace_err(J, LJ_TRERR_NYICALL);
|
|
lj_trace_err(J, LJ_TRERR_NYICALL);
|
|
|
|
+ }
|
|
if ((ct->info & CTF_VARARG)
|
|
if ((ct->info & CTF_VARARG)
|
|
#if LJ_TARGET_X86
|
|
#if LJ_TARGET_X86
|
|
|| ctype_cconv(ct->info) != CTCC_CDECL
|
|
|| ctype_cconv(ct->info) != CTCC_CDECL
|
|
@@ -923,17 +914,17 @@ static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd)
|
|
J->postproc = LJ_POST_FIXGUARDSNAP;
|
|
J->postproc = LJ_POST_FIXGUARDSNAP;
|
|
tr = TREF_TRUE;
|
|
tr = TREF_TRUE;
|
|
}
|
|
}
|
|
|
|
+ } else if (t == IRT_PTR || (LJ_64 && t == IRT_P32) ||
|
|
|
|
+ t == IRT_I64 || t == IRT_U64 || ctype_isenum(ctr->info)) {
|
|
|
|
+ TRef trid = lj_ir_kint(J, ctype_cid(ct->info));
|
|
|
|
+ tr = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, tr);
|
|
|
|
+ if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J);
|
|
} else if (t == IRT_FLOAT || t == IRT_U32) {
|
|
} else if (t == IRT_FLOAT || t == IRT_U32) {
|
|
tr = emitconv(tr, IRT_NUM, t, 0);
|
|
tr = emitconv(tr, IRT_NUM, t, 0);
|
|
} else if (t == IRT_I8 || t == IRT_I16) {
|
|
} else if (t == IRT_I8 || t == IRT_I16) {
|
|
tr = emitconv(tr, IRT_INT, t, IRCONV_SEXT);
|
|
tr = emitconv(tr, IRT_INT, t, IRCONV_SEXT);
|
|
} else if (t == IRT_U8 || t == IRT_U16) {
|
|
} else if (t == IRT_U8 || t == IRT_U16) {
|
|
tr = emitconv(tr, IRT_INT, t, 0);
|
|
tr = emitconv(tr, IRT_INT, t, 0);
|
|
- } else if (t == IRT_PTR || (LJ_64 && t == IRT_P32) ||
|
|
|
|
- (t == IRT_I64 || t == IRT_U64)) {
|
|
|
|
- TRef trid = lj_ir_kint(J, ctype_cid(ct->info));
|
|
|
|
- tr = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, tr);
|
|
|
|
- if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J);
|
|
|
|
}
|
|
}
|
|
J->base[0] = tr;
|
|
J->base[0] = tr;
|
|
J->needsnap = 1;
|
|
J->needsnap = 1;
|
|
@@ -981,12 +972,25 @@ static TRef crec_arith_int64(jit_State *J, TRef *sp, CType **s, MMS mm)
|
|
CTypeID id;
|
|
CTypeID id;
|
|
TRef tr;
|
|
TRef tr;
|
|
MSize i;
|
|
MSize i;
|
|
|
|
+ IROp op;
|
|
lj_needsplit(J);
|
|
lj_needsplit(J);
|
|
if (((s[0]->info & CTF_UNSIGNED) && s[0]->size == 8) ||
|
|
if (((s[0]->info & CTF_UNSIGNED) && s[0]->size == 8) ||
|
|
((s[1]->info & CTF_UNSIGNED) && s[1]->size == 8)) {
|
|
((s[1]->info & CTF_UNSIGNED) && s[1]->size == 8)) {
|
|
dt = IRT_U64; id = CTID_UINT64;
|
|
dt = IRT_U64; id = CTID_UINT64;
|
|
} else {
|
|
} else {
|
|
dt = IRT_I64; id = CTID_INT64;
|
|
dt = IRT_I64; id = CTID_INT64;
|
|
|
|
+ if (mm < MM_add &&
|
|
|
|
+ !((s[0]->info | s[1]->info) & CTF_FP) &&
|
|
|
|
+ s[0]->size == 4 && s[1]->size == 4) { /* Try to narrow comparison. */
|
|
|
|
+ if (!((s[0]->info ^ s[1]->info) & CTF_UNSIGNED) ||
|
|
|
|
+ (tref_isk(sp[1]) && IR(tref_ref(sp[1]))->i >= 0)) {
|
|
|
|
+ dt = (s[0]->info & CTF_UNSIGNED) ? IRT_U32 : IRT_INT;
|
|
|
|
+ goto comp;
|
|
|
|
+ } else if (tref_isk(sp[0]) && IR(tref_ref(sp[0]))->i >= 0) {
|
|
|
|
+ dt = (s[1]->info & CTF_UNSIGNED) ? IRT_U32 : IRT_INT;
|
|
|
|
+ goto comp;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
for (i = 0; i < 2; i++) {
|
|
for (i = 0; i < 2; i++) {
|
|
IRType st = tref_type(sp[i]);
|
|
IRType st = tref_type(sp[i]);
|
|
@@ -994,16 +998,16 @@ static TRef crec_arith_int64(jit_State *J, TRef *sp, CType **s, MMS mm)
|
|
sp[i] = emitconv(sp[i], dt, st, IRCONV_TRUNC|IRCONV_ANY);
|
|
sp[i] = emitconv(sp[i], dt, st, IRCONV_TRUNC|IRCONV_ANY);
|
|
else if (!(st == IRT_I64 || st == IRT_U64))
|
|
else if (!(st == IRT_I64 || st == IRT_U64))
|
|
sp[i] = emitconv(sp[i], dt, IRT_INT,
|
|
sp[i] = emitconv(sp[i], dt, IRT_INT,
|
|
- ((st - IRT_I8) & 1) ? 0 : IRCONV_SEXT);
|
|
|
|
|
|
+ (s[i]->info & CTF_UNSIGNED) ? 0 : IRCONV_SEXT);
|
|
}
|
|
}
|
|
if (mm < MM_add) {
|
|
if (mm < MM_add) {
|
|
|
|
+ comp:
|
|
/* Assume true comparison. Fixup and emit pending guard later. */
|
|
/* Assume true comparison. Fixup and emit pending guard later. */
|
|
- IROp op;
|
|
|
|
if (mm == MM_eq) {
|
|
if (mm == MM_eq) {
|
|
op = IR_EQ;
|
|
op = IR_EQ;
|
|
} else {
|
|
} else {
|
|
op = mm == MM_lt ? IR_LT : IR_LE;
|
|
op = mm == MM_lt ? IR_LT : IR_LE;
|
|
- if (dt == IRT_U64)
|
|
|
|
|
|
+ if (dt == IRT_U32 || dt == IRT_U64)
|
|
op += (IR_ULT-IR_LT);
|
|
op += (IR_ULT-IR_LT);
|
|
}
|
|
}
|
|
lj_ir_set(J, IRTG(op, dt), sp[0], sp[1]);
|
|
lj_ir_set(J, IRTG(op, dt), sp[0], sp[1]);
|
|
@@ -1116,26 +1120,33 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd)
|
|
goto trymeta;
|
|
goto trymeta;
|
|
} else if (tref_iscdata(tr)) {
|
|
} else if (tref_iscdata(tr)) {
|
|
CTypeID id = argv2cdata(J, tr, &rd->argv[i])->ctypeid;
|
|
CTypeID id = argv2cdata(J, tr, &rd->argv[i])->ctypeid;
|
|
|
|
+ IRType t;
|
|
ct = ctype_raw(cts, id);
|
|
ct = ctype_raw(cts, id);
|
|
|
|
+ t = crec_ct2irt(cts, ct);
|
|
if (ctype_isptr(ct->info)) { /* Resolve pointer or reference. */
|
|
if (ctype_isptr(ct->info)) { /* Resolve pointer or reference. */
|
|
- IRType t = (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32;
|
|
|
|
- if (ctype_isref(ct->info)) ct = ctype_rawchild(cts, ct);
|
|
|
|
tr = emitir(IRT(IR_FLOAD, t), tr, IRFL_CDATA_PTR);
|
|
tr = emitir(IRT(IR_FLOAD, t), tr, IRFL_CDATA_PTR);
|
|
- } else if (ctype_isinteger(ct->info) && ct->size == 8) {
|
|
|
|
- IRType t = (ct->info & CTF_UNSIGNED) ? IRT_U64 : IRT_I64;
|
|
|
|
|
|
+ if (ctype_isref(ct->info)) {
|
|
|
|
+ ct = ctype_rawchild(cts, ct);
|
|
|
|
+ t = crec_ct2irt(cts, ct);
|
|
|
|
+ }
|
|
|
|
+ } else if (t == IRT_I64 || t == IRT_U64) {
|
|
tr = emitir(IRT(IR_FLOAD, t), tr, IRFL_CDATA_INT64);
|
|
tr = emitir(IRT(IR_FLOAD, t), tr, IRFL_CDATA_INT64);
|
|
lj_needsplit(J);
|
|
lj_needsplit(J);
|
|
goto ok;
|
|
goto ok;
|
|
|
|
+ } else if (t == IRT_INT || t == IRT_U32) {
|
|
|
|
+ tr = emitir(IRT(IR_FLOAD, t), tr, IRFL_CDATA_INT);
|
|
|
|
+ if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
|
|
|
|
+ goto ok;
|
|
} else if (ctype_isfunc(ct->info)) {
|
|
} else if (ctype_isfunc(ct->info)) {
|
|
tr = emitir(IRT(IR_FLOAD, IRT_PTR), tr, IRFL_CDATA_PTR);
|
|
tr = emitir(IRT(IR_FLOAD, IRT_PTR), tr, IRFL_CDATA_PTR);
|
|
ct = ctype_get(cts,
|
|
ct = ctype_get(cts,
|
|
lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|id), CTSIZE_PTR));
|
|
lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|id), CTSIZE_PTR));
|
|
|
|
+ goto ok;
|
|
} else {
|
|
} else {
|
|
tr = emitir(IRT(IR_ADD, IRT_PTR), tr, lj_ir_kintp(J, sizeof(GCcdata)));
|
|
tr = emitir(IRT(IR_ADD, IRT_PTR), tr, lj_ir_kintp(J, sizeof(GCcdata)));
|
|
}
|
|
}
|
|
if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
|
|
if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
|
|
if (ctype_isnum(ct->info)) {
|
|
if (ctype_isnum(ct->info)) {
|
|
- IRType t = crec_ct2irt(ct);
|
|
|
|
if (t == IRT_CDATA) goto trymeta;
|
|
if (t == IRT_CDATA) goto trymeta;
|
|
if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J);
|
|
if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J);
|
|
tr = emitir(IRT(IR_XLOAD, t), tr, 0);
|
|
tr = emitir(IRT(IR_XLOAD, t), tr, 0);
|
|
@@ -1147,6 +1158,21 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd)
|
|
ct = ctype_get(cts, CTID_P_VOID);
|
|
ct = ctype_get(cts, CTID_P_VOID);
|
|
} else if (tref_isinteger(tr)) {
|
|
} else if (tref_isinteger(tr)) {
|
|
ct = ctype_get(cts, CTID_INT32);
|
|
ct = ctype_get(cts, CTID_INT32);
|
|
|
|
+ } else if (tref_isstr(tr)) {
|
|
|
|
+ TRef tr2 = J->base[1-i];
|
|
|
|
+ CTypeID id = argv2cdata(J, tr2, &rd->argv[1-i])->ctypeid;
|
|
|
|
+ ct = ctype_raw(cts, id);
|
|
|
|
+ if (ctype_isenum(ct->info)) { /* Match string against enum constant. */
|
|
|
|
+ GCstr *str = strV(&rd->argv[i]);
|
|
|
|
+ CTSize ofs;
|
|
|
|
+ CType *cct = lj_ctype_getfield(cts, ct, str, &ofs);
|
|
|
|
+ if (cct && ctype_isconstval(cct->info)) {
|
|
|
|
+ /* Specialize to the name of the enum constant. */
|
|
|
|
+ emitir(IRTG(IR_EQ, IRT_STR), tr, lj_ir_kstr(J, str));
|
|
|
|
+ ct = ctype_child(cts, cct);
|
|
|
|
+ tr = lj_ir_kint(J, (int32_t)ofs);
|
|
|
|
+ } /* else: interpreter will throw. */
|
|
|
|
+ } /* else: interpreter will throw. */
|
|
} else if (!tref_isnum(tr)) {
|
|
} else if (!tref_isnum(tr)) {
|
|
goto trymeta;
|
|
goto trymeta;
|
|
}
|
|
}
|
|
@@ -1203,7 +1229,6 @@ void LJ_FASTCALL recff_clib_index(jit_State *J, RecordFFData *rd)
|
|
void *sp = *(void **)cdataptr(cdataV(tv));
|
|
void *sp = *(void **)cdataptr(cdataV(tv));
|
|
TRef ptr;
|
|
TRef ptr;
|
|
ct = ctype_raw(cts, sid);
|
|
ct = ctype_raw(cts, sid);
|
|
- if (rd->data && ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
|
|
|
|
if (LJ_64 && !checkptr32(sp))
|
|
if (LJ_64 && !checkptr32(sp))
|
|
ptr = lj_ir_kintp(J, (uintptr_t)sp);
|
|
ptr = lj_ir_kintp(J, (uintptr_t)sp);
|
|
else
|
|
else
|