diff options
author | Mike Pall <mike> | 2011-06-06 19:56:55 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2011-06-06 19:56:55 +0200 |
commit | 22946f268b1b25820c1d026779c147db314f7135 (patch) | |
tree | c8b67dd956edda831d87af34748afa11a890c296 | |
parent | a48058a791266fbbda14363f6f6530aff66b0f23 (diff) | |
download | luajit-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.c | 25 | ||||
-rw-r--r-- | src/lj_crecord.c | 16 |
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) | |||
1138 | void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd) | 1138 | void 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 |