diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-05-13 07:40:11 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-05-13 07:40:11 -0700 |
commit | 396830c9122ea7973cfcf406421671c82604128c (patch) | |
tree | 405033c36a75a2fc1321ddd0904de8da9bfb5e5d | |
parent | de8a9d9b460786a994aeb48d3fe181b9f3974fc4 (diff) | |
download | txr-396830c9122ea7973cfcf406421671c82604128c.tar.gz txr-396830c9122ea7973cfcf406421671c82604128c.tar.bz2 txr-396830c9122ea7973cfcf406421671c82604128c.zip |
ffi: use dynamic allocation for wstr and wstr-d.
The direct pointer use of the wstr type causes problems
for callbacks. Plus allowing the foreign world to retain
the pointers into string objects is inherenty unsafe.
We can introduce an "unsafe wstr" type in a later release
for efficiency.
* ffi.c (ffi_wstr_in): New function.
(ffi_wstr_put): Removed by ffi_wstr_d_put rename.
(ffi_wstr_d_put): Renamed to ffi_wstr_put: both wstr and
wstr-d strings have a dynamically-allocating put.
(ffi_init_types): Give wstr type ffi_wstr_in handler.
wstr-d type's registration switched to ffi_wstr_put,
which is just ffi_wstr_d_put renamed.
* txr.1: Memory management notes for wstr updated.
-rw-r--r-- | ffi.c | 34 | ||||
-rw-r--r-- | txr.1 | 29 |
2 files changed, 24 insertions, 39 deletions
@@ -618,15 +618,15 @@ static val ffi_str_d_get(struct txr_ffi_type *tft, mem_t *src, val self) return ret; } -static void ffi_wstr_put(struct txr_ffi_type *tft, val s, mem_t *dst, - val self) +static val ffi_wstr_in(struct txr_ffi_type *tft, int copy, + mem_t *src, val obj, val self) { - if (s == nil) { - *coerce(const wchar_t **, dst) = 0; - } else { - const wchar_t *ws = c_str(s); - *coerce(const wchar_t **, dst) = ws; - } + wchar_t **loc = coerce(wchar_t **, src); + if (copy) + obj = if2(*loc, string(*loc)); + free(*loc); + *loc = 0; + return obj; } static val ffi_wstr_get(struct txr_ffi_type *tft, mem_t *src, val self) @@ -635,7 +635,7 @@ static val ffi_wstr_get(struct txr_ffi_type *tft, mem_t *src, val self) return p ? string(p) : 0; } -static void ffi_wstr_d_put(struct txr_ffi_type *tft, val s, mem_t *dst, +static void ffi_wstr_put(struct txr_ffi_type *tft, val s, mem_t *dst, val self) { if (s == nil) { @@ -1689,12 +1689,20 @@ static void ffi_init_types(void) ffi_typedef(str_d_s, make_ffi_type_builtin(str_d_s, str_s, sizeof (mem_t *), &ffi_type_pointer, ffi_str_put, ffi_str_d_get)); - ffi_typedef(wstr_s, make_ffi_type_builtin(wstr_s, str_s, - sizeof (mem_t *), &ffi_type_pointer, - ffi_wstr_put, ffi_wstr_get)); + { + val type = ffi_typedef(wstr_s, make_ffi_type_builtin(wstr_s, str_s, + sizeof (mem_t *), + &ffi_type_pointer, + ffi_wstr_put, + ffi_wstr_get)); + struct txr_ffi_type *tft = ffi_type_struct(type); + tft->in = ffi_wstr_in; + ffi_typedef(wstr_s, type); + } + ffi_typedef(wstr_d_s, make_ffi_type_builtin(wstr_d_s, str_s, sizeof (mem_t *), &ffi_type_pointer, - ffi_wstr_d_put, ffi_wstr_d_get)); + ffi_wstr_put, ffi_wstr_d_get)); ffi_typedef(bstr_d_s, make_ffi_type_builtin(bstr_d_s, str_s, sizeof (mem_t *), &ffi_type_pointer, ffi_bstr_put, ffi_bstr_d_get)); @@ -53390,34 +53390,11 @@ corresponds to the C type .code "wchar_t *" pointing to the first character of a null terminated wide string. It converts between Lisp strings and symbols, and C strings. -Since \*(TX represents strings in this format natively, the -.code wstr -type has a different memory management profile from that of +The memory management is similar to the .code str and -.codn bstr . - -Under the -.code wstr -type's put operation, no memory allocation takes place. The internal string -pointer is retrieved from within the Lisp object, and written into the argument -space as-is. The type has no in operation, since there is no memory to clean -up. The get semantics of -.code wstr -duplicate the C string, producing a new Lisp object which doesn't share -storage with the original. - -Under the -.code wstr-d -type's put operation, memory allocation does take place. A new C string -is allocated via -.code malloc -and that pointer is written into the argument space. The type has no in -operation. The get semantics of -.code wstr-d -produces a Lisp string object which directly takes ownership of the C string. -The C string will be freed if and when that Lisp string is recognized as -unreachable by \*(TX's garbage collector. +.code str-d +types, except that no UTF-8 conversion takes place. .ccIP @ buf and @ buf-d The |