| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure, txr.1: Bumped version and date.
* share/txr/stdlib/ver.tl: Likewise.
* txr.vim, tl.vim: Regenerated.
|
|
|
|
|
|
|
|
|
| |
On 64 bit Darwin, sigset_t is 32 bits, sso our small_sigset_t is
actually larger. Let's use unsigned int.
* signal.h (small_sigset_t): Use unsignd int for set member.
* signal.c (small_sigfillset): Change cast to unsigned int.
|
|
|
|
|
|
|
|
|
|
|
| |
* unwind.c (revive_cont): Don't just reserve frame_slack
bytes below the continuation for any stack frame, but
clear the bytes to zero. On Cygwin, this fixes a failing
continuation test case. The issue is that the cont_obj
variable in capture_cont lands into this area (implying
it is not captured). When the continuation is revived,
the variable has a garbage value, rather than nil,
as expected.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When continuations are captured/restored in the middle of
variable binding constructs, a hidden problem occurs.
Binding constructs work by allocating an empty environment
and then destructively extending it. Since the environment
is not on the stack, but a referenced object, it doesn't
get deep copied into a continuation. As the continuation is
revived repeatedly, parts of the variable binding code are
repeatedly re-executed, and keep pushing fresh bindings into
the same environment object. Though the new bindings
correctly shadow the old, the old bindings are there and
potentially hang on to garbage.
The solution taken here is to introduce a new kind of frame
for handling the situation: a continuation copy handling
frame. This frame allows functions to register objects to
be copied more deeply if a continuation is captured/revived
across them.
* eval.c (copy_env): New static function.
(copy_env_handler): New static function.
(bind_args, bind_macro_params): Install continuation copy
handling frame for cloning new_env.
(struct bindings_helper_vars): New struct type.
(copy_bh_env_handler): New static function.
(bindings_helper): Install continuation copy handling frame
for de and ne variables which hold environments. The variables
are moved to a struct to facilitate access from the handler.
* eval.h (copy_env): Declared.
* unwind.c (uw_push_cont_copy): New function.
(call_copy_handler): New static function.
(revive_cont): When a continuation is being revived invoke the
copying actions in its continuation copy handling frames,
but not if it is only being temporarily revived for immediate
unwinding.
(capture_cont): After copying the continuation, invoke any
continuation copying frames in the "parent": the original
frames that were captured.
* unwind.h (enum uw_frtype): New type, UW_CONT_COPY.
(struct uw_cont_copy): New struct type.
(union uw_frame): New member cp.
(uw_push_cont_copy): Declared.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/yield.tl (sys:rcv-item): New struct type.
(sys:obtain-impl): Handle rcv-item, produced by a no-argument
yield-from, which requests an immediate resumption with
the previously given resume value. The reply value
is renamed the resume value.
(yield-from, yield): Form argument is optional.
* txr.1: Rewrote obtain and yield documentation with
lesser focus on implementation and greater focus on
abstract semantics.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (set_dyn_env): Static function becomes external.
* eval.h (set_dyn_env): Declared.
* match.c (eval_with_bindings, eval_progn_with_bindings):
Evaluate Lisp code in null lexical environment. Instead
install the pattern variables as dynamic, so they shadow
global variables. A compatibility check for 121 or earlier
provides the old behavior.
* txr.1: Document scoping rules, and added compatibility
notes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We only need to stash the TXR matcher's context in an
environment frame when there is the possibility that
Lisp code may be called, or filters which re-enter
the matcher directly or through Lisp code.
* match.c (eval_with_bindings, eval_progn_with_bindings): New
static functions.
(dest_bind): Use eval_with_bindings instead of five lines
of boilerplate code.
(h_chr): No need to stash context around dest_bind;
lower levels take care of it.
(subst_vars): Do set up match context around the body
of this function, for the sake of Lisp calls and filtering
in format_field. Use eval_with_bindings.
(do_txeval): Remove match context environment frame setup
around subst_vars. Use eval_with_bindings, too.
(do_output_line): Use eval_with_bindings.
(v_output): No match context environment frame around
do_output.
(v_do, v_require): Use eval_progn_with_bindings instead of
five line boilerplate.
(v_line): No match context frame around dest_bind.
(h_do): Use eval_progn_with_bindings.
|
|
|
|
|
|
| |
* tests/012/cont.tl (amb-scope): New macro.
(amb): New function.
New test case using amb.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* unwind.c (revive_cont): Don't wrap cons cell around
passed arg; just pass it directly. We don't need
that convention any more.
* capture_cont: Take functional argument. Pass the captured
continuation to the function. If the function returns,
return whatever it returned. When resuming, return the
continuation argument.
(uw_capture_cont): Take functional second argument
and pass to capture_cont. Context form becomes third
argument.
(uw_late_init): Update registration of sys:capture-cont
to three arguments, two required.
* unwind.h (uw_capture_cont): Declaration updated.
* share/txr/stdlib/yield.tl (sys:yield-impl): Not
needed any more; all this was doing was implementing
a call/cc style interface around sys:capture-cont
which can now be used directly.
(yield-from): Use sys:capture-cont directly.
(suspend): Simplified to the point of triviality
with new sys:capture-cont.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register intrinsic functions rcons,
rangep from and to.
(eval_init): Register rangep intrinsic.
* gc.c (mark_obj): Traverse RNG objects.
(finalize): Handle RNG in switch.
* hash.c (equal_hash, eql_hash): Hashing for for RNG objects.
* lib.c (range_s, rcons_s): New symbol variables.
(code2type): Handle RNG type.
(eql, equal): Equality for ranges.
(less_tab_init): Table extended to cover RNG.
(less): Semantics defined for ranges.
(rcons, rangep, from, to): New functions.
(obj_init): range_s and rcons_s variables initialized.
(obj_print_impl): Produce #R notation for ranges.
(generic_funcall, dwim_set): Recognize range objects for indexing
* lib.h (enum type): New enum member, RNG. MAXTYPE redefined
to RNG value.
(TYPE_SHIFT): Increased to 5 since there are now 16 type
codes.
(struct range): New struct type.
(union obj): New member rn, of type struct range.
(range_s, rcons_s, rcons, rangep, from, to): Declared.
(range_bind): New macro.
* parser.l (grammar): New rule for recognizing
the #R sequence as HASH_R token.
* parser.y (HASH_R): New terminal symbol.
(range): New nonterminal symbol.
(n_expr): Derives the new range symbol.
The n_expr DOTDOT n_expr rule produces rcons expression rather
than const.
* match.c (format_field): Recognize rcons syntax in fields
which is now what ranges translate to. Also recognize range
object.
* tests/013/maze.tl (neigh): Fix code which destructures
range as a cons. That can't be done any more.
* txr.1: Document ranges.
|
|
|
|
| |
* txr.1: Compatibility -> COMPATIBILITY
|
|
|
|
|
|
|
|
|
|
| |
* lisplib.c (yield_set_entries): Added "suspend" to
end of name.
* share/txr/stdlib/yield.tl (suspend): New macro.
* txr.1: Documented suspend. Replaced subtly incorect
shift/reset implementation example with suspend implementation.
|
|
|
|
|
|
| |
* jmp.S (jmp_save, jmp_restore): Add PPC64 versions.
* signal.h (struct jmp): Add PPC64 version.
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure, txr.1: Bumped version and date.
* share/txr/stdlib/ver.tl: Likewise.
* txr.vim, tl.vim: Regenerated.
|
|
|
|
| |
* txr.1: Improperly terminated .cblk.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/yield.tl (sys:obtain-impl): Pass
sys:cont-free symbol to each abandoned continuation
to release its stack buffer.
(obtain): Handle the sys:cont-free symbol in the
lambda, so the initial lambda can be treated
uniformly with continuation functions.
* txr.1: Documented sys:obtain-impl.
* unwind.c (sys_cont_free_s): New symbol variable.
(cont_mark): Check for null stack pointer and avoid marking.
(revive_cont): If arg is sys:cont-free, then free the
continuation and return nil. If the continuation has a null
stack buffer, throw an error.
(uw_late_init): Initialize sys_cont_free_s.
|
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/yield.tl (sys:obtain-impl): Add a finalizer
to the returned closure which will feed sys:cont-poison object
to the most recently captured continuation. Thus abandoned
obtain blocks which have become garbage shall have their
unwinding performed.
* txr.1: Documented the finalization behavior.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* unwind.c (sys_cont_poison_s): New symbol variable.
(revive_cont): If the argument is the poison symbol, then
unwind through the continuation all the way back to
revive_cont's own block, instead of to the continuation's very
top block. Thus the continuation is not restarted but
completely unwound.
(uw_late_init): Initialize sys_cont_poison_s.
* txr.1: Documented sys:cont-poison.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (sys_abscond_from_s): New symbol variable.
(op_abscond_from): New static function.
(do_expand): Handle abscond-from like return-from.
(eval_init): Initialize sys_abscond_from_s and
register sys:abscond-from operator.
* share/txr/stdlib/yield.tl (yield-from): Use
sys:abscond-from instead of return-from, to avoid
tearing down the continuation's resources that it may
need when restarted.
* txr.1: Documented sys:abscond-from and added
a mention to the Delimited Continuations introduction.
* unwind.c (uw_abscond_to_exit_point): New static function.
(uw_block_abscond): New function.
* unwind.h (uw_block_abscond): Declared.
|
|
|
|
|
|
| |
* txr.1: Some wording changes and dialect note that
flet and labels do not genearate implict named
blocks in the function bodies.
|
|
|
|
|
|
|
|
|
|
|
| |
The C code doesn't call hash_next once it returns nil,
so it doesn't matter that doing so will dereference
a null pointer. But hash_next is now exposed as
the Lisp function hash-next.
* hash.c (hash_next): If the hash table in the iterator
is nil, then return nil, avoiding the dereference of
a null pointer.
|
|
|
|
|
|
|
| |
* lisplib.c (hash_set_entries): Change with-hash-table-iter
to with-hash-iter.
* txr.1: Likewise.
|
|
|
|
|
|
| |
* tests/012/cont.tl: New file.
* tests/012/cont.expected: New file.
|
|
|
|
|
|
|
|
|
|
|
| |
* lisplib.c (yield_set_entries, yield_instantiate):
New static functions.
(dlt_register): Registered new functions.
* share/txr/stdlib/yield.tl: New file.
* txr.1: Documented obtain, yield-from, obtain-block
and yield.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* unwind.c (sys_capture_cont_s): New variable.
(uw_capture_cont): Second argument is now a context
form rather than a symbol; eval_error is used for error
reporting. The form's operator symbol si used in the
error message, or else sys:capture-cont if the
context argument is null or missing.
(uw_late_init): Initialize sys_capture_cont_s.
* unwind.h (uw_capture_cont): Declaration updated.
* txr.1: Documented.
|
|
|
|
|
|
| |
* eval.c (eval_error): Static function made external.
* eval.h (eval_error): Declared.
|
|
|
|
|
|
| |
* lib.h (noreturn): Defined here.
* unwind.h (noreturn): Removed from here.
|
|
|
|
|
|
|
|
| |
* eval.c (form_k): New keyword symbol variable.
(bind_macro_params): Implement form_k.
(eval_init): Initialize form_k.
* txr.1: Documented :form parameter.
|
|
|
|
|
|
|
|
|
|
|
| |
Expansion of places now gives priority to place macros.
Moreover, it iterates over place macro and ordinary macro
expansion.
* share/txr/stdlib/place.tl (sys:trigger-load): Removed.
(sys:pl-expand): Rewritten.
* txr.1: Documented.
|
|
|
|
|
|
|
| |
* signal.c (mem_set_bits, mem_clr_bits): Static functions
removed.
(sig_mask): Operate on set member of small_sigset_t directly
rather than as an array of bytes.
|
|
|
|
|
| |
* struct.c (make_struct_type): Don't use nullptr identifier
as variable name.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
On glibc, sigset_t has a ridiculous size: one kilobyte!
The kernel doesn't access most of it in the sigprocmask call.
Yet it blows up the size of our dynamic frames quite a lot.
In this commit, we define a small_sigset_t type and
use that instead. We convert to the bloated one when
calling the library.
* signal.c (sig_blocked_cache): Type changes to small_sigset_t.
(sig_reload_cache): Retrieve signal mask with sigprocmask into a local
variable, then copy a small portion from that to sig_blocked_cache.
(small_sigfillset): New static function.
(set_sig_handler): Local variables of sigset_t changed to small_sigset_t.
(sig_mask): Arguments are pointers to small_sigset_t. Conversion to
sigset_t done around the call to sigprocmask.
* signal.h (copy_sigset): Inline funtion removed.
(small_sigset_t): New struct type.
(extended_jmp_buf): Member blocked changed to small_sigset_t.
(extended_setjmp): Cast expression updated with small_sigset_t *.
(extended_longjmp): Use assignment instead of copy_sigset.
(sig_blocked_cache, sig_mask): Declarations updated.
|
|
|
|
|
|
|
|
|
|
| |
On startup, the history is trimmed to 100 lines regardless of
the variable's value in the profile file.
* parser.c (repl): Load the rc file first, then load the
history file. Furthermore, call lino_hist_set_max_len
between these operations with the latest value pulled
from the *listener-hist-len* variable.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The issue is that captures from within a restarted
continuation of the same continuation, are using the
restart prompt as the delimiter rather than re-using
captured block of the same name. Thus each successive
capture adds a new frame, causing the size to grow
drastically.
* unwind.c (uw_capture_cont): Allow the existing captured
block to be the delimiter; don't delimit up to
the revive_cont's prompt block of the same name.
|
|
|
|
|
|
|
|
|
|
| |
Without this we don't properly capture some of the context in
some built-in special operator functions like op_for when we
capture up to their implicit blocks.
* unwind.c (capture_cont): Capture an extra region of the
stack above the delimiting block. 32 words seems like a
reasonable fudge value.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* unwind.c (sys_cont_s): New symbol variable.
(uw_pop_block): New function, supporting uw_block_end macro.
Special logic is needed for popping blocks now, because a
block can be a captured stub at the top of a continuation,
which must not be popped in the
regular manner.
(struct cont): New struct type.
(cont_destroy, cont_mark): New static functions.
(cont_ops): New static structure.
(revive_cont, capture_cont): New static functions.
(uw_capture_cont): New functions.
(uw_init): Initialize sys_cont_s.
Register sys:capture-cont intrinsic.
* unwind.h (enum uw_frtype): New enum member
UW_CAPTURED_BLOCK. When a block is captured as a stub copy of
the prompt block of a delimited continuation, its type is
changed from UW_BLOCK to this new type. This does two things:
it makes the block invisible to block-related code that does
nothing with continuations (code that looks for UW_BLOCK
and ignores anything else). Secondly, there is some special
handling related to UW_CAPTURED_BLOCK frames.
(uw_pop_block, uw_capture_cont): Declared.
(uw_block_begin): New local pointer uw_rslt introduced
which helps communicate the result variable over to the
uw_block_end macro (so we don't have to add a variable
argument to the latter).
(uw_block_end): Use uw_pop_block instead of uw_pop_frame.
* txr.1: Documented delimited continuations.
|
|
|
|
| |
* share/txr/stdlib/place.tl (zap): Missing second argument.
|
|
|
|
|
|
| |
* gc.c (gc_mark_mem): New function.
* gc.h (gc_mark_mem): Declared.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
TXR is moving to custom assembly-language routines.
This is mainly motivated by a very dubious thing done in the
GNU C Library setjmp and longjmp in the name of security.
Evidently, glibc's setjmp "mangles" certain pointer values
which are stored into the jmp_buf buffer. It's been that way
since 2005, evidently. This means that, firstly, all along,
the use of setjmp in gc.c to get registers into a buffer so
they can be scanned has not actually worked properly. More
importantly, this pointer mangling in setjmp and longjmp is
very hostile to a stack copying implementation of delimited
continuations. The reason is that continuations contain
jmp_buf buffers, which get relocated in the process of
capturing and reviving a continuation. Any pointers in a
jmp_buf which point into the captured stack segment have to be
fixed up to point into the relocated location. Mangled
pointers make this difficult, requiring hacks which are
specific to glibc and the machine architecture. We might as
well implement a clean, well-behaved setjmp and longjmp.
* Makefile (jmp.o): New object file.
(dbg/%.o, opt/%.o): New rules for .S prerequisites.
* args.c, arith.c, cadr.c, combi.c, cadr.c, combi.c, debug.c,
eval.c, filter.c, glob.c, hash.c, lib.c, match.c, parser.c,
rand.c, regex.c, signal.c, stream.c, struct.c, sysif.c,
syslog.c, txr.c, unwind.c, utf8.c: Removed <setjmp.h>
include.
* gc.c: Switch to struct jmp and jmp_save, instead
of jmp_buf and setjmp.
* jmp.S: New source file.
* signal.h (struct jmp): New struct type.
(jmp_save, jmp_restore): New function declarations
denoting assembly language routines in jmp.S.
(extended_jmp_buf): Uses struct jmp instead of
setjmp.
(extended_setjmp): Use jmp_save instead of setjmp.
(extended_longjmp): Use jmp_restore instead of
longjmp.
|
|
|
|
|
|
| |
* eval.c (apply, do_eval): Use ARGS_MIN instead of ARGS_MAX.
* unwind.c (uw_throw): Ditto, when invoking handler.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* configure: Test for ftruncate and chsize.
* stream.c (unimpl_truncate): New static function.
(fill_stream_ops): Default the truncate operation to unimpl_truncate.
(null_ops): Initialize truncate to unimpl_truncate.
(stdio_truncate): New static function.
(stdio_ops, tail_ops): Initialize truncate to stdio_truncate.
(pipe_ops, dir_ops, string_ops, byte_in_ops, string_out_ops,
strlist_out_ops, cat_stream_ops): Initialize truncate to null,
so it gets defaulted by fill_stream_ops.
(truncate_stream): New function.
(stream_init): Register truncate-stream intrinsic.
* stream.h (struct strm_ops): New member, truncate.
(strm_ops_init): New truncate argument added to macro.
(truncate_stream): Declared.
*syslog.c (syslog_strm_ops): Initialize truncate to null.
* txr.1: Documented.
|
|
|
|
|
| |
* stream.c (unimpl_seek): Function should identify itself
as seek-stream, not seek.
|
|
|
|
|
| |
* txr.1: mention defmeth in Structures intro plus
a number of wording changes and corrections.
|
|
|
|
|
| |
* txr.1: Bad syntax formatting in defmeth.
Missing .desc under with-objects.
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure, txr.1: Bumped version and date.
* share/txr/stdlib/ver.tl: Likewise.
* txr.vim, tl.vim: Regenerated.
|
|
|
|
|
| |
* parser.c (repl): Missing nao terminator in format
call which computes expression name.
|
|
|
|
|
|
|
|
| |
* stream.c (formatv): New 'b' case along side 'o', handling
binary in straightforward way for bignums, and with binary
formatting loop code for fixnums.
* txr.1: Documented b.
|
|
|
|
|
|
|
|
| |
* struct.c (make_struct_type): Use chk_manage_vec
for initial allocation of static slot array.
(static_slot_ensure): Use chk_manage_vec to grow
the array when adding a slot. The function will
automatically double the array in power of two step sizes.
|
|
|
|
|
|
|
|
|
|
|
|
| |
This function manages a dynamic array using only the filled
size as input, while minimizing reallocations. The allocated
size is implicitly always the next power of two at or above
the filled size.
* lib.c (next_pow_two): New static function.
(chk_manage_vec): New function.
* lib.h (chk_manage_vec): Declared.
|
|
|
|
|
| |
* lib.c (chk_grow_vec): It is newelems which must be compared against
the no_oflow value, not bytes.
|