ffi/unsafe: add _stdbool

This commit is contained in:
Matthew Flatt 2014-04-04 09:56:11 -06:00
parent 3b030e393d
commit 1d8cfea1fc
9 changed files with 176 additions and 18 deletions

View File

@ -229,10 +229,20 @@ values.}
@section{Other Atomic Types} @section{Other Atomic Types}
@defthing[_stdbool ctype?]{
The @racket[_stdbool] type represents the C99 @cpp{bool} type from
@cpp{<stdbool.h>}. It translates @racket[#f] to a @racket[0]
@cpp{bool} and any other value to a @racket[1] @cpp{bool}.
@history[#:added "6.0.0.6"]}
@defthing[_bool ctype?]{ @defthing[_bool ctype?]{
Translates @racket[#f] to a @racket[0] @racket[_int], and any other Translates @racket[#f] to a @racket[0] @cpp{int} and any other
value to @racket[1].} value to a @racket[1] @cpp{int}, reflecting one of many
traditional (i.e., pre-C99) encodings of booleans. See also
@racket[_stdbool].}
@defthing[_void ctype?]{ @defthing[_void ctype?]{

View File

@ -16,7 +16,7 @@
_void _int8 _uint8 _int16 _uint16 _int32 _uint32 _int64 _uint64 _void _int8 _uint8 _int16 _uint16 _int32 _uint32 _int64 _uint64
_fixint _ufixint _fixnum _ufixnum _fixint _ufixint _fixnum _ufixnum
_float _double _longdouble _double* _float _double _longdouble _double*
_bool _pointer _gcpointer _scheme (rename-out [_scheme _racket]) _fpointer function-ptr _bool _stdbool _pointer _gcpointer _scheme (rename-out [_scheme _racket]) _fpointer function-ptr
memcpy memmove memset memcpy memmove memset
malloc-immobile-cell free-immobile-cell malloc-immobile-cell free-immobile-cell
make-late-weak-box make-late-weak-hasheq) make-late-weak-box make-late-weak-hasheq)

34
racket/src/configure vendored
View File

@ -5718,6 +5718,40 @@ cat >>confdefs.h <<_ACEOF
_ACEOF _ACEOF
# The cast to long int works around a bug in the HP C Compiler
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
# This bug is HP SR number 8606223364.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of bool" >&5
$as_echo_n "checking size of bool... " >&6; }
if ${ac_cv_sizeof_bool+:} false; then :
$as_echo_n "(cached) " >&6
else
if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (bool))" "ac_cv_sizeof_bool" "#include <stdbool.h>
"; then :
else
if test "$ac_cv_type_bool" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error 77 "cannot compute sizeof (bool)
See \`config.log' for more details" "$LINENO" 5; }
else
ac_cv_sizeof_bool=0
fi
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_bool" >&5
$as_echo "$ac_cv_sizeof_bool" >&6; }
cat >>confdefs.h <<_ACEOF
#define SIZEOF_BOOL $ac_cv_sizeof_bool
_ACEOF
ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "$ac_includes_default" ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "$ac_includes_default"

View File

@ -12,6 +12,13 @@
#include <errno.h> #include <errno.h>
#ifndef SIZEOF_BOOL
# define SIZEOF_BOOL 0
#endif /* SIZEOF_BOOL */
#if SIZEOF_BOOL != 0
# include <stdbool.h>
#endif /* SIZEOF_BOOL != 0 */
#ifndef WINDOWS_DYNAMIC_LOAD #ifndef WINDOWS_DYNAMIC_LOAD
# include <dlfcn.h> # include <dlfcn.h>
#else /* WINDOWS_DYNAMIC_LOAD defined */ #else /* WINDOWS_DYNAMIC_LOAD defined */
@ -868,11 +875,47 @@ static Scheme_Object *unsupported_make_long_double() {
* C->Racket: (<C>?scheme_true:scheme_false) * C->Racket: (<C>?scheme_true:scheme_false)
*/ */
#if SIZEOF_BOOL == 0
typedef signed char stdbool;
# define ffi_type_stdbool ffi_type_sint8
#else /* SIZEOF_BOOL == 0 */
typedef bool stdbool;
#if SIZEOF_BOOL == 1
# define ffi_type_stdbool ffi_type_sint8
#else /* SIZEOF_BOOL == 1 */
#if SIZEOF_BOOL == 2
# define ffi_type_stdbool ffi_type_sint16
#else /* SIZEOF_BOOL == 2 */
#if SIZEOF_BOOL == 4
# define ffi_type_stdbool ffi_type_sint32
#else /* SIZEOF_BOOL == 4 */
#if SIZEOF_BOOL == 8
# define ffi_type_stdbool ffi_type_sint64
#else /* SIZEOF_BOOL == 8 */
/* ??? Pick something */
# define ffi_type_stdbool ffi_type_int
#endif /* SIZEOF_BOOL == 8 */
#endif /* SIZEOF_BOOL == 4 */
#endif /* SIZEOF_BOOL == 2 */
#endif /* SIZEOF_BOOL == 1 */
#endif /* SIZEOF_BOOL == 0 */
/* Booleans -- implemented as an int which is 1 or 0: */
#define FOREIGN_stdbool (19)
/* Type Name: stdbool
* LibFfi type: ffi_type_stdbool
* C type: stdbool
* Predicate: 1
* Racket->C: SCHEME_TRUEP(<Scheme>)
* S->C offset: 0
* C->Racket: (<C>?scheme_true:scheme_false)
*/
/* Strings -- no copying is done (when possible). /* Strings -- no copying is done (when possible).
* #f is not NULL only for byte-strings, for other strings it is * #f is not NULL only for byte-strings, for other strings it is
* meaningless to use NULL. */ * meaningless to use NULL. */
#define FOREIGN_string_ucs_4 (19) #define FOREIGN_string_ucs_4 (20)
/* Type Name: string/ucs-4 (string_ucs_4) /* Type Name: string/ucs-4 (string_ucs_4)
* LibFfi type: ffi_type_gcpointer * LibFfi type: ffi_type_gcpointer
* C type: mzchar* * C type: mzchar*
@ -882,7 +925,7 @@ static Scheme_Object *unsupported_make_long_double() {
* C->Racket: scheme_make_char_string_without_copying(<C>) * C->Racket: scheme_make_char_string_without_copying(<C>)
*/ */
#define FOREIGN_string_utf_16 (20) #define FOREIGN_string_utf_16 (21)
/* Type Name: string/utf-16 (string_utf_16) /* Type Name: string/utf-16 (string_utf_16)
* LibFfi type: ffi_type_gcpointer * LibFfi type: ffi_type_gcpointer
* C type: unsigned short* * C type: unsigned short*
@ -895,7 +938,7 @@ static Scheme_Object *unsupported_make_long_double() {
/* Byte strings -- not copying C strings, #f is NULL. /* Byte strings -- not copying C strings, #f is NULL.
* (note: these are not like char* which is just a pointer) */ * (note: these are not like char* which is just a pointer) */
#define FOREIGN_bytes (21) #define FOREIGN_bytes (22)
/* Type Name: bytes /* Type Name: bytes
* LibFfi type: ffi_type_gcpointer * LibFfi type: ffi_type_gcpointer
* C type: char* * C type: char*
@ -905,7 +948,7 @@ static Scheme_Object *unsupported_make_long_double() {
* C->Racket: (<C>==NULL)?scheme_false:scheme_make_byte_string_without_copying(<C>) * C->Racket: (<C>==NULL)?scheme_false:scheme_make_byte_string_without_copying(<C>)
*/ */
#define FOREIGN_path (22) #define FOREIGN_path (23)
/* Type Name: path /* Type Name: path
* LibFfi type: ffi_type_gcpointer * LibFfi type: ffi_type_gcpointer
* C type: char* * C type: char*
@ -915,7 +958,7 @@ static Scheme_Object *unsupported_make_long_double() {
* C->Racket: (<C>==NULL)?scheme_false:scheme_make_path_without_copying(<C>) * C->Racket: (<C>==NULL)?scheme_false:scheme_make_path_without_copying(<C>)
*/ */
#define FOREIGN_symbol (23) #define FOREIGN_symbol (24)
/* Type Name: symbol /* Type Name: symbol
* LibFfi type: ffi_type_pointer * LibFfi type: ffi_type_pointer
* C type: char* * C type: char*
@ -928,7 +971,7 @@ static Scheme_Object *unsupported_make_long_double() {
/* This is for any C pointer: #f is NULL, cpointer values as well as /* This is for any C pointer: #f is NULL, cpointer values as well as
* ffi-obj and string values pass their pointer. When used as a return * ffi-obj and string values pass their pointer. When used as a return
* value, either a cpointer object or #f is returned. */ * value, either a cpointer object or #f is returned. */
#define FOREIGN_pointer (24) #define FOREIGN_pointer (25)
/* Type Name: pointer /* Type Name: pointer
* LibFfi type: ffi_type_pointer * LibFfi type: ffi_type_pointer
* C type: void* * C type: void*
@ -938,7 +981,7 @@ static Scheme_Object *unsupported_make_long_double() {
* C->Racket: scheme_make_foreign_external_cpointer(<C>) * C->Racket: scheme_make_foreign_external_cpointer(<C>)
*/ */
#define FOREIGN_gcpointer (25) #define FOREIGN_gcpointer (26)
/* Type Name: gcpointer /* Type Name: gcpointer
* LibFfi type: ffi_type_gcpointer * LibFfi type: ffi_type_gcpointer
* C type: void* * C type: void*
@ -950,7 +993,7 @@ static Scheme_Object *unsupported_make_long_double() {
/* This is used for passing and Scheme_Object* value as is. Useful for /* This is used for passing and Scheme_Object* value as is. Useful for
* functions that know about Scheme_Object*s, like Racket's. */ * functions that know about Scheme_Object*s, like Racket's. */
#define FOREIGN_scheme (26) #define FOREIGN_scheme (27)
/* Type Name: scheme /* Type Name: scheme
* LibFfi type: ffi_type_gcpointer * LibFfi type: ffi_type_gcpointer
* C type: Scheme_Object* * C type: Scheme_Object*
@ -963,7 +1006,7 @@ static Scheme_Object *unsupported_make_long_double() {
/* Special type, not actually used for anything except to mark values /* Special type, not actually used for anything except to mark values
* that are treated like pointers but not referenced. Used for * that are treated like pointers but not referenced. Used for
* creating function types. */ * creating function types. */
#define FOREIGN_fpointer (27) #define FOREIGN_fpointer (28)
/* Type Name: fpointer /* Type Name: fpointer
* LibFfi type: ffi_type_pointer * LibFfi type: ffi_type_pointer
* C type: void* * C type: void*
@ -991,6 +1034,7 @@ typedef union _ForeignAny {
mz_long_double x_longdouble; mz_long_double x_longdouble;
double x_doubleS; double x_doubleS;
int x_bool; int x_bool;
stdbool x_stdbool;
mzchar* x_string_ucs_4; mzchar* x_string_ucs_4;
unsigned short* x_string_utf_16; unsigned short* x_string_utf_16;
char* x_bytes; char* x_bytes;
@ -1003,9 +1047,9 @@ typedef union _ForeignAny {
} ForeignAny; } ForeignAny;
/* This is a tag that is used to identify user-made struct types. */ /* This is a tag that is used to identify user-made struct types. */
#define FOREIGN_struct (28) #define FOREIGN_struct (29)
#define FOREIGN_array (29) #define FOREIGN_array (30)
#define FOREIGN_union (30) #define FOREIGN_union (31)
XFORM_NONGCING static int is_gcable_pointer(Scheme_Object *o) { XFORM_NONGCING static int is_gcable_pointer(Scheme_Object *o) {
if (SCHEME_FFIOBJP(o)) return 0; if (SCHEME_FFIOBJP(o)) return 0;
@ -1139,6 +1183,7 @@ XFORM_NONGCING static intptr_t ctype_sizeof(Scheme_Object *type)
case FOREIGN_longdouble: return sizeof(mz_long_double); case FOREIGN_longdouble: return sizeof(mz_long_double);
case FOREIGN_doubleS: return sizeof(double); case FOREIGN_doubleS: return sizeof(double);
case FOREIGN_bool: return sizeof(int); case FOREIGN_bool: return sizeof(int);
case FOREIGN_stdbool: return sizeof(stdbool);
case FOREIGN_string_ucs_4: return sizeof(mzchar*); case FOREIGN_string_ucs_4: return sizeof(mzchar*);
case FOREIGN_string_utf_16: return sizeof(unsigned short*); case FOREIGN_string_utf_16: return sizeof(unsigned short*);
case FOREIGN_bytes: return sizeof(char*); case FOREIGN_bytes: return sizeof(char*);
@ -1746,6 +1791,7 @@ static Scheme_Object *C2SCHEME(Scheme_Object *already_ptr, Scheme_Object *type,
case FOREIGN_longdouble: return scheme_make_maybe_long_double(REF_CTYPE(mz_long_double)); case FOREIGN_longdouble: return scheme_make_maybe_long_double(REF_CTYPE(mz_long_double));
case FOREIGN_doubleS: return scheme_make_double(REF_CTYPE(double)); case FOREIGN_doubleS: return scheme_make_double(REF_CTYPE(double));
case FOREIGN_bool: return (REF_CTYPE(int)?scheme_true:scheme_false); case FOREIGN_bool: return (REF_CTYPE(int)?scheme_true:scheme_false);
case FOREIGN_stdbool: return (REF_CTYPE(stdbool)?scheme_true:scheme_false);
case FOREIGN_string_ucs_4: return scheme_make_char_string_without_copying(REF_CTYPE(mzchar*)); case FOREIGN_string_ucs_4: return scheme_make_char_string_without_copying(REF_CTYPE(mzchar*));
case FOREIGN_string_utf_16: return utf16_pointer_to_ucs4_string(REF_CTYPE(unsigned short*)); case FOREIGN_string_utf_16: return utf16_pointer_to_ucs4_string(REF_CTYPE(unsigned short*));
case FOREIGN_bytes: return (REF_CTYPE(char*)==NULL)?scheme_false:scheme_make_byte_string_without_copying(REF_CTYPE(char*)); case FOREIGN_bytes: return (REF_CTYPE(char*)==NULL)?scheme_false:scheme_make_byte_string_without_copying(REF_CTYPE(char*));
@ -2118,6 +2164,27 @@ static void* SCHEME2C(const char *who,
wrong_value(who, "_bool", val);; wrong_value(who, "_bool", val);;
return NULL; /* hush the compiler */ return NULL; /* hush the compiler */
} }
case FOREIGN_stdbool:
# ifdef SCHEME_BIG_ENDIAN
if (sizeof(stdbool)<sizeof(intptr_t) && ret_loc) {
((int*)W_OFFSET(dst,delta))[0] = 0;
delta += (sizeof(intptr_t)-sizeof(stdbool));
}
# endif /* SCHEME_BIG_ENDIAN */
# ifdef FFI_CALLBACK_NEED_INT_CLEAR
if (sizeof(stdbool)<sizeof(intptr_t) && ret_loc) {
((int*)W_OFFSET(dst,delta))[0] = 0;
}
# endif /* FFI_CALLBACK_NEED_INT_CLEAR */
if (1) {
stdbool tmp;
tmp = MZ_TYPE_CAST(stdbool, SCHEME_TRUEP(val));
(((stdbool*)W_OFFSET(dst,delta))[0]) = tmp; return NULL;
} else {
wrong_value(who, "_stdbool", val);;
return NULL; /* hush the compiler */
}
case FOREIGN_string_ucs_4: case FOREIGN_string_ucs_4:
# ifdef SCHEME_BIG_ENDIAN # ifdef SCHEME_BIG_ENDIAN
if (sizeof(mzchar*)<sizeof(intptr_t) && ret_loc) { if (sizeof(mzchar*)<sizeof(intptr_t) && ret_loc) {
@ -4369,6 +4436,13 @@ void scheme_init_foreign(Scheme_Env *env)
t->scheme_to_c = ((Scheme_Object*)(void*)(&ffi_type_sint)); t->scheme_to_c = ((Scheme_Object*)(void*)(&ffi_type_sint));
t->c_to_scheme = ((Scheme_Object*)FOREIGN_bool); t->c_to_scheme = ((Scheme_Object*)FOREIGN_bool);
scheme_add_global_constant("_bool", (Scheme_Object*)t, menv); scheme_add_global_constant("_bool", (Scheme_Object*)t, menv);
s = scheme_intern_symbol("stdbool");
t = (ctype_struct*)scheme_malloc_tagged(sizeof(ctype_struct));
t->so.type = ctype_tag;
t->basetype = (s);
t->scheme_to_c = ((Scheme_Object*)(void*)(&ffi_type_stdbool));
t->c_to_scheme = ((Scheme_Object*)FOREIGN_stdbool);
scheme_add_global_constant("_stdbool", (Scheme_Object*)t, menv);
s = scheme_intern_symbol("string/ucs-4"); s = scheme_intern_symbol("string/ucs-4");
t = (ctype_struct*)scheme_malloc_tagged(sizeof(ctype_struct)); t = (ctype_struct*)scheme_malloc_tagged(sizeof(ctype_struct));
t->so.type = ctype_tag; t->so.type = ctype_tag;
@ -4603,6 +4677,7 @@ void scheme_init_foreign(Scheme_Env *env)
scheme_add_global_constant("_longdouble", scheme_false, menv); scheme_add_global_constant("_longdouble", scheme_false, menv);
scheme_add_global_constant("_double*", scheme_false, menv); scheme_add_global_constant("_double*", scheme_false, menv);
scheme_add_global_constant("_bool", scheme_false, menv); scheme_add_global_constant("_bool", scheme_false, menv);
scheme_add_global_constant("_stdbool", scheme_false, menv);
scheme_add_global_constant("_string/ucs-4", scheme_false, menv); scheme_add_global_constant("_string/ucs-4", scheme_false, menv);
scheme_add_global_constant("_string/utf-16", scheme_false, menv); scheme_add_global_constant("_string/utf-16", scheme_false, menv);
scheme_add_global_constant("_bytes", scheme_false, menv); scheme_add_global_constant("_bytes", scheme_false, menv);

View File

@ -15,6 +15,13 @@ exec racket "$0" > `echo "$0" | sed 's/rktc$/c/'` "$0"
#include <errno.h> #include <errno.h>
@@IFNDEF{SIZEOF_BOOL}{
# define SIZEOF_BOOL 0
}
@@IF{SIZEOF_BOOL != 0}{
# include <stdbool.h>
}
@@@IFNDEF{WINDOWS_DYNAMIC_LOAD}{ @@@IFNDEF{WINDOWS_DYNAMIC_LOAD}{
# include <dlfcn.h> # include <dlfcn.h>
}{ }{
@ -816,6 +823,34 @@ static Scheme_Object *utf16_pointer_to_ucs4_string(unsigned short *utf)
's->c "SCHEME_TRUEP" 's->c "SCHEME_TRUEP"
'c->s (lambda (x) @list{(@|x|?scheme_true:scheme_false)})) 'c->s (lambda (x) @list{(@|x|?scheme_true:scheme_false)}))
@@@IF{SIZEOF_BOOL == 0}{
typedef signed char stdbool;
# define ffi_type_stdbool ffi_type_sint8
}{
typedef bool stdbool;
@@@IF{SIZEOF_BOOL == 1}{
# define ffi_type_stdbool ffi_type_sint8
}{
@@@IF{SIZEOF_BOOL == 2}{
# define ffi_type_stdbool ffi_type_sint16
}{
@@@IF{SIZEOF_BOOL == 4}{
# define ffi_type_stdbool ffi_type_sint32
}{
@@@IF{SIZEOF_BOOL == 8}{
# define ffi_type_stdbool ffi_type_sint64
}{
/* ??? Pick something */
# define ffi_type_stdbool ffi_type_int
}}}}}
/* Booleans -- implemented as an int which is 1 or 0: */
@(defctype 'stdbool
'ftype "stdbool"
'pred (lambda (x aux) "1")
's->c "SCHEME_TRUEP"
'c->s (lambda (x) @list{(@|x|?scheme_true:scheme_false)}))
/* Strings -- no copying is done (when possible). /* Strings -- no copying is done (when possible).
* #f is not NULL only for byte-strings, for other strings it is * #f is not NULL only for byte-strings, for other strings it is
* meaningless to use NULL. */ * meaningless to use NULL. */

View File

@ -1115,6 +1115,7 @@ AC_CHECK_SIZEOF(int)
AC_CHECK_SIZEOF(long) AC_CHECK_SIZEOF(long)
AC_CHECK_SIZEOF(long long) AC_CHECK_SIZEOF(long long)
AC_CHECK_SIZEOF([void *]) AC_CHECK_SIZEOF([void *])
AC_CHECK_SIZEOF(bool, unused, [#include <stdbool.h>])
AC_TYPE_INTPTR_T AC_TYPE_INTPTR_T
AC_TYPE_UINTPTR_T AC_TYPE_UINTPTR_T

View File

@ -22,6 +22,9 @@
/* The size of a `void *', as computed by sizeof. */ /* The size of a `void *', as computed by sizeof. */
#undef SIZEOF_VOID_P #undef SIZEOF_VOID_P
/* The size of a `bool' with <stdbool.h>, as computed by sizeof. */
#undef SIZEOF_BOOL
/* Whether `intptr_t' is available. */ /* Whether `intptr_t' is available. */
#undef HAVE_INTPTR_T #undef HAVE_INTPTR_T

View File

@ -19,7 +19,7 @@
#define EXPECTED_FLFXNUM_COUNT 69 #define EXPECTED_FLFXNUM_COUNT 69
#define EXPECTED_EXTFL_COUNT 45 #define EXPECTED_EXTFL_COUNT 45
#define EXPECTED_FUTURES_COUNT 15 #define EXPECTED_FUTURES_COUNT 15
#define EXPECTED_FOREIGN_COUNT 78 #define EXPECTED_FOREIGN_COUNT 79
#ifdef MZSCHEME_SOMETHING_OMITTED #ifdef MZSCHEME_SOMETHING_OMITTED
# undef USE_COMPILED_STARTUP # undef USE_COMPILED_STARTUP

View File

@ -13,12 +13,12 @@
consistently.) consistently.)
*/ */
#define MZSCHEME_VERSION "6.0.0.5" #define MZSCHEME_VERSION "6.0.0.6"
#define MZSCHEME_VERSION_X 6 #define MZSCHEME_VERSION_X 6
#define MZSCHEME_VERSION_Y 0 #define MZSCHEME_VERSION_Y 0
#define MZSCHEME_VERSION_Z 0 #define MZSCHEME_VERSION_Z 0
#define MZSCHEME_VERSION_W 5 #define MZSCHEME_VERSION_W 6
#define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y)
#define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W)