summaryrefslogtreecommitdiffstats
path: root/ffi.c
Commit message (Collapse)AuthorAgeFilesLines
...
* 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.
* ffi: arrays: be more forgiving of length mismatches.Kaz Kylheku2019-01-151-9/+34
| | | | | | | | | | * ffi.c (min): New macro. (ffi_array_put_common): Tolerate sequences which are shorter than the array. Use seq_info to classify the sequence and use separate code for the vector and list case, avoiding taking the length of the list. * txr.1: Documented.
* ffi: bugfix: char array shouldn't null terminate.Kaz Kylheku2019-01-151-1/+3
| | | | | | | | | | | * ffi.c (ffi_char_array_put): The char array put operation should only null terminate when the null_term flag is set; i.e. it's a zarray type. The bug here is that when a Lisp string of length > N is put into an (array N char), the C array gets null terminated, which is wrong. Only in the case when the string is exactly of length N is there no null termination. In all cases when the length >= N, we want truncation without null termination.
* ffi: remove useless loop.Kaz Kylheku2019-01-151-12/+6
| | | | | | * ffi.c (make_ffi_type_array): Remove a useless loop that was left behind when the essential part of its body was removed.
* Eliminate ALLOCA_H.Kaz Kylheku2018-12-311-1/+1
| | | | | | | | | | | | | * configure: Instead of generating a definition of ALLOCA_H, generate the variable HAVE_ALLOCA_<name> with a value of 1, where <name> is one of stdlib, alloca or malloc. * alloca.h: New header. * args.c, eval.c, ffi.c ffi.c, ftw.c, hash.c, lib.c, match.c, parser.c, parser.y, regex.c, socket.c, stream.c, struct.c, sysif.c, syslog.c, termios.c, unwind.c, vm.c: Include "alloca.h" instead of ALLOCA_H.
* Drastically reduce inclusion of <dirent.h>.Kaz Kylheku2018-12-111-1/+0
| | | | | | | | | | | | | | | | | | | The <dirent.h> header is included all over the place because it is needed by a single declaration in stream.h. That declaration is for a function that is only called within stream.c, so we make it internal. Now only stream.c has to include <dirent.h>. * buf.c, debug.c, eval.c, ffi.c, filter.c, gc.c, gencadr.txr, hash.c, lib.c, lisplib.c, match.c, parser.c, regex.c, socket.c, struct.c, strudel.c, sysif.c, syslog.c, termios.c, txr.c, unwind.c, vm.c: Remove #include <dirent.h>. * cadr.c: Regenerated. * stream.c (make_dir_stream): Make external function static. * stream.h (make_dir_stream): Declaration updated.
* Better identify functions that misuse COBJ-s and hashes.Kaz Kylheku2018-11-071-83/+96
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In this patch, the cobj_handle, cobj_ops and variants of gethash get an additional argument to identify the caller. Many functions are updated to pass this down. * buf.c (buf_strm): Pass self name to cobj_handle. * eval.c (env_fbind, env_vbind, rt_defvarl, me_case): Pass self name to gethash_c or gethash_e. (load): Pass self name to read_eval_stream and read_compiled_file. (reg_symacro): Pass situation-identifying string to gethash_c. * ffi.c (ffi_type_struct_checked, ffi_closure_struct_checked, ffi_call_desc_checked, uni_struct_checked): Take self name parameter, and pass down to cobj_handle. (ffi_get_type, ffi_get_lisp_type): Take self name and pass down to ffi_type_struct_checked. (union_get_ptr): Take self name and pass to uni_struct_checked. (ffi_union_in, ffi_union_put): Pass self name to union_get_ptr. (ffi_type_compile): Pass self name to ffi_get_lisp_type. (ffi_make_call_desc): Pass self name to ffi_type_struct_checked, ffi_get_type and ffi_call_desc_checked. (ffi_make_closure): Pass self name to ffi_call_desc_checked. (ffi_closure_get_fptr): Take self name, pass to ffi_closure_struct_checked. (ffi_typedef, ffi_size, ffi_alignof, ffi_offsetof, ffi_arraysize, ffi_elemsize, ffi_elemtype, ffi_put_into, ffi_put, ffi_in, ffi_get, ffi_out, make_carray): Pass self name to ffi_closure_struct_checked. (carray_struct_checked): Take self name, pass to cobj_handle. (carray_set_length, carray_dup, carray_own, carray_free, carray_type, length_carray, copy_carray, carray_ptr, buf_carray, vec_carray, list_carray, carray_ref, carray_refset, carray_sub, carray_replace, carray_get_common, carray_put_common, unum_carray, num_carray, put_carray, fill_carray): Pass self name to carray_struct_checked. (carray_blank, carray_buf, carray_cptr): Pass self name ffi_type_struct_checked. (carray_pun): Pass self name to carray_struct_checked and ffi_type_struct_checked. (make_union): Pass self name to ffi_type_struct_checked. (union_members, union_get, union_put, union_in, union_out): Pass self name to uni_struct_checked. (make_zstruct, zero_fill, put_obj, get_obj, fill_obj): Pass self-name to ffi_type_struct_checked. * ffi.h (ffi_closure_get_fptr, union_get_ptr): Declarations updated. * filter.c (trie_add): Pass self-name to gethash_l. * hash.c (make_similar_hash, copy_hash, hash_count, get_hash_userdata, set_hash_userdata, hash_begin, hash_next, hash_uni, hash_diff, hash_isec): Pass self name to cobj_handle. (gethash_c, gethash_e): Take self name parameter and pass down to cobj_handle. (gethash_f): Take self parameter and pass down to gethash_e. (gethash, inhash, gethash_n, sethash, pushhash, remhash, clearhash, hash_update_1): Pass self name to gethash_e or gethash_c. * hash.h (gethash_c, gethash_e, gethash_f): Declarations updated. (gethash_l): Take self name, and pass down to gethash_c. * lib.c (class_check): Take self name parameter and use in type mismatch diagnostic. (use_sym, unuse_sym, symbol_needs_prefix, find_symbol, intern, unintern, intern_fallback, unique, in, sel, obj_print_impl, populate_obj_hash, obj_hash_merge): Pass self name to gethash_f or gethash_l. (symbol_visible, obj_init): Pass situation-identifying string to gethash_e. (cobj_handle, cobj_ops): Take self name parameter and pass down to class_check. * lib.h (class_check, cobj_handle, cobj_ops): Declarations updated. * match.c (v_load): Pass self name to read_compiled_file and read_eval_stream. * parser.c (get_parser_impl): Take self name and pass to cobj_handle. (ensure_parser): Pass situation-identifying string to gethash_c. (parser_circ_def): Pass self-name to gethash_c. (lisp_parser_impl): Pass self name to get_parser_impl and class_check. (lisp_parse, nread, iread): Pass self-name to lisp_parser_impl. (read_file_common): Take self name parameter and pass down to get_parser_impl. (read_eval_stream, read_compiled_file): Take self name and pass down to read_file_common. (load_rcfile): Pass situation-identifying string to read_eval_streem. (get_visible_syms): Pass situation-identifying string to gethash_c. (parser_errors, parser_eof): Pass self name to cobj_handle. * parser.h (read_eval_stream, read_compiled_file): Declarations updated. * parser.y (rlset): Pass self name to gethash_c. * rand.c (make_random_state, random_state_get_vec,l random_fixnum, random_float): Pass self name to cobj_handle. * regex.c (regex_source, regex_print, regex_run): Pass self-name to cobj_handle. (regex_machine_init): Take self name param and pass to cobj_handle. (search_regex, match_regex, match_regex_right, regex_prefix_match, read_until_match): Pass self-name to regex_machine_init. * stream.c (stdio_get_fd): Pass self name to cobj_handle. (generic_get_line): Get COBJ operations via unsafe, diret object access rather than cobj_ops. (set_mode_props): Get object handle via unsafe, direct object access. (stream_fd, sock_family, sock_type, sock_peer, set_sock_peer, get_string_from_stream, get_list_from_stream, stream_set_prop, stream_get_prop, close_stream, get_error, get_error_str, clear_error, get_line, get_char, get_byte, unget_char, unget_byte, put_buf, fill_buf, put_string, put_char, put_byte, flush_stream, seek_stream, truncate_stream, get_indent_mode, test_set_indent_mode, set_indent_mode, get_indent, set_indent, inc_indent, width_check, force_break, get_set_ctx, get_ctx): Pass self name to cobj_ops. (make_delegate_stream): Take self name parameter, pass down to cobj_ops. (record_adapter): Pass self name down to make_delegate_stream. (format): Pass self name to class_check. * struct.c (stype_handle): Pass self name to cobj_handle. (make_struct_type): Pass self name to class_check. * txr.c (read_eval_stream_noerr): Take self name parameter, pass to read_eval_stream. (txr_main): Pass istuation-identifying string to read_compiled_file and read_eval_stream_noerr. * unwind.c (revive_cont): Pass self-name to cobj_handle. * vm.c (vm_desc_struct): Take self name parameter, pass to cobj_handle. (vm_desc_nlevels, vm_desc_nregs, vm_desc_bytecode, vm_desc_datavec, vm_desc_symvec, vm_execute_toplevel, vm_execute_closure, vm_closure_entry): Pass self name to vm_desc_struct. (vm_closure_struct): Take self name parameter, pass to cobj_handle.
* Fix wrong uses of ~s for function name string.Kaz Kylheku2018-11-071-7/+7
| | | | | | | | | | | | * ffi.c (make_ffi_type_enum): Use ~a for function name rather than ~s because it's a string which is quoted under ~s. * lib.c (chk_xalloc, string_extend, find_symbol, intern_fallback): Likewise. * stream.c (open_process, run): Likewise. * sysif.c (exec_wrap, setgroups_wrap, dlclose_wrap): Likewise.
* math: improve error diagnosis.Kaz Kylheku2018-11-071-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | More streamlined code, better identification of functions. * arith.c (not_number, not_integer, invalid_ops, invalid_op, divzero): New static functions. (num_to_buffer, bugnum_len, plus, minus, neg, abso, signum, mul, trunc1, mod, floordiv, round1, roundiv, divi, zerop, plusp, minusp, evenp, oddp, gt, lt, ge, le, numeq, expt, exptmod, floorf, ceili, sine, cosi, tang, asine, acosi, atang, loga, logten, logtwo, expo, sqroot, int_flo, flo_int, cum_norm_dist, inv_cum_norm): Establish function's Lisp name as self variable. Use new static functions for reporting common errors. Pass function name to new argument of c_flo function. * buf.c (buf_put_float, buf_put_double): Pass function's Lisp name to c_flo function. * ffi.c (ffi_float_put, ffi_double_put): Likewise. * lib.c (c_flo): Takes new argument, name of calling function. * lib.h (c_flo): Declaration updated. * stream.c (formatv): Pass function name to c_flo.
* ffi: use existing local instead of struct access.Kaz Kylheku2018-06-251-4/+4
| | | | | | * ffi.c (ffi_closure_dispatch, ffi_closure_dispatch_safe): The nargs variable holds a copy of tfcl->nparam, so use it instead of accessing tfcl->nparam again.
* bugfix: include most negative two's in cnum range.Kaz Kylheku2018-04-291-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The INT_PTR_MIN value isn't the smallest value actually representable in cnum, because it is just the additive inverse of INT_PTR_MAX. In two's complement, the INT_PTR_MIN-1 value is still representable. But we are excluding it. If a Lisp integer has the value INT_PTR_MIN-1, the c_num function will fail to convert it to a cnum. This situation occurs in FFI, where code may expect that the Lisp value #x-80000000 can convert to an external 32 bit integer type. This will be done by way of a conversion to cnum first via c_num (see ffi_i32_put for instance, which calls c_i32 which relies on c_num). * arith.c (INT_PTR_MAX_SUCC_MP): New static variable. This holds a bignum equivalent to INT_PTR_MAX + 1. (in_int_ptr_range): We now check whether the value against the range [-(INT_PTR_MAX + 1), (INT_PTR_MAX + 1)] and then check all possible return values. The MP_LT case is clearly in range, and MP_GT is out of the range. The interesting situation is MP_EQ: in that case we just test the sign to see whether we are looking at -(INT_PTR_MAX + 1). (int_flo): INT_PTR_MIN is referenced in this function, so we use INT_PTR_MIN - 1 instead. This allows that value to be handled via the simple bignum(n) case. (arith_init): Initialize INT_PTR_MAX_SUCC_MP. We cannot initialize it to INT_PTR_MAX + 1 directly because that expression overflows: insted we use INT_PTR_MIN - 1 and then flip the resulting bignum's sign. (arith_free_all): Call mp_clear on the new variable to release its digit buffer. * ffi.c (make_ffi_type_enum): Use INT_PTR_MIN - 1 as the initial value of the highest variable, to accurately calculate the range of the enum values if they contain INT_PTR_MIN - 1.
* args: overhaul for clarity and reduced consing.Kaz Kylheku2018-03-091-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * args.c (args_normalize): Renamed to args_normalize_exact, because this tries to split the arguments between an exact array fill quantity and trailing list. Not all places using this function actually need an exact fill, which causes unnecessary consing when args->fill is reduced in order to move items to args->list. (args_normalize_least): New function. Variant of args_normalize that can be used by functions which only require a minimum fill. (args_normalize_fill): Use args_normalize_least rather than args_normalize_exact. This reduces consing in generic_funcall, in handling variadic calls where arrayed arguments have been supplied for trailing parameters. * args.h (args_normalize): Renamed to args_normalize_exact. (args_normalize_least): Declared. (args_get_list, args_get_rest): Use args_normalize_exact. (args_clear): Inline function removed. Was used only in one place in generic_funcall and is no longer. * eval.c (gather_free_refs): Use args_normalize_least. (prod_common): Use args_normalize_exact. * ffi.c (ffi_call_wrap): Use args_normalize_least. * lib.c (generic_funcall): Use args_normalize_least in switch statement that handles various callable non-function objects. When copying args, ensure that there are ARGS_MIN. A different strategy is used for producing the trailing args for variadic calls, further reducing consing. Rather than normalize the args to the fixed number, and then set args->fill to zero so that args contains just the list, we use args_cat_zap_from to create a copy of the args in which the fixed ones are trimmed out. The resulting args is not renormalized to be purely a list so no consing or list traversal takes place. If the rebalancing is needed, the called function will have to do it. (dwim_set): Streamline the code that handles hashes assigned via two or three args. * struct.c (method_args_fun, umethod_args_fun): Use args_normalize_exact.
* Copyright year bump 2018.Kaz Kylheku2018-02-151-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.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, 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/awk.tl, share/txr/stdlib/build.tl, share/txr/stdlib/cadr.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/txr-case.tl, share/txr/stdlib/type.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, win/cleansvg.txr: Extended Copyright line to 2018.
* carray: check type object in several API functions.Kaz Kylheku2017-10-261-4/+4
| | | | | | | * ffi.c (carray_blank, carray_buf, carray_cptr, carray_pun): these functions should be using ffi_type_struct_checked, since they are public interfaces to which anything can be passed. Otherwise TXR can easily be crashed by misusing them.
* carray: bugfix: allow negative indexing in ref operation.Kaz Kylheku2017-10-261-0/+3
| | | | | | * ffi.c (carray_ref): If the index is negative, displace it by the length of the array. (Then if it is still negative, the function will throw.)
* ffi: new FFI type I/O functions.Kaz Kylheku2017-08-161-0/+45
| | | | | | | | | * ffi.c (put_obj, get_obj, fill_obj): New functions. (ffi_init): put-obj, get-obj, fill-obj intrinsics registered. * ffi.h (put_obj, get_obj, fill_obj): Declared. * txr.1: Documented.
* ffi: new buf-carray function.Kaz Kylheku2017-08-081-0/+9
| | | | | | | | | * ffi.c (buf_carray): New function. (ffi_init): Registered buf-carray intrinsic. * ffi.c (buf_carray): Declared. * txr.1: Documented.
* ffi: add offset argument to ffi buffer functions.Kaz Kylheku2017-07-161-26/+50
| | | | | | | | | | | | | * 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!
* carray: add offset to carray-buf.Kaz Kylheku2017-07-151-15/+31
| | | | | | | | | | | | | | * 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.
* Fix use of raw null constant in carray implementation.Kaz Kylheku2017-07-151-1/+1
| | | | | | * 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: new function, zero-fill.Kaz Kylheku2017-07-091-0/+33
| | | | | | | | | * ffi.c (zero_fill): New function. (ffi_init): zero-fill intrinsic registered. * ffi.h (zero_fill): Declared. * txr.1: Documented.
* ffi: new make-zstruct function and znew macro.Kaz Kylheku2017-07-021-0/+45
| | | | | | | | | | | | | * 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: new ffi-type-operator-p and ffi-type-p.Kaz Kylheku2017-06-301-0/+18
| | | | | | | | | | * 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: fix more bugginess in struct bitfield allocation.Kaz Kylheku2017-06-291-2/+2
| | | | | | | | | * 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: make-union can initialize.Kaz Kylheku2017-06-291-3/+12
| | | | | | | | | | | * 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: fix union printing as struct.Kaz Kylheku2017-06-291-1/+1
| | | | | * ffi.c (ffi_type_compile): Syntax for union type wrongly using struct symbol rather than union.
* ffi: fix bool printing as integer type.Kaz Kylheku2017-06-291-1/+1
| | | | | | * ffi.c (ffi_type_compile): Assign full bool syntax to cloned type, rather than just the argument syntax denoting the base type.
* ffi: reject bitfields as arguments or return values.Kaz Kylheku2017-06-291-0/+6
| | | | | * ffi.c (ffi_make_call_desc): Throw error if argument or return value is a bitfield.
* ffi: tighten syntax validation in type compiler.Kaz Kylheku2017-06-291-2/+46
| | | | | * ffi.c (ffi_type_compile): Check for too few or too many arguments in a compound form.
* ffi: new enumed type operator: enums with base type.Kaz Kylheku2017-06-271-1/+13
| | | | | | | | | | * 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.
* ffi: prepare for variably sized enum implementation.Kaz Kylheku2017-06-271-17/+26
| | | | | | | | | | | | | | | | | | | 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: bugfix: diagnostic problems in enum put.Kaz Kylheku2017-06-271-6/+8
| | | | | | * 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.
* ffi: add missing rput/rget ops for big endian.Kaz Kylheku2017-06-271-0/+35
| | | | | | | | | | | | 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: fix incorrect null-terminated array in op.Kaz Kylheku2017-06-271-3/+4
| | | | | | | | | * 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: bugfix: varray alloc not accounting for null term.Kaz Kylheku2017-06-261-1/+1
| | | | * ffi.c (ffi_varray_alloc): Add tft->null_term to length.
* ffi: bugfix: null-terminated zarray in semantics.Kaz Kylheku2017-06-261-1/+1
| | | | | | * 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: fix leak in new union code.Kaz Kylheku2017-06-251-1/+1
| | | | | | * ffi.c (make_ffi_type_union): Create cobj with correct cobj_ops structure: ffi_type_struct_ops, not ffi_type_enum_ops.
* ffi: fix incorrect cptr type tag implementation.Kaz Kylheku2017-06-241-6/+14
| | | | | | | | | | | | | | | | | | | 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.
* ffi: fix memory leak regression.Kaz Kylheku2017-06-241-0/+3
| | | | | | | | | | | | 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.
* ffi: provide longlong and ulonglong types.Kaz Kylheku2017-06-241-0/+4
|
* ffi: elide useless by-value in calls.Kaz Kylheku2017-06-241-11/+16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* ffi: short-circuit useless by-value in semantics.Kaz Kylheku2017-06-231-15/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.