| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The root slot is just supposed to be (car bl.list): the
first basic block. Unfortunately, it's not maintained
when bl.list is edited, which could cause bugs.
This change makes no difference in the stdlib compiled files,
other than of course the changes in optimize.tlo from this
code change itself; so that is evidence suggesting
this change is least not making anything worse.
* stdlib/optimize.tl (basic-blocks): Remove root slot.
(basic-blocks (link-graph, calc-liveness, elim-dead-code):
Refer to (car bl.list) instead of bl.root.
|
|
|
|
|
|
|
|
|
|
|
| |
* parser.c (repl): Also push and pop the warning handler
around the linenoise call, like we do around evaluation.
The reason is that when the library is used in source code
form, it can generate warnings while loading. Loading can
be triggered by completion from inside linenoise. Neglecting
to handle warnings and throw a continue causes a problem
because the warnings then fall victim to the listener's
master catch. That then interferes with the load.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The problem being addressed here showed up for me when compiling with
either gcc-7 or gcc-11 on Ubuntu 18, using -fsanitize-undefined.
A few test test cases run under --gc-debug were crashing. I narrowed
it down to this small test case, whose correct output would be "1":
./txr --gc-debug -p '(sys:fmt-simple 1 : : : :)'
"\x6700ACB0缻\x6700ACB0缻 "
The issue doesn't have anything to do with -fsanitize-undefined;
that just how it got reproduced by chance. I'm reasonably certain
that in builds for which "make tests" passes, and the above test
case doesn't repro, this issue is absent: the code got generated
in such a way that it the string_own call doesn't cause the stream
object to be reclaimed.
* stream.c (get_string_from_stream): change the order of operations in
the ownership transfer of the string from the stream to the returned
string object. We capture the string in a local variable, and null out
so->buf before calling string_own. The problem is that
get_string_from_stream is called in a way where the caller no longer
has any use for the stream, and so the object is no longer live.
It's possible for the string_own call to cause the stream object to be
garbage collected. Therefore, the object must not still be hanging on
to the wchar_t * string, which was already transferred to the string
object.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The --free-all feature is broken. It is needed for confirming
lack of memory leaks during development. What breaks it is the
atexit call to run_load_hooks in eval.c, which occurs after
the atexit call to free_all in txr.c which blows everything
away.
* Makefile (tst/tests/019/load-hook.ok): Let's put --free-all
on this test case, because it has to with the load hooks.
Make no mistake though: everything crashes with --free-all,
not this test case specifically.
* txr.c (opt_free_all): New global variable.
(free_all): Free resources only if opt_free_all is true.
Lose the paranoid called flag.
(main): Register free_all with atexit before callilng init.
This ensures that it will be called after any atexit
handlers registered as part of init, like the one in sysif.c
and eval.c.
(txr_main): The --free-all option now just sets opt_free_all.
* txr.h (opt_free_all): Declared.
|
|
|
|
| |
* txr.1: Add missing "If" at start of sentence.
|
|
|
|
|
|
|
|
|
|
|
| |
* parser.c (open_txr_file): Use liberal heaps of #if HAVE_ZLIB.
If there is no Zlib, and the caller explicitly requests a
.tlo.gz file to be loaded, then throw. Do not implicitly look
for a .tlo.gz file.
* stream.c (open_file): #if HAVE_ZLIB around a goto label that
is only used out of HAVE_ZLIB code, to eliminate unused label
warning.
|
|
|
|
|
|
| |
* stream.c (parse_mode, open_file, open_fileno): Since self
is a string, use ~a to print it, or else quotes
will appear.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure (txr_ver): Bumped version.
* stdlib/ver.tl (lib-version): Bumped.
* txr.1: Bumped version and date.
* txr.vim, tl.vim: Regenerated.
|
|
|
|
|
|
|
| |
* chksum.c (crc32): Stop-gap solution: make it static.
Also, fix wrong self-string.
* chksum.h (crc32): Declaration removed.
|
|
|
|
| |
* inst.nsi: pull in cygz.dll.
|
|
|
|
|
|
|
|
|
|
| |
* stream.c (sh): Use a single definition for this function,
which uses the shell and shell_arg variables to use
either /bin/sh -c or cmd.exe /c. We only want to use
cmd.exe when running as a Windows native program on Cygnal.
* tests/018/process.tl: Remove workaround from test case.
This is what was causing the weirdness.
|
|
|
|
| |
* gzio.c (gzio_set_prop): Remove unused ops variable.
|
|
|
|
|
|
|
|
| |
Failed on Cygwin.
* gzio.c (gzio_stream_s): Variable defined here.
* gzio.h (gzio_stream_s): Turn to declaration with extern.
|
|
|
|
|
|
|
|
|
|
| |
* buf.c (buf_compress): Let's use the level value of -1
if not specified, so Zlib defaults it to 6, or whatever.
* tests/012/buf.tl: New tests.
* txr.1: Note that -1 is a valid level value and that
is the default.
|
|
|
|
| |
* tests/018/gzip.tl: New file.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Instead of trying to work the new count parameter into the spl and
tok functions, it's better to make new ones.
* eval.c (eval_init): spln and tokn intrinsics registered.
* lib.[ch] (spln, tokn): New functions.
* tests/015/split.tl: New test cases.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Update registration of tok-str.
* lib.c (tok_str): New argument, count_opt. Implemented
in the compat 155 case; what the heck.
(tok): Pass nil to new parameter of tok_str.
* lib.h (tok_str): Declaration updated.
* tests/015/split.tl: New tests.
* txr.1: Documented.
|
|
|
|
| |
* gzio.c (gzio_stream_print, gzio_get_prop): Remove unused locals.
|
|
|
|
|
|
|
|
|
| |
* buf.c (buf_compress, buf_decompress): New static functions.
(buf_init): buf-compress and buf-decompress intrinsics registered.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
| |
* buf.c (utf8_dup_to_buf): stray declaration removed.
|
|
|
|
|
|
|
|
| |
* tags.tl: File renamed to txrtags.tl.
* libtags.txr: load "txrtags" rather than "tags". And here is where
we can explain the problem being fixed: (load "tags") loads the
actual tags file, if it already exists, and not tags.tl.
|
|
|
|
|
|
| |
* stream.c (se_putc): Remove a workaround for a Cygwin bug that was
fixed in 2016 in 2.5.0. Here is the mailing list thread:
https://sourceware.org/pipermail/cygwin/2016-March/226554.html
|
|
|
|
|
| |
* txr.1: In all places that mention .tlo in relation to loading,
mention support for .tlo.gz suffix.
|
|
|
|
|
|
| |
* parser.c (open_txr_file): If a file ends in .tlo.gz,
open a gzio stream on it. Also search for .tlo.gz if
.tlo is not found.
|
|
|
|
|
| |
* gc.c (mark_obj_maybe): Avoid declaration after statement,
which is enforced when configured in --maintainer mode.
|
|
|
|
|
|
| |
* gzio.c (gzio_stream_print): New static function.
(gzio_ops_rd, gzio_ops_wr): Wire in function instead of
stream_print_op.
|
|
|
|
|
|
| |
* gzio.c (gzio_get_prop): Don't play games with a computed :name;
this property is relied upon for getting the path associated
with an open file.
|
|
|
|
|
| |
* txr.1: Document the "z" option letter, its optional digit arg,
and the restrictions.
|
|
|
|
|
|
|
| |
* gzio.c (gzio_get_prop, gzio_set_prop): Handle :byte-oriented
symbol, connecting it to the is_byte_oriented flag.
This is already implemented, by copy and paste from the
stdio routines.
|
|
|
|
|
| |
* gzio.c (struct gzio_handle): Remove is_real_time flag.
(make_gzio_stream): Remove initialization of flag.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is motivated by the desired to be able to
specify gzip compression: e.g.
(file-put-string "file.gz" "abc" "z")
However, it has other uses. For instance with "x",
we can exclusively create a file with content in one
call.
* stdlib/getput.tl (file-get, file-put, file-append,
file-get-string, file-put-string, file-append-string,
file-put-lines, file-append-lines, file-get-buf,
file-put-buf, file-place-buf, file-append-buf, file-get-json,
file-put-json, file-append-json, file-get-jsons,
file-put-jsons, file-append-jsons): New option argument
which combines with the open-file mode.
* txr.1: Documented.
|
|
|
|
|
| |
* stream.c (open_fileno): Use w_gzdopen_mode and make_gzio_stream
to make a gzio stream if the gzip flag is present.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* gzio.c (w_gzopen_mode): Use w_open_mode if available, in order
to support most of the flags (including "x" which Zlib has,
but which we are not passing through).
* stream.c (w_open_mode): New function formed from w_fopen_mode
content.
(w_fopen_mode): Call w_open_mode.
* stream.c (w_open_mode): Declared.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Makefile (OBJS): Conditionally include new gzio.o object file.
* configure: Detect external zlib, setting up new have_zlib
variable in config.make, HAVE_ZLIB in config.h, and also -lz
in conf_ldlibs.
* gzio.[ch]: New files, implementing the stream abstraction
over the gzip file I/O routines in zlib.
* stream.h (struct stdio_mode): New gzip flag and gzlevel
bitfield to hold a value 0 to 9.
(stdio_mode_init_blank, stdio_mode_init_r, stdio_mode_init_rpb):
Update intializers to cover new bitfield members.
* stream.c: Include <zlib.h> and "gzio.h" if HAVE_ZLIB.
(do_parse_mode): Recognize new mode modifier letter "z",
setting the gzip flag in the mode structure. If it's followed
by a digit, set the gziplevel to that value.
(format_mode): Don't output "b" letter for binary mode if
gzip is set, because gzopen interprets "b" differently.
Don't put out "t" if gzip is set. If gzip mode is specified,
do put out the level. If gzip is set, and gziplevel is nonzero
then encode the level: gzopen will understand it.
(open_file): If gzip mode is requested, then open the file
using gzopen mode, a new function in gzio.c. The return a
gzio stream based on the returned gzip file handle. However,
if we are reading, and the gzip stream indicates that it's
not decompressing anything, then we close it and open the
file using an ordinary stream.
(stream_init): Call gzio_init if HAVE_ZLIB is true. This is done
here because the module is integrated with stream.c, and also
so that lib.c doesn't have to know about HAVE_ZLIB and <zlib.h>.
|
|
|
|
|
|
| |
* stream.c (normalize_mode): Include the self symbol in the
error message being thrown. This was not forgotten in the
sister function normalize_mode_no_bin.
|
|
|
|
|
|
| |
* stream.c (stdio_set_prop): When setting the :name property,
return t, to indicate it was recognized and stored, as is
documented.
|
|
|
|
|
| |
* stream.c (stdio_maybe_read_error): Access errno once, and
refer to the value.
|
|
|
|
|
|
| |
* configure: do not treat the failure to detect mmap as
a fatal condition. This was just debugging commands accidentally
left behind.
|
|
|
|
|
|
| |
* tests/019/load-search.tl: skip a certain test if it is run as
superuser; it fails because superuser is not affected by denied
directory search and execute permissions.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure (txr_ver): Bumped version.
* stdlib/ver.tl (lib-version): Bumped.
* txr.1: Bumped version and date.
* txr.vim, tl.vim: Regenerated.
* protsym.c: Likewise.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We've already taken care of imitating the situation that GNU
C allows __attribute__((aligned(n))) to weaken the alignment
of a bitfield, contrary to it being documented that align only
strengthens alignment. Even a value of n == 1 is meaningful
in that it can cause the bitfield to start allocating from
a new byte.
This patch corrects a newly discovered nuance: when a bitfield
is attributed with a weaker alignment than its underlying
type (e.g. uint32_t field marked with 2 byte alignment),
the original type's alignment is still in effect for calculating
the alignment of the structure, and the padding.
* ffi.c (struct txr_ffi_type): New member oalign, for keeping
track of the type's original alignment, prior to adjustment.
(make_ffi_type_struct): For a named bitfield, take the oalign
value into account when determining the most strict member
alignment.
(ffi_type_compile): When marking a type as aligned, the
we remember the original alignment in atft->oalign.
* tests/017/bitfields.tl: New test case, struct s16.
* txr.1: Documented.
|
| |
|
|
|
|
|
| |
* txr.1: pack with alignment values greater than 1 doesn't
directly correspond to a single GNU C feature.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (make_ffi_type_struct): Add check for impossible condition.
The bits_alloc variable could only exceed bits_type (and thus
cause the room variable to have a nonsensical, large value)
if the bitfield allocation tried to continue allocating bits into
an aligned unit, whose alignment exceeds the size of the underlying
type. But in that case, tft->aligned would have to be true, and
so the offset would have been aligned prior to this code, rendering
bits_alloc zero.
* tests/017/bitfields.tl: New tests.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* struct.c (alloc_seen): Fix under-sized alloca and memset,
where the size being used is the number of elements,
but should be the number of bytes. This showed up as a
failure in the tests/012/oop-mi.tl on PPC64, uncovered by
a completely unrelated change in eval.c. The unrelated code
never executes during the failed test case; it just affects
some memory contents of the stack somehow. The under-allocated
array is used during structure type initialization to hold
a bitmask which helps to suppress the duplicate initiation of
base structures which are inherited multiple times (duplicate
bases). I think why this shows up on PPC64 is the big endian
order. The sizes involved are small. The test case has a couple
of duplicate bases only, but a full 64 bit mask needs to be
allocated for that since the mask is an array of ucnum. On
little endian, it doesn't matter than only a single byte is
allocated: that is enough for 8 duplicate bases, and because of
the byte order, those bases land into the byte that is allocated.
On big endian, the bases will be on the high part of the 64
bit word, and thus over in the area we didn't allocate.
To reproduce an issue on little endian, you need an inheritance
hierarchy with more duplicate bases.
|
|
|
|
|
|
| |
* ffi.c (swap_get32, swap_put32, swap_get64, swap_put64):
correct implementations for operating on little-endian
words on big endian.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The bitfield allocation rules are wrong. Some of it is due
to the recent changes which are based on incorrect analysis,
but reverting things doesn't fix it.
The idea that we compare the current member's alignment
with the previous is wrong; it is not borne out by empirical
tests with gcc. So we do a straight revert of that.
In GNU C, an __attribute__((aligned (N))) attribute applied
to a bitfield member will perform the requested alignment if,
evidently, the bit field is already being placed into a new
byte. (If the bit field is about to be packed into an existing
byte, then there is a warning about the align attribute being
ignored). Because we don't have alignment as a member attribute,
but only as a type attribute, we must implement a flag which
indicates that a type has had align applied to it (even if
the alignment didn't change) so we can then honor this in the
right place in the bitfield allocation code.
* ffi.c (struct txr_ffi_type): New attribute flag, aligned.
(make_ffi_type_struct): Remove the prev_align variable and
all related logic. Consolidate all alignment into one place,
which is done before we allocate the bitfield or regular member.
We align if the new member isn't a bitfield, or even if it is
a bitfield if it has the aligned attribute, or if the bitfield
is changing endian compared to the previous member (our local
rule, not from GNU C).
(ffi_type_compile): The align and pack operators now set the
aligned attribute, except in the (pack 1 ...) case which
semantically denotes lack of alignment.
* tests/017/bitfields.tl: New file.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is very nice: you can now declaratively match a structure
that uses bitfields, and comes from a different endian system.
* ffi.c (ffi_kind_t): Replace FFI_KIND_NUM type with FFI_KIND_INT,
FFI_KIND_UINT and FFI_KIND_FLO. Now using the tft->kind value,
we can distinguish integer and floating types, and determine
signedness.
(struct txr_ffi_type): New flag, bigendian, which is set to 1
for all big types that are big endian. This is not just the endian
types like be-int32, but natural types like int, if the underlying
platform is big endian.
(swap_get32, swap_put32, swap_get64, swap_put64): New static functions.
(ffi_generic_swap_fat_ubit_put, ffi_generic_swap_fat_sbit_put,
ffi_generic_swap_fat_ubit_get, ffi_generic_swap_fat_sbit_get,
ffi_generic_swap_ubit_put, ffi_generic_swap_sbit_put,
ffi_generic_swap_ubit_get, ffi_generic_swap_sbit_get): New
static functions.
(ffi_make_type_builtin): On big endian, set the bigendian flag on every
type. For the endian types, this will get adjusted as an additional
construction step.
(make_ffi_type_endian): New static function. Calls ffi_make_type_builtin,
and then initializes the bigendian flag with the given value.
(make_ffi_type_struct, make_ffi_type_union): Because bitfields can
have endiannness now, we can no longer refer to the machine's own
endianness in laying them out; we have to look at the mtft->bigendian
value. Furthermore, we need an additional rule: when a bitfield member
follows a member that has different endian, a new allocation unit
has to begin.
(ffi_type_compile): the sbit and ubit types must set the type to
FFI_KIND_INT and FFI_KIND_UINT now. For the big operator, we can
simplify the error checking: instead of exhaustively comparing the
type to all the supported integer types, we just now check whether
it is FFI_KIND_INT or FFI_KIND_UINT. Here, if we detect that an
endian bitfield has opposite byte order from the machine, then we
instantiate the bitfield with the ffi_generic_swap_* virtual
functions. These perform the required byte swapping accesses to
the bitfield storage cells, so then the bit field manipulation
code just works using the local integer representation (shifting
and masking). Of course, the shift amount depends on the endian;
and that is calculated at type creation time in make_ffi_type_struct.
(ffi_init_types): Replace FFI_KIND_NUM with the appropriate constant
for each affected type. In some cases, we have to calculate whether
to use the INT or UINT one, for the types whose signedness is
not specified. We switch all the endian types to new constructor
make_ffi_type_endian, passing the required value of the bigendian
flag.
* txr.1: Documented.
|
|
|
|
|
|
|
| |
* ffi.c (make_ffi_type_struct, make_ffi_type_union): We must
take fat bitfields into account when calculating mtft->shift
on big endian. We must subtract from bits_llint not bits_int
for big endian.
|
|
|
|
|
|
|
|
|
| |
* ffi.c (ffi_init_types): The be-float, be-double, le-float and
le-double types wrongly have integer indicated as their Lisp
type symbol; it should be float. This doesn't fix any actual bug;
the Lisp type is only important for structures/unions. The
conversion of be-double is driven by the behavior of the type's
virtual functions, which don't look at the Lisp type symbol.
|