From 692c82523abcc55709dcbc785578826b70597189 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Mon, 15 May 2017 21:45:49 -0700 Subject: Splitting cptr object into separate CPTR tag. CPTR shares representation and a lot of implementation with COBJ. The COBJ class symbol is the CPTR type tag. There is no hierarchy among CPTR tags. The nil tag is used for a modicum of type looseness, so that we don't straitjacket ourselves too much into this tag-based typing scheme. All existing cptr objects are becoming CPTR, and all get a nil tag, except for dlopen library handles, and dlsym symbols, which are tagged as dlhandle and dlsym. The FFI framework will support tag-declared cptr's. This will help with safety. For instance, suppose an API has half a dozen different kinds of opaque handles. If they are all just cptr on the TXR Lisp side, it's easy to mix them up, passing the wrong one to the wrong C function. * lib.h (enum type): New enum member, CPTR. (cptr_print_op, cptr_typed, cptrp, cptr_type, cptr_handle): Declared. (cptr_addr_of): Parameters added. * lib.c (code2type): Map CPTR type code to cptr_s. (equal): Handle CPTR objects. They are only equal to other CPTR objects which have the same operations, and are equal under the equal function of those operations. (cptr_print_op): New function. (cptr_ops): Use cptr_print_op rather than cobj_print_op. (cptr_typed): New function. (cptr): Use cptr_typed to make a cptr with tag nil, rather than using cobj. (cptrp, cptr_handle, cptr_type): New functions. (cptr_get): Go through cptr_handle rather than cobj_handle. (cptr_addr_of, cptr_zap, cptr_free): Use call to cptr_handle rather than cobj_handle for the type checking side effect. New parameters for type and parent function name. (obj_print_impl): Handle CPTR with same case as COBJ. * gc.c (finalize, mark_obj): Handle CPTR cases using common code with COBJ. * hash.c (equal_hash): Handle CPTR just like COBJ. * eval.c (eval_init): Register cptrp and cptr-type intrinsic functions. * ffi.c (ffi_cptr_put, ffi_cptr_get, ffi_cptr_alloc): Use the potentially type-safe cptr_handle, instead of cptr_get. However, for an untagged cptr, there is no type safety because tft->mtypes is nil. The argument can be any kind of cptr. * sysif.c (dlhandle_s, dlsym_s): New symbol variables. (cptr_dl_ops): Use cptr_print_op. (dlopen_wrap, dlclose_wrap): Use typed cptr with dlhandle as the type. (dlsym_wrap, dlsym_checked, dlvsym_wrap, dlvsym_checked): Recognize only a cptr of type dlhandle for the library. Construct a typed cptr of type dlsym. (sysif_init): Initialize dlhandle_s and dlsym_s. Register dlsym function using dlsym_s. --- ffi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'ffi.c') diff --git a/ffi.c b/ffi.c index e72b3d1f..15b862f9 100644 --- a/ffi.c +++ b/ffi.c @@ -566,19 +566,19 @@ static val ffi_wchar_get(struct txr_ffi_type *tft, mem_t *src, val self) static void ffi_cptr_put(struct txr_ffi_type *tft, val n, mem_t *dst, val self) { - mem_t *p = cptr_get(n); + mem_t *p = cptr_handle(n, tft->mtypes, self); *coerce(mem_t **, dst) = p; } static val ffi_cptr_get(struct txr_ffi_type *tft, mem_t *src, val self) { mem_t *p = *coerce(mem_t **, src); - return cptr(p); + return cptr_typed(p, tft->mtypes, 0); } static mem_t *ffi_cptr_alloc(struct txr_ffi_type *tft, val ptr, val self) { - return coerce(mem_t *, cptr_addr_of(ptr)); + return coerce(mem_t *, cptr_addr_of(ptr, tft->mtypes, self)); } static val ffi_str_in(struct txr_ffi_type *tft, int copy, -- cgit v1.2.3