summaryrefslogtreecommitdiffstats
path: root/ffi.c
Commit message (Collapse)AuthorAgeFilesLines
* warning cleanup: signed/unsigned in ternaries.Kaz Kylheku2020-04-051-1/+1
| | | | | | | | | | | | | | | | | | | | | This is the third round of an effort to enable GCC's -Wextra option. Instances of signed/unsigned mismatch between the branches of ternary conditionals are addressed. * ffi.c (pad_retval): Add cast into the consequent of the conditional so it yields size_t, like the alternative. * lib.c (split_str_keep): Likewise. (vector): Cast -1 to ucnum so it has the same type as the alloc_plus opposite to it. * parser.c (lino_getch): Add a cast to wint_t to match return value and opposite WEOF operand. * stream.c (generic_get_line): Likewise. * sysif.c (c_time): Convert both consequent and alternative to time_t to silence warning.
* warning cleanup: add casts for unused parameters.Kaz Kylheku2020-04-051-1/+195
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is the first round of an effort to enable GCC's -Wextra option. All function parameters that are unused an that we cannot eliminate are treated with a cast to void in the function body. * args.c (args_key_check_store): Cast unused param to void. * combi.c (perm_list_gen_fill): Likewise. * eval.c (op_error, op_meta_error, op_quote op_qquote_error, op_unquote_error, op_load_time_lit, me_each, me_for, me_quasilist, me_flet_labels, hash_min_max, me_ignerr, me_whilet, me_iflet_whenlet, me_dotimes, me_mlet, me_load_time, me_load_for): Likewise. * ffi.c (ffi_void_put, ffi_fixed_dynsize, *ffi_fixed_alloc, ffi_noop_free, ffi_void_get, ffi_simple_release, ffi_i8_put, ffi_i8_get, ffi_u8_put, ffi_u8_get, 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_put, ffi_uchar_get, ffi_bchar_get, ffi_short_put, 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_val_put, ffi_val_get, ffi_be_i16_put, ffi_be_i16_get, ffi_be_u16_put, ffi_be_u16_get, ffi_le_i16_put, ffi_le_i16_get, ffi_le_u16_put, ffi_le_u16_get, ffi_be_i32_put, ffi_be_i32_get, ffi_be_u32_put, ffi_be_u32_get, ffi_le_i32_put, ffi_le_i32_get, ffi_le_u32_put, ffi_le_u32_get, ffi_be_i64_put, ffi_be_i64_get, ffi_be_u64_put, ffi_be_u64_get, ffi_le_i64_put, ffi_le_i64_get, ffi_le_u64_put, ffi_le_u64_get, ffi_wchar_put, ffi_wchar_get, ffi_sbit_get, ffi_ubit_get, ffi_cptr_get, ffi_str_in, ffi_str_put, ffi_str_get, ffi_str_d_get, ffi_wstr_in, ffi_wstr_get, ffi_wstr_put, ffi_wstr_d_get, ffi_bstr_in, ffi_bstr_put, ffi_bstr_get, ffi_bstr_d_get, ffi_buf_in, ffi_buf_put, ffi_buf_get, ffi_buf_d_in, ffi_buf_d_put, ffi_buf_d_get, ffi_closure_put, ffi_ptr_in_in, ffi_ptr_in_d_in, ffi_ptr_in_out, ffi_ptr_out_in, ffi_ptr_out_out, ffi_ptr_out_null_put, ffi_ptr_out_s_in, ffi_flex_struct_in, ffi_carray_get, ffi_union_get, make_ffi_type_builtin, make_ffi_type_array, ffi_closure_dispatch, ffi_closure_dispatch_safe): Likewise. * gc.c (cobj_destroy_stub_op, cobj_destroy_free_op, cobj_mark_op): Likewise. * lib.c (seq_iter_get_nil, seq_iter_peek_nil): Likewise. * linenoise/linenoise.c (sigwinch_handler): Likewise. * parser.c (repl_intr, read_eval_ret_last, repl_warning, is_balanced_line): Likewise. * parser.y (yydebug_onoff): Likewise. * socket.c (dgram_close): Likewise. * stream.c (unimpl_put_string, unimpl_put_char, unimpl_put_byte, unimpl_unget_char, unimpl_unget_byte, unimpl_put_buf, unimpl_fill_buf, unimpl_seek, unimpl_truncate, unimpl_set_sock_peer, null_put_string, null_put_char, null_put_byte, null_get_line, null_get_char, null_get_byte, null_close, null_flush, null_seek, null_set_prop, null_get_error, null_get_error_str, null_clear_error, null_get_fd, dir_close): Likewise. * struct.c (struct_type_print): Likewise. * unwind.c (me_defex): Likewise.
* ffi: varray: g++ signed/unsigned warning.Kaz Kylheku2020-02-081-1/+1
| | | | | | * ffi.c (ffi_varray_alloc): Add cast to this conversion. The idea here is we are checking for truncation when cnum is converted to size_t.
* ffi: fix broken char handling in undimensioned arrays.Kaz Kylheku2020-01-171-36/+99
| | | | | | | | | | | | | | | | | | | | | | | | | | | The undimensioned (array <type>) and (zarray <type>) types are not doing UTF-8 conversion when <type> is char or zchar, or doing what they are supposed to with the FFI character types, which is inconsistent from their dimensioned counterparts. * ffi.c (ffi_varray_dynsize): if the element type is marked for character conversion, then do the size calculation for char and zchar by measuring the UTF-8 coded size. (ffi_varray_alloc): Call ffi_varray_dynsize to get the size, to benefit from the char handling. Thus when FFI allocates buffers for a variable length array, it will allocate correct size required for the UTF-8 encoded string. (ffi_varray_put, ffi_varray_in): Here we must call ffi_varray_dynsize and divide by the element type to get the proper numer of elements. Then we must check for character conversion and handle the cases. (ffi_varray_null_term_in): Check for character conversion cases and route those through ffi_varray_in, which handles null-terminated strings. * tests/017/ffi-misc.tl: New file. * tests/017/ffi-misc.expected: New file.
* ffi: fix non-libffi build on big endian.Kaz Kylheku2020-01-061-0/+1
| | | | | | | | This is cribbed from a patch by q66 <daniel@oct***rge.org>, commited recently to the Void Linux distro. * ffi.c (ffi_arg): Define this type when HAVE_FFI is not enabled. Some big-endian-specific code refers to it.
* Copyright year bump 2020.Kaz Kylheku2019-12-311-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * LICENSE, LICENSE-CYG, METALICENSE, Makefile, alloca.h, args.c, args.h, arith.c, arith.h, buf.c, buf.h, cadr.c, cadr.h, chksum.c, chksum.h, chksums/crc32.c, chksums/crc32.h, combi.c, combi.h, configure, debug.c, debug.h, eval.c, eval.h, ffi.c, ffi.h, filter.c, filter.h, ftw.c, ftw.h, gc.c, gc.h, glob.c, glob.h, hash.c, hash.h, itypes.c, itypes.h, jmp.S, lib.c, lib.h, linenoise/linenoise.c, linenoise/linenoise.h, lisplib.c, lisplib.h, match.c, match.h, parser.c, parser.h, parser.l, parser.y, protsym.c, rand.c, rand.h, regex.c, regex.h, share/txr/stdlib/asm.tl, share/txr/stdlib/awk.tl, share/txr/stdlib/build.tl, share/txr/stdlib/cadr.tl, share/txr/stdlib/compiler.tl, share/txr/stdlib/conv.tl, share/txr/stdlib/debugger.tl, share/txr/stdlib/defset.tl, share/txr/stdlib/doloop.tl, share/txr/stdlib/error.tl, share/txr/stdlib/except.tl, share/txr/stdlib/ffi.tl, share/txr/stdlib/getopts.tl, share/txr/stdlib/getput.tl, share/txr/stdlib/hash.tl, share/txr/stdlib/ifa.tl, share/txr/stdlib/keyparams.tl, share/txr/stdlib/op.tl, share/txr/stdlib/package.tl, share/txr/stdlib/param.tl, share/txr/stdlib/path-test.tl, share/txr/stdlib/place.tl, share/txr/stdlib/pmac.tl, share/txr/stdlib/save-exe.tl, share/txr/stdlib/socket.tl, share/txr/stdlib/stream-wrap.tl, share/txr/stdlib/struct.tl, share/txr/stdlib/tagbody.tl, share/txr/stdlib/termios.tl, share/txr/stdlib/trace.tl, share/txr/stdlib/txr-case.tl, share/txr/stdlib/type.tl, share/txr/stdlib/vm-param.tl, share/txr/stdlib/with-resources.tl, share/txr/stdlib/with-stream.tl, share/txr/stdlib/yield.tl, signal.c, signal.h, socket.c, socket.h, stream.c, stream.h, struct.c, struct.h, strudel.c, strudel.h, sysif.c, sysif.h, syslog.c, syslog.h, termios.c, termios.h, tree.c, tree.h, txr.1, txr.c, txr.h, unwind.c, unwind.h, utf8.c, utf8.h, vm.c, vm.h, vmop.h, win/cleansvg.txr: Extended copyright notices to 2020.
* ffi: bug: zchar not handled in array out semantics.Kaz Kylheku2019-12-161-0/+1
| | | | * ffi.c (ffi_array_out): Add missing zchar case.
* ffi: shut up gcc7 warnings about switch case.Kaz Kylheku2019-12-161-0/+7
| | | | | | * ffi.c (ffi_array_put, ffi_array_out): Handle conv_none in the switch, even though the whole switch is conditional on the value being other than conv_none.
* ffi: new type zcharKaz Kylheku2019-12-141-1/+41
| | | | | | | | | | | | | | | | | | | The zchar type, when used as an array element, specifies an optionally null-terminated or padded field, which is subject to UTF-8 conversion. * ffi.c (zchar_s): New symbol variable. (enum char_conv): New member, conv_zchar. (ffi_zchar_array_get): New static function. (ffi_array_in, ffi_array_get_common): Handle conv_zchar via ffi_zchar_array_get. (ffi_array_put): Handle conv_char together with conv_zchar. (ffi_type_compile): Handle zchar array element type, mapping to conv_zchar. (ffi_init_types): Register zhar type. (ffi_init): Initialize zchar_s symbol variable. * txr.1: Documented.
* ffi: turn char conversion flags into enum.Kaz Kylheku2019-12-141-52/+85
| | | | | | | | | | | | | | | | | | The three flags controlling character array conversion semantics are mutually exclusive. Let's turn them into an enumeration, so we can (1) test that a conversion is in effect by testing a single value and (2) switch on the conversion type instead of successively testing the flags and (3) assure the aforementioned mutual exclusion. * ffi.c (enum char_conv): New enum. (struct txr_ffi_type): Members char_conv, wchar_conv and bchar_conv gone, replaced by ch_conv. (ffi_array_in, ffi_array_put, ffi_array_out, ffi_array_get_common, ffi_array_release_common, ffi_varray_null_term_get, ffi_type_compile, carray_ensure_artype): Work with ch_conv instead of three flags.
* ffi: allow init-forms for slots.Kaz Kylheku2019-12-061-9/+40
| | | | | | | | | | | | | | | * ffi.c (ffi_memb_compile): Don't complain about three-argument slot specifiers, only about longer ones. (ffi_struct_init): New static function. (ffi_type_compile): Deal with third element in the slot syntax. If there are any non-nil initializing expressions, then we when we call make_struct_type, we specify an initfun, which will plant the values into the slots, using logic similar to that of the initfun generated defstruct, except that the init-forms are reduced to values up-front. * txr.1: Specify optional init-form for slots in FFI struct syntax.
* ffi: rename functions in the carray-num group.Kaz Kylheku2019-11-181-12/+27
| | | | | | | | | | | | | | * ffi.c (carray_unum, carray_num, unum_carray, num_carray): Functions renamed to carray_uint, carray_int, uint_carray, int_carray. (ffi_init): Functions registered under new names: carray-uint, carray-int, uint-carray, int-carray. Compat values of 227 or less provide the old old names. * ffi.h (carray_unum, carray_num, unum_carray, num_carray): Declarations renamed. * txr.1: Updated to new names; compat note added.
* ffi: carray-num using wrong function name.Kaz Kylheku2019-11-181-1/+1
| | | | | * ffi.c (carray_num): Use the correct name carray-num rather than carray-unum in diagnostics.
* safety: fix type tests that code can subvert.Kaz Kylheku2019-09-301-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch fixes numerous instances of a safety hole which involves the type of a COBJ object being tested to be of a given class using logic that can be subverted by the definition of a like-named struct. Specifically logic like (typeof(obj) == hash_s) is broken, because if a struct type called hash is defined, then the test will yield true for instances of that struct type. Those instances can then be passed into code that only works on COBJ hashes, and relies on this test to reject invalid objects. * ffi.c (make_carray): Replace fragile test with strong one, using new cobjclassp function. * hash.c (hashp): Likewise. * lib.c (class_check): The expression used here for the type test moves into the new function cobjclassp and so is replaced by a call to that function. (cobjclassp): New function. * lib.h (cobjclassp): Declared. * rand.c (random_state_p): Replace fragile test using cobjclassp. * regex.c (char_set_compile): Replace fragile typeof tests for character type with is_chr. (reg_derivative, regexp): Replace fragile test with cobjclassp. * struct.c (struct_type_p): Replace fragile test with cobjclassp.
* lib: access special methods via special slot mechanism.Kaz Kylheku2019-09-061-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | * ffi.c (ffi_flex_struct_in): Use get_special_slot to obtain length method. * lib.c (nullify_s, from_list_s, lambda_set_s): Definitions removed from here. (seq_info, car, cdr, rplaca, rplacd, make_like, nullify, replace_obj, length, empty, sub, ref, refset, dwim_set): Use get_special_slot to obtain special method from object, rather than maybe_slot. (obj_init): Remove initializations of nullify_s, from_list_s and lambda_set_s from here. * struct.c (enum special_slot): Definition removed from here. (nullify_s, from_list_s, lambda_set_s): Definitions moved here from lib.c. (special_sym): New static array. (struct_init): Initializations of nullify_s, from_list_s and lambda_set_s moved here from lib.c. (get_special_slot): New function. * struct.h (lambda_set_s): Declared. (enum special_slot): Definition moved here. (get_special_slot): Declared. * txr.1: Added compat note, since get_special_slot behaves like maybe_slot under 224 compatibility.
* ffi: bugfix: kind enum in wrong argument positions.Kaz Kylheku2019-07-301-10/+14
| | | | | | | | | | | | * ffi.c (ffi_type_compile, ffi_init_types): Fixed a number of instances of make_ffi_type_builtin being passed the type kind as the fourth rather than the third argument. The strange fluke here is that FFI_KIND_NUM is 1, so this actually made no difference in all the case in ffi_init_types! However in ffi_type_compile, it would have set the type of cptr-s to struct, and its size to 3. Anyway, we were saved from a regression by the good pre-release habit of compiling as C++!
* FFI: bugfix: GC-correctness of assignments.Kaz Kylheku2019-07-281-0/+11
| | | | | | | | | | | Recent work has introduced wrong-way assignments. When we compile the slots after we have created the type object, the slot types may be in a newer generation than the type object. If we are reusing an old type object, it can be older than the syntax, or the Lisp object being stored in it. * ffi.c (make_ffi_type_struct, make_ffi_type_union): add some setcheck calls to handle anti-generational assignments.
* FFI: bugfix: properly re-use existing struct type.Kaz Kylheku2019-07-281-2/+6
| | | | | | | | | This is a bug in the prior commit's change. * ffi.c (make_ffi_type_struct, make_ffi_type_union): When using an existing type, do not call cobj to make a new Lisp object for the type structure; pull the existing one out from tft->self.
* FFI: self-referential structs.Kaz Kylheku2019-07-281-90/+200
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | With this commit, FFI a struct definitions can contain references to the struct type being defined. It becomes possible to pass a (non-circular) linked list of structures to and from C foreign function. * ffi.c (ffi_kind_t): New enum. We need some tag in the txr_ffi_type struct to indicate type. (ffi_struct_tag_hash): New static variable. (struct txr_ffi_type): New members: kind and flexible. (ffi_struct_in, ffi_struct_get): Use the new flexible bit as an indicator that the struct has a flexible member, rather than the incomplete bit. (make_ffi_type_builtin): Take new argument indicating type kind, and store it in the kind member. (make_ffi_type_pointer): Initialize kind field. (ffi_memb_compile): New static function. (make_ffi_type_struct): No longer receives the list of slot names and their compiled types as arguments. The compiling is done in this function on-the-fly as the slots are initialized, using the ffi_memb_compile function helper. If a same-named struct/union type already exists, this is passed in; the function will replace that type by freeing and reallocating the member vector, clearing the existing struct type to all zero and re-initializing it from scratch. The new kind field is initialized. The incomplete flag is set initially and then updated at the end, so during the processing of the member types, the struct type is considered incomplete. If a struct has no members, it is considered incomplete now. It is flexible only if it ends in a flexible array. The struct type is added to ffi_struct_tag_hash, keyed on its tag. (make_ffi_type_union): Similar changes as in make_ffi_type_struct. (ffi_membs_compile): Function removed. (ffi_type_compile): Change to struct compilation logic. An empty struct definition now avoids creating a Lisp struct type. If a FFI struct type already exists, that one is returned, otherwise an empty one (considered incomplete) is created. A struct definition with members replaces an existing one. The new make_ffi_type_struct interface is used which simplifies things here, since we just pass down the syntax and the existing type, without having to compile the member types. Not a big change for unions: just use the new make_ffi_type_union interface, which requires the existing type, and just the syntax now, rather than compiled slots. For varrays, set the type kind to FFI_KIND_ARRAY, overriding the FFI_KIND_PTR type that is already there due to varrays being implemented as pointers. Perhaps varray should have its own kind, but for now this approach serves fine. For buffer types, set the kind to FFI_KIND_PTR, and for the bitfields, set it to FFI_KIND_NUM. (ffi_init_types): Pass an appropriately-valued kind argument in ach call to the make_ffi_type_builtin constructor. (ffi_init): GC-protect the ffi_struct_tag_hash variable, and initialize it.
* FFI: bugfix: pointer "in" ops must map null to nil.Kaz Kylheku2019-07-271-0/+8
| | | | | | | | | * ffi.c (ffi_ptr_in_in, ffi_ptr_in_d_in, ffi_ptr_out_in, ffi_ptr_out_s_in): If the memory location which holds the pointer to the C object is null, then just return nil. If we don't do this, we then crash trying to extract the object from a null pointer via the recursive tgtft->in or tgtft->get call.
* FFI: elemtype as type operator, not just macro.Kaz Kylheku2019-07-261-1/+18
| | | | | | | | * ffi.c (elemtype_s): New symbol variable. (ffi_type_compile): Handle elemtype. (ffi_init): Initialize elemtype_s. * txr.1: Document elemtype.
* FFI: document: elemsize and elemtype work on enums.Kaz Kylheku2019-07-261-2/+2
| | | | | | | | * ffi.c (ffi_elemsize, ffi_elemtype): Fix error messages to include enum among possible argument types. * txr.1: Extend documentation for ffi-elemsize and ffi-elemtype to include base integer type of enumerations.
* FFI: allow member type reference using referencing dot.Kaz Kylheku2019-07-261-0/+26
| | | | | | * ffi.c (ffi_type_compile): New case handling qref_s symbol. * txr.1: Documented.
* ffi: bugfix: flexible struct get not working right.Kaz Kylheku2019-07-221-7/+13
| | | | | | | | | | The get operation must use the flexible array's in virtual function, because incomplete arrays have a no-op get function. * ffi.c (ffi_flex_struct_in): return the value of the slot. (ffi_struct_get): When processing the terminating slot of a flexible struct, we invoke its in-semantics, using the updated slot value as the object.
* ffi: support flexible structures.Kaz Kylheku2019-07-201-62/+120
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit adds support for working with foreign structures which use the C99 "flexible array member", or possibly the old "C struct hack". Some improvements are made in the FFI code the area of incomplete types and bitfields. * ffi.c (struct txr_ffi_type): New flag members incomplete and bitfield. (ffi_varray_dynsize): Check incomplete type flag rather than for zero size. (ffi_flex_dynsize, ffi_flex_alloc, ffi_flex_struct_in): New static functions. (ffi_struct_in): Call ffi_flex_struct_in when doing by-value semantics on a flexible structure, just before converting last member. This checks for the length method, calls it, and adjusts the last member object as documented. (ffi_struct_get): Likewise. (bitfield_syntax_p): Static function removed; there is a flag for this now in the type, so no need to parse its syntax. (make_ffi_type_pointer): Test bitfield flag rather than using bitfield_syntax_p. (make_ffi_type_struct): Take new argument indicating that the struct is flexible. Wire in appropriate virtual functions based on this flag, and set the type's incomplete flag accordingly. Check bitfield flag rather than using bitfield_syntax_p for detecting bitfield members. Calculate the size of flexible struct differently: it is the offset of the last member. (make_ffi_type_union): Test bitfield flag rather than using bitfield_syntax_p. (ffi_struct_compile): Renamed to ffi_membs_compile. (ffi_membs_compile): New pointer parameter for returning an indication whether the member list specifies a flexible struct. Test the incomplete flag of a member type rather than size being zero. (ffi_type_compile): Follow rename of ffi_struct_compile to ffi_membs_compile. Pass down the flag obtained from ffi_membs_compile into make_ffi_type_struct so that a flexible struct type is created when necessary. Disallow arrays of bitfields. Set bitfield flag on bitfield types. (ffi_init_types): Set incomplete flag on void type. (ffi_make_call_desc): Test for incomplete and bitfield types using new flags. (ffi_typedef, ffi_size, ffi_alignof): Test for bitfield type using new bitfield flag. (carray_elem_check): New static function. (carray_buf, carray_pun, carray_unum, carray_num): Use new carray_elem_check to check for bad array element type. This uses the incomplete flag rather than checking for zero size, and also disallows bitfields. * lib.h (length_s): Declared. * txr.1: Flexible structs documented in new section. Also section on incomplete types. Description of sizeof operator gives more detaild about incomplete types including flexible structs.
* ffi: two-argument form of sizeof.Kaz Kylheku2019-07-111-0/+8
| | | | | | | | | | | | | | | If sizeof is given an extra argument (an expression which evaluates to an object), it can calculate the dynamic size of the FFI type in relation to representing that object. * ffi.c (dyn_size): New static function. (ffi_init): Register sys:dyn-size intrinsic. * share/txr/stdlib/ffi.tl (sizeof): Support additional argument, avoiding run-time compilation of the type expression with the help of load-time. * txr.1: Update documentation for sizeof macro.
* ffi: handle variable length types in buffer ops.Kaz Kylheku2019-07-111-4/+31
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The motivating bug here is that (ffi-put #(1 2 3 5) (ffi (array int))) perpetrates a buffer overrun. The size of (array int) is zero, and so a zero-length buffer is allocated. But then an array of five ints is stored. This is made to work correctly: allocating a buffer large enough. A new virtual function is introduced into the txr_ffi_type structure to calculate a type's dynamic size, from a prototype Lisp object. * ffi.c (struct txr_ffi_type): New function pointer member, dynsize. (ffi_fixed_dynsize, ffi_varray_dynsize): New static functions. (make_ffi_type_builtin, make_ffi_type_pointer, make_ffi_type_struct, make_ffi_type_union, make_ffi_type_array): Initialize new dynsize member of type structure with pointer to ffi_fixed_dynsize. (ffi_type_compile): Initialize the dynsize pointer of variable array types to ffi_varray_dynsize. (ffi_put_into, ffi_put, ffi_in, ffi_out): Use dynsize to calculate the real size required to store or extract the given object. * txr.1: Update doc for ffi-put, ffi-put-into and ffi-in. Looks like we are missing ffi-out; it is not documented!
* bugfix: broken carray-replace.Kaz Kylheku2019-07-051-1/+1
| | | | | | | | * ffi.c (carray_replace): Use original fn < vn loop guard, like in the original code that was replaced by the generic sequence iteration loop. For instance, when we replace a range like 1..1, fn == tn, and so the loop doesn't copy anything.
* carray-replace: use seq_iter.Kaz Kylheku2019-06-181-15/+5
| | | | | * ffi.c (carray_replace): Use generic sequence iteration for range replacement instead of separate list/vector code.
* carray-refset: bugfix: support negative indexing.Kaz Kylheku2019-06-141-0/+3
| | | | | | * ffi.c (carray_refset): Support negative indexing by adding the length of the array to a negative index value. This is already done in carray_ref.
* carray-replace: missing functionality.Kaz Kylheku2019-06-131-7/+24
| | | | | * ffi.c (carray_replace): add missing index list assignment semantics required by documentation.
* ffi: adjust in semantics of variable zarray.Kaz Kylheku2019-06-121-1/+1
| | | | | | | | | | | | | | | | | The replace function now returns a list if a nil object's is replaced with a range, rather than just returning the original item sequence. This breaks the variable array in operation, causing it to produce a list. We fix this sproblem, and also the nonsense semantics of the operation also; the operation should replace the original sequence, with the array, similarly to how null terminated strings work. * ffi.c (ffi_varray_null_term_in): If the original Lisp object isn't nil, then assume it's a sequence and replace it with the items gathered in the vector. Otherwise, replace it with the vector. * txr.1: Adjust documentation.
* bugfix: c_num won't convert most negative value.Kaz Kylheku2019-05-251-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | This bug causes a problem particularly in FFI. THe conversion of an integer to the FFI int type begins by conversion via c_num to the cnum type, which is at least as wide as int. Alas, the INT_MIN value (e.g. #x-80000000 on 32 bits) will not convert! Fixing this has a ripple effect. We alter the INT_PTR_MIN constant to include this value. This causes the derived NUM_MIN to also include the extra negative value, extending the fixnum range by one value. Everything seems to be okay. * configure: Decrease value of INT_PTR_MIN and DOUBLE_INTPTR_MIN constants by one to include the most negative two's complement value. * ffi.c (make_ffi_type_enum): We must not subtract 1 from INT_PTR_MIN here any more. * mpi.c (mp_in_range): If the bignum is negative, then extend the range check by one value, so that we don't reject the most negative two's complement value.
* c++ maintenance: multiple defs of mod_s and bit_s.Kaz Kylheku2019-03-301-1/+1
| | | | | | | | | * arith.h (mod_s, bit_s): Add extern declarations. * ffi.c (bit_s): Remove definition. * match.c (mod_s): Remove definition. Include "arith.h" to obtain declaration of mod_s.
* ffi, eval: move struct_s.Kaz Kylheku2019-03-021-2/+1
| | | | | | | | | | * eval.c (struct_s): Now defined here. (eval_init): struct now interned here. * eval.h (struct_s): Declared. * ffi.c (struct_s): Definition removed. (ffi_init) struct no longer interned here.
* ffi: gc bug in cptr type.Kaz Kylheku2019-02-241-0/+1
| | | | | * ffi.c (ffi_type_common_mark): We must mark tft->tag field whih is used by the cptr type and is otherwise nil.
* ffi: gc bug in enum type.Kaz Kylheku2019-02-241-5/+5
| | | | | | | | * ffi.c (make_ffi_type_enum): Allocate the sym_num an num_sym hashes before the type object. That ensures they are older, and may be assigned into the object without setcheck. Also, move those assignments earlier, before the loop which populates the hashes.
* ffi: closure: clear stale saved exit point.Kaz Kylheku2019-02-071-0/+2
| | | | | | | | | | | | | | | | | What happens if a FFI closure intercepts an exception, returns to the foreign code, but that caller does not return to Lisp where the exception will continue? Suppose the caller invokes another closure. In that situation, the lingering value of the s_exit_point variable causes problems for FFI calls. An example of this is callbacks from an event dispatching framework such as a GUI. When these callback closures return, control returns to the event loop, which itself doesn't immediately return to Lisp code. Rather, it processes more events and invokes more callbacks. * ffi.c (ffi_closure_dispatch_safe): One thing we can do is clear s_exit_point whenever we dispatch a closure.
* ffi: use padded return size in closure dispatch.Kaz Kylheku2019-02-071-2/+3
| | | | | | | * ffi.c (ffi_closure_dispatch_safe): When initially clearing a return value that has release semantics, use the padded size, not the nominal size. Let's get calculate this once and put it in a local.
* ffi: don't pad void return size to sizeof (ffi_arg).Kaz Kylheku2019-02-071-1/+1
| | | | * ffi.c (pad_retval): If the size is zero, don't pad it.
* bugfix: ffi-make-closure safe-p param.Kaz Kylheku2019-02-061-1/+1
| | | | | | * ffi.c (ffi_make_closure): Fix wrong argument defaulting on safe_p_in parameter, which leaves it always true, preventing unsafely dispatched closures from being created.
* ffi: make-zstruct must ignore padding slots.Kaz Kylheku2019-02-061-2/+4
| | | | | | | * ffi.c (make_zstruct): Don't convert zeros to a Lisp type and don't try to set the slot, if the slot name is nil. That's a padding slot which doesn't exist in the Lisp type; the slotset will blow up on it.
* ffi: whitespace fix.Kaz Kylheku2019-02-061-1/+1
| | | | * ffi.c (make_zstruct): space around assignment operator.
* ffi: use enhanced 64 bit support in itypes.c.Kaz Kylheku2019-01-251-155/+24
| | | | | | | | | * ffi.c (ffi_be_i64_put, ffi_be_i64_get, ffi_be_u64_put, ffi_be_u64_get, ffe_le_i64_put, ffi_le_i64_get, ffi_le_u64_put, ffi_le_u64_get): Functions simplified by using u64_t and i64_t types and functions from itypes.c. Conditional compilation and range tests are no longer required.
* ffi: fix range checks in be/le i64 put ops.Kaz Kylheku2019-01-241-4/+4
| | | | | | | | | * ffi.c (ffi_be_i64_put, ffi_le_i64_put): Fix incorrect range check, causing most negative two values to be rejected. The aim here is to accept the #x-80..00 most negative two's complement value. We can't express that directly using the C expression -0x8000000000000000 because it's not a simple constant; it's the unary minus applied an unsigned number.
* ffi: incorrect big endian int64 get.Kaz Kylheku2019-01-241-2/+2
| | | | | * ffi.c (ffi_le_i64_get): Fix wrong array indices, causing lower half of 64 bit word to be taken as the upper half.
* ffi: almost bug: 64 bit signed big/little endian type.Kaz Kylheku2019-01-231-4/+4
| | | | | | | | | | | | | | * ffi.c (ffi_be_i64_get, ffi_le_i64_get): The code here for 32 bit platforms is fishy: it is using the signed cnum type for the low 32 bits, when that should be ucnum. We are actually okay because ths code would only be executed on a platform where cnum is 32 bits. We are saved by the fact that we are doing left shifts (no sign extension), that shifting a 1 into a sign bit is harmless on two's complement machines, and that the lo32 value is ultimately passed to unum whereby it is coerced to a ucnum argument type (which preserves the bit representation) and prevents logior from seeing a negative value.
* Fix some instances of 4 bytes = 32 bits assumption.Kaz Kylheku2019-01-231-8/+8
| | | | | | | | | | | | | | | | | * hash.c (equal_hash, eql_hash, cobj_eq_hash_op, hash_hash_op): Multiply object size by CHAR_BIT and switch on number of bits, rather than bytes. * sysif.c (off_t_num): Likewise. * arith.c, ffi.c, itypes.c, rand.c: In numerous #if directive, fix size tests from bytes to bits. * configure: in the test that detects integer types, and in the test for enabling large file offsets, detect one more variable from the system: the value of CHAR_BIT. This turns into SIZEOF_BYTE. We use that value instead of a hard-coded 8.
* carray: fix vec/list conversion bug.Kaz Kylheku2019-01-171-12/+30
| | | | | | | | | | | | | | | | | | | | If a zero-length carray is converted with vec-carray or list-carray and the null-term-p argument is t, there is an exception about a negative index. An empty vector or list should be returned in this case, and the documentation says exactly that. Also, if a carray of unknown length is converted, there is an exception from vec-carray, as documented, but it's an uninformative one that is incidentally produced when -1 is passed to the vec function. The list-carray just returns nil, contravening the documentation. * ffi.c (vec_carray, list_carray): Fix the problems described above. * txr.1: Reviewing the documentation for these functions, an improperly terminated sentence was found.
* Copyright year bump 2019.Kaz Kylheku2019-01-161-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * LICENSE, LICENSE-CYG, METALICENSE, Makefile, args.c, args.h, arith.c, arith.h, buf.c, buf.h, cadr.c, cadr.h, combi.c, combi.h, configure, debug.c, debug.h, eval.c, eval.h, ffi.c, ffi.h, filter.c, filter.h, ftw.h, gc.c, gc.h, glob.c, glob.h, hash.c, hash.h, itypes.c, itypes.h, jmp.S, lib.c, lib.h, lisplib.c, lisplib.h, match.c, match.h, parser.c, parser.h, parser.l, parser.y, protsym.c, rand.c, rand.h, regex.c, regex.h, share/txr/stdlib/asm.tl, share/txr/stdlib/awk.tl, share/txr/stdlib/build.tl, share/txr/stdlib/cadr.tl, share/txr/stdlib/compiler.tl, share/txr/stdlib/conv.tl, share/txr/stdlib/doloop.tl, share/txr/stdlib/error.tl, share/txr/stdlib/except.tl, share/txr/stdlib/ffi.tl, share/txr/stdlib/getopts.tl, share/txr/stdlib/getput.tl, share/txr/stdlib/hash.tl, share/txr/stdlib/ifa.tl, share/txr/stdlib/keyparams.tl, share/txr/stdlib/op.tl, share/txr/stdlib/package.tl, share/txr/stdlib/path-test.tl, share/txr/stdlib/place.tl, share/txr/stdlib/pmac.tl, share/txr/stdlib/socket.tl, share/txr/stdlib/stream-wrap.tl, share/txr/stdlib/struct.tl, share/txr/stdlib/tagbody.tl, share/txr/stdlib/termios.tl, share/txr/stdlib/trace.tl, share/txr/stdlib/txr-case.tl, share/txr/stdlib/type.tl, share/txr/stdlib/vm-param.tl, share/txr/stdlib/with-resources.tl, share/txr/stdlib/with-stream.tl, share/txr/stdlib/yield.tl, signal.c, signal.h, socket.c, socket.h, stream.c, stream.h, struct.c, struct.h, strudel.c, strudel.h, sysif.c, sysif.h, syslog.c, syslog.h, termios.c, termios.h, txr.1, txr.c, txr.h, unwind.c, unwind.h, utf8.c, utf8.h, vm.c, vm.h, vmop.h, win/cleansvg.txr: Extended Copyright line to 2018.