From 4d9c29a78cde2596ea3286744d93d29dd2a6d9ca Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Tue, 17 Jul 2012 22:20:03 +0200 Subject: FFI: Box all accessed or returned enums. --- src/lib_ffi.c | 4 +- src/lj_asm_arm.h | 2 +- src/lj_asm_x86.h | 5 ++- src/lj_carith.c | 31 ++++++++++++++-- src/lj_ccall.c | 1 - src/lj_ccallback.c | 1 - src/lj_cconv.c | 1 - src/lj_cdata.c | 4 +- src/lj_crecord.c | 107 +++++++++++++++++++++++++++++++++-------------------- src/lj_opt_fold.c | 2 + 10 files changed, 105 insertions(+), 53 deletions(-) (limited to 'src') diff --git a/src/lib_ffi.c b/src/lib_ffi.c index c74b497a..5cb9086e 100644 --- a/src/lib_ffi.c +++ b/src/lib_ffi.c @@ -297,6 +297,9 @@ LJLIB_CF(ffi_meta___tostring) goto checkgc; } else if (ctype_isfunc(ct->info)) { p = *(void **)p; + } else if (ctype_isenum(ct->info)) { + msg = "cdata<%s>: %d"; + p = (void *)(uintptr_t)*(uint32_t **)p; } else { if (ctype_isptr(ct->info)) { p = cdata_getptr(p, ct->size); @@ -348,7 +351,6 @@ LJLIB_CF(ffi_clib___index) LJLIB_REC(clib_index 1) CTypeID sid = ctype_cid(s->info); void *sp = *(void **)cdataptr(cd); CType *ct = ctype_raw(cts, sid); - if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct); if (lj_cconv_tv_ct(cts, ct, sid, L->top-1, sp)) lj_gc_check(L); return 1; diff --git a/src/lj_asm_arm.h b/src/lj_asm_arm.h index 9ef785c3..6a44e5ef 100644 --- a/src/lj_asm_arm.h +++ b/src/lj_asm_arm.h @@ -1287,7 +1287,7 @@ static void asm_intcomp(ASMState *as, IRIns *ir) Reg left; uint32_t m; int cmpprev0 = 0; - lua_assert(irt_isint(ir->t) || irt_isaddr(ir->t)); + lua_assert(irt_isint(ir->t) || irt_isu32(ir->t) || irt_isaddr(ir->t)); if (asm_swapops(as, lref, rref)) { Reg tmp = lref; lref = rref; rref = tmp; if (cc >= CC_GE) cc ^= 7; /* LT <-> GT, LE <-> GE */ diff --git a/src/lj_asm_x86.h b/src/lj_asm_x86.h index c68768b4..ceeefbee 100644 --- a/src/lj_asm_x86.h +++ b/src/lj_asm_x86.h @@ -337,7 +337,7 @@ static Reg asm_fuseload(ASMState *as, IRRef ref, RegSet allow) } } else if (ir->o == IR_FLOAD) { /* Generic fusion is only ok for 32 bit operand (but see asm_comp). */ - if ((irt_isint(ir->t) || irt_isaddr(ir->t)) && + if ((irt_isint(ir->t) || irt_isu32(ir->t) || irt_isaddr(ir->t)) && noconflict(as, ref, IR_FSTORE, 0)) { asm_fusefref(as, ir, xallow); return RID_MRM; @@ -2064,7 +2064,8 @@ static void asm_comp(ASMState *as, IRIns *ir, uint32_t cc) IROp leftop = (IROp)(IR(lref)->o); Reg r64 = REX_64IR(ir, 0); int32_t imm = 0; - lua_assert(irt_is64(ir->t) || irt_isint(ir->t) || irt_isaddr(ir->t)); + lua_assert(irt_is64(ir->t) || irt_isint(ir->t) || + irt_isu32(ir->t) || irt_isaddr(ir->t)); /* Swap constants (only for ABC) and fusable loads to the right. */ if (irref_isk(lref) || (!irref_isk(rref) && opisfusableload(leftop))) { if ((cc & 0xc) == 0xc) cc ^= 0x53; /* L <-> G, LE <-> GE */ diff --git a/src/lj_carith.c b/src/lj_carith.c index c5275f70..8c76abe9 100644 --- a/src/lj_carith.c +++ b/src/lj_carith.c @@ -46,6 +46,7 @@ static int carith_checkarg(lua_State *L, CTState *cts, CDArith *ca) ct = ctype_get(cts, lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|id), CTSIZE_PTR)); } + if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct); ca->ct[i] = ct; ca->p[i] = p; } else if (tvisint(o)) { @@ -57,6 +58,25 @@ static int carith_checkarg(lua_State *L, CTState *cts, CDArith *ca) } else if (tvisnil(o)) { ca->ct[i] = ctype_get(cts, CTID_P_VOID); ca->p[i] = (uint8_t *)0; + } else if (tvisstr(o)) { + TValue *o2 = i == 0 ? o+1 : o-1; + CType *ct = ctype_raw(cts, cdataV(o2)->ctypeid); + ca->ct[i] = NULL; + ca->p[i] = NULL; + ok = 0; + if (ctype_isenum(ct->info)) { + CTSize ofs; + CType *cct = lj_ctype_getfield(cts, ct, strV(o), &ofs); + if (cct && ctype_isconstval(cct->info)) { + ca->ct[i] = ctype_child(cts, cct); + ca->p[i] = (uint8_t *)&cct->size; /* Assumes ct does not grow. */ + ok = 1; + } else { + ca->ct[1-i] = ct; /* Use enum to improve error message. */ + ca->p[1-i] = NULL; + break; + } + } } else { ca->ct[i] = NULL; ca->p[i] = NULL; @@ -204,17 +224,22 @@ static int lj_carith_meta(lua_State *L, CTState *cts, CDArith *ca, MMS mm) tv = lj_ctype_meta(cts, cdataV(L->base+1)->ctypeid, mm); if (!tv) { const char *repr[2]; - int i; + int i, isenum = -1, isstr = -1; if (mm == MM_eq) { /* Equality checks never raise an error. */ setboolV(L->top-1, 0); return 1; } for (i = 0; i < 2; i++) { - if (ca->ct[i]) + if (ca->ct[i]) { + if (ctype_isenum(ca->ct[i]->info)) isenum = i; repr[i] = strdata(lj_ctype_repr(L, ctype_typeid(cts, ca->ct[i]), NULL)); - else + } else { + if (tvisstr(&L->base[i])) isstr = i; repr[i] = lj_typename(&L->base[i]); + } } + if ((isenum ^ isstr) == 1) + lj_err_callerv(L, LJ_ERR_FFI_BADCONV, repr[isstr], repr[isenum]); lj_err_callerv(L, mm == MM_len ? LJ_ERR_FFI_BADLEN : mm == MM_concat ? LJ_ERR_FFI_BADCONCAT : mm < MM_add ? LJ_ERR_FFI_BADCOMP : LJ_ERR_FFI_BADARITH, diff --git a/src/lj_ccall.c b/src/lj_ccall.c index 22171778..c3eb25f6 100644 --- a/src/lj_ccall.c +++ b/src/lj_ccall.c @@ -684,7 +684,6 @@ static int ccall_get_results(lua_State *L, CTState *cts, CType *ct, #endif /* No reference types end up here, so there's no need for the CTypeID. */ lua_assert(!(ctype_isrefarray(ctr->info) || ctype_isstruct(ctr->info))); - if (ctype_isenum(ctr->info)) ctr = ctype_child(cts, ctr); return lj_cconv_tv_ct(cts, ctr, 0, L->top-1, sp); } diff --git a/src/lj_ccallback.c b/src/lj_ccallback.c index c3f37f2d..a9567bc5 100644 --- a/src/lj_ccallback.c +++ b/src/lj_ccallback.c @@ -426,7 +426,6 @@ static void callback_conv_args(CTState *cts, lua_State *L) MSize n; lua_assert(ctype_isfield(ctf->info)); cta = ctype_rawchild(cts, ctf); - if (ctype_isenum(cta->info)) cta = ctype_child(cts, cta); isfp = ctype_isfp(cta->info); sz = (cta->size + CTSIZE_PTR-1) & ~(CTSIZE_PTR-1); n = sz / CTSIZE_PTR; /* Number of GPRs or stack slots needed. */ diff --git a/src/lj_cconv.c b/src/lj_cconv.c index 9964f8a4..f33ed56d 100644 --- a/src/lj_cconv.c +++ b/src/lj_cconv.c @@ -374,7 +374,6 @@ int lj_cconv_tv_ct(CTState *cts, CType *s, CTypeID sid, TValue *o, uint8_t *sp) { CTInfo sinfo = s->info; - lua_assert(!ctype_isenum(sinfo)); if (ctype_isnum(sinfo)) { if (!ctype_isbool(sinfo)) { if (ctype_isinteger(sinfo) && s->size > 4) goto copyval; diff --git a/src/lj_cdata.c b/src/lj_cdata.c index 461b55a2..2f10113b 100644 --- a/src/lj_cdata.c +++ b/src/lj_cdata.c @@ -231,8 +231,8 @@ int lj_cdata_get(CTState *cts, CType *s, TValue *o, uint8_t *sp) s = ctype_get(cts, sid); } - /* Skip attributes and enums. */ - while (ctype_isattrib(s->info) || ctype_isenum(s->info)) + /* Skip attributes. */ + while (ctype_isattrib(s->info)) s = ctype_child(cts, s); return lj_cconv_tv_ct(cts, s, sid, o, sp); diff --git a/src/lj_crecord.c b/src/lj_crecord.c index 6cb565c3..49b2341a 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c @@ -111,8 +111,9 @@ static CTypeID argv2ctype(jit_State *J, TRef tr, cTValue *o) */ /* 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 ((ct->info & CTF_FP)) { 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, 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; 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) 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) { CTState *cts = ctype_ctsG(J2G(J)); + IRType t = crec_ct2irt(cts, s); CTInfo sinfo = s->info; - lua_assert(!ctype_isenum(sinfo)); if (ctype_isnum(sinfo)) { - IRType t = crec_ct2irt(s); TRef tr; if (t == IRT_CDATA) 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 { 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)) { cts->L = J->L; sid = lj_ctype_intern(cts, CTINFO_REF(sid), CTSIZE_PTR); /* Create ref. */ } 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); TRef ptr, tr1, tr2, dp; 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: 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); } @@ -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)); if (cct && ctype_isconstval(cct->info)) { 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); } /* else: interpreter will throw. */ } 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; s = ctype_raw(cts, sid); 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)) { sp = emitir(IRT(IR_FLOAD, t), sp, IRFL_CDATA_PTR); if (ctype_isref(s->info)) { svisnz = *(void **)svisnz; 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 { goto doconv; } @@ -554,10 +550,8 @@ again: } else if (tref_iscdata(idx)) { GCcdata *cdk = cdataV(&rd->argv[1]); 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) { idx = emitir(IRT(IR_FLOAD, t), idx, IRFL_CDATA_INT64); } else if (ctk->size == 4) { @@ -637,7 +631,6 @@ again: ct = ctype_child(cts, ct); /* Skip attributes. */ 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); } else { /* __newindex metamethod. */ rd->nres = 0; @@ -888,7 +881,7 @@ static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd) if (ctype_isfunc(ct->info)) { TRef func = emitir(IRT(IR_FLOAD, tp), J->base[0], IRFL_CDATA_PTR); CType *ctr = ctype_rawchild(cts, ct); - IRType t = crec_ct2irt(ctr); + IRType t = crec_ct2irt(cts, ctr); TRef tr; TValue tv; /* 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)) { t = IRT_NIL; 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); + } if ((ct->info & CTF_VARARG) #if LJ_TARGET_X86 || 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; 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) { tr = emitconv(tr, IRT_NUM, t, 0); } else if (t == IRT_I8 || t == IRT_I16) { tr = emitconv(tr, IRT_INT, t, IRCONV_SEXT); } else if (t == IRT_U8 || t == IRT_U16) { 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->needsnap = 1; @@ -981,12 +972,25 @@ static TRef crec_arith_int64(jit_State *J, TRef *sp, CType **s, MMS mm) CTypeID id; TRef tr; MSize i; + IROp op; lj_needsplit(J); if (((s[0]->info & CTF_UNSIGNED) && s[0]->size == 8) || ((s[1]->info & CTF_UNSIGNED) && s[1]->size == 8)) { dt = IRT_U64; id = CTID_UINT64; } else { 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++) { 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); else if (!(st == IRT_I64 || st == IRT_U64)) 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) { + comp: /* Assume true comparison. Fixup and emit pending guard later. */ - IROp op; if (mm == MM_eq) { op = IR_EQ; } else { op = mm == MM_lt ? IR_LT : IR_LE; - if (dt == IRT_U64) + if (dt == IRT_U32 || dt == IRT_U64) op += (IR_ULT-IR_LT); } 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; } else if (tref_iscdata(tr)) { CTypeID id = argv2cdata(J, tr, &rd->argv[i])->ctypeid; + IRType t; ct = ctype_raw(cts, id); + t = crec_ct2irt(cts, ct); 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); - } 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); lj_needsplit(J); 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)) { tr = emitir(IRT(IR_FLOAD, IRT_PTR), tr, IRFL_CDATA_PTR); ct = ctype_get(cts, lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|id), CTSIZE_PTR)); + goto ok; } else { 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_isnum(ct->info)) { - IRType t = crec_ct2irt(ct); if (t == IRT_CDATA) goto trymeta; if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J); 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); } else if (tref_isinteger(tr)) { 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)) { goto trymeta; } @@ -1203,7 +1229,6 @@ void LJ_FASTCALL recff_clib_index(jit_State *J, RecordFFData *rd) void *sp = *(void **)cdataptr(cdataV(tv)); TRef ptr; ct = ctype_raw(cts, sid); - if (rd->data && ctype_isenum(ct->info)) ct = ctype_child(cts, ct); if (LJ_64 && !checkptr32(sp)) ptr = lj_ir_kintp(J, (uintptr_t)sp); else diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c index 156db426..f4aadb8d 100644 --- a/src/lj_opt_fold.c +++ b/src/lj_opt_fold.c @@ -575,6 +575,8 @@ LJFOLDF(kfold_conv_kintu32_num) LJFOLD(CONV KINT IRCONV_I64_INT) LJFOLD(CONV KINT IRCONV_U64_INT) +LJFOLD(CONV KINT IRCONV_I64_U32) +LJFOLD(CONV KINT IRCONV_U64_U32) LJFOLDF(kfold_conv_kint_i64) { if ((fins->op2 & IRCONV_SEXT)) -- cgit v1.2.3-55-g6feb