diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-06-19 23:21:41 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-06-19 23:21:41 -0700 |
commit | 1ebafaf91f4f2bb09a1f4d23d7bfcfa97506a0e8 (patch) | |
tree | 686dd3007265a9e16a122521e3b18e6351006944 | |
parent | 9dbcde8882a8a917b6d0329e06ea2232e62b1c8c (diff) | |
download | txr-1ebafaf91f4f2bb09a1f4d23d7bfcfa97506a0e8.tar.gz txr-1ebafaf91f4f2bb09a1f4d23d7bfcfa97506a0e8.tar.bz2 txr-1ebafaf91f4f2bb09a1f4d23d7bfcfa97506a0e8.zip |
cptr-int and cptr-obj can make typed cptr objects.
* eval.c (eval_init): Update registration of cptr-int and
cptr-obj with one optional argument.
* lib.c (cptr_int): New type symbol argument, defaulting
to nil. Also, don't bother defaulting the integer argument;
the function isn't registered for that being optional.
(cptr_obj): New type symbol argument, defaulting to nil.
* lib.h (cptr_int, cptr_obj): Declarations updated.
* txr.1: Documented cptr-int and cptr-obj function changes.
Added discussion of type tag to introductory paragraph.
Also added neglected documentation of the FFI cptr type,
both unparametrized and parametrized.
-rw-r--r-- | eval.c | 4 | ||||
-rw-r--r-- | lib.c | 10 | ||||
-rw-r--r-- | lib.h | 4 | ||||
-rw-r--r-- | txr.1 | 116 |
4 files changed, 123 insertions, 11 deletions
@@ -6157,8 +6157,8 @@ void eval_init(void) reg_fun(intern(lit("rlcp"), user_package), func_n2(rlcp)); reg_fun(intern(lit("rlcp-tree"), user_package), func_n2(rlcp_tree)); - reg_fun(intern(lit("cptr-int"), user_package), func_n1(cptr_int)); - reg_fun(intern(lit("cptr-obj"), user_package), func_n1(cptr_obj)); + reg_fun(intern(lit("cptr-int"), user_package), func_n2o(cptr_int, 1)); + reg_fun(intern(lit("cptr-obj"), user_package), func_n2o(cptr_obj, 1)); reg_fun(intern(lit("cptr-zap"), user_package), func_n1(cptr_zap)); reg_fun(intern(lit("cptr-free"), user_package), func_n1(cptr_free)); reg_fun(intern(lit("cptrp"), user_package), func_n1(cptrp)); @@ -7531,14 +7531,16 @@ val cptr_type(val cptr) return cptr->co.cls; } -val cptr_int(val n) +val cptr_int(val n, val type_sym_in) { - return if3(missingp(n), cptr(0), cptr(coerce(mem_t *, c_num(n)))); + val type_sym = default_null_arg(type_sym_in); + return cptr_typed(coerce(mem_t *, c_num(n)), type_sym, 0); } -val cptr_obj(val obj) +val cptr_obj(val obj, val type_sym_in) { - return cptr(coerce(mem_t *, obj)); + val type_sym = default_null_arg(type_sym_in); + return cptr_typed(coerce(mem_t *, obj), type_sym, 0); } val cptr_zap(val cptr) @@ -957,8 +957,8 @@ val cptr(mem_t *ptr); val cptr_typed(mem_t *handle, val type_sym, struct cobj_ops *ops); val cptrp(val obj); val cptr_type(val cptr); -val cptr_int(val n); -val cptr_obj(val obj); +val cptr_int(val n, val type_sym); +val cptr_obj(val obj, val type_sym); val cptr_zap(val cptr); val cptr_free(val cptr); mem_t *cptr_get(val cptr); @@ -53584,11 +53584,32 @@ function and is generally useful in conjunction with the Foreign Function Interface (FFI). An arbitrary pointer emanating from a foreign function can be captured as a .code cptr -value, which can be passed back into foreign code. +value, which can be passed back into foreign code. For this purpose, there +exits also a matching FFI type called +.codn cptr . + +The +.code cptr +type supports a symbolic type tag, which defaults to +.codn nil . +The type tag plays a role in FFI. The FFI +.code cptr +type supports a tag attribute. When a +.code cptr +object is converted to a foreign pointer under the control of the FFI +type, an that FFI type has a tag other than +.codn nil , +the object's tag must exactly match that of the FFI type, or the conversion +throws an error. In the reverse direction, when a foreign pointer is +converted to a +.code cptr +object under control of the FFI +.code cptr +type, the object inherits the type tag from the FFI type. .coNP Function @ cptr-int .synb -.mets (cptr-int << integer ) +.mets (cptr-int < integer <> [ type-symbol ]) .syne .desc The @@ -53610,9 +53631,17 @@ range; a portion of the range of .code bignum integers can denote pointers. +The +.meta type-symbol +argument should be a symbol. If omitted, it defaults to +.codn nil . +This symbol becomes the +.code cptr +object's type tag. + .coNP Function @ cptr-obj .synb -.mets (cptr-int << object ) +.mets (cptr-int < object <> [ type-symbol ]) .syne .desc The @@ -53632,6 +53661,14 @@ is simply stored in a new instance of .code cptr and returned. +The +.meta type-symbol +argument should be a symbol. If omitted, it defaults to +.codn nil . +This symbol becomes the +.code cptr +object's type tag. + .coNP Function @ cptr-zap .synb .mets (cptr-zap << cptr ) @@ -54289,6 +54326,34 @@ macro. The type is useful for passing callbacks to foreign functions: Lisp functions which appear to be C functions to foreign code. +.ccIP @ cptr +The +.code cptr +type converts between a foreign pointer and a Lisp object of type +.codn cptr . + +Lisp objects of type +.code cptr +are tagged with a symbolic tag, which may be +.codn nil . + +The unparametrized +.code cptr +converts foreign pointers to +.code cptr +objects which are tagged with +.codn nil . + +In the reverse direction, it converts +.code cptr +Lisp objects of type +.code cptr +to foreign pointer, without regard for their type tag. + +There is a parametrized version of the +.code cptr +FFI type, which provides a measure of type safety. + .ccIP @ void The .code void @@ -55052,6 +55117,51 @@ It is possible to create a view over a buffer, using .codn carray-buf . +.meIP (cptr << type-sym ) +The parametrized +.code cptr +type is very similar to the unparametrized +.codn cptr . +It also converts between Lisp objects of type +.code cptr +and foreign pointers. However, it provides a measure of type safety. + +When a foreign pointer is converted to a Lisp object under control of the +parametrized +.codn cptr , +the resulting Lisp +.code cptr +object is tagged with the +.meta type-sym +symbol. + +In the reverse direction, when a Lisp +.code cptr +object is converted to the parametrized type, its type tag must match +.metn type-sym , +or else the conversion fails with an error exception. + +Note that if +.meta type-sym +is specified as +.codn nil , +then this is precisely equivalent to the unparametrized +.code cptr +which doesn't provides the above safety measure. + +Pointer type safety is useful, because FFI can be used to create bindings +to large application programming interfaces (APIs) in which objects of +many different kinds are referenced using pointer handles. The erroneous +situation can occur that a FFI call passes a handle of one kind to a function +expecting a different kind of handle. If all pointer handles are represented +by a single +.code cptr +type, then such a situation proceeds without diagnosis. +If handles of different types are all mapped to +.code cptr +types with different tags, the situation is intercepted and diagnosed +with an error exception. + .meIP (align < width << type ) The FFI type operator .code align |