diff options
author | Mike Pall <mike> | 2012-07-17 22:20:03 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2012-07-17 22:22:07 +0200 |
commit | 4d9c29a78cde2596ea3286744d93d29dd2a6d9ca (patch) | |
tree | 62af9fd2c6765a06005f8fa8ed00a1b491c0a356 /src | |
parent | 2139c6791f4b802560ce62dc688293786803a9ca (diff) | |
download | luajit-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.c | 4 | ||||
-rw-r--r-- | src/lj_asm_arm.h | 2 | ||||
-rw-r--r-- | src/lj_asm_x86.h | 5 | ||||
-rw-r--r-- | src/lj_carith.c | 31 | ||||
-rw-r--r-- | src/lj_ccall.c | 1 | ||||
-rw-r--r-- | src/lj_ccallback.c | 1 | ||||
-rw-r--r-- | src/lj_cconv.c | 1 | ||||
-rw-r--r-- | src/lj_cdata.c | 4 | ||||
-rw-r--r-- | src/lj_crecord.c | 107 | ||||
-rw-r--r-- | src/lj_opt_fold.c | 2 |
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. */ |
114 | static IRType crec_ct2irt(CType *ct) | 114 | static 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) | |||
162 | static TRef crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp, | 163 | static 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, | |||
317 | static TRef crec_tv_ct(jit_State *J, CType *s, CTypeID sid, TRef sp) | 318 | static 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 | ||
576 | LJFOLD(CONV KINT IRCONV_I64_INT) | 576 | LJFOLD(CONV KINT IRCONV_I64_INT) |
577 | LJFOLD(CONV KINT IRCONV_U64_INT) | 577 | LJFOLD(CONV KINT IRCONV_U64_INT) |
578 | LJFOLD(CONV KINT IRCONV_I64_U32) | ||
579 | LJFOLD(CONV KINT IRCONV_U64_U32) | ||
578 | LJFOLDF(kfold_conv_kint_i64) | 580 | LJFOLDF(kfold_conv_kint_i64) |
579 | { | 581 | { |
580 | if ((fins->op2 & IRCONV_SEXT)) | 582 | if ((fins->op2 & IRCONV_SEXT)) |