unsigned argument/return handling in ffi
This commit is contained in:
parent
d245867d9a
commit
9d74ec842f
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
#include 'Moo.moo'.
|
#include "Moo.moo".
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////#
|
////////////////////////////////////////////////////////////////#
|
||||||
// MAIN
|
// MAIN
|
||||||
@ -20,7 +20,7 @@ class MyObject(Object)
|
|||||||
divr := 1.
|
divr := 1.
|
||||||
while (divr <= divr_ubound)
|
while (divr <= divr_ubound)
|
||||||
{
|
{
|
||||||
('divr => ' & divr asString) dump.
|
("divr => " & divr asString) dump.
|
||||||
|
|
||||||
divd := 0.
|
divd := 0.
|
||||||
while (divd <= divd_ubound)
|
while (divd <= divd_ubound)
|
||||||
@ -40,45 +40,46 @@ class MyObject(Object)
|
|||||||
| ffi now |
|
| ffi now |
|
||||||
|
|
||||||
|
|
||||||
[ ffi := FFI new: 'libc.so.6'. ] on: Exception do: [:ex | ffi := FFI new: 'libc.so' ].
|
[ ffi := FFI new: "libc.so.6". ] on: Exception do: [:ex | ffi := FFI new: "libc.so" ].
|
||||||
|
|
||||||
now := ffi call: #time signature: 'l>i' arguments: #(0).
|
now := ffi call: #time signature: "l>i" arguments: #(0).
|
||||||
////ffi call: #srand signature: 'i>' arguments: ##(now).
|
////ffi call: #srand signature: "i>" arguments: ##(now).
|
||||||
ffi call: #srandom signature: 'i>' arguments: ##(now).
|
ffi call: #srandom signature: "i>" arguments: ##(now).
|
||||||
|
|
||||||
[
|
[
|
||||||
| i q r divd divr divd_ubound divr_ubound x |
|
| i q r divd divr divd_ubound divr_ubound x |
|
||||||
|
|
||||||
divr_ubound := 16rFFFFFFFFFFFFFFFFFFFFFFFF.
|
divr_ubound := 16rFFFFFFFFFFFFFFFFFFFFFFFF.
|
||||||
divd_ubound := 16rFFFFFFFFFFFFFFFFFFFFFFFF.
|
divd_ubound := 16rFFFFFFFFFFFFFFFFFFFFFFFF.
|
||||||
i := 0.
|
i := 0.
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
//x := (ffi call: #rand signature: '>i' arguments: nil) rem: 20.
|
//x := (ffi call: #rand signature: ">i" arguments: nil) rem: 20.
|
||||||
//divd := (ffi call: #rand signature: '>i' arguments: nil).
|
//divd := (ffi call: #rand signature: ">i" arguments: nil).
|
||||||
x := (ffi call: #random signature: '>l' arguments: nil) rem: 20.
|
x := (ffi call: #random signature: ">l" arguments: nil) rem: 20.
|
||||||
divd := (ffi call: #random signature: '>l' arguments: nil).
|
divd := (ffi call: #random signature: ">l" arguments: nil).
|
||||||
while (x > 0)
|
while (x > 0)
|
||||||
{
|
{
|
||||||
//divd := (divd bitShift: 7) bitOr: (ffi call: #rand signature: '>i' arguments: nil).
|
//divd := (divd bitShift: 7) bitOr: (ffi call: #rand signature: ">i" arguments: nil).
|
||||||
divd := (divd bitShift: 7) bitOr: (ffi call: #random signature: '>l' arguments: nil).
|
divd := (divd bitShift: 7) bitOr: (ffi call: #random signature: ">l" arguments: nil).
|
||||||
x := x - 1.
|
x := x - 1.
|
||||||
}.
|
}.
|
||||||
|
|
||||||
//x := (ffi call: #rand signature: '>i' arguments: nil) rem: 20.
|
//x := (ffi call: #rand signature: ">i" arguments: nil) rem: 20.
|
||||||
//divr := (ffi call: #rand signature: '>i' arguments: nil).
|
//divr := (ffi call: #rand signature: ">i" arguments: nil).
|
||||||
x := (ffi call: #random signature: '>l' arguments: nil) rem: 20.
|
x := (ffi call: #random signature: ">l" arguments: nil) rem: 20.
|
||||||
divr := (ffi call: #random signature: '>l' arguments: nil).
|
divr := (ffi call: #random signature: ">l" arguments: nil).
|
||||||
while (x > 0)
|
while (x > 0)
|
||||||
{
|
{
|
||||||
//divr := (divr bitShift: 7) bitOr: (ffi call: #rand signature: '>i' arguments: nil).
|
//divr := (divr bitShift: 7) bitOr: (ffi call: #rand signature: ">i" arguments: nil).
|
||||||
divr := (divr bitShift: 7) bitOr: (ffi call: #random signature: '>l' arguments: nil).
|
divr := (divr bitShift: 7) bitOr: (ffi call: #random signature: ">l" arguments: nil).
|
||||||
x := x - 1.
|
x := x - 1.
|
||||||
}.
|
}.
|
||||||
if (divr = 0) { divr := 1 }.
|
if (divr = 0) { divr := 1 }.
|
||||||
|
|
||||||
i := i + 1.
|
i := i + 1.
|
||||||
ffi call: #printf signature: 's|l>l' arguments: ##("%d\r", i).
|
ffi call: #printf signature: "s | l > l" arguments: ##("%d\r", i).
|
||||||
|
|
||||||
q := divd div: divr.
|
q := divd div: divr.
|
||||||
r := divd rem: divr.
|
r := divd rem: divr.
|
||||||
@ -92,7 +93,7 @@ class MyObject(Object)
|
|||||||
(q * divr + r) dump.
|
(q * divr + r) dump.
|
||||||
^false.
|
^false.
|
||||||
}.
|
}.
|
||||||
////((q asString) & ' ' & (r asString)) dump
|
////((q asString) & " " & (r asString)) dump
|
||||||
}.
|
}.
|
||||||
] ensure: [ ffi close. ].
|
] ensure: [ ffi close. ].
|
||||||
^true
|
^true
|
||||||
|
342
moo/mod/ffi.c
342
moo/mod/ffi.c
@ -49,9 +49,34 @@
|
|||||||
# endif
|
# endif
|
||||||
#elif defined(USE_DYNCALL)
|
#elif defined(USE_DYNCALL)
|
||||||
# include <dyncall.h>
|
# include <dyncall.h>
|
||||||
|
|
||||||
|
#define __dcArgInt8 dcArgChar
|
||||||
|
#define __dcCallInt8 dcCallChar
|
||||||
|
|
||||||
|
#define __dcArgInt16 dcArgShort
|
||||||
|
#define __dcCallInt16 dcCallShort
|
||||||
|
|
||||||
|
#if (MOO_SIZEOF_INT32_T == MOO_SIZEOF_INT)
|
||||||
|
#define __dcArgInt32 dcArgInt
|
||||||
|
#define __dcCallInt32 dcCallInt
|
||||||
|
#elif (MOO_SIZEOF_INT32_T == MOO_SIZEOF_LONG)
|
||||||
|
#define __dcArgInt32 dcArgLong
|
||||||
|
#define __dcCallInt32 dcCallLong
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (MOO_SIZEOF_INT64_T == MOO_SIZEOF_LONG)
|
||||||
|
#define __dcArgInt64 dcArgLong
|
||||||
|
#define __dcCallInt64 dcCallLong
|
||||||
|
#elif (MOO_SIZEOF_INT64_T == MOO_SIZEOF_LONG_LONG)
|
||||||
|
#define __dcArgInt64 dcArgLongLong
|
||||||
|
#define __dcCallInt64 dcCallLongLong
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define FMTC_NULL '\0' /* internal use only */
|
#define FMTC_NULL '\0' /* internal use only */
|
||||||
|
|
||||||
#define FMTC_CHAR 'c'
|
#define FMTC_CHAR 'c'
|
||||||
#define FMTC_SHORT 'h'
|
#define FMTC_SHORT 'h'
|
||||||
#define FMTC_INT 'i'
|
#define FMTC_INT 'i'
|
||||||
@ -62,6 +87,11 @@
|
|||||||
#define FMTC_BLOB 'b'
|
#define FMTC_BLOB 'b'
|
||||||
#define FMTC_POINTER 'p'
|
#define FMTC_POINTER 'p'
|
||||||
|
|
||||||
|
#define FMTC_INT8 '1'
|
||||||
|
#define FMTC_INT16 '2'
|
||||||
|
#define FMTC_INT32 '4'
|
||||||
|
#define FMTC_INT64 '8'
|
||||||
|
|
||||||
typedef struct link_t link_t;
|
typedef struct link_t link_t;
|
||||||
struct link_t
|
struct link_t
|
||||||
{
|
{
|
||||||
@ -85,6 +115,18 @@ union ffi_sv_t
|
|||||||
unsigned long long int ull;
|
unsigned long long int ull;
|
||||||
long long int ll;
|
long long int ll;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
moo_uint8_t ui8;
|
||||||
|
moo_int8_t i8;
|
||||||
|
moo_uint16_t ui16;
|
||||||
|
moo_int16_t i16;
|
||||||
|
moo_uint32_t ui32;
|
||||||
|
moo_int32_t i32;
|
||||||
|
#if (MOO_SIZEOF_INT64_T > 0)
|
||||||
|
moo_uint64_t ui64;
|
||||||
|
moo_int64_t i64;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -194,6 +236,14 @@ static moo_pfrc_t pf_open (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
|
|||||||
ffi->fmtc_to_type[0][FMTC_LONGLONG] = &ffi_type_slonglong;
|
ffi->fmtc_to_type[0][FMTC_LONGLONG] = &ffi_type_slonglong;
|
||||||
ffi->fmtc_to_type[1][FMTC_LONGLONG] = &ffi_type_ulonglong;
|
ffi->fmtc_to_type[1][FMTC_LONGLONG] = &ffi_type_ulonglong;
|
||||||
#endif
|
#endif
|
||||||
|
ffi->fmtc_to_type[0][FMTC_INT8] = &ffi_type_sint8;
|
||||||
|
ffi->fmtc_to_type[1][FMTC_INT8] = &ffi_type_uint8;
|
||||||
|
ffi->fmtc_to_type[0][FMTC_INT16] = &ffi_type_sint16;
|
||||||
|
ffi->fmtc_to_type[1][FMTC_INT16] = &ffi_type_uint16;
|
||||||
|
ffi->fmtc_to_type[0][FMTC_INT32] = &ffi_type_sint32;
|
||||||
|
ffi->fmtc_to_type[1][FMTC_INT32] = &ffi_type_uint32;
|
||||||
|
ffi->fmtc_to_type[0][FMTC_INT64] = &ffi_type_sint64;
|
||||||
|
ffi->fmtc_to_type[1][FMTC_INT64] = &ffi_type_uint64;
|
||||||
|
|
||||||
ffi->fmtc_to_type[0][FMTC_POINTER] = &ffi_type_pointer;
|
ffi->fmtc_to_type[0][FMTC_POINTER] = &ffi_type_pointer;
|
||||||
ffi->fmtc_to_type[1][FMTC_POINTER] = &ffi_type_pointer;
|
ffi->fmtc_to_type[1][FMTC_POINTER] = &ffi_type_pointer;
|
||||||
@ -292,6 +342,112 @@ static MOO_INLINE int add_ffi_arg (moo_t* moo, ffi_t* ffi, moo_ooch_t fmtc, int
|
|||||||
|
|
||||||
switch (fmtc)
|
switch (fmtc)
|
||||||
{
|
{
|
||||||
|
case FMTC_INT8:
|
||||||
|
if (_unsigned)
|
||||||
|
{
|
||||||
|
moo_oow_t v;
|
||||||
|
if (moo_inttooow(moo, arg, &v) == 0) goto oops;
|
||||||
|
#if defined(USE_DYNCALL)
|
||||||
|
__dcArgInt8 (ffi->dc, v);
|
||||||
|
#elif defined(USE_LIBFFI)
|
||||||
|
ffi->arg_values[ffi->arg_count] = &ffi->arg_svs[ffi->arg_count].ui8;
|
||||||
|
ffi->arg_svs[ffi->arg_count].ui8 = v;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
moo_ooi_t v;
|
||||||
|
if (moo_inttoooi(moo, arg, &v) == 0) goto oops;
|
||||||
|
#if defined(USE_DYNCALL)
|
||||||
|
__dcArgInt8 (ffi->dc, v);
|
||||||
|
#elif defined(USE_LIBFFI)
|
||||||
|
ffi->arg_values[ffi->arg_count] = &ffi->arg_svs[ffi->arg_count].i8;
|
||||||
|
ffi->arg_svs[ffi->arg_count].i8 = v;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FMTC_INT16:
|
||||||
|
if (_unsigned)
|
||||||
|
{
|
||||||
|
moo_oow_t v;
|
||||||
|
if (moo_inttooow(moo, arg, &v) == 0) goto oops;
|
||||||
|
#if defined(USE_DYNCALL)
|
||||||
|
__dcArgInt16 (ffi->dc, v);
|
||||||
|
#elif defined(USE_LIBFFI)
|
||||||
|
ffi->arg_values[ffi->arg_count] = &ffi->arg_svs[ffi->arg_count].ui16;
|
||||||
|
ffi->arg_svs[ffi->arg_count].ui16 = v;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
moo_ooi_t v;
|
||||||
|
if (moo_inttoooi(moo, arg, &v) == 0) goto oops;
|
||||||
|
#if defined(USE_DYNCALL)
|
||||||
|
__dcArgInt16 (ffi->dc, v);
|
||||||
|
#elif defined(USE_LIBFFI)
|
||||||
|
ffi->arg_values[ffi->arg_count] = &ffi->arg_svs[ffi->arg_count].i16;
|
||||||
|
ffi->arg_svs[ffi->arg_count].i16 = v;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case FMTC_INT32:
|
||||||
|
if (_unsigned)
|
||||||
|
{
|
||||||
|
moo_oow_t v;
|
||||||
|
if (moo_inttooow(moo, arg, &v) == 0) goto oops;
|
||||||
|
#if defined(USE_DYNCALL)
|
||||||
|
__dcArgInt32 (ffi->dc, v);
|
||||||
|
#elif defined(USE_LIBFFI)
|
||||||
|
ffi->arg_values[ffi->arg_count] = &ffi->arg_svs[ffi->arg_count].ui32;
|
||||||
|
ffi->arg_svs[ffi->arg_count].ui32 = v;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
moo_ooi_t v;
|
||||||
|
if (moo_inttoooi(moo, arg, &v) == 0) goto oops;
|
||||||
|
#if defined(USE_DYNCALL)
|
||||||
|
__dcArgInt32 (ffi->dc, v);
|
||||||
|
#elif defined(USE_LIBFFI)
|
||||||
|
ffi->arg_values[ffi->arg_count] = &ffi->arg_svs[ffi->arg_count].i32;
|
||||||
|
ffi->arg_svs[ffi->arg_count].i32 = v;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case FMTC_INT64:
|
||||||
|
#if (MOO_SIZEOF_INT64_T > 0)
|
||||||
|
if (_unsigned)
|
||||||
|
{
|
||||||
|
moo_oow_t v;
|
||||||
|
if (moo_inttooow(moo, arg, &v) == 0) goto oops;
|
||||||
|
#if defined(USE_DYNCALL)
|
||||||
|
__dcArgInt64 (ffi->dc, v);
|
||||||
|
#elif defined(USE_LIBFFI)
|
||||||
|
ffi->arg_values[ffi->arg_count] = &ffi->arg_svs[ffi->arg_count].ui64;
|
||||||
|
ffi->arg_svs[ffi->arg_count].ui64 = v;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
moo_ooi_t v;
|
||||||
|
if (moo_inttoooi(moo, arg, &v) == 0) goto oops;
|
||||||
|
#if defined(USE_DYNCALL)
|
||||||
|
__dcArgInt64 (ffi->dc, v);
|
||||||
|
#elif defined(USE_LIBFFI)
|
||||||
|
ffi->arg_values[ffi->arg_count] = &ffi->arg_svs[ffi->arg_count].i64;
|
||||||
|
ffi->arg_svs[ffi->arg_count].i64 = v;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#else
|
||||||
|
goto inval_sig_ch;
|
||||||
|
#endif
|
||||||
|
|
||||||
case FMTC_CHAR:
|
case FMTC_CHAR:
|
||||||
if (!MOO_OOP_IS_CHAR(arg)) goto inval_arg_value;
|
if (!MOO_OOP_IS_CHAR(arg)) goto inval_arg_value;
|
||||||
if (_unsigned)
|
if (_unsigned)
|
||||||
@ -318,7 +474,7 @@ static MOO_INLINE int add_ffi_arg (moo_t* moo, ffi_t* ffi, moo_ooch_t fmtc, int
|
|||||||
if (_unsigned)
|
if (_unsigned)
|
||||||
{
|
{
|
||||||
moo_oow_t v;
|
moo_oow_t v;
|
||||||
if (moo_inttooow(moo, arg, &v) == 0) goto inval_arg_value;
|
if (moo_inttooow(moo, arg, &v) == 0) goto oops;
|
||||||
#if defined(USE_DYNCALL)
|
#if defined(USE_DYNCALL)
|
||||||
dcArgShort (ffi->dc, v);
|
dcArgShort (ffi->dc, v);
|
||||||
#elif defined(USE_LIBFFI)
|
#elif defined(USE_LIBFFI)
|
||||||
@ -503,8 +659,9 @@ static MOO_INLINE int add_ffi_arg (moo_t* moo, ffi_t* ffi, moo_ooch_t fmtc, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
inval_sig_ch:
|
||||||
/* invalid argument signature specifier */
|
/* invalid argument signature specifier */
|
||||||
moo_seterrbfmt (moo, MOO_EINVAL, "invalid signature character - %jc", fmtc);
|
moo_seterrbfmt (moo, MOO_EINVAL, "invalid argument type signature - %jc", fmtc);
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -527,7 +684,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
|
|||||||
#if defined(USE_DYNCALL) || defined(USE_LIBFFI)
|
#if defined(USE_DYNCALL) || defined(USE_LIBFFI)
|
||||||
ffi_t* ffi;
|
ffi_t* ffi;
|
||||||
moo_oop_t fun, sig, args;
|
moo_oop_t fun, sig, args;
|
||||||
moo_oow_t i, j, nfixedargs;
|
moo_oow_t i, j, nfixedargs, _unsigned;
|
||||||
void* f;
|
void* f;
|
||||||
moo_oop_oop_t arr;
|
moo_oop_oop_t arr;
|
||||||
int vbar = 0;
|
int vbar = 0;
|
||||||
@ -578,7 +735,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* check argument signature */
|
/* check argument signature */
|
||||||
for (i = 0, j = 0, nfixedargs = 0; i < MOO_OBJ_GET_SIZE(sig); i++)
|
for (i = 0, j = 0, nfixedargs = 0, _unsigned = 0; i < MOO_OBJ_GET_SIZE(sig); i++)
|
||||||
{
|
{
|
||||||
fmtc = MOO_OBJ_GET_CHAR_VAL(sig, i);
|
fmtc = MOO_OBJ_GET_CHAR_VAL(sig, i);
|
||||||
if (fmtc == ' ')
|
if (fmtc == ' ')
|
||||||
@ -605,11 +762,17 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
else if (fmtc == 'u')
|
||||||
|
{
|
||||||
|
_unsigned = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* more items in signature than the actual argument */
|
/* more items in signature than the actual argument */
|
||||||
if (j >= MOO_OBJ_GET_SIZE(arr)) goto inval;
|
if (j >= MOO_OBJ_GET_SIZE(arr)) goto inval;
|
||||||
|
|
||||||
if (add_ffi_arg(moo, ffi, fmtc, 0, MOO_OBJ_GET_OOP_VAL(arr, j)) <= -1) goto softfail;
|
if (add_ffi_arg(moo, ffi, fmtc, _unsigned, MOO_OBJ_GET_OOP_VAL(arr, j)) <= -1) goto softfail;
|
||||||
|
_unsigned = 0;
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -628,19 +791,141 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
|
|||||||
ffi_call (&ffi->cif, FFI_FN(f), &ffi->ret_sv, ffi->arg_values);
|
ffi_call (&ffi->cif, FFI_FN(f), &ffi->ret_sv, ffi->arg_values);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (fmtc == 'u')
|
||||||
|
{
|
||||||
|
_unsigned = 1;
|
||||||
|
fmtc++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_unsigned = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* check the return value type in signature */
|
/* check the return value type in signature */
|
||||||
switch (fmtc)
|
switch (fmtc)
|
||||||
{
|
{
|
||||||
/* TODO: support more types... */
|
/* TODO: support more types... */
|
||||||
/* TODO: proper return value conversion */
|
/* TODO: proper return value conversion */
|
||||||
/* TODO: handle unsigned */
|
case FMTC_INT8:
|
||||||
|
{
|
||||||
|
moo_oop_t r;
|
||||||
|
if (_unsigned)
|
||||||
|
{
|
||||||
|
#if defined(USE_DYNCALL)
|
||||||
|
r = moo_oowtoint(moo, __dcCallInt8(ffi->dc, f));
|
||||||
|
#elif defined(USE_LIBFFI)
|
||||||
|
r = moo_oowtoint(moo, ffi->ret_sv.ui8);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if defined(USE_DYNCALL)
|
||||||
|
r = moo_ooitoint(moo, __dcCallInt8(ffi->dc, f));
|
||||||
|
#elif defined(USE_LIBFFI)
|
||||||
|
r = moo_ooitoint(moo, ffi->ret_sv.i8);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (!r) goto hardfail;
|
||||||
|
|
||||||
|
MOO_STACK_SETRET (moo, nargs, r);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case FMTC_INT16:
|
||||||
|
{
|
||||||
|
moo_oop_t r;
|
||||||
|
if (_unsigned)
|
||||||
|
{
|
||||||
|
#if defined(USE_DYNCALL)
|
||||||
|
r = moo_oowtoint(moo, __dcCallInt16(ffi->dc, f));
|
||||||
|
#elif defined(USE_LIBFFI)
|
||||||
|
r = moo_oowtoint(moo, ffi->ret_sv.ui16);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if defined(USE_DYNCALL)
|
||||||
|
r = moo_ooitoint(moo, __dcCallInt16(ffi->dc, f));
|
||||||
|
#elif defined(USE_LIBFFI)
|
||||||
|
r = moo_ooitoint(moo, ffi->ret_sv.i16);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (!r) goto hardfail;
|
||||||
|
|
||||||
|
MOO_STACK_SETRET (moo, nargs, r);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case FMTC_INT32:
|
||||||
|
{
|
||||||
|
moo_oop_t r;
|
||||||
|
if (_unsigned)
|
||||||
|
{
|
||||||
|
#if defined(USE_DYNCALL)
|
||||||
|
r = moo_oowtoint(moo, __dcCallInt32(ffi->dc, f));
|
||||||
|
#elif defined(USE_LIBFFI)
|
||||||
|
r = moo_oowtoint(moo, ffi->ret_sv.ui32);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if defined(USE_DYNCALL)
|
||||||
|
r = moo_ooitoint(moo, __dcCallInt32(ffi->dc, f));
|
||||||
|
#elif defined(USE_LIBFFI)
|
||||||
|
r = moo_ooitoint(moo, ffi->ret_sv.i32);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (!r) goto hardfail;
|
||||||
|
|
||||||
|
MOO_STACK_SETRET (moo, nargs, r);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case FMTC_INT64:
|
||||||
|
{
|
||||||
|
#if (MOO_SIZEOF_INT64_T > 0)
|
||||||
|
moo_oop_t r;
|
||||||
|
if (_unsigned)
|
||||||
|
{
|
||||||
|
#if defined(USE_DYNCALL)
|
||||||
|
r = moo_oowtoint(moo, __dcCallInt64(ffi->dc, f));
|
||||||
|
#elif defined(USE_LIBFFI)
|
||||||
|
r = moo_oowtoint(moo, ffi->ret_sv.ui64);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if defined(USE_DYNCALL)
|
||||||
|
r = moo_ooitoint(moo, __dcCallInt64(ffi->dc, f));
|
||||||
|
#elif defined(USE_LIBFFI)
|
||||||
|
r = moo_ooitoint(moo, ffi->ret_sv.i64);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (!r) goto hardfail;
|
||||||
|
|
||||||
|
MOO_STACK_SETRET (moo, nargs, r);
|
||||||
|
break;
|
||||||
|
#else
|
||||||
|
moo_seterrbfmt (moo, MOO_EINVAL, "invalid return type signature - %jc", fmtc);
|
||||||
|
goto softfail;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
case FMTC_CHAR:
|
case FMTC_CHAR:
|
||||||
{
|
{
|
||||||
#if defined(USE_DYNCALL)
|
#if defined(USE_DYNCALL)
|
||||||
char r = dcCallChar(ffi->dc, f);
|
char r = dcCallChar(ffi->dc, f);
|
||||||
MOO_STACK_SETRET (moo, nargs, MOO_CHAR_TO_OOP(r));
|
MOO_STACK_SETRET (moo, nargs, MOO_CHAR_TO_OOP(r));
|
||||||
#elif defined(USE_LIBFFI)
|
#elif defined(USE_LIBFFI)
|
||||||
|
if (_unsigned)
|
||||||
|
{
|
||||||
|
MOO_STACK_SETRET (moo, nargs, MOO_CHAR_TO_OOP(ffi->ret_sv.uc));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
MOO_STACK_SETRET (moo, nargs, MOO_CHAR_TO_OOP(ffi->ret_sv.c));
|
MOO_STACK_SETRET (moo, nargs, MOO_CHAR_TO_OOP(ffi->ret_sv.c));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -648,11 +933,22 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
|
|||||||
case FMTC_SHORT:
|
case FMTC_SHORT:
|
||||||
{
|
{
|
||||||
moo_oop_t r;
|
moo_oop_t r;
|
||||||
|
if (_unsigned)
|
||||||
|
{
|
||||||
|
#if defined(USE_DYNCALL)
|
||||||
|
r = moo_oowtoint(moo, dcCallShort(ffi->dc, f));
|
||||||
|
#elif defined(USE_LIBFFI)
|
||||||
|
r = moo_oowtoint(moo, ffi->ret_sv.uh);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
#if defined(USE_DYNCALL)
|
#if defined(USE_DYNCALL)
|
||||||
r = moo_ooitoint(moo, dcCallShort(ffi->dc, f));
|
r = moo_ooitoint(moo, dcCallShort(ffi->dc, f));
|
||||||
#elif defined(USE_LIBFFI)
|
#elif defined(USE_LIBFFI)
|
||||||
r = moo_ooitoint(moo, ffi->ret_sv.h);
|
r = moo_ooitoint(moo, ffi->ret_sv.h);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
if (!r) goto hardfail;
|
if (!r) goto hardfail;
|
||||||
|
|
||||||
MOO_STACK_SETRET (moo, nargs, r);
|
MOO_STACK_SETRET (moo, nargs, r);
|
||||||
@ -662,11 +958,22 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
|
|||||||
case FMTC_INT:
|
case FMTC_INT:
|
||||||
{
|
{
|
||||||
moo_oop_t r;
|
moo_oop_t r;
|
||||||
|
if (_unsigned)
|
||||||
|
{
|
||||||
|
#if defined(USE_DYNCALL)
|
||||||
|
r = moo_oowtoint(moo, dcCallInt(ffi->dc, f));
|
||||||
|
#elif defined(USE_LIBFFI)
|
||||||
|
r = moo_oowtoint(moo, ffi->ret_sv.ui);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
#if defined(USE_DYNCALL)
|
#if defined(USE_DYNCALL)
|
||||||
r = moo_ooitoint(moo, dcCallInt(ffi->dc, f));
|
r = moo_ooitoint(moo, dcCallInt(ffi->dc, f));
|
||||||
#elif defined(USE_LIBFFI)
|
#elif defined(USE_LIBFFI)
|
||||||
r = moo_ooitoint(moo, ffi->ret_sv.i);
|
r = moo_ooitoint(moo, ffi->ret_sv.i);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
if (!r) goto hardfail;
|
if (!r) goto hardfail;
|
||||||
MOO_STACK_SETRET (moo, nargs, r);
|
MOO_STACK_SETRET (moo, nargs, r);
|
||||||
break;
|
break;
|
||||||
@ -676,11 +983,22 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
|
|||||||
{
|
{
|
||||||
moo_oop_t r;
|
moo_oop_t r;
|
||||||
ret_as_long:
|
ret_as_long:
|
||||||
|
if (_unsigned)
|
||||||
|
{
|
||||||
|
#if defined(USE_DYNCALL)
|
||||||
|
r = moo_oowtoint(moo, dcCallLong(ffi->dc, f));
|
||||||
|
#elif defined(USE_LIBFFI)
|
||||||
|
r = moo_oowtoint(moo, ffi->ret_sv.ul);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
#if defined(USE_DYNCALL)
|
#if defined(USE_DYNCALL)
|
||||||
r = moo_ooitoint(moo, dcCallLong(ffi->dc, f));
|
r = moo_ooitoint(moo, dcCallLong(ffi->dc, f));
|
||||||
#elif defined(USE_LIBFFI)
|
#elif defined(USE_LIBFFI)
|
||||||
r = moo_ooitoint(moo, ffi->ret_sv.l);
|
r = moo_ooitoint(moo, ffi->ret_sv.l);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
if (!r) goto hardfail;
|
if (!r) goto hardfail;
|
||||||
MOO_STACK_SETRET (moo, nargs, r);
|
MOO_STACK_SETRET (moo, nargs, r);
|
||||||
break;
|
break;
|
||||||
@ -692,12 +1010,22 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
|
|||||||
goto ret_as_long;
|
goto ret_as_long;
|
||||||
#else
|
#else
|
||||||
moo_oop_t r;
|
moo_oop_t r;
|
||||||
|
if (_unsigned)
|
||||||
|
{
|
||||||
|
#if defined(USE_DYNCALL)
|
||||||
|
r = moo_uintmaxtoint(moo, dcCallLongLong(ffi->dc, f));
|
||||||
|
#elif defined(USE_LIBFFI)
|
||||||
|
r = moo_uintmaxtoint(moo, ffi->ret_sv.ull);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
#if defined(USE_DYNCALL)
|
#if defined(USE_DYNCALL)
|
||||||
r = moo_intmaxtoint(moo, dcCallLongLong(ffi->dc, f));
|
r = moo_intmaxtoint(moo, dcCallLongLong(ffi->dc, f));
|
||||||
#elif defined(USE_LIBFFI)
|
#elif defined(USE_LIBFFI)
|
||||||
/* TODO: unsigned */
|
|
||||||
r = moo_intmaxtoint(moo, ffi->ret_sv.ll);
|
r = moo_intmaxtoint(moo, ffi->ret_sv.ll);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
if (!r) goto hardfail;
|
if (!r) goto hardfail;
|
||||||
MOO_STACK_SETRET (moo, nargs, r);
|
MOO_STACK_SETRET (moo, nargs, r);
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user