aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2011-06-06 19:56:55 +0200
committerMike Pall <mike>2011-06-06 19:56:55 +0200
commit22946f268b1b25820c1d026779c147db314f7135 (patch)
treec8b67dd956edda831d87af34748afa11a890c296
parenta48058a791266fbbda14363f6f6530aff66b0f23 (diff)
downloadluajit-22946f268b1b25820c1d026779c147db314f7135.tar.gz
luajit-22946f268b1b25820c1d026779c147db314f7135.tar.bz2
luajit-22946f268b1b25820c1d026779c147db314f7135.zip
FFI: Change tonumber(cdata) semantics. Return nil for non-numbers.
-rw-r--r--src/lib_base.c25
-rw-r--r--src/lj_crecord.c16
2 files changed, 24 insertions, 17 deletions
diff --git a/src/lib_base.c b/src/lib_base.c
index fd7279af..8c71ae32 100644
--- a/src/lib_base.c
+++ b/src/lib_base.c
@@ -197,21 +197,20 @@ LJLIB_ASM(tonumber) LJLIB_REC(.)
197#if LJ_HASFFI 197#if LJ_HASFFI
198 if (tviscdata(o)) { 198 if (tviscdata(o)) {
199 CTState *cts = ctype_cts(L); 199 CTState *cts = ctype_cts(L);
200 if (LJ_DUALNUM) { 200 CType *ct = lj_ctype_rawref(cts, cdataV(o)->typeid);
201 CType *ct = ctype_raw(cts, cdataV(o)->typeid); 201 if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
202 if (ctype_isinteger_or_bool(ct->info)) { 202 if (ctype_isnum(ct->info) || ctype_iscomplex(ct->info)) {
203 int64_t i; 203 if (LJ_DUALNUM && ctype_isinteger_or_bool(ct->info) &&
204 lj_cconv_ct_tv(cts, ctype_get(cts, CTID_INT64), (uint8_t *)&i, o, 0); 204 ct->size <= 4 && !(ct->size == 4 && (ct->info & CTF_UNSIGNED))) {
205 if ((ct->size == 8 && (ct->info & CTF_UNSIGNED)) ? 205 int32_t i;
206 (uint64_t)i <= 0x7fffffffu : checki32(i)) { 206 lj_cconv_ct_tv(cts, ctype_get(cts, CTID_INT32), (uint8_t *)&i, o, 0);
207 setintV(L->base-1, (int32_t)i); 207 setintV(L->base-1, i);
208 return FFH_RES(1); 208 return FFH_RES(1);
209 } /* else: retry and convert to double. */
210 } 209 }
210 lj_cconv_ct_tv(cts, ctype_get(cts, CTID_DOUBLE),
211 (uint8_t *)&(L->base-1)->n, o, 0);
212 return FFH_RES(1);
211 } 213 }
212 lj_cconv_ct_tv(cts, ctype_get(cts, CTID_DOUBLE),
213 (uint8_t *)&(L->base-1)->n, o, 0);
214 return FFH_RES(1);
215 } 214 }
216#endif 215#endif
217 } else { 216 } else {
diff --git a/src/lj_crecord.c b/src/lj_crecord.c
index 8373faaa..743137de 100644
--- a/src/lj_crecord.c
+++ b/src/lj_crecord.c
@@ -1138,10 +1138,18 @@ void LJ_FASTCALL recff_ffi_abi(jit_State *J, RecordFFData *rd)
1138void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd) 1138void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd)
1139{ 1139{
1140 CTState *cts = ctype_ctsG(J2G(J)); 1140 CTState *cts = ctype_ctsG(J2G(J));
1141 IRType st = crec_ct2irt(ctype_raw(cts, cdataV(&rd->argv[0])->typeid)); 1141 CType *d, *ct = lj_ctype_rawref(cts, cdataV(&rd->argv[0])->typeid);
1142 CTypeID did = (st >= IRT_I8 && st <= IRT_INT) ? CTID_INT32 : CTID_DOUBLE; 1142 if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
1143 CType *d = ctype_get(cts, did); 1143 if (ctype_isnum(ct->info) || ctype_iscomplex(ct->info)) {
1144 J->base[0] = crec_ct_tv(J, d, 0, J->base[0], &rd->argv[0]); 1144 if (ctype_isinteger_or_bool(ct->info) && ct->size <= 4 &&
1145 !(ct->size == 4 && (ct->info & CTF_UNSIGNED)))
1146 d = ctype_get(cts, CTID_INT32);
1147 else
1148 d = ctype_get(cts, CTID_DOUBLE);
1149 J->base[0] = crec_ct_tv(J, d, 0, J->base[0], &rd->argv[0]);
1150 } else {
1151 J->base[0] = TREF_NIL;
1152 }
1145} 1153}
1146 1154
1147#undef IR 1155#undef IR