unsigned argument/return handling in ffi
This commit is contained in:
		@ -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
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										386
									
								
								moo/mod/ffi.c
									
									
									
									
									
								
							
							
						
						
									
										386
									
								
								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)
 | 
				
			||||||
			MOO_STACK_SETRET (moo, nargs, MOO_CHAR_TO_OOP(ffi->ret_sv.c));
 | 
								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));
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		#endif
 | 
							#endif
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -648,13 +933,24 @@ 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 defined(USE_DYNCALL)
 | 
								if (_unsigned)
 | 
				
			||||||
			r = moo_ooitoint(moo, dcCallShort(ffi->dc, f));
 | 
								{
 | 
				
			||||||
		#elif defined(USE_LIBFFI)
 | 
								#if defined(USE_DYNCALL)
 | 
				
			||||||
			r = moo_ooitoint(moo, ffi->ret_sv.h);
 | 
									r = moo_oowtoint(moo, dcCallShort(ffi->dc, f));
 | 
				
			||||||
		#endif
 | 
								#elif defined(USE_LIBFFI)
 | 
				
			||||||
 | 
									r = moo_oowtoint(moo, ffi->ret_sv.uh);
 | 
				
			||||||
 | 
								#endif
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
								#if defined(USE_DYNCALL)
 | 
				
			||||||
 | 
									r = moo_ooitoint(moo, dcCallShort(ffi->dc, f));
 | 
				
			||||||
 | 
								#elif defined(USE_LIBFFI)
 | 
				
			||||||
 | 
									r = moo_ooitoint(moo, ffi->ret_sv.h);
 | 
				
			||||||
 | 
								#endif
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			if (!r) goto hardfail;
 | 
								if (!r) goto hardfail;
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
			MOO_STACK_SETRET (moo, nargs, r);
 | 
								MOO_STACK_SETRET (moo, nargs, r);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -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 defined(USE_DYNCALL)
 | 
								if (_unsigned)
 | 
				
			||||||
			r = moo_ooitoint(moo, dcCallInt(ffi->dc, f));
 | 
								{
 | 
				
			||||||
		#elif defined(USE_LIBFFI)
 | 
								#if defined(USE_DYNCALL)
 | 
				
			||||||
			r = moo_ooitoint(moo, ffi->ret_sv.i);
 | 
									r = moo_oowtoint(moo, dcCallInt(ffi->dc, f));
 | 
				
			||||||
		#endif
 | 
								#elif defined(USE_LIBFFI)
 | 
				
			||||||
 | 
									r = moo_oowtoint(moo, ffi->ret_sv.ui);
 | 
				
			||||||
 | 
								#endif
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
								#if defined(USE_DYNCALL)
 | 
				
			||||||
 | 
									r = moo_ooitoint(moo, dcCallInt(ffi->dc, f));
 | 
				
			||||||
 | 
								#elif defined(USE_LIBFFI)
 | 
				
			||||||
 | 
									r = moo_ooitoint(moo, ffi->ret_sv.i);
 | 
				
			||||||
 | 
								#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 defined(USE_DYNCALL)
 | 
								if (_unsigned)
 | 
				
			||||||
			r = moo_ooitoint(moo, dcCallLong(ffi->dc, f));
 | 
								{
 | 
				
			||||||
		#elif defined(USE_LIBFFI)
 | 
								#if defined(USE_DYNCALL)
 | 
				
			||||||
			r = moo_ooitoint(moo, ffi->ret_sv.l);
 | 
									r = moo_oowtoint(moo, dcCallLong(ffi->dc, f));
 | 
				
			||||||
		#endif
 | 
								#elif defined(USE_LIBFFI)
 | 
				
			||||||
 | 
									r = moo_oowtoint(moo, ffi->ret_sv.ul);
 | 
				
			||||||
 | 
								#endif
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
								#if defined(USE_DYNCALL)
 | 
				
			||||||
 | 
									r = moo_ooitoint(moo, dcCallLong(ffi->dc, f));
 | 
				
			||||||
 | 
								#elif defined(USE_LIBFFI)
 | 
				
			||||||
 | 
									r = moo_ooitoint(moo, ffi->ret_sv.l);
 | 
				
			||||||
 | 
								#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 defined(USE_DYNCALL)	
 | 
								if (_unsigned)
 | 
				
			||||||
			r = moo_intmaxtoint(moo, dcCallLongLong(ffi->dc, f));
 | 
								{
 | 
				
			||||||
		#elif defined(USE_LIBFFI)
 | 
								#if defined(USE_DYNCALL)	
 | 
				
			||||||
			/* TODO: unsigned  */
 | 
									r = moo_uintmaxtoint(moo, dcCallLongLong(ffi->dc, f));
 | 
				
			||||||
			r = moo_intmaxtoint(moo, ffi->ret_sv.ll);
 | 
								#elif defined(USE_LIBFFI)
 | 
				
			||||||
		#endif
 | 
									r = moo_uintmaxtoint(moo, ffi->ret_sv.ull);
 | 
				
			||||||
 | 
								#endif
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
								#if defined(USE_DYNCALL)	
 | 
				
			||||||
 | 
									r = moo_intmaxtoint(moo, dcCallLongLong(ffi->dc, f));
 | 
				
			||||||
 | 
								#elif defined(USE_LIBFFI)
 | 
				
			||||||
 | 
									r = moo_intmaxtoint(moo, ffi->ret_sv.ll);
 | 
				
			||||||
 | 
								#endif
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			if (!r) goto hardfail;
 | 
								if (!r) goto hardfail;
 | 
				
			||||||
			MOO_STACK_SETRET (moo, nargs, r);
 | 
								MOO_STACK_SETRET (moo, nargs, r);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user