| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
|
|
|
|
|
|
|
|
|
| |
In sysif.c, we have conditionally defined symbol variables.
This has to be reflected with #if directivec in protsym.c.
* genprotsym.txr: Associate each symbol with a list
of preprocessor symbols which controls it, via a hash.
All symbols coming from a conditional file are tagged with
a list which includes at least the controlling symbol.
If symbols are wrapped with #if <sym> directives, that
is added. Nesting is supported. We group the symbols
according to their controlling preprocessor symbol lists.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
| |
* lib.c (less_tab_init): The type_prec table initialization
will become incorrect if new type enums are added other than
at the end. Let's switch to assignments. Anything not
mentioned is zero.
* lib.h: Add more advice to comment about extending type_t:
consider all places where MAX_TYPE is used.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Since cptr objects are equal if their handles are equal, they
must have a hashing function over the handle rather than over
their own address.
* lib.c (cobj_handle_hash_op): New function.
(cptr_ops): Use cobj_handle_hash_op instead of
cobj_eq_hash_op.
* lib.h (cobj_handle_hash_op): Declared.
* sysif.c (cptr_dl_ops): Use cobj_handle_hash_op instead of
cobj_eq_hash_op.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Renaming cobj_hash_op to cobj_eq_hash_op. This function is
only appropriate to use with COBJ objects which use
eq as their equal funtion. I've spotted one instance of an
inappropriate use which have to be addressed by a different
commit: the equal function is other than eq, but cobj_hash_op
is used for the equal hash.
* lib.h (cobj_hash_op): Declaration renamed to
cobj_eq_hash_op.
* hash.c (cobj_hash_op): Renamed to cobj_eq_hash_op.
(hash_iter_ops): Refer to renamed cobj_hash_eq_op.
* ffi.c (ffi_type_builtin_ops, ffi_type_struct_ops,
ffi_type_ptr_ops, ffi-closure_ops, ffi_call_desc_ops):
Likewise.
* lib.c (cptr_ops): Likewise.
* parser.c (parser_ops): Likewise.
* rand.c (random_state_ops): Likewise.
* regex.c (char_set_ops, regex_obj_ops): Likewise.
* socket.c (dgram_strm_ops): Likewise.
* stream.c (null_ops, stdio_ops, tail_ops, pipe_ops, dir_ops,
string_in_ops, byte_in_ops, strlist_in_ops, string_out_ops,
strlist_out_ops, cat_stream_ops, record_adapter_ops):
Likewise.
* struct.c (struct_type_ops): Likewise.
* sysif.c (cptr_dl_ops): Likewise.
* syslog.c (syslog_strm_ops): Likewise.
* unwind.c (cont_ops): Likewise.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The protsym.c generated file refers to symbol variables
without regard for whether they actually exist.
Some symbol variables are defined in source files whose
object files are only linked in conditionally.
* genprotsym.txr: Update the logic to scan the Makefile
to determine which files are conditionally included, based on
what makefile flag, which is related to a preprocessor symbol.
Thus, with some hashes, for each symbolic variable we
subsequently scan, we know whether it came from a file that is
associated with a preprocessor symbol. We group the emitted
material accordingly, placing the conditionally existent
symbols into #if...#endif blocks.
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure, txr.1: Bumped version and date.
* share/txr/stdlib/ver.tl: Likewise.
* txr.vim, tl.vim, protsym.c: Regenerated.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (ffi_varray_alloc, ffi_char_array_put): Use cnum type
consistently to avoid signed/unsigned comparison warning from g++.
(ffi_closure_dispatch_safe): Put block of code into a braced
statement so that the macro-generated switch case branch isn't
crossing the initialization of a variable. Also, convert
cast added where we are passing a void * to a mem_* parameter.
* utf8.c (utf8_dup_from): Fix coerce macros being used to strip
qualifiers, not only convert type.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stream.c (make_catenated_stream): Fix incorrect order
of operations: list of streams stored into a structure
that is not yet visible to the garbage collector.
(Rules for coding this properly are explained in
HACKING.) This was found by running a test with --gc-debug
on 64 bit Darwin. The read_eval_stream function calls
make_catenated_stream with an argument that is freshly
constructed in the argument expression itself, triggering
the issue.
|
|
|
|
|
|
|
|
|
|
|
| |
* tests/017/qsort.expected: New file.
* tests/017/qsort.tl: New file.
* tests/common.tl (libc): New function.
* Makefile (tst/tests/017/%): Clear TXR_DBG_OPTS so the GC
stress test isn't applied to tests in this directory.
|
|
|
|
|
|
|
|
|
|
| |
* tests/common.tl (osname): Function based on calling
shell command removed.
(os-symbol): New symbol-returning function based on
uname system call.
* tests/014/dgram-stream.tl (dgram-test): Use os-symbol
function rather than osname.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When taking ownership of any pointer from FFI space, null it
out. This is safer in general and prevents corruption
problems in the callback interface when an exception is
thrown. For instance (ptr wstr-d) callback argument:
callback takes ownership of the pointer in a string object;
throws an exception. The FFI call dispatch runs the in
semantics to get the string value out; but the old pointer
is still there which may not be used.
* ffi.c (ffi_str_d_get, ffi_wstr_d_get, ffi_bstr_d_get,
ffi_buf_d_in, ffi_buf_d_get, ffi_ptr_d_get): Overwrite
the source location of a freed or owned pointer with
null.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
| |
* gc.c (gc_free_all): Mark defined the current block being
iterated, not the next one. Otherwise Valgrind generates
numerous false errors from accesses to free objects in the
first block. Not to mention that next is a null pointer in
the last iteration.
|
|
|
|
|
|
|
| |
* gc.c (mark_obj): The vector alloc size and length
which lie at negative indices should be accessed using
the index constants vec_alloc and vec_length, rather
than -2 and -1.
|
|
|
|
|
|
|
|
| |
* configure: detect clockid_t and loff_t, providing
HAVE_CLOCKID_T and HAVE_LOFF_T config macros.
* ffi.c (ffi_init_extra_types): Register clockid-t
and loff-t types only if available.
|
|
|
|
|
| |
* itypes.c (c_i64): Fix c_num being called on the function
pointer num rather than the correct operand n.
|
|
|
|
| |
* inst.nsi: Add cygffi-6.dll to package.
|
|
|
|
| |
* buf.c, ffi.c: Must include <stdarg.h> for va_list.
|
|
|
|
|
|
|
| |
* configure: the dlvsym test relies on a nonexistent
make variable EXTRA_CFLAGS. The correct one is EXTRA_FLAGS.
The function name is misspelled in the test code and the
test message.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (stuct txr_ffi_closure): New member, abort_retval.
(ffi_closure_mark_op): Mark the new member.
(ffi_closure_dispatch_safe): Implement the abort_retval.
If it is not nil, use put to place the value into the
return buffer. There is a risk that this could also throw
an exception, which is no longer protected: programer's
problem.
(ffi_make_closure): New abort_ret_in argument, which is
defaulted and stored.
(ffi_init): Update registration of ffi-make-closure to
reflect new argument.
* ffi.h (ffi_make_closure): Declaration updated.
* share/txr/stdlib/ffi.tl (sys:deffi-cb-expander):
Add abort-retval parameter; insert into ffi-make-closure
call.
(deffi-cb): Take optional abort-retval expression;
pass it down to the expander function.
(deffi-cb-unsafe): Pass nil as abort-retval down to expander.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We don't want, by default, for callbacks to capture delimited
continuations across foreign code, or perpetrate non-local
transfers across foreign code. Here, we take an approach
similar for what was done in ftw_wrap.
* ffi.c (s_exit_point): New global variable with internal
linkage.
(ffi_call_wrap): If s_exit_point isn't nil, then it means that
the callback intercepted a nonlocal transfer and stored its
exit point. We resume the transfer to that exit point instead
of returning normally.
(ffi_closure_dispatch_safe): New static function.
(ffi_make_closure): Support a new argument which indicates
whether to make a closure which uses
ffi_closure_dispatch_safe, or ffi_closure_dispatch.
(ffi_init): Update registration of ffi-make-closure intrinsic.
* ffi.h (ffi_make_closure): Declaration updated.
* share/txr/stdlib/ffi.tl (sys:deffi-cb-expander): New
function.
(deffi-cb): Macro internals replaced by call to new
function.
(deffi-cb-safe): New macro.
* txr.1: Documentation of ffi-make-closure updated.
New deffi-cb-unsafe macro documented.
|
|
|
|
|
|
|
|
|
|
|
|
| |
If the object being encoded is a string, and the array element
type is char, wchar or bchar, then encode a string, honoring
null termination flag. Unused space in the destination array
is filled with zeros.
* ffi.c (ffi_char_array_put, ffi_wchar_array_put,
ffi_bchar_array_put): New functions.
(ffi_array_put, ffi_array_out): Use new functions under
the right conditions.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (struct txr_ffi_type): is_varray flag removed.
We no longer need to test this and adjust behavior.
(ffi_array_in, ffi_array_out): Don't calculate nelem
differently based on flag; just pass down tft->nelem. Code
cleaned up.
(ffi_varray_put, ffi_varray_in): New functions.
(ffi_type_compile): Use ffi_varray_put and ffi_varray_in for
variable array type instead of setting flag. Also, specify the
out function as null; it never made sense to have one, since
there is no get. Finally, set the size of the type to zero,
since it has no pass by value semantics.
|
|
|
|
|
|
| |
* ffi.c (ffi_varray_alloc): We must use the element type's
size, not the array's size. Also, cosmetic issue in error
message fixed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This anticipates a redesign of variable arrays. Variable
arrays will have their own put, in, get and out functions,
which will share some implementation.
* ffi.c (ffi_array_in_common): New function.
(ffi_array_in): Bulk of code replaced by call to
ffi_array_in_common.
(ffi_array_put_common, ffi_array_out_common,
ffi_array_get_common): New functions.
(ffi_array_put, ffi_array_out, ffi_array_get): Reduced to thin
wrappers.
|
|
|
|
|
|
| |
* ffi.c (ffi_make_call_desc): Throw if any argument
type is something with zero size. Throw if the return
type has zero size and isn't the type void.
|
|
|
|
|
|
|
| |
* ffi.c (ffi_char_array_get, ffi_wchar_array_get,
ffi_bchar_array_get): New static functions.
(ffi_array_in, ffi_array_get): Replace common code
with calls to code moved out into functons.
|
|
|
|
|
|
|
|
|
| |
Arrays can be varray, whose size is just pointer size.
The string extraction operations shouldn't be referring
to the size.
* ffi.c (ffi_array_in, ffi_array_et): Use nelem instead
of tft->size.
|
|
|
|
|
|
|
|
|
|
|
|
| |
What this allows is for situations when a foreign function
returns the pointer that it has been passed. If that pointer
is temporary storage allocated by FFI, then it is no longer
valid after performing the in pass on the args. Therefore, we
should decode the return value first, while the returned
pointer is valid.
* ffi.c (ffi_call_wrap): Move the return value get before
the argument post-processing in pass.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We want to be able to extract null-terminated UTF-8 strings
from arrays, without trailing junk, yet retain the ability to
extract the entire array including embedded nulls. The natural
way is to use the array/zarray distinction.
* ffi.c (ffi_array_in, ffi_array_get): Don't try to guess
whether the array is null terminated; just rely on the
null_term flag, and treat accordingly.
* txr.1: Doc updated.
|
|
|
|
| |
* txr.1: The cptr type is now documented.
|
|
|
|
|
|
| |
* txr.1: Buffer literals are now described much
earlier in the document under Additional Syntax
rather than in the Buffers section.
|
|
|
|
| |
* txr.1: Update ASCII diagram in Object Types section.
|
|
|
|
|
| |
* txr.1: Documented dlopen, dlclose and friends,
plus the rtld-* variables.
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register cptr-int, ctpr-obj, cptr-zap
and cptr-free functions and cptr-null variable.
* lib.c (cptr_int, cptr_obj, cptr_zap, cptr_free): New
functions.
* lib.c (cptr_int, cptr_obj, cptr_zap, cptr_free): Declared.
|
|
|
|
|
| |
* ffi.c (cptr_make): Function removed.
(ffi_init): Registration of cptr and cptr-null removed.
|
|
|
|
|
|
|
|
|
| |
* ffi.c (ffi_float_put, ffi_double_put): Support a useful
type looseness by allowing integers and character Lisp
values to pair with FFI floating-point types, imitating
the conversion which happens in C function calls.
* txr.1: Updated.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (ffi_i8_put, ffi_u8_put, ffi_i16_put, ffi_i16_get,
ffi_u16_put, ffi_u16_get, ffi_i32_put, ffi_i32_get,
ffi_u32_put, ffi_u32_get, ffi_i64_put, ffi_i64_get,
ffi_u64_put, ffi_u64_get, ffi_char_put, ffi_char_get,
ffi_uchar_get, ffi_short_get, ffi_ushort_put, ffi_ushort_get,
ffi_int_put, ffi_int_get, ffi_uint_put, ffi_uint_get,
ffi_long_put, ffi_long_get, ffi_ulong_put, ffi_ulong_get,
ffi_float_put, ffi_float_get, ffi_double_put, ffi_double_get,
ffi_wchar_put, ffi_wchar_get, ffi_cptr_put, ffi_cptr_get):
memcpy operations replaced by by assignments through pointer
casts.
|
|
|
|
|
|
| |
* ffi.c (ffi_closure_print_op): Add information to the
printed representation: the Lisp function, and call desc.
Eliminate spurious # character before closing angle bracket.
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (ffi_struct_put, ffi_struct_out): Just skip the space
corresponding to the anonymous padding member; don't memset
with zeros. Doing this is inconsistent because we are not
zero-filling the ordinary alignment padding between members
and at the end of the struct. If the uninitialized garbage
is a problem in some uses, we can provide a variation of
the struct type which is zero initialized.
|
| |
|
|
|
|
|
|
|
| |
* buf.c (buf_put_bytes): We must extend the buffer based
on looking at the end position of the data transfer,
not the start position, so the buffer is large enough to
old the entire transfer.
|
|
|
|
|
|
|
| |
* buf.c (buf_shrink): If a buffer has zero length,
don't shrink the allocation size all the way down to
zero, because that value indicates a non-resizeable
buffer.
|
|
|
|
|
|
|
| |
* ffi.c (ffi_array_put, ffi_array_out): If dealign with
a variable array that is null terminated, let's add one to
nelem, so that all elements of the Lisp sequence are
converted, and then a null.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Backing out of the scheme of (ptr buf) passing the
address of the internal pointer within buf objects.
Also giving buf in handlers, to prevent the fallback
on get.
* buf.c (buf_addr_of): Function removed.
* buf.h (buf_addr_of): Declaration removed.
* ffi.c (ffi_buf_in, ffi_buf_d_in): New functions.
(ffi_buf_alloc): Function removed.
(ffi_type_compile, ffi_init_types): Remove specialty alloc and
free functions from buffers, so the regular fixed allocator is
used. Give buffers the new in functions.
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (ffi_ptr_in_in): Don't just free the buffer for
the pointer itself, but call the in handler of the target
type if it has one. Pass a false copy flag to it, so that
that a ptr-in pass semantically resembles a by-value pass.
(ffi_ptr_in_d_in): New static function.
(ffi_type_compile): Give ptr-in-d type the ffi_ptr_in_d_in
function.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (ffi_ptr_out_in, ffi_ptr_out_s_in): If the target type
has no in handler, fall back on its get. Here, it is without
regard for the copy flag, because a zero value of that flag
just indicates that the ptr-out itself is passed by-value.
The target object is never by value
(ffi_in): Add copy flag parameter, so the full interface
is exposed, like in ffi_out. Fall back on get, if there is
no in and the copy flag is true. Just return the original
object if the type has no in, and copy is false.
(ffi_init): Registration of ffi-in adjusted to four
parameters.
* ffi.h (ffi_in): Declaration updated.
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (ffi_struct_in, ffi_array_in): Only fall back on get
if the copy flag is true. If the copy flag is false, we must
not extract. That's not ony as an optimization (no point in
extracting back from by-value objects). We also avoid
extracting from pointers we don't own, like in the case
of str-d, where the pointer is owned by the foreign function
and may have been freed.
|