| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
|
|
|
|
|
| |
* ffi.c (buf_carray): New function.
(ffi_init): Registered buf-carray intrinsic.
* ffi.c (buf_carray): Declared.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (ffi_put_into, ffi_in, ffi_get, ffi_out): New offset
parameter.
(ffi_init): Re-register ffi-put-into, ffi-in, ffi-get and
ffi-out with new optional parameter.
* ffi.c (ffi_put_into, ffi_in, ffi_get, ffi_out): Declarations
updated.
* txr.1: Documented new argument on ffi-put-into, ffi-in
and ffi-get. The documentation for ffi-out doesn't exist!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (struct carray): New member, offs.
(make_carray): Initiialize offs member from new argument.
(copy_carray, carray_blank, carry_ptr, carray_sub,
carray_pun, carray_unum, carray_num): Pass zero offset to
(carray_buf): New optional parameter off_in.
(carray_buf_sync): Handle offset.
(ffi_init): Update registration of carray-buf.
* ffi.h (make_carray, carray_buf): Declaration updated.
* txr.1: Documented.
|
|
|
|
|
|
| |
* ffi.c (carray_cptr): Ref argument in make_carray
call should be specified as nil not 0. The meaning is
the same, but it's wrong style for TXR internals.
|
|
|
|
|
|
|
|
|
| |
* ffi.c (zero_fill): New function.
(ffi_init): zero-fill intrinsic registered.
* ffi.h (zero_fill): Declared.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (make_zstruct): New function.
(ffi_init): Register make-zstruct instrinsic.
* ffi.h (make_zstruct): Declared.
* lisplib.c (ffi_set_entries): Add znew to autload list.
* share/txr/stdlib/ffi.tl (znew): New macro.
* txr.1: Documented make-zstruct and znew.
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (ffi_type_operator_p, ffi_type_p): New functions.
(ffi_init): Register ffi-type-operator-p and ffi-type-p
intrinsics.
* ffi.h (ffi_type_operator_p, ffi_type_p): Declared.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
| |
* ffi.c (make_ffi_type_struct): Fix incorrect shift
calculations, which are still being done from the
unit_offs byte rather than the correct offs byte where
the bitfield is actually placed. It is bit_offs which
has the correct bit offset of the bitfield relative
to offs.
|
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (make_union): Two arguments added. These
are optional.
(ffi_init): Update registration of make-union as
three-parameter function, with one required arg.
* ffi.h (make_union): Declaration updated.
* txr.1: Documented.
|
|
|
|
|
| |
* ffi.c (ffi_type_compile): Syntax for union type wrongly
using struct symbol rather than union.
|
|
|
|
|
|
| |
* ffi.c (ffi_type_compile): Assign full bool syntax to
cloned type, rather than just the argument syntax denoting the
base type.
|
|
|
|
|
| |
* ffi.c (ffi_make_call_desc): Throw error if argument or
return value is a bitfield.
|
|
|
|
|
| |
* ffi.c (ffi_type_compile): Check for too few or too many
arguments in a compound form.
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (enumed_s): New symbol variable.
(ffi_type_compile): New case for enumed type op.
(ffi_init): Initialize enumed_s.
* ffi.h (enumed_s): Declared.
* txr.1: enumed documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This lays the groundwork for enumerations based off types
other than int. All we need to do is implement the
syntax for this.
* ffi.c (ffi_enum_put, ffi_enum_get, ffi_enum_rput,
ffi_enum_rget): Retrieve the element type descriptor
and recurse into its put, get, rput and rget operation,
respectively, instead of hard-coded calls to the int
operations.
(make_ffi_type_enum): New argument, base_type.
Numerous properties of the enum type are taken from base_type:
the FFI type, the alignment, size, and alloc, free and
clone operations. The base type is installed as eltype.
(ffi_type_lookup): Static function relocated.
(ffi_type_compile): In the enum case, resolve the int type
and pass to make_ffi_type_enum.
|
|
|
|
|
|
| |
* ffi.c (ffi_enum_put, ffi_enum_rput): Fix function name
appearing in quotes in error diagnostic. Fix nonexistent
member being wrongly reported as nil.
|
|
|
|
|
|
|
|
|
|
|
|
| |
We either mishandle return values, or crash due to
a null rput/rget function pointers on aggregate types
and bools.
* ffi.c (ffi_bool_rput, ffi_bool_rget): New static functions.
(make_ffi_type_pointer, make_ffi_type_struct,
make_ffi_type_union, make_ffi_type_array): Fill in rput and rget.
(ffi_type_compile): Fill in rget and rput for bool with new
functions.
|
|
|
|
|
|
|
|
|
| |
* ffi.c (ffi_varray_null_term_in): Rewrite nonsensical
code that refers to the newly created empty output array
as input. We must perform the in semantics on all the
original elements. Then get semantics on any new elements
if the array was extended, and the copy flag is true
(by-ref nuance).
|
|
|
|
| |
* ffi.c (ffi_varray_alloc): Add tft->null_term to length.
|
|
|
|
|
|
| |
* ffi.c (ffi_varray_null_term_in): Pass zero to replace
rather than 0, which corresponds to nil and is interpreted
as a list by replace.
|
|
|
|
|
|
| |
* ffi.c (make_ffi_type_union): Create cobj with correct
cobj_ops structure: ffi_type_struct_ops, not
ffi_type_enum_ops.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We can't use the eltype field of the type structure
to store the cptr tag symbol, because that is expected
to be a type object and not a symbol.
* ffi.c (struct txr_ffi_type): New member, tag.
(ffi_cptr_put, ffi_cptr_get, ffi_cptr_alloc): Refer to
tag rather than eltype.
(ffi_type_compile): Handle the compound cptr type
using the same code as the simple one in ffi_init_types: use
make_ffi_type_builtin rather than make_ffi_type_pointer.
Install the tag into the tag field. Also set up the forgotten
alloc and free routines.
(ffi_init_types): For cptr, explicitly initialize the tag
to nil. This is not necessary since the structure is calloced,
and we rely on that for nil all over the place, but here it
serves as a reminder that cptr has a tag.
|
|
|
|
|
|
|
|
|
|
|
|
| |
The recent commit "ffi: elide useless by-value in calls."
neglects to mark a few types with the by_value_in flag.
The string types need it because their in action performs
memory freeing, which must be done regardless of the
by-value or by-pointer semantics.
* ffi.c (ffi_init_types): set by_value_in to 1 for str,
bstr and wstr. In general, if the type needs a release
function, it needs by_value_in to be set.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We can avoid calling in methods in the by-value nuance
(copy == 0) on types known not to have by-value in semantics.
Basic types have no by-value in.
Pointers inherently have by-value in.
An aggregate has by-value in semantics if any of one
of its members does, otherwise not.
* ffi.c (struct txr_ffi_type): New bitfield member,
by_value_in.
(ffi_ptr_in_in, ffi_ptr_in_d_in): Elite in call if target
type's by_value_in flag is clear.
(ffi_struct_in): Short-circuit to a return if doing by-value,
and the FFI struct type has no by-value semantics.
(ffi_array_in_common): Likewise. In this code change, we
just have to replace the test whether the element type has
an in method with a test of its by_value_in flag.
(make_ffi_type_pointer): Set by_value_in flag to 1, since
pointers have by value in semantics. This is true also of
ptr-in, because a structure passed as an in parameter to a
function via ptr-in could itself contain ptr or ptr-out
elements.
(make_ffi_type_struct): Set the type's by_value_in if
any element type's by_value_in is true.
(make_ffi_type_array): Propagate the by_value_in flag from
the element type to the array type.
(ffi_call_wrap): Calculate the in_pass_needed local flag
from the by_value_in flags of the arguments, not from whether
or not they have an in function. Only call the in function
for arguments which have the flag set.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The theme here is that if a struct or array is
being subject to a by-value in operation, there
is nothing to do for that aggregate itself. So
if there is no corresponding Lisp object, we
should not create one. The caller isn't expecting
it and will throw it away. If it is known that no
element of an aggregate supports by-value semantics,
then the operation should short-circuit, and not
perform a useless loop.
* ffi.c (ffi_struct_in): If the strct parameter is nil,
don't unconditionally make a new structure; do so only
when the copy flag is asserted (by reference semantics).
If there is no Lisp struct object and by value semantics is
in effect, there is no point in doing anything; just
short-circuit to a nil return.
(ffi_array_in_common): If doing by value semantics, and
there is no vector object or the structure element type
has no by value in semantics (such as a basic type),
then short circuit to an early return.
(ffi_array_in): Only do the special string decoding when
reference semantics is in effect; there is no point
in extracting strings back from a by-value struct.
If by-value semantics is in effect, we fall through to
the ffi_array_in_common call even for character types;
but since those types have no by-value in semantics,
that function will just short-circuit, which is what we want.
(ffi_varray_in): If there is no vec, bail out with nil,
regardless of whether this is by value or not.
Just return vec if by-value semantics is in effect; don't
try to update it.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (union_s): New symbol variable.
(ffi_find_memb, ffi_memb_not_found): New static functions.
(ffi_union_in, ffi_union_put, ffi_union_get): New static
functions.
(make_ffi_type_union): New static function.
(ffi_struct_compile): Handle union syntax using
ffi_struct_compile to compile the member definitions to types,
and make_ffi_type_union to produce the type node.
(struct uni): New struct type.
(uni_struct, uni_struct_checked): New static functions.
(union_destroy_op, union_mark_op): New static functions.
(union_ops): New static struct.
(make_union_common, make_union_tft): New static functions.
(union_get_ptr, make_union, union_members, union_get,
union_put, union_in, union_out): New functions.
(ffi_init): Initialize union_s. Register intrinsics
make-union, union-members, union-get, union-put, union-in,
union-out.
* ffi.h (union_s, union_get_ptr, make_union, union_members,
union_get, union_put, union_in, union_out): Declared.
* txr.1: Documented unions.
|
|
|
|
|
|
|
|
|
|
|
| |
Upcoming work is going to benefit from a pointer for
navigating from the txr_ffi_type structure to the Lisp object
whose implementation is that structure.
* ffi.c (struct txr_ffi_type): New member, self.
(make_ffi_type_builtin, make_ffi_type_pointer,
make_ffi_type_struct, make_ffi_type_array,
make_ffi_type_enum): Initialize self pointer.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Don't bother creating and filling the ffi_type elements[]
array for a structs or array. Let's punch in the size and
alignment fields with the values we calculate ourselves
already, and set up a dummy elements[] array that contains
only a null terminator.
* ffi.c (struct txr_ffi_type): New member, elements:
one element dummy array that holds a null pointer.
(ffi_type_struct_destroy_op): Do not free ft->elements,
since it isn't dynamically allocated any more.
(ffi_struct_clone, ffi_array_clone): Don't copy the elements
array; just set up a dummy elements array in the copied type.
(make_ffi_type_struct, make_ffi_type_array): Eliminate the
dynamic allocation of the elements array. Point ft->elements
to the dummy array. Set up the ft->size and ft->alignment.
|
|
|
|
|
|
|
|
| |
* ffi.c (ffi_float_put): Fix silly range check:
FLT_MIN and FLT_MAX are, of course, both positive.
Also, fix num being used as an argument in the error
diagnostic. It's the address of a C function, not
an object.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (bool_s): New symbol variable.
(ffi_bool_put, ffi_bool_get): New static functions.
(ffi_type_compile): Handle (bool <type>) parametrized type.
(ffi_init_types): Register bool typedef for (bool uchar).
(ffi_init): Initialize bool_s.
* ffi.h (bool_s): Declared.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
| |
* arith.c (do_mp_error): New function.
(num_from_buffer, plus, minus, mul, floordiv, expt, exptmod,
logtrunc, sign_extend, ash, bit): Handle errors from select
MPI functions: those that have the mp_ign attribute.
* ffi.c (unum_carray, num_carray): Likewise.
* rand.c (random): Likewise.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (copy_carray): New function
(ffi_init): Register copy-carray intrinsic.
* ffi.h (copy_carray): Declared.
* lib.c (copy): Call copy_array for carray objects.
* txr.1: Documented copy-carray and updated
copy description.
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (put_carray, fill_carray): New functions.
(ffi_init): put-carray and fill-carray intrinsics
registered.
* ffi.h (put_carray, fill_carray): Declared.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (carray_unum, carray_num, unum_carray, num_carray):
New functions.
(ffi_init): New intrinsics registered: carray-unum,
carray-num, unum-carray, num-carray.
* ffi.h (carray_unum, carray_num, unum_carray, num_carray):
Declared.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (make_ffi_type_struct): When there is no room in the
current bitfield, two mistakes are made. When bit_offs is
reset to zero in this case, the dependent variable bits_alloc
that was calculated from it (bits allocated to current unit)
must also be reset. The subsequent shift depends on it.
Secondly, when we establish the memb[i].offs field, that
must come from offs, not from unit_offs, because unit_offs
is always the base offset of the existing cell (which doesn't
have room for the new bitfield in this case); the main offset
variable offs is what gets gets adjusted to the cell which has
room for the new bitfield.
|
|
|
|
|
|
|
|
|
| |
* ffi.c (ffi_generic_sbit_put, fi_generic_sbit_get,
ffi_generic_ubit_put, fi_generic_ubit_get): Add needed
coerce from zalloca to mem_t *.
(make_ffi_type_struct): Fix signed/unsigned comparison.
* lib.c (vector): Fix signed/unsigned comparison.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (make_ffi_type_struct): Use chk_xalloc instead of
chk_malloc.
(make_ffi_type_array): Use chk_xalloc. Since there are
multiple callers, take a self argument to pass down to
chk_xalloc.
(ffi_type_compile): Pass self down to make_ffi_type_array.
(ffi_make_call_desc): Use chk_xalloc.
(carray_ensure_artype): Take a self argument and pass down to
make_ffi_type_array.
(carray_get_common, carray_put_common): Pass self down to
carray_ensure_artype.
|
|
|
|
|
|
|
|
| |
* ffi.c (carray_dup): Do size multiplication using unsigned
type, then coerce back to signed. Check for overflow correctly
by first testing result for negative, then doing division check.
(carray_replace): Add check for negative size, which confirms
overflow.
|
|
|
|
|
|
|
|
|
| |
* ffi.c (carrayp): New function.
(ffi_init): Register carrayp intrinsic.
* ffi.h (carrayp): Declared.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Thanks to this (set [ca from..to] list) works.
* ffi.c (carray_replace): New function.
(ffi_init): Register carray-replace intrinsic.
* ffi.h (carray_replace): Declared.
* ffi.c (replace): Hook in carray_replace.
* txr.1: Mention carray under replace, and document
carray-replace.
|
|
|
|
|
|
|
|
|
| |
* ffi.c (carray_pun): New function.
(ffi_init): Registered carray-pun intrinsic.
* ffi.h (carray_pun): Declared.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Thus, [ca 3..5] syntax works for slice extraction.
However, this works referentially, not by making a copy.
The extracted subarray points to the original memory,
until carray-dup is invoked on it.
* ffi.c (carray_sub): New function.
(ffi_init): carray-sub intrinsic registered.
* ffi.h (carray_sub): Declared.
* lib.c (sub): Handle carray via carray_sub.
* txr.1: Documented changes in sub.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Thus (select ca '(0 3 4 ...)) works and so does the
sytnax [ca '(0 3 4 ...)]. This is inefficiently implemented.
The selected elements are extracted to a list which is then
converted to a carray of the same kind agan.
* ffi.c (carray_list): New function.
(ffi_init): Register carray-list intrinsic.
* ffi.h (carray_list): Declared.
* lib.c (make_like): Add carray case, so we can turn
a list into a carray based on an example carray.
This uses carray_list, with the type pulled from the
original carray. The target isn't null terminated.
(sel): Handle carray via vector case.
* txr.1: Document changes in select and make-like.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (struct carray): New member, artype.
(carray_mark_op): Mark artype member.
(make_carray): Initialize artype to nil.
(carray_ensure_artype, carray_get_common, carray_put_common):
New static functions.
(carray_get, carray_getz, carray_put, carray_putz): New
functions.
(ffi_init): Register intrinsics carray-get, carray-getz,
carray-put, carray-putz.
* ffi.h (carray_get, carray_getz, carray_put, carray_putz):
Declared.
* txr.1: Documented new functions.
|
|
|
|
|
|
|
|
| |
* ffi.c (carray_get): Renamed to carray_ptr.
(ffi_carray_put): Follow rename.
* ffi.h (carray_get): Declaration removed.
(carray_put): Declared.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The FFI module is more than just foreign calls and callbacks;
it provides a type system and operations for working with
binary data. None of it depends on libffi being present and so
shouldn't be disabled if libffi is not available.
* Makefile (ffi.o): Unconditionally link this object file,
not subject to the have_libffi variable.
* configure (have_libffi): Variable removed.
(gen_config_make): Do not generate a have_libffi
variable into config.make, since nothing needs it.
* ffi.c (ffi_type): Fake ffi_type defined if libffi is
missing.
(FFI_TYPE_STRUCT): Fake macro.
(ffi_type ffi_type_void, ffi_type_pointer, ffi_type_sint,
ffi_type ffi_type_schar, ffi_type_uchar, ffi_type
ffi_type_sshort, ffi_type_ushort, ffi_type ffi_type_sint,
ffi_type_uint, ffi_type ffi_type_slong, ffi_type_ulong,
ffi_type ffi_type_sint8, ffi_type_uint8, ffi_type
ffi_type_sint16, ffi_type_uint16, ffi_type ffi_type_sint32,
ffi_type_uint32, ffi_type ffi_type_sint64, ffi_type_uint64,
ffi_type ffi_type_float, ffi_type_double): Fake libffi type
objects, so that code which references these things will
build without modification.
(ffi_get_type): Function only defined if we have libffi.
(ffi_type_struct_destroy_op, ffi_struct_clone,
make_ffi_type_struct, ffi_array_clone, make_ffi_type_array):
Don't work with ffi_type's element array if we don't have
libffi; our fake ffi_type doesn't have such an array.
(struct txr_ffi_closure): Type only defined if we have libffi.
(ffi_closure_struct, ffi_closure_struct_checked,
ffi_closure_print_op, ffi_closure_destroy_op,
ffi_closure_mark_op, ffi_closure_put): Functions only defined
if we have libffi.
(ffi_closure_ops): Static structure only defined if we have
libffi.
(ffi_init_types): Don't register a closure type if we don't
have libffi.
(struct txr_ffi_call_desc): Don't define type if we don't have
libffi.
(ffi_call_desc, ffi_call_desc_checked, ffi_call_desc_print_op,
ffi_call_desc_destroy_op, ffi_call_desc_mark_op,
ffi_make_call_desc, ffi_call_wrap, ffi_closure_dispatch,
ffi_closure_dispatch_safe, ffi_make_closure,
ffi_closure_get_fptr): Functions only defined if we have
libffi.
(ffi_call_desc_ops): Static structure only defined if we have
libffi.
(ffi_init): Only register ffi-make-call-desc, ffi-call, and
ffi-make-closure if we have libffi.
* lib.c: Include "ffi.h" header unconditionally.
(generic_funcall, ref, refset, int): Remove #if HAVE_LIBFFI.
|
|
|
|
|
|
|
|
|
|
|
|
| |
The problem is that the get semantics (zarray char)
produces a vector of characters, not a string. Ditto for
bchar and wchar.
* ffi.c (ffi_varray_null_term_in): Check for the char_conv,
wchar_conv or bchar_conv flag and delegate to
ffi_array_get_common.
(ffi_type_compile): Set char_conv, wchar_conv or bchar_conv
flag for incomplete zarray.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The problem is that if we have a typedef like (typedef x char)
then (array 256 x) will not do string conversion in the manner
of (array 256 char). This is because the raw syntax is checked
for the symbol char, rather than inspecting the type object.
* ffi.c (ffi_type_compile): When checking whether the array
element is a char, bchar or wchar, look at the syntax in
the compiled type object, not the raw syntax. The compiled
type object is the original type pulled from behind the
typedef alias and has the symbol char, bchar or wchar as
its syntax.
|
|
|
|
|
|
|
|
|
|
|
| |
The way bitfields are laid out must be changed. The
requirements were reverse-engineered by experimentation.
* ffi.c (make_ffi_type_struct): Member allocation loop
substantially rewritten.
* txr.1: Documentation rewritten. Description of the
bitfield allocation algorithm moved to a separate paragraph.
|