| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.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.c (elemtype_s): New symbol variable.
(ffi_type_compile): Handle elemtype.
(ffi_init): Initialize elemtype_s.
* txr.1: Document elemtype.
|
|
|
|
|
|
|
|
| |
* 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.c (ffi_type_compile): New case handling qref_s symbol.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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!
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
| |
* ffi.c (carray_replace): Use generic sequence iteration for
range replacement instead of separate list/vector code.
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
| |
* ffi.c (carray_replace): add missing index list assignment
semantics required by documentation.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
| |
* 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.c (ffi_type_common_mark): We must mark tft->tag field
whih is used by the cptr type and is otherwise nil.
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.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.c (pad_retval): If the size is zero, don't pad it.
|
|
|
|
|
|
| |
* 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.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.c (make_zstruct): space around assignment operator.
|
|
|
|
|
|
|
|
|
| |
* 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.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.c (ffi_le_i64_get): Fix wrong array indices, causing
lower half of 64 bit word to be taken as the upper half.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.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.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.c (make_ffi_type_array): Remove a useless loop that
was left behind when the essential part of its body was
removed.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
| |
* 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.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.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.
|