aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2011-10-13 20:44:31 +0200
committerMike Pall <mike>2011-10-13 20:44:31 +0200
commitbc95d54ec932fddca832e35344efbecf1344e984 (patch)
treeefa14255e22a76dc92eef5d0935dbe759c40554c /src
parent120c3adbff2acbbee5932f28345cde292ef044ec (diff)
downloadluajit-bc95d54ec932fddca832e35344efbecf1344e984.tar.gz
luajit-bc95d54ec932fddca832e35344efbecf1344e984.tar.bz2
luajit-bc95d54ec932fddca832e35344efbecf1344e984.zip
FFI: Fix call argument and return handling for I8/U8/I16/U16 types.
Diffstat (limited to 'src')
-rw-r--r--src/lj_ccall.c22
-rw-r--r--src/lj_crecord.c13
2 files changed, 27 insertions, 8 deletions
diff --git a/src/lj_ccall.c b/src/lj_ccall.c
index b5cfe616..281b45a6 100644
--- a/src/lj_ccall.c
+++ b/src/lj_ccall.c
@@ -515,11 +515,8 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
515 /* Find out how (by value/ref) and where (GPR/FPR) to pass an argument. */ 515 /* Find out how (by value/ref) and where (GPR/FPR) to pass an argument. */
516 if (ctype_isnum(d->info)) { 516 if (ctype_isnum(d->info)) {
517 if (sz > 8) goto err_nyi; 517 if (sz > 8) goto err_nyi;
518 if ((d->info & CTF_FP)) { 518 if ((d->info & CTF_FP))
519 isfp = 1; 519 isfp = 1;
520 } else if (sz < CTSIZE_PTR) {
521 d = ctype_get(cts, CTID_INT_PSZ);
522 }
523 } else if (ctype_isvector(d->info)) { 520 } else if (ctype_isvector(d->info)) {
524 if (CCALL_VECTOR_REG && (sz == 8 || sz == 16)) 521 if (CCALL_VECTOR_REG && (sz == 8 || sz == 16))
525 isfp = 1; 522 isfp = 1;
@@ -557,6 +554,15 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
557 dp = rp; 554 dp = rp;
558 } 555 }
559 lj_cconv_ct_tv(cts, d, (uint8_t *)dp, o, CCF_ARG(narg)); 556 lj_cconv_ct_tv(cts, d, (uint8_t *)dp, o, CCF_ARG(narg));
557 /* Extend passed integers to 32 bits at least. */
558 if (ctype_isinteger_or_bool(d->info) && d->size < 4) {
559 if (d->info & CTF_UNSIGNED)
560 *(uint32_t *)dp = d->size == 1 ? (uint32_t)*(uint8_t *)dp :
561 (uint32_t)*(uint16_t *)dp;
562 else
563 *(int32_t *)dp = d->size == 1 ? (int32_t)*(int8_t *)dp :
564 (int32_t)*(int16_t *)dp;
565 }
560#if LJ_TARGET_X64 && LJ_ABI_WIN 566#if LJ_TARGET_X64 && LJ_ABI_WIN
561 if (isva) { /* Windows/x64 mirrors varargs in both register sets. */ 567 if (isva) { /* Windows/x64 mirrors varargs in both register sets. */
562 if (nfpr == ngpr) 568 if (nfpr == ngpr)
@@ -593,7 +599,7 @@ static int ccall_get_results(lua_State *L, CTState *cts, CType *ct,
593 CCallState *cc, int *ret) 599 CCallState *cc, int *ret)
594{ 600{
595 CType *ctr = ctype_rawchild(cts, ct); 601 CType *ctr = ctype_rawchild(cts, ct);
596 void *sp = &cc->gpr[0]; 602 uint8_t *sp = (uint8_t *)&cc->gpr[0];
597 if (ctype_isvoid(ctr->info)) { 603 if (ctype_isvoid(ctr->info)) {
598 *ret = 0; /* Zero results. */ 604 *ret = 0; /* Zero results. */
599 return 0; /* No additional GC step. */ 605 return 0; /* No additional GC step. */
@@ -613,17 +619,19 @@ static int ccall_get_results(lua_State *L, CTState *cts, CType *ct,
613 CCALL_HANDLE_COMPLEXRET2 619 CCALL_HANDLE_COMPLEXRET2
614 return 1; /* One GC step. */ 620 return 1; /* One GC step. */
615 } 621 }
622 if (LJ_BE && ctype_isinteger_or_bool(ctr->info) && ctr->size < CTSIZE_PTR)
623 sp += (CTSIZE_PTR - ctr->size);
616#ifdef CCALL_HANDLE_RET 624#ifdef CCALL_HANDLE_RET
617 CCALL_HANDLE_RET 625 CCALL_HANDLE_RET
618#endif 626#endif
619#if CCALL_NUM_FPR 627#if CCALL_NUM_FPR
620 if (ctype_isfp(ctr->info) || ctype_isvector(ctr->info)) 628 if (ctype_isfp(ctr->info) || ctype_isvector(ctr->info))
621 sp = &cc->fpr[0]; 629 sp = (uint8_t *)&cc->fpr[0];
622#endif 630#endif
623 /* No reference types end up here, so there's no need for the CTypeID. */ 631 /* No reference types end up here, so there's no need for the CTypeID. */
624 lua_assert(!(ctype_isrefarray(ctr->info) || ctype_isstruct(ctr->info))); 632 lua_assert(!(ctype_isrefarray(ctr->info) || ctype_isstruct(ctr->info)));
625 if (ctype_isenum(ctr->info)) ctr = ctype_child(cts, ctr); 633 if (ctype_isenum(ctr->info)) ctr = ctype_child(cts, ctr);
626 return lj_cconv_tv_ct(cts, ctr, 0, L->top-1, (uint8_t *)sp); 634 return lj_cconv_tv_ct(cts, ctr, 0, L->top-1, sp);
627} 635}
628 636
629/* Call C function. */ 637/* Call C function. */
diff --git a/src/lj_crecord.c b/src/lj_crecord.c
index c688caa3..001cf600 100644
--- a/src/lj_crecord.c
+++ b/src/lj_crecord.c
@@ -759,7 +759,14 @@ static TRef crec_call_args(jit_State *J, RecordFFData *rd,
759 if (!(ctype_isnum(d->info) || ctype_isptr(d->info) || 759 if (!(ctype_isnum(d->info) || ctype_isptr(d->info) ||
760 ctype_isenum(d->info))) 760 ctype_isenum(d->info)))
761 lj_trace_err(J, LJ_TRERR_NYICALL); 761 lj_trace_err(J, LJ_TRERR_NYICALL);
762 args[n] = crec_ct_tv(J, d, 0, J->base[n+1], &rd->argv[n+1]); 762 tr = crec_ct_tv(J, d, 0, J->base[n+1], &rd->argv[n+1]);
763 if (ctype_isinteger_or_bool(d->info) && d->size < 4) {
764 if ((d->info & CTF_UNSIGNED))
765 tr = emitconv(tr, IRT_INT, d->size==1 ? IRT_U8 : IRT_U16, 0);
766 else
767 tr = emitconv(tr, IRT_INT, d->size==1 ? IRT_I8 : IRT_I16, IRCONV_SEXT);
768 }
769 args[n] = tr;
763 } 770 }
764 tr = args[0]; 771 tr = args[0];
765 for (i = 1; i < n; i++) 772 for (i = 1; i < n; i++)
@@ -799,6 +806,10 @@ static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd)
799 tr = emitir(IRT(IR_CALLXS, t), crec_call_args(J, rd, cts, ct), func); 806 tr = emitir(IRT(IR_CALLXS, t), crec_call_args(J, rd, cts, ct), func);
800 if (t == IRT_FLOAT || t == IRT_U32) { 807 if (t == IRT_FLOAT || t == IRT_U32) {
801 tr = emitconv(tr, IRT_NUM, t, 0); 808 tr = emitconv(tr, IRT_NUM, t, 0);
809 } else if (t == IRT_I8 || t == IRT_I16) {
810 tr = emitconv(tr, IRT_INT, t, IRCONV_SEXT);
811 } else if (t == IRT_U8 || t == IRT_U16) {
812 tr = emitconv(tr, IRT_INT, t, 0);
802 } else if (t == IRT_PTR || (LJ_64 && t == IRT_P32) || 813 } else if (t == IRT_PTR || (LJ_64 && t == IRT_P32) ||
803 (t == IRT_I64 || t == IRT_U64)) { 814 (t == IRT_I64 || t == IRT_U64)) {
804 TRef trid = lj_ir_kint(J, ctype_cid(ct->info)); 815 TRef trid = lj_ir_kint(J, ctype_cid(ct->info));