aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2012-07-17 22:20:03 +0200
committerMike Pall <mike>2012-07-17 22:22:07 +0200
commit4d9c29a78cde2596ea3286744d93d29dd2a6d9ca (patch)
tree62af9fd2c6765a06005f8fa8ed00a1b491c0a356 /src
parent2139c6791f4b802560ce62dc688293786803a9ca (diff)
downloadluajit-4d9c29a78cde2596ea3286744d93d29dd2a6d9ca.tar.gz
luajit-4d9c29a78cde2596ea3286744d93d29dd2a6d9ca.tar.bz2
luajit-4d9c29a78cde2596ea3286744d93d29dd2a6d9ca.zip
FFI: Box all accessed or returned enums.
Diffstat (limited to 'src')
-rw-r--r--src/lib_ffi.c4
-rw-r--r--src/lj_asm_arm.h2
-rw-r--r--src/lj_asm_x86.h5
-rw-r--r--src/lj_carith.c31
-rw-r--r--src/lj_ccall.c1
-rw-r--r--src/lj_ccallback.c1
-rw-r--r--src/lj_cconv.c1
-rw-r--r--src/lj_cdata.c4
-rw-r--r--src/lj_crecord.c107
-rw-r--r--src/lj_opt_fold.c2
10 files changed, 105 insertions, 53 deletions
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)
297 goto checkgc; 297 goto checkgc;
298 } else if (ctype_isfunc(ct->info)) { 298 } else if (ctype_isfunc(ct->info)) {
299 p = *(void **)p; 299 p = *(void **)p;
300 } else if (ctype_isenum(ct->info)) {
301 msg = "cdata<%s>: %d";
302 p = (void *)(uintptr_t)*(uint32_t **)p;
300 } else { 303 } else {
301 if (ctype_isptr(ct->info)) { 304 if (ctype_isptr(ct->info)) {
302 p = cdata_getptr(p, ct->size); 305 p = cdata_getptr(p, ct->size);
@@ -348,7 +351,6 @@ LJLIB_CF(ffi_clib___index) LJLIB_REC(clib_index 1)
348 CTypeID sid = ctype_cid(s->info); 351 CTypeID sid = ctype_cid(s->info);
349 void *sp = *(void **)cdataptr(cd); 352 void *sp = *(void **)cdataptr(cd);
350 CType *ct = ctype_raw(cts, sid); 353 CType *ct = ctype_raw(cts, sid);
351 if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
352 if (lj_cconv_tv_ct(cts, ct, sid, L->top-1, sp)) 354 if (lj_cconv_tv_ct(cts, ct, sid, L->top-1, sp))
353 lj_gc_check(L); 355 lj_gc_check(L);
354 return 1; 356 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)
1287 Reg left; 1287 Reg left;
1288 uint32_t m; 1288 uint32_t m;
1289 int cmpprev0 = 0; 1289 int cmpprev0 = 0;
1290 lua_assert(irt_isint(ir->t) || irt_isaddr(ir->t)); 1290 lua_assert(irt_isint(ir->t) || irt_isu32(ir->t) || irt_isaddr(ir->t));
1291 if (asm_swapops(as, lref, rref)) { 1291 if (asm_swapops(as, lref, rref)) {
1292 Reg tmp = lref; lref = rref; rref = tmp; 1292 Reg tmp = lref; lref = rref; rref = tmp;
1293 if (cc >= CC_GE) cc ^= 7; /* LT <-> GT, LE <-> GE */ 1293 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)
337 } 337 }
338 } else if (ir->o == IR_FLOAD) { 338 } else if (ir->o == IR_FLOAD) {
339 /* Generic fusion is only ok for 32 bit operand (but see asm_comp). */ 339 /* Generic fusion is only ok for 32 bit operand (but see asm_comp). */
340 if ((irt_isint(ir->t) || irt_isaddr(ir->t)) && 340 if ((irt_isint(ir->t) || irt_isu32(ir->t) || irt_isaddr(ir->t)) &&
341 noconflict(as, ref, IR_FSTORE, 0)) { 341 noconflict(as, ref, IR_FSTORE, 0)) {
342 asm_fusefref(as, ir, xallow); 342 asm_fusefref(as, ir, xallow);
343 return RID_MRM; 343 return RID_MRM;
@@ -2064,7 +2064,8 @@ static void asm_comp(ASMState *as, IRIns *ir, uint32_t cc)
2064 IROp leftop = (IROp)(IR(lref)->o); 2064 IROp leftop = (IROp)(IR(lref)->o);
2065 Reg r64 = REX_64IR(ir, 0); 2065 Reg r64 = REX_64IR(ir, 0);
2066 int32_t imm = 0; 2066 int32_t imm = 0;
2067 lua_assert(irt_is64(ir->t) || irt_isint(ir->t) || irt_isaddr(ir->t)); 2067 lua_assert(irt_is64(ir->t) || irt_isint(ir->t) ||
2068 irt_isu32(ir->t) || irt_isaddr(ir->t));
2068 /* Swap constants (only for ABC) and fusable loads to the right. */ 2069 /* Swap constants (only for ABC) and fusable loads to the right. */
2069 if (irref_isk(lref) || (!irref_isk(rref) && opisfusableload(leftop))) { 2070 if (irref_isk(lref) || (!irref_isk(rref) && opisfusableload(leftop))) {
2070 if ((cc & 0xc) == 0xc) cc ^= 0x53; /* L <-> G, LE <-> GE */ 2071 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)
46 ct = ctype_get(cts, 46 ct = ctype_get(cts,
47 lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|id), CTSIZE_PTR)); 47 lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|id), CTSIZE_PTR));
48 } 48 }
49 if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
49 ca->ct[i] = ct; 50 ca->ct[i] = ct;
50 ca->p[i] = p; 51 ca->p[i] = p;
51 } else if (tvisint(o)) { 52 } else if (tvisint(o)) {
@@ -57,6 +58,25 @@ static int carith_checkarg(lua_State *L, CTState *cts, CDArith *ca)
57 } else if (tvisnil(o)) { 58 } else if (tvisnil(o)) {
58 ca->ct[i] = ctype_get(cts, CTID_P_VOID); 59 ca->ct[i] = ctype_get(cts, CTID_P_VOID);
59 ca->p[i] = (uint8_t *)0; 60 ca->p[i] = (uint8_t *)0;
61 } else if (tvisstr(o)) {
62 TValue *o2 = i == 0 ? o+1 : o-1;
63 CType *ct = ctype_raw(cts, cdataV(o2)->ctypeid);
64 ca->ct[i] = NULL;
65 ca->p[i] = NULL;
66 ok = 0;
67 if (ctype_isenum(ct->info)) {
68 CTSize ofs;
69 CType *cct = lj_ctype_getfield(cts, ct, strV(o), &ofs);
70 if (cct && ctype_isconstval(cct->info)) {
71 ca->ct[i] = ctype_child(cts, cct);
72 ca->p[i] = (uint8_t *)&cct->size; /* Assumes ct does not grow. */
73 ok = 1;
74 } else {
75 ca->ct[1-i] = ct; /* Use enum to improve error message. */
76 ca->p[1-i] = NULL;
77 break;
78 }
79 }
60 } else { 80 } else {
61 ca->ct[i] = NULL; 81 ca->ct[i] = NULL;
62 ca->p[i] = NULL; 82 ca->p[i] = NULL;
@@ -204,17 +224,22 @@ static int lj_carith_meta(lua_State *L, CTState *cts, CDArith *ca, MMS mm)
204 tv = lj_ctype_meta(cts, cdataV(L->base+1)->ctypeid, mm); 224 tv = lj_ctype_meta(cts, cdataV(L->base+1)->ctypeid, mm);
205 if (!tv) { 225 if (!tv) {
206 const char *repr[2]; 226 const char *repr[2];
207 int i; 227 int i, isenum = -1, isstr = -1;
208 if (mm == MM_eq) { /* Equality checks never raise an error. */ 228 if (mm == MM_eq) { /* Equality checks never raise an error. */
209 setboolV(L->top-1, 0); 229 setboolV(L->top-1, 0);
210 return 1; 230 return 1;
211 } 231 }
212 for (i = 0; i < 2; i++) { 232 for (i = 0; i < 2; i++) {
213 if (ca->ct[i]) 233 if (ca->ct[i]) {
234 if (ctype_isenum(ca->ct[i]->info)) isenum = i;
214 repr[i] = strdata(lj_ctype_repr(L, ctype_typeid(cts, ca->ct[i]), NULL)); 235 repr[i] = strdata(lj_ctype_repr(L, ctype_typeid(cts, ca->ct[i]), NULL));
215 else 236 } else {
237 if (tvisstr(&L->base[i])) isstr = i;
216 repr[i] = lj_typename(&L->base[i]); 238 repr[i] = lj_typename(&L->base[i]);
239 }
217 } 240 }
241 if ((isenum ^ isstr) == 1)
242 lj_err_callerv(L, LJ_ERR_FFI_BADCONV, repr[isstr], repr[isenum]);
218 lj_err_callerv(L, mm == MM_len ? LJ_ERR_FFI_BADLEN : 243 lj_err_callerv(L, mm == MM_len ? LJ_ERR_FFI_BADLEN :
219 mm == MM_concat ? LJ_ERR_FFI_BADCONCAT : 244 mm == MM_concat ? LJ_ERR_FFI_BADCONCAT :
220 mm < MM_add ? LJ_ERR_FFI_BADCOMP : LJ_ERR_FFI_BADARITH, 245 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,
684#endif 684#endif
685 /* No reference types end up here, so there's no need for the CTypeID. */ 685 /* No reference types end up here, so there's no need for the CTypeID. */
686 lua_assert(!(ctype_isrefarray(ctr->info) || ctype_isstruct(ctr->info))); 686 lua_assert(!(ctype_isrefarray(ctr->info) || ctype_isstruct(ctr->info)));
687 if (ctype_isenum(ctr->info)) ctr = ctype_child(cts, ctr);
688 return lj_cconv_tv_ct(cts, ctr, 0, L->top-1, sp); 687 return lj_cconv_tv_ct(cts, ctr, 0, L->top-1, sp);
689} 688}
690 689
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)
426 MSize n; 426 MSize n;
427 lua_assert(ctype_isfield(ctf->info)); 427 lua_assert(ctype_isfield(ctf->info));
428 cta = ctype_rawchild(cts, ctf); 428 cta = ctype_rawchild(cts, ctf);
429 if (ctype_isenum(cta->info)) cta = ctype_child(cts, cta);
430 isfp = ctype_isfp(cta->info); 429 isfp = ctype_isfp(cta->info);
431 sz = (cta->size + CTSIZE_PTR-1) & ~(CTSIZE_PTR-1); 430 sz = (cta->size + CTSIZE_PTR-1) & ~(CTSIZE_PTR-1);
432 n = sz / CTSIZE_PTR; /* Number of GPRs or stack slots needed. */ 431 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,
374 TValue *o, uint8_t *sp) 374 TValue *o, uint8_t *sp)
375{ 375{
376 CTInfo sinfo = s->info; 376 CTInfo sinfo = s->info;
377 lua_assert(!ctype_isenum(sinfo));
378 if (ctype_isnum(sinfo)) { 377 if (ctype_isnum(sinfo)) {
379 if (!ctype_isbool(sinfo)) { 378 if (!ctype_isbool(sinfo)) {
380 if (ctype_isinteger(sinfo) && s->size > 4) goto copyval; 379 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)
231 s = ctype_get(cts, sid); 231 s = ctype_get(cts, sid);
232 } 232 }
233 233
234 /* Skip attributes and enums. */ 234 /* Skip attributes. */
235 while (ctype_isattrib(s->info) || ctype_isenum(s->info)) 235 while (ctype_isattrib(s->info))
236 s = ctype_child(cts, s); 236 s = ctype_child(cts, s);
237 237
238 return lj_cconv_tv_ct(cts, s, sid, o, sp); 238 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)
111*/ 111*/
112 112
113/* Convert CType to IRType. */ 113/* Convert CType to IRType. */
114static IRType crec_ct2irt(CType *ct) 114static IRType crec_ct2irt(CTState *cts, CType *ct)
115{ 115{
116 if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
116 if (LJ_LIKELY(ctype_isnum(ct->info))) { 117 if (LJ_LIKELY(ctype_isnum(ct->info))) {
117 if ((ct->info & CTF_FP)) { 118 if ((ct->info & CTF_FP)) {
118 if (ct->size == sizeof(double)) 119 if (ct->size == sizeof(double))
@@ -162,10 +163,10 @@ static int crec_isnonzero(CType *s, void *p)
162static TRef crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp, 163static TRef crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp,
163 void *svisnz) 164 void *svisnz)
164{ 165{
166 IRType dt = crec_ct2irt(ctype_ctsG(J2G(J)), d);
167 IRType st = crec_ct2irt(ctype_ctsG(J2G(J)), s);
165 CTSize dsize = d->size, ssize = s->size; 168 CTSize dsize = d->size, ssize = s->size;
166 CTInfo dinfo = d->info, sinfo = s->info; 169 CTInfo dinfo = d->info, sinfo = s->info;
167 IRType dt = crec_ct2irt(d);
168 IRType st = crec_ct2irt(s);
169 170
170 if (ctype_type(dinfo) > CT_MAYCONVERT || ctype_type(sinfo) > CT_MAYCONVERT) 171 if (ctype_type(dinfo) > CT_MAYCONVERT || ctype_type(sinfo) > CT_MAYCONVERT)
171 goto err_conv; 172 goto err_conv;
@@ -317,10 +318,9 @@ static TRef crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp,
317static TRef crec_tv_ct(jit_State *J, CType *s, CTypeID sid, TRef sp) 318static TRef crec_tv_ct(jit_State *J, CType *s, CTypeID sid, TRef sp)
318{ 319{
319 CTState *cts = ctype_ctsG(J2G(J)); 320 CTState *cts = ctype_ctsG(J2G(J));
321 IRType t = crec_ct2irt(cts, s);
320 CTInfo sinfo = s->info; 322 CTInfo sinfo = s->info;
321 lua_assert(!ctype_isenum(sinfo));
322 if (ctype_isnum(sinfo)) { 323 if (ctype_isnum(sinfo)) {
323 IRType t = crec_ct2irt(s);
324 TRef tr; 324 TRef tr;
325 if (t == IRT_CDATA) 325 if (t == IRT_CDATA)
326 goto err_nyi; /* NYI: copyval of >64 bit integers. */ 326 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)
338 } else { 338 } else {
339 return tr; 339 return tr;
340 } 340 }
341 } else if (ctype_isptr(sinfo)) { 341 } else if (ctype_isptr(sinfo) || ctype_isenum(sinfo)) {
342 IRType t = (LJ_64 && s->size == 8) ? IRT_P64 : IRT_P32; 342 sp = emitir(IRT(IR_XLOAD, t), sp, 0); /* Box pointers and enums. */
343 sp = emitir(IRT(IR_XLOAD, t), sp, 0);
344 } else if (ctype_isrefarray(sinfo) || ctype_isstruct(sinfo)) { 343 } else if (ctype_isrefarray(sinfo) || ctype_isstruct(sinfo)) {
345 cts->L = J->L; 344 cts->L = J->L;
346 sid = lj_ctype_intern(cts, CTINFO_REF(sid), CTSIZE_PTR); /* Create ref. */ 345 sid = lj_ctype_intern(cts, CTINFO_REF(sid), CTSIZE_PTR); /* Create ref. */
347 } else if (ctype_iscomplex(sinfo)) { /* Unbox/box complex. */ 346 } else if (ctype_iscomplex(sinfo)) { /* Unbox/box complex. */
348 IRType t = s->size == 2*sizeof(double) ? IRT_NUM : IRT_FLOAT;
349 ptrdiff_t esz = (ptrdiff_t)(s->size >> 1); 347 ptrdiff_t esz = (ptrdiff_t)(s->size >> 1);
350 TRef ptr, tr1, tr2, dp; 348 TRef ptr, tr1, tr2, dp;
351 dp = emitir(IRTG(IR_CNEW, IRT_CDATA), lj_ir_kint(J, sid), TREF_NIL); 349 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)
362 err_nyi: 360 err_nyi:
363 lj_trace_err(J, LJ_TRERR_NYICONV); 361 lj_trace_err(J, LJ_TRERR_NYICONV);
364 } 362 }
365 /* Box pointer, ref or 64 bit integer. */ 363 /* Box pointer, ref, enum or 64 bit integer. */
366 return emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, sid), sp); 364 return emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, sid), sp);
367} 365}
368 366
@@ -403,8 +401,8 @@ static TRef crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, cTValue *sval)
403 emitir(IRTG(IR_EQ, IRT_STR), sp, lj_ir_kstr(J, str)); 401 emitir(IRTG(IR_EQ, IRT_STR), sp, lj_ir_kstr(J, str));
404 if (cct && ctype_isconstval(cct->info)) { 402 if (cct && ctype_isconstval(cct->info)) {
405 lua_assert(ctype_child(cts, cct)->size == 4); 403 lua_assert(ctype_child(cts, cct)->size == 4);
406 svisnz = (void *)(intptr_t)(cct->size != 0); 404 svisnz = (void *)(intptr_t)(ofs != 0);
407 sp = lj_ir_kint(J, (int32_t)cct->size); 405 sp = lj_ir_kint(J, (int32_t)ofs);
408 sid = ctype_cid(cct->info); 406 sid = ctype_cid(cct->info);
409 } /* else: interpreter will throw. */ 407 } /* else: interpreter will throw. */
410 } else if (ctype_isrefarray(d->info)) { /* Copy string to array. */ 408 } 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)
418 sid = argv2cdata(J, sp, sval)->ctypeid; 416 sid = argv2cdata(J, sp, sval)->ctypeid;
419 s = ctype_raw(cts, sid); 417 s = ctype_raw(cts, sid);
420 svisnz = cdataptr(cdataV(sval)); 418 svisnz = cdataptr(cdataV(sval));
421 if (ctype_isenum(s->info)) s = ctype_child(cts, s); 419 t = crec_ct2irt(cts, s);
422 t = crec_ct2irt(s);
423 if (ctype_isptr(s->info)) { 420 if (ctype_isptr(s->info)) {
424 sp = emitir(IRT(IR_FLOAD, t), sp, IRFL_CDATA_PTR); 421 sp = emitir(IRT(IR_FLOAD, t), sp, IRFL_CDATA_PTR);
425 if (ctype_isref(s->info)) { 422 if (ctype_isref(s->info)) {
426 svisnz = *(void **)svisnz; 423 svisnz = *(void **)svisnz;
427 s = ctype_rawchild(cts, s); 424 s = ctype_rawchild(cts, s);
428 if (ctype_isenum(s->info)) s = ctype_child(cts, s); 425 t = crec_ct2irt(cts, s);
429 t = crec_ct2irt(s);
430 } else { 426 } else {
431 goto doconv; 427 goto doconv;
432 } 428 }
@@ -554,10 +550,8 @@ again:
554 } else if (tref_iscdata(idx)) { 550 } else if (tref_iscdata(idx)) {
555 GCcdata *cdk = cdataV(&rd->argv[1]); 551 GCcdata *cdk = cdataV(&rd->argv[1]);
556 CType *ctk = ctype_raw(cts, cdk->ctypeid); 552 CType *ctk = ctype_raw(cts, cdk->ctypeid);
557 IRType t; 553 IRType t = crec_ct2irt(cts, ctk);
558 if (ctype_isenum(ctk->info)) ctk = ctype_child(cts, ctk); 554 if (ctype_ispointer(ct->info) && t >= IRT_I8 && t <= IRT_U64) {
559 if (ctype_ispointer(ct->info) &&
560 ctype_isinteger(ctk->info) && (t = crec_ct2irt(ctk)) != IRT_CDATA) {
561 if (ctk->size == 8) { 555 if (ctk->size == 8) {
562 idx = emitir(IRT(IR_FLOAD, t), idx, IRFL_CDATA_INT64); 556 idx = emitir(IRT(IR_FLOAD, t), idx, IRFL_CDATA_INT64);
563 } else if (ctk->size == 4) { 557 } else if (ctk->size == 4) {
@@ -637,7 +631,6 @@ again:
637 ct = ctype_child(cts, ct); /* Skip attributes. */ 631 ct = ctype_child(cts, ct); /* Skip attributes. */
638 632
639 if (rd->data == 0) { /* __index metamethod. */ 633 if (rd->data == 0) { /* __index metamethod. */
640 if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct); /* Skip enums. */
641 J->base[0] = crec_tv_ct(J, ct, sid, ptr); 634 J->base[0] = crec_tv_ct(J, ct, sid, ptr);
642 } else { /* __newindex metamethod. */ 635 } else { /* __newindex metamethod. */
643 rd->nres = 0; 636 rd->nres = 0;
@@ -888,7 +881,7 @@ static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd)
888 if (ctype_isfunc(ct->info)) { 881 if (ctype_isfunc(ct->info)) {
889 TRef func = emitir(IRT(IR_FLOAD, tp), J->base[0], IRFL_CDATA_PTR); 882 TRef func = emitir(IRT(IR_FLOAD, tp), J->base[0], IRFL_CDATA_PTR);
890 CType *ctr = ctype_rawchild(cts, ct); 883 CType *ctr = ctype_rawchild(cts, ct);
891 IRType t = crec_ct2irt(ctr); 884 IRType t = crec_ct2irt(cts, ctr);
892 TRef tr; 885 TRef tr;
893 TValue tv; 886 TValue tv;
894 /* Check for blacklisted C functions that might call a callback. */ 887 /* 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)
899 if (ctype_isvoid(ctr->info)) { 892 if (ctype_isvoid(ctr->info)) {
900 t = IRT_NIL; 893 t = IRT_NIL;
901 rd->nres = 0; 894 rd->nres = 0;
902 } else if (ctype_isenum(ctr->info)) { 895 } else if (!(ctype_isnum(ctr->info) || ctype_isptr(ctr->info) ||
903 ctr = ctype_child(cts, ctr); 896 ctype_isenum(ctr->info)) || t == IRT_CDATA) {
904 }
905 if (!(ctype_isnum(ctr->info) || ctype_isptr(ctr->info) ||
906 ctype_isvoid(ctr->info)) || t == IRT_CDATA)
907 lj_trace_err(J, LJ_TRERR_NYICALL); 897 lj_trace_err(J, LJ_TRERR_NYICALL);
898 }
908 if ((ct->info & CTF_VARARG) 899 if ((ct->info & CTF_VARARG)
909#if LJ_TARGET_X86 900#if LJ_TARGET_X86
910 || ctype_cconv(ct->info) != CTCC_CDECL 901 || ctype_cconv(ct->info) != CTCC_CDECL
@@ -923,17 +914,17 @@ static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd)
923 J->postproc = LJ_POST_FIXGUARDSNAP; 914 J->postproc = LJ_POST_FIXGUARDSNAP;
924 tr = TREF_TRUE; 915 tr = TREF_TRUE;
925 } 916 }
917 } else if (t == IRT_PTR || (LJ_64 && t == IRT_P32) ||
918 t == IRT_I64 || t == IRT_U64 || ctype_isenum(ctr->info)) {
919 TRef trid = lj_ir_kint(J, ctype_cid(ct->info));
920 tr = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, tr);
921 if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J);
926 } else if (t == IRT_FLOAT || t == IRT_U32) { 922 } else if (t == IRT_FLOAT || t == IRT_U32) {
927 tr = emitconv(tr, IRT_NUM, t, 0); 923 tr = emitconv(tr, IRT_NUM, t, 0);
928 } else if (t == IRT_I8 || t == IRT_I16) { 924 } else if (t == IRT_I8 || t == IRT_I16) {
929 tr = emitconv(tr, IRT_INT, t, IRCONV_SEXT); 925 tr = emitconv(tr, IRT_INT, t, IRCONV_SEXT);
930 } else if (t == IRT_U8 || t == IRT_U16) { 926 } else if (t == IRT_U8 || t == IRT_U16) {
931 tr = emitconv(tr, IRT_INT, t, 0); 927 tr = emitconv(tr, IRT_INT, t, 0);
932 } else if (t == IRT_PTR || (LJ_64 && t == IRT_P32) ||
933 (t == IRT_I64 || t == IRT_U64)) {
934 TRef trid = lj_ir_kint(J, ctype_cid(ct->info));
935 tr = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, tr);
936 if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J);
937 } 928 }
938 J->base[0] = tr; 929 J->base[0] = tr;
939 J->needsnap = 1; 930 J->needsnap = 1;
@@ -981,12 +972,25 @@ static TRef crec_arith_int64(jit_State *J, TRef *sp, CType **s, MMS mm)
981 CTypeID id; 972 CTypeID id;
982 TRef tr; 973 TRef tr;
983 MSize i; 974 MSize i;
975 IROp op;
984 lj_needsplit(J); 976 lj_needsplit(J);
985 if (((s[0]->info & CTF_UNSIGNED) && s[0]->size == 8) || 977 if (((s[0]->info & CTF_UNSIGNED) && s[0]->size == 8) ||
986 ((s[1]->info & CTF_UNSIGNED) && s[1]->size == 8)) { 978 ((s[1]->info & CTF_UNSIGNED) && s[1]->size == 8)) {
987 dt = IRT_U64; id = CTID_UINT64; 979 dt = IRT_U64; id = CTID_UINT64;
988 } else { 980 } else {
989 dt = IRT_I64; id = CTID_INT64; 981 dt = IRT_I64; id = CTID_INT64;
982 if (mm < MM_add &&
983 !((s[0]->info | s[1]->info) & CTF_FP) &&
984 s[0]->size == 4 && s[1]->size == 4) { /* Try to narrow comparison. */
985 if (!((s[0]->info ^ s[1]->info) & CTF_UNSIGNED) ||
986 (tref_isk(sp[1]) && IR(tref_ref(sp[1]))->i >= 0)) {
987 dt = (s[0]->info & CTF_UNSIGNED) ? IRT_U32 : IRT_INT;
988 goto comp;
989 } else if (tref_isk(sp[0]) && IR(tref_ref(sp[0]))->i >= 0) {
990 dt = (s[1]->info & CTF_UNSIGNED) ? IRT_U32 : IRT_INT;
991 goto comp;
992 }
993 }
990 } 994 }
991 for (i = 0; i < 2; i++) { 995 for (i = 0; i < 2; i++) {
992 IRType st = tref_type(sp[i]); 996 IRType st = tref_type(sp[i]);
@@ -994,16 +998,16 @@ static TRef crec_arith_int64(jit_State *J, TRef *sp, CType **s, MMS mm)
994 sp[i] = emitconv(sp[i], dt, st, IRCONV_TRUNC|IRCONV_ANY); 998 sp[i] = emitconv(sp[i], dt, st, IRCONV_TRUNC|IRCONV_ANY);
995 else if (!(st == IRT_I64 || st == IRT_U64)) 999 else if (!(st == IRT_I64 || st == IRT_U64))
996 sp[i] = emitconv(sp[i], dt, IRT_INT, 1000 sp[i] = emitconv(sp[i], dt, IRT_INT,
997 ((st - IRT_I8) & 1) ? 0 : IRCONV_SEXT); 1001 (s[i]->info & CTF_UNSIGNED) ? 0 : IRCONV_SEXT);
998 } 1002 }
999 if (mm < MM_add) { 1003 if (mm < MM_add) {
1004 comp:
1000 /* Assume true comparison. Fixup and emit pending guard later. */ 1005 /* Assume true comparison. Fixup and emit pending guard later. */
1001 IROp op;
1002 if (mm == MM_eq) { 1006 if (mm == MM_eq) {
1003 op = IR_EQ; 1007 op = IR_EQ;
1004 } else { 1008 } else {
1005 op = mm == MM_lt ? IR_LT : IR_LE; 1009 op = mm == MM_lt ? IR_LT : IR_LE;
1006 if (dt == IRT_U64) 1010 if (dt == IRT_U32 || dt == IRT_U64)
1007 op += (IR_ULT-IR_LT); 1011 op += (IR_ULT-IR_LT);
1008 } 1012 }
1009 lj_ir_set(J, IRTG(op, dt), sp[0], sp[1]); 1013 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)
1116 goto trymeta; 1120 goto trymeta;
1117 } else if (tref_iscdata(tr)) { 1121 } else if (tref_iscdata(tr)) {
1118 CTypeID id = argv2cdata(J, tr, &rd->argv[i])->ctypeid; 1122 CTypeID id = argv2cdata(J, tr, &rd->argv[i])->ctypeid;
1123 IRType t;
1119 ct = ctype_raw(cts, id); 1124 ct = ctype_raw(cts, id);
1125 t = crec_ct2irt(cts, ct);
1120 if (ctype_isptr(ct->info)) { /* Resolve pointer or reference. */ 1126 if (ctype_isptr(ct->info)) { /* Resolve pointer or reference. */
1121 IRType t = (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32;
1122 if (ctype_isref(ct->info)) ct = ctype_rawchild(cts, ct);
1123 tr = emitir(IRT(IR_FLOAD, t), tr, IRFL_CDATA_PTR); 1127 tr = emitir(IRT(IR_FLOAD, t), tr, IRFL_CDATA_PTR);
1124 } else if (ctype_isinteger(ct->info) && ct->size == 8) { 1128 if (ctype_isref(ct->info)) {
1125 IRType t = (ct->info & CTF_UNSIGNED) ? IRT_U64 : IRT_I64; 1129 ct = ctype_rawchild(cts, ct);
1130 t = crec_ct2irt(cts, ct);
1131 }
1132 } else if (t == IRT_I64 || t == IRT_U64) {
1126 tr = emitir(IRT(IR_FLOAD, t), tr, IRFL_CDATA_INT64); 1133 tr = emitir(IRT(IR_FLOAD, t), tr, IRFL_CDATA_INT64);
1127 lj_needsplit(J); 1134 lj_needsplit(J);
1128 goto ok; 1135 goto ok;
1136 } else if (t == IRT_INT || t == IRT_U32) {
1137 tr = emitir(IRT(IR_FLOAD, t), tr, IRFL_CDATA_INT);
1138 if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
1139 goto ok;
1129 } else if (ctype_isfunc(ct->info)) { 1140 } else if (ctype_isfunc(ct->info)) {
1130 tr = emitir(IRT(IR_FLOAD, IRT_PTR), tr, IRFL_CDATA_PTR); 1141 tr = emitir(IRT(IR_FLOAD, IRT_PTR), tr, IRFL_CDATA_PTR);
1131 ct = ctype_get(cts, 1142 ct = ctype_get(cts,
1132 lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|id), CTSIZE_PTR)); 1143 lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|id), CTSIZE_PTR));
1144 goto ok;
1133 } else { 1145 } else {
1134 tr = emitir(IRT(IR_ADD, IRT_PTR), tr, lj_ir_kintp(J, sizeof(GCcdata))); 1146 tr = emitir(IRT(IR_ADD, IRT_PTR), tr, lj_ir_kintp(J, sizeof(GCcdata)));
1135 } 1147 }
1136 if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct); 1148 if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
1137 if (ctype_isnum(ct->info)) { 1149 if (ctype_isnum(ct->info)) {
1138 IRType t = crec_ct2irt(ct);
1139 if (t == IRT_CDATA) goto trymeta; 1150 if (t == IRT_CDATA) goto trymeta;
1140 if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J); 1151 if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J);
1141 tr = emitir(IRT(IR_XLOAD, t), tr, 0); 1152 tr = emitir(IRT(IR_XLOAD, t), tr, 0);
@@ -1147,6 +1158,21 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd)
1147 ct = ctype_get(cts, CTID_P_VOID); 1158 ct = ctype_get(cts, CTID_P_VOID);
1148 } else if (tref_isinteger(tr)) { 1159 } else if (tref_isinteger(tr)) {
1149 ct = ctype_get(cts, CTID_INT32); 1160 ct = ctype_get(cts, CTID_INT32);
1161 } else if (tref_isstr(tr)) {
1162 TRef tr2 = J->base[1-i];
1163 CTypeID id = argv2cdata(J, tr2, &rd->argv[1-i])->ctypeid;
1164 ct = ctype_raw(cts, id);
1165 if (ctype_isenum(ct->info)) { /* Match string against enum constant. */
1166 GCstr *str = strV(&rd->argv[i]);
1167 CTSize ofs;
1168 CType *cct = lj_ctype_getfield(cts, ct, str, &ofs);
1169 if (cct && ctype_isconstval(cct->info)) {
1170 /* Specialize to the name of the enum constant. */
1171 emitir(IRTG(IR_EQ, IRT_STR), tr, lj_ir_kstr(J, str));
1172 ct = ctype_child(cts, cct);
1173 tr = lj_ir_kint(J, (int32_t)ofs);
1174 } /* else: interpreter will throw. */
1175 } /* else: interpreter will throw. */
1150 } else if (!tref_isnum(tr)) { 1176 } else if (!tref_isnum(tr)) {
1151 goto trymeta; 1177 goto trymeta;
1152 } 1178 }
@@ -1203,7 +1229,6 @@ void LJ_FASTCALL recff_clib_index(jit_State *J, RecordFFData *rd)
1203 void *sp = *(void **)cdataptr(cdataV(tv)); 1229 void *sp = *(void **)cdataptr(cdataV(tv));
1204 TRef ptr; 1230 TRef ptr;
1205 ct = ctype_raw(cts, sid); 1231 ct = ctype_raw(cts, sid);
1206 if (rd->data && ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
1207 if (LJ_64 && !checkptr32(sp)) 1232 if (LJ_64 && !checkptr32(sp))
1208 ptr = lj_ir_kintp(J, (uintptr_t)sp); 1233 ptr = lj_ir_kintp(J, (uintptr_t)sp);
1209 else 1234 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)
575 575
576LJFOLD(CONV KINT IRCONV_I64_INT) 576LJFOLD(CONV KINT IRCONV_I64_INT)
577LJFOLD(CONV KINT IRCONV_U64_INT) 577LJFOLD(CONV KINT IRCONV_U64_INT)
578LJFOLD(CONV KINT IRCONV_I64_U32)
579LJFOLD(CONV KINT IRCONV_U64_U32)
578LJFOLDF(kfold_conv_kint_i64) 580LJFOLDF(kfold_conv_kint_i64)
579{ 581{
580 if ((fins->op2 & IRCONV_SEXT)) 582 if ((fins->op2 & IRCONV_SEXT))