diff options
Diffstat (limited to 'src/lj_crecord.c')
-rw-r--r-- | src/lj_crecord.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/src/lj_crecord.c b/src/lj_crecord.c index 791c177c..b474a6b9 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c | |||
@@ -569,6 +569,34 @@ void LJ_FASTCALL recff_ffi_new(jit_State *J, RecordFFData *rd) | |||
569 | crec_alloc(J, rd, argv2ctype(J, J->base[0], &rd->argv[0])); | 569 | crec_alloc(J, rd, argv2ctype(J, J->base[0], &rd->argv[0])); |
570 | } | 570 | } |
571 | 571 | ||
572 | /* -- Miscellaneous library functions ------------------------------------- */ | ||
573 | |||
574 | void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd) | ||
575 | { | ||
576 | CTypeID sid = argv2cdata(J, J->base[0], &rd->argv[0])->typeid; | ||
577 | CTState *cts = ctype_ctsG(J2G(J)); | ||
578 | CType *s = ctype_raw(cts, sid); | ||
579 | TRef sp = J->base[0]; | ||
580 | if (ctype_isref(s->info)) { | ||
581 | sp = emitir(IRT(IR_FLOAD, IRT_PTR), sp, IRFL_CDATA_PTR); | ||
582 | s = ctype_rawchild(cts, s); | ||
583 | } else { | ||
584 | sp = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, sizeof(GCcdata))); | ||
585 | } | ||
586 | if (ctype_isenum(s->info)) s = ctype_child(cts, s); | ||
587 | if (ctype_isnum(s->info) || ctype_iscomplex(s->info)) { | ||
588 | IRType t = crec_ct2irt(s); | ||
589 | if (t != IRT_CDATA) { | ||
590 | TRef tr = emitir(IRT(IR_XLOAD, t), sp, 0); /* Load number value. */ | ||
591 | if (t == IRT_FLOAT || t == IRT_U32 || t == IRT_I64 || t == IRT_U64) | ||
592 | tr = emitconv(tr, IRT_NUM, t, 0); | ||
593 | J->base[0] = tr; | ||
594 | return; | ||
595 | } | ||
596 | } | ||
597 | lj_trace_err(J, LJ_TRERR_BADTYPE); | ||
598 | } | ||
599 | |||
572 | #undef IR | 600 | #undef IR |
573 | #undef emitir | 601 | #undef emitir |
574 | #undef emitconv | 602 | #undef emitconv |