From 1605526ba14aca4594c487048d85931794d82221 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Tue, 11 Jul 2006 21:44:37 +0000 Subject: [PATCH] fixed more big-endian problems svn: r3683 --- src/foreign/foreign.c | 140 ++++++++++++++++++++++++++++++++++++++-- src/foreign/foreign.ssc | 33 ++++++++-- 2 files changed, 161 insertions(+), 12 deletions(-) diff --git a/src/foreign/foreign.c b/src/foreign/foreign.c index f5715e0e55..8bea9a3923 100644 --- a/src/foreign/foreign.c +++ b/src/foreign/foreign.c @@ -1127,12 +1127,25 @@ static Scheme_Object *C2SCHEME(Scheme_Object *type, void *src, int args_loc) } #undef REF_CTYPE +/* On big endian machines we need to know whether we're pulling a value from an + * argument location where it always takes a whole word or straight from a + * memory location -- deal with it as above, via a SCHEME2C macro wrapper that + * is used for both the function definition and calls, but the actual code in + * the function is different: in the relevant cases zero an int and offset the + * ptr */ +#ifdef SCHEME_BIG_ENDIAN +#define SCHEME2C(typ,dst,val,basep,retloc) scheme_to_c(typ,dst,val,basep,retloc) +#else +#define SCHEME2C(typ,dst,val,basep,retloc) scheme_to_c(typ,dst,val,basep) +#endif + /* Usually writes the C object to dst and returns NULL. When basetype_p is not * NULL, then any pointer value (any pointer or a struct) is returned, and the * basetype_p is set to the corrsponding number tag. If basetype_p is NULL, * then a struct value will be *copied* into dst. */ -static void* scheme_to_c(Scheme_Object *type, void *dst, - Scheme_Object *val, long *basetype_p) +static void* SCHEME2C(Scheme_Object *type, void *dst, + Scheme_Object *val, long *basetype_p, + int ret_loc) { if (!SCHEME_CTYPEP(type)) scheme_wrong_type("Scheme->C", "C-type", 0, 1, &type); @@ -1155,6 +1168,12 @@ static void* scheme_to_c(Scheme_Object *type, void *dst, case FOREIGN_void: scheme_wrong_type("Scheme->C","non-void-C-type",0,1,&(type)); case FOREIGN_int8: +#ifdef SCHEME_BIG_ENDIAN + if (sizeof(Tsint8)C","uint64",0,1,&(val)); return NULL; case FOREIGN_fixint: +#ifdef SCHEME_BIG_ENDIAN + if (sizeof(Tsint32)itypes; iproc, argc, argv); - scheme_to_c(data->otype, resultp, p, NULL); + SCHEME2C(data->otype, resultp, p, NULL, 1); } /* see ffi-callback below */ diff --git a/src/foreign/foreign.ssc b/src/foreign/foreign.ssc index 386a659e00..2a0a2c41d3 100755 --- a/src/foreign/foreign.ssc +++ b/src/foreign/foreign.ssc @@ -936,12 +936,25 @@ static Scheme_Object *C2SCHEME(Scheme_Object *type, void *src, int args_loc) } #undef REF_CTYPE +/* On big endian machines we need to know whether we're pulling a value from an + * argument location where it always takes a whole word or straight from a + * memory location -- deal with it as above, via a SCHEME2C macro wrapper that + * is used for both the function definition and calls, but the actual code in + * the function is different: in the relevant cases zero an int and offset the + * ptr */ +#ifdef SCHEME_BIG_ENDIAN +#define SCHEME2C(typ,dst,val,basep,retloc) scheme_to_c(typ,dst,val,basep,retloc) +#else +#define SCHEME2C(typ,dst,val,basep,retloc) scheme_to_c(typ,dst,val,basep) +#endif + /* Usually writes the C object to dst and returns NULL. When basetype_p is not * NULL, then any pointer value (any pointer or a struct) is returned, and the * basetype_p is set to the corrsponding number tag. If basetype_p is NULL, * then a struct value will be *copied* into dst. */ -static void* scheme_to_c(Scheme_Object *type, void *dst, - Scheme_Object *val, long *basetype_p) +static void* SCHEME2C(Scheme_Object *type, void *dst, + Scheme_Object *val, long *basetype_p, + int ret_loc) { if (!SCHEME_CTYPEP(type)) scheme_wrong_type("Scheme->C", "C-type", 0, 1, &type); @@ -971,6 +984,13 @@ static void* scheme_to_c(Scheme_Object *type, void *dst, (if (procedure? p) (p "val" x) (list p"(val)")))]) (if s->c (begin + (display "#ifdef SCHEME_BIG_ENDIAN\n") + (~ " if (sizeof("ctype")c)");") @@ -1316,7 +1336,7 @@ static void* scheme_to_c(Scheme_Object *type, void *dst, scheme_wrong_type(MYNAME, "integer", 2, argc, argv); ptr = (char*)ptr XFORM_OK_PLUS (size * SCHEME_INT_VAL(argv[2])); } - scheme_to_c(argv[1], ptr, val, NULL); + SCHEME2C(argv[1], ptr, val, NULL, 0); return scheme_void; } @@ -1450,7 +1470,7 @@ Scheme_Object *ffi_do_call(void *data, int argc, Scheme_Object *argv[]) /* iterate on input values and types */ for (i=0; iitypes; iproc, argc, argv); - scheme_to_c(data->otype, resultp, p, NULL); + SCHEME2C(data->otype, resultp, p, NULL, 1); } /* see ffi-callback below */