summaryrefslogtreecommitdiff
path: root/libguile/foreign.h
diff options
context:
space:
mode:
Diffstat (limited to 'libguile/foreign.h')
-rw-r--r--libguile/foreign.h64
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);