diff options
Diffstat (limited to 'src/riscv/ffi.c')
-rw-r--r-- | src/riscv/ffi.c | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/src/riscv/ffi.c b/src/riscv/ffi.c index c910858..ebd05ba 100644 --- a/src/riscv/ffi.c +++ b/src/riscv/ffi.c @@ -373,7 +373,32 @@ ffi_call_int (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue, cb.used_float = cb.used_integer = 0; if (!return_by_ref && rvalue) - unmarshal(&cb, cif->rtype, 0, rvalue); + { + if (IS_INT(cif->rtype->type) + && cif->rtype->size < sizeof (ffi_arg)) + { + /* Integer types smaller than ffi_arg need to be extended. */ + switch (cif->rtype->type) + { + case FFI_TYPE_SINT8: + case FFI_TYPE_SINT16: + case FFI_TYPE_SINT32: + unmarshal_atom (&cb, (sizeof (ffi_arg) > 4 + ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32), + rvalue); + break; + case FFI_TYPE_UINT8: + case FFI_TYPE_UINT16: + case FFI_TYPE_UINT32: + unmarshal_atom (&cb, (sizeof (ffi_arg) > 4 + ? FFI_TYPE_UINT64 : FFI_TYPE_UINT32), + rvalue); + break; + } + } + else + unmarshal(&cb, cif->rtype, 0, rvalue); + } } void |