diff options
Diffstat (limited to 'libguile/foreign.h')
-rw-r--r-- | libguile/foreign.h | 64 |
1 files changed, 39 insertions, 25 deletions
diff --git a/libguile/foreign.h b/libguile/foreign.h index 954c1c5b3..d48027799 100644 --- a/libguile/foreign.h +++ b/libguile/foreign.h @@ -21,10 +21,24 @@ -/* A subset of libffi's types. */ +/* A foreign value is some value that exists outside of Guile. It is represented + by a cell whose second word is a pointer. The first word has the + scm_tc7_foreign typecode and type of the aliased (pointed-to) value in its + lower 16 bits. + + There are numeric types, like uint32 and float, and there is a "generic + pointer" type, void. Void pointers also have a length associated with them, + in the high bits of the first word of the SCM object, but since they really + are pointers out into the wild wooly world of C, perhaps we don't actually + know how much memory they take up. In that, most general case, the "len" + will be stored as 0. + + The basic idea is that we can help the programmer to avoid cutting herself, + but we won't take away her knives. +*/ typedef enum { - SCM_FOREIGN_TYPE_VOID, + SCM_FOREIGN_TYPE_VOID, /* a pointer out into the wilderness */ SCM_FOREIGN_TYPE_FLOAT, SCM_FOREIGN_TYPE_DOUBLE, SCM_FOREIGN_TYPE_UINT8, @@ -35,8 +49,7 @@ typedef enum SCM_FOREIGN_TYPE_INT32, SCM_FOREIGN_TYPE_UINT64, SCM_FOREIGN_TYPE_INT64, - SCM_FOREIGN_TYPE_STRUCT, - SCM_FOREIGN_TYPE_POINTER + SCM_FOREIGN_TYPE_LAST = SCM_FOREIGN_TYPE_INT64 } scm_t_foreign_type; @@ -48,12 +61,16 @@ typedef void (*scm_t_foreign_finalizer) (void *); SCM_MAKE_VALIDATE (pos, x, FOREIGN_P) #define SCM_FOREIGN_TYPE(x) \ ((scm_t_foreign_type)((SCM_CELL_WORD_0 (x) >> 8)&0xff)) -#define SCM_FOREIGN_OBJECT(x, ctype) \ - ((ctype*)SCM_CELL_OBJECT_1 (x)) -#define SCM_FOREIGN_OBJECT_REF(x, ctype) \ - (*SCM_FOREIGN_OBJECT (x, ctype)) -#define SCM_FOREIGN_OBJECT_SET(x, ctype, val) \ - (*SCM_FOREIGN_OBJECT (x, ctype) = (val)) +#define SCM_FOREIGN_POINTER(x, ctype) \ + ((ctype*)SCM_CELL_WORD_1 (x)) +#define SCM_FOREIGN_VALUE_REF(x, ctype) \ + (*SCM_FOREIGN_POINTER (x, ctype)) +#define SCM_FOREIGN_VALUE_SET(x, ctype, val) \ + (*SCM_FOREIGN_POINTER (x, ctype) = (val)) +#define SCM_FOREIGN_HAS_FINALIZER(x) \ + ((SCM_CELL_WORD_0 (x) >> 16) & 0x1) +#define SCM_FOREIGN_LEN(x) \ + ((size_t)(SCM_CELL_WORD_0 (x) >> 17)) #define SCM_FOREIGN_TYPED_P(x, type) \ (SCM_FOREIGN_P (x) && SCM_FOREIGN_TYPE (x) == SCM_FOREIGN_TYPE_##type) @@ -63,21 +80,18 @@ typedef void (*scm_t_foreign_finalizer) (void *); "FOREIGN_"#type"_P"); \ } while (0) -#define SCM_FOREIGN_SIMPLE_P(x) \ - (SCM_FOREIGN_P (x) \ - && SCM_FOREIGN_TYPE (x) != SCM_FOREIGN_TYPE_VOID \ - && SCM_FOREIGN_TYPE (x) != SCM_FOREIGN_TYPE_STRUCT \ - && SCM_FOREIGN_TYPE (x) != SCM_FOREIGN_TYPE_POINTER) -#define SCM_VALIDATE_FOREIGN_SIMPLE(pos, x) \ - SCM_MAKE_VALIDATE (pos, x, FOREIGN_SIMPLE_P) - -SCM_API SCM scm_c_from_foreign (scm_t_foreign_type type, void *val, size_t size, - scm_t_foreign_finalizer finalizer); -SCM_API SCM scm_c_take_foreign (scm_t_foreign_type type, void *val, - scm_t_foreign_finalizer finalizer); - -SCM_API SCM scm_foreign_ref (SCM foreign); -SCM_API SCM scm_foreign_set_x (SCM foreign, SCM val); +#define SCM_FOREIGN_VALUE_P(x) \ + (SCM_FOREIGN_P (x) && SCM_FOREIGN_TYPE (x) != SCM_FOREIGN_TYPE_VOID) +#define SCM_VALIDATE_FOREIGN_VALUE(pos, x) \ + SCM_MAKE_VALIDATE (pos, x, FOREIGN_VALUE_P) + +SCM_API SCM scm_take_foreign_pointer (scm_t_foreign_type type, void *ptr, + size_t len, + scm_t_foreign_finalizer finalizer); + +SCM_API SCM scm_foreign_type (SCM foreign); +SCM_API SCM scm_foreign_ref (SCM foreign, SCM type, SCM offset, SCM len); +SCM_API SCM scm_foreign_set_x (SCM foreign, SCM val, SCM type, SCM offset); SCM_INTERNAL void scm_i_foreign_print (SCM foreign, SCM port, scm_print_state *pstate); |