diff options
Diffstat (limited to 'src/lj_cconv.c')
-rw-r--r-- | src/lj_cconv.c | 37 |
1 files changed, 28 insertions, 9 deletions
diff --git a/src/lj_cconv.c b/src/lj_cconv.c index 94a9895f..884edef1 100644 --- a/src/lj_cconv.c +++ b/src/lj_cconv.c | |||
@@ -375,10 +375,20 @@ int lj_cconv_tv_ct(CTState *cts, CType *s, CTypeID sid, | |||
375 | if (ctype_isnum(sinfo)) { | 375 | if (ctype_isnum(sinfo)) { |
376 | if (!ctype_isbool(sinfo)) { | 376 | if (!ctype_isbool(sinfo)) { |
377 | if (ctype_isinteger(sinfo) && s->size > 4) goto copyval; | 377 | if (ctype_isinteger(sinfo) && s->size > 4) goto copyval; |
378 | lj_cconv_ct_ct(cts, ctype_get(cts, CTID_DOUBLE), s, | 378 | if (LJ_DUALNUM && ctype_isinteger(sinfo)) { |
379 | (uint8_t *)&o->n, sp, 0); | 379 | int32_t i; |
380 | /* Numbers are NOT canonicalized here! Beware of uninitialized data. */ | 380 | lj_cconv_ct_ct(cts, ctype_get(cts, CTID_INT32), s, |
381 | lua_assert(tvisnum(o)); | 381 | (uint8_t *)&i, sp, 0); |
382 | if ((sinfo & CTF_UNSIGNED) && i < 0) | ||
383 | setnumV(o, (lua_Number)(uint32_t)i); | ||
384 | else | ||
385 | setintV(o, i); | ||
386 | } else { | ||
387 | lj_cconv_ct_ct(cts, ctype_get(cts, CTID_DOUBLE), s, | ||
388 | (uint8_t *)&o->n, sp, 0); | ||
389 | /* Numbers are NOT canonicalized here! Beware of uninitialized data. */ | ||
390 | lua_assert(tvisnum(o)); | ||
391 | } | ||
382 | } else { | 392 | } else { |
383 | uint32_t b = ((*sp) & 1); | 393 | uint32_t b = ((*sp) & 1); |
384 | setboolV(o, b); | 394 | setboolV(o, b); |
@@ -426,10 +436,15 @@ int lj_cconv_tv_bf(CTState *cts, CType *s, TValue *o, uint8_t *sp) | |||
426 | lj_err_caller(cts->L, LJ_ERR_FFI_NYIPACKBIT); | 436 | lj_err_caller(cts->L, LJ_ERR_FFI_NYIPACKBIT); |
427 | if (!(info & CTF_BOOL)) { | 437 | if (!(info & CTF_BOOL)) { |
428 | CTSize shift = 32 - bsz; | 438 | CTSize shift = 32 - bsz; |
429 | if (!(info & CTF_UNSIGNED)) | 439 | if (!(info & CTF_UNSIGNED)) { |
430 | setnumV(o, (lua_Number)((int32_t)(val << (shift-pos)) >> shift)); | 440 | setintV(o, (int32_t)(val << (shift-pos)) >> shift); |
431 | else | 441 | } else { |
432 | setnumV(o, (lua_Number)((val << (shift-pos)) >> shift)); | 442 | val = (val << (shift-pos)) >> shift; |
443 | if (!LJ_DUALNUM || (int32_t)val < 0) | ||
444 | setnumV(o, (lua_Number)(uint32_t)val); | ||
445 | else | ||
446 | setintV(o, (int32_t)val); | ||
447 | } | ||
433 | } else { | 448 | } else { |
434 | lua_assert(bsz == 1); | 449 | lua_assert(bsz == 1); |
435 | setboolV(o, (val >> pos) & 1); | 450 | setboolV(o, (val >> pos) & 1); |
@@ -519,7 +534,11 @@ void lj_cconv_ct_tv(CTState *cts, CType *d, | |||
519 | CType *s; | 534 | CType *s; |
520 | void *tmpptr; | 535 | void *tmpptr; |
521 | uint8_t tmpbool, *sp = (uint8_t *)&tmpptr; | 536 | uint8_t tmpbool, *sp = (uint8_t *)&tmpptr; |
522 | if (LJ_LIKELY(tvisnum(o))) { | 537 | if (LJ_LIKELY(tvisint(o))) { |
538 | sp = (uint8_t *)&o->i; | ||
539 | sid = CTID_INT32; | ||
540 | flags |= CCF_FROMTV; | ||
541 | } else if (LJ_LIKELY(tvisnum(o))) { | ||
523 | sp = (uint8_t *)&o->n; | 542 | sp = (uint8_t *)&o->n; |
524 | sid = CTID_DOUBLE; | 543 | sid = CTID_DOUBLE; |
525 | flags |= CCF_FROMTV; | 544 | flags |= CCF_FROMTV; |