summaryrefslogtreecommitdiffstats
path: root/unwind.c
Commit message (Collapse)AuthorAgeFilesLines
* C99: get rid of useless inline instantiations.Kaz Kylheku2019-05-021-5/+0
| | | | | | | | | | | * hash.c, lib.c, parser.y, unwind.c: Remove useless declarations that were believed to be C99 inline instantiations. This was mistakenly added at the time the Solaris issue was discovered that _XOPEN_SOURCE values of 600 or greater require compiling in C99 mode. We use "static inline" under C99 for inline functions; instantiation is not applicable at all to inline functions that don't have external linkage.
* lib: more nuanced file access errors.Kaz Kylheku2019-05-011-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Several new more specific exception types are derived from file-error and used. Error handlers can distinguish unexpected non-existence, unexpected existence and permission errors from each other and other errors. * lib.c (path_not_found_s, path_exists_s, path_permission_s): New symbol variables. (obj_init): New variables initialized. * lib.h (path_not_found_s, path_exists_s, path_permission_s): Declared. * parser.c (open_txr_file): Use new errno_to_file_error function to convert errno to exception symbol. * socket.c (open_sockfd): Likewise. * stream.c (open_directory, open_file, open_fileno, open_command, open_process, run, remove_path, rename_path): Likewise, and process-error is used in open_process and run instead of file-error for problems related to creating the process. * sysif.c (errno_to_file_error): New function. (mkdir_wrap, ensure_dir, chdir_wrap, getcwd_wrap, mknod_wrap, chmod_wrap, symlink_wrap, link_wrap, readlink_wrap, stat_impl, umask_wrap, ): Use errno_to_file_error to convert errno to exception symbol. (exec_wrap): Use process-error instead of file-error. * sysif.c (errno_to_file_error): Declared. * unwind.c (uw_init): Register path-not-found, path-exists and path-permission as subtypes of file-error. * txr.1: Documented.
* debugger: expand frames.Kaz Kylheku2019-04-291-1/+39
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch adds special unwind frames for backtracing expansions. With this, we can get rid of the global variable last_form_expanded, since to get the last form expanded, we just search for the most enclosing expand frame. * eval.c (last_form_expanded): Global variable removed. (error_trace): Use uw_last_form_expanded() instead of last_form_expanded. (expand_eval): No need to save and restore last_form_expanded any more. (expand_lisp_setq, expand_setqf, expand_lisp1, do_expand): Use uw_last_form_expanded(). (expand, do_macroexpand_1): Push and pop expand frame. This fixes a bug: do_macroexpand_1 was not recording last_form_expanded. Evaluation of top-level forms uses explicit macroexpansion, therefore top-level evaluation was neglecting to set last_form_expanded. This explains weird behavior I saw in the listener from time to time, when errors would report against the expansion of the wrong form. (eval_init): Remove reference to last_form_expanded variable. * eval.h (last_form_expanded): Declaration removed. * share/txr/stdlib/debug.tl (expand-frame print-trace, expand-frame loc): New methods. (print-backtrace): Include uw-expand frames in the backtrace. * unwind.c (expand_frame_type): New static variable. (uw_find_frames_by_mask): Handle UW_EXPAND. (uw_last_form_expanded, uw_push_expand): New functions. (uw_late_init): Register expand-frame struct type. * unwind.h (enum uw_frtype): New enum member, UW_EXPAND. (uw_last_form_expanded, uw_push_expand): Declared.
* debugger: move uw-* symbols into sys package.Kaz Kylheku2019-04-291-9/+9
| | | | | | * unwind.c (uw_late_init): Move uw-block, uw-captured-block, uw-menv, uw-catch, uw-handle, uw-cont-copy, uw-guard, uw-fcall and uw-eval into the system package.
* debugger: eval frames.Kaz Kylheku2019-04-211-3/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We introduce evaluation tracking frames. The backtrace function can use these to deduce the line from which a function is called (if called from interpreted code). Eventually we will have analogous virtual machine frames to do this for compiled code. * eval.c (do_eval): If backtraces are enabled, then push and pop an eval frame, which holds the two key pieces: the form and environment. * share/txr/stdlib/debug.tl ((fcall-frame loc), (fcall-frame print-trace), (eval-frame loc), (eval-frame print-trace)): New methods. (print-backtrace): Loop reduced to just dispatching frame-specific print-trace methods. It gives the previous and next frame to each method. The (fcall-frame print-trace) method prints function frames, using the previous form to deduce the location from which the function is called. The (eval-frame print-trace) method mostly suppresses the printing of eval frames. We print an eval frame if it is the parent of an internal function frame, and if it is the topmost frame (to identify the toplevel form at the root of the backtrace). * unwind.c (form_s): New symbol variable. (eval_frame_type): New static variable. (uw_find_frames_by_mask): Handle UW_EVAL case, producing eval-frame struct. (uw_push_eval): New function. (uw_late_init): Allocate eval-frame struct type, storing it in eval_frame_type, and gc-protect that new variable. Register uw-eval variable evaluating to a one bit mask with the UW_EVAL-th bit set. * unwind.h (enum uw_frtype): New enum constant UW_EVAL. (struct uw_eval): New struct type. (union uw_frame): New member, el. (uw_push_eval): Declared.
* unwind: use allocate-struct in frame reification.Kaz Kylheku2019-04-201-10/+6
| | | | | | | | | | * struct.c (allocate_struct): Changed from internal to external linkage. * struct.h (allocate_struct): Declared. * unwind.c (uw_get_frames, uw_find_frames_by_mask): Use allocate_struct instead of make_struct.
* debugger: initial backtrace support.Kaz Kylheku2019-04-161-0/+98
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * debug.c (debug_state): Switch to unsigned, since this is now a bitmask. (sys_print_backtrace_s): New symbol variable. (dbg_clear, dbg_set, dbg_restore): New static functions. (debug_init): Initialize sys_print_backtrace_s. Register dbg-clear, dbg-set, dbg-restore intrinsics. Register dbg-enable, dbg-step, dbg-backtrace and dbg-all bitmask variables, Lisp equivalents of DBG_ENABLE, DBG_SETP, DBG_BACKTRACE and DBG_ALL. (debug_dump_backtrace): New function. * debug.h (opt_debugger): Declaration removed. (debug_state): Declaration updated. (DBG_ENABLE, DBG_STEP, DBG_BACKTRACE, DBG_ALL): New preprocessor symbols. (debug_set_state): Inline function removed. (debug_clear, debug_set, debug_restore): New inline functions. (dbg_backtrace, dbg_fcall_begin, dbg_fcall_end): New macros. (debug_dump_backtrace): Declared. * eval.c (error_trace): Invoke debug_dump_backtrace if support is compiled in and backtraces are enabled. * lib.c (do_generic_funcall): New function, copy of generic_funcall. (generic_funcall): Now a wrapper for do_generic_funcall which registers fcall frames if backtrace support is enabled. (funcall, funcall1, funcall2, funcall3, funcall4): Route to slow generic_funcall path if backtraces are enabled. * lisplib.c (debugger_instantiate, debugger_set_entries): New static functions. (lisplib_init): Autload support for debug module via above new functions. (lisplib_try_load): Save and restore debugger state in new way using debug_set and debug_restore, with specific mask values. * parser.y (parse_once): Disable debugging in new way. * share/txr/stdlib/debug.tl New file. * sighal.h (EJ_DBG_MEMB, EJ_DBG_SAVE, EJ_DBG_REST): New macros for saving/restoring debug state. (EJ_OPT_MEMB, EJ_OPT_SAVE, EJ_OPT_REST): Reference the above macros to include debug state in extended jump context. * txr.c (help): Document --backtrace and that that -d implies --backtrace. (txr_main): Enable debugger using debug_set. Provide new --backtrace option to enable backtraces only. * unwind.c (args_s): New symbol variable. (fcall_frame_type): New static variable. (unwind_to_exit_point): Save pointer to original frame stack and restore it when calling error_trace. This is so that error_trace can walk the stack to collect a backtrace. (uw_find_frames_by_mask, uw_push_fcall): New functions. (uw_late_init): Initialize args_s and fcall_frame_type. gc-protect fcall_frame_type. Register uw-* variables corresponding to the UW_* frame types. * unwind.h (uw_frtype_t): New enum constant UW_FCALL. (struct uw_fcall): New frame structure. (union uw_frame): New member fc. (uw_push_fcall, uw_find_frames_by_mask): Declared.
* cmdline: use handler instead of catch for errors.Kaz Kylheku2019-04-161-0/+7
| | | | | | | | | | | | | | | | | | | Errors encountered when parsing or evaluating a source file should be handled using a handler rather than a catch, so that the unwind stack is available to the error reporting function. This anticipates being able to dump a backtrace. * txr.c (parse_once_noerr, read_eval_stream_noerr): Adjust to reduced argument count in ignerr_func_body macro. * unwind.c (uw_trace_error): New function. * unwind.h (uw_trace_error): Declared. (ignerr_func_body): Revised to establish a handler in addition to the catch. The catch now doesn't do anything other than provide an intercepting exit point; the error_trace call is moved into the handler, and so it executes in a context where unwinding hasn't happened yet.
* exceptions: allow description field in catch frames.Kaz Kylheku2019-04-101-4/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * eval.c (op_catch): Extra argument in sys:catch syntax specifies an expression that evaluates to a description field. (expand_catch): Expand the desc expression in sys:catch syntax. * parser.c (read_file_common): Increase acceptance of compiled files from versions 1-4 to 1-5, since we are now marking compiled files with version 5.0 rather than 4.0. * share/txr/stdlib/asm.tl (op-catch catch): Support new argument in the opcode syntax. Turns out we have a spare field in the instruction format which was previously set to zero We can use that for the description. Thus, the instruction set and VM remain backward compatible: old code works. * share/txr/stdlib/compiler.tl (compiler comp-catch): Handle the desc argument introduced into the sys:catch form. We must compile it as an expression, then inject the code into the instruction template, and reference the output register of that code block in the catch instruction. (%tlo-ver%): Bump up the compiled file version to 5.0. * share/txr/stdlib/except.tl (usr:catch, catch*): Add desc argument to generated sys:catch form, specifying it as nil. * unwind.c (desc_s): New symbol variable. (uw_find_frames_impl): Set the desc member of the extracted catch structure from the corresponding field in the catch frame. (uw_late_init): Initialize desc_s with interned symbol. Add desc slot to catch-frame type. * unwind.h (struct uw_catch): New member, desc. (uw_catch_begin_w_desc): New macro. * vm.c (vm_catch): Extract the desc field from the catch instruction, and use uw_catch_begin_w_desc to propagate that to the catch frame.
* debug support: crude debugger removed.Kaz Kylheku2019-04-091-17/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * debug.c (debug_depth, debug_quit_s): Variables removed. (step_mode, next_depth, breakpoints, last_command, cols): Static variables removed. (debug_check): C99 inline instantiation removed. (help, show_bindings): Static functions removed. (debug): Function removed. (debug_set_state): Now takes one int argument, returns int. It's anticipated that the new debug system will have a simple on-off switch; there won't be a debug_depth hack. (debug_restore_state): Function removed. (debug_init): Emptied. * debug.h (debug_depth, debug_state_t): Declarations removed. (debug_enter, debug_leave, debug_return): Macros removed. (debug_check): Inline function removed. (debug_set_state): Declaration updated. (debug_restore_state): Declaration removed. (debug_frame, debug_end): Macros removed. * eval.c (do_eval, me_interp_macro): Debugging support scrubbed. * lisplib.c (lisplib_try_load): Adapt to debug_set_state interface change. * match.c (h_fun, do_match_line, v_fun, match_files, match_fun): Debugging support scrubbed. * parser.y (parse_once): Adapt to debug_set_state interface change. * protsym.c: Regenerated. * signal.h (debug_depth): Declaration removed. (EJ_DBG_MEMB, EJ_DBG_SAVE, EJ_DBG_REST): Macros removed. (EJ_OPT_MEMB, EJ_OPT_SAVE, EJ_OPT_REST): Reduced to unconditionally empty definitions for future use. * unwind.c (uw_push_debug): Function removed. * unwind.h (uw_frtype_t): UW_DBG enum member removed. (struct uw_debug): struct declaration removed. (union uw_frame): db member removed. (uw_push_debug): Declaration removed. * txr.1: Debugger doc removed.
* unwind: rename env frames.Kaz Kylheku2019-04-061-15/+15
| | | | | | | | | | | | | | | | | | | | | | Unwind frames of type ENV exist for the sake of the pattern language. Let's rename them accordingly. * match.c (tleval, tleval_progn, h_fun, tx_subst_vars, v_bind, v_output, v_filter, v_fun): Occurrences of the macros uw_env_begin and uw_env_end are renamed. * unwind.c (uw_env_stack): Renamed to uw_menv_stack. (uw_unwind_to_exit_point, uw_abscond_to_exit_point, uw_find_env, uw_pop_frame, revive_cont): Follow rename of UW_ENV to UW_MENV and uw_env_stack to uw_menv_stack. (uw_push_env): Renamed to uw_push_match_env, and updated to follow renames. * unwind.h (enum uw_frtype, uw_frtype_t): UW_ENV renamed to UW_MENV. (uw_push_env): Renamed to uw_push_match_env. (uw_env_begin, uw_env_end): Renamed to uw_match_env_begin an uw_match_env_end.
* 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.
* 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-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* defvar: warn about prior lexical uses.Kaz Kylheku2018-10-261-0/+5
| | | | | | | | | | | | | | | | | | | Now that the compiler has a more efficient treatment of global lexical variables, code which accesses global variables that have not yet been defined will misbehave if the intent is to for those variables to be dynamically scoped. There is such a bug in the op expander, in fact. * eval.c (me_def_variable): When defvar/defparm are expanding, they now check whether there is an outstanding unbound warning against the variable. If so, then a warning is issued that the variable was previously used lexically and is now being marked special. * unwind.c (uw_warning_exists): New function. * unwind.h (uw_warning_exists): Declared.
* continuations: don't fixup pointers if delta is zero.Kaz Kylheku2018-03-291-1/+1
| | | | | | * unwind.c (revive_cont): If delta is zero, skip the loop. This is an important optimization. The delta zero case can occur frequently; I have observed it.
* vm: integrate with delimited continuations.Kaz Kylheku2018-03-291-2/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | It doesn't Just Work out of the box. Here is why. The struct vm state is declared somewhere on the stack, and then the vm executes various recursive functions. A block is established by vm_block(). Then if a continuation is captured up to that block, it will not include that part of the stack which holds the VM state. When the continuation is restarted, the struct vm * pointers inside the stack will be garbage. The solution: when a continuation is captured to a prompt that is set up by the VM block instruction (vm_block function), we put information into the block which says "don't just capture me plus some slack: please capture the stack all the way up to this specific address here". That address, of course, is just past the VM state, ensuring that the VM state is included in the snapshot. In short: a delimited continuation terminating in a prompt set up by the VM just include the entire VM context from the stack frame where the struct vm on down (i.e. up the stack) to the capture point. * unwind.c (uw_push_block): Initialize cont_bottom member to zero. Interpreted blocks leave this as zero. Blocks set up by the VM override it. (revive_cont): Critical: the range check must include the orig_end endpoint, because when the struct vm is captured into the continuation it is right at the end of the capture memory, and the prompt block's cont_bottom member points exactly to orig_end: one element past the struct vm. The cont_bottom member must be adjusted by delta so that continuations captured by the revived VM inside the continuation get the adjusted cont_bottom at their current stack location. (capture_cont): If the block is publishing a non-zer cont_bottom value, then take that value if it is a higher address than the lim (including the UW_CONT_FRAME_AFTER slack). * unwind.h (struct uw_block): New member, cont_bottom. By means of this, a block can indicate a higher address to which a continuation capture can extend. * vm.c (vm_block): Publish the address one byte past the virtual machine state as the stack bottom for continuations.
* unwind: better debugging of exceptions.Kaz Kylheku2018-03-121-0/+9
| | | | | | | | | | | | | | | Once upon a time when we didn't have continuable warning exceptions, it was easy to debug internal error throws in TXR: just set a breakpoint on uw_throw and catch it in the debugger. This approach became unworkable with uw_throw being executed numerous times as part of the ordinary program control flow. With this change, we get that debugging experience back. * unwind.c (uw_break_on_error): New static variable. (uw_throw): If the break-on-error variable is set and we are processing an exception derived from error, then call the breakpt function.
* 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.
* Use rplaca and rplacd instead of set over car_l/cdr_l.Kaz Kylheku2018-01-011-1/+1
| | | | | | | | | | | | | | | | | | | | | | | This reduces the proliferation of car_l and cdr_l. With this change, nreverse should work on chains of objects that implement rplacd. * combi.c (comb_gen_fun_common, rcomb_gen_fun_common): Use rplaca. * eval.c (mappendv, mapdov): Likewise * hash.c (hash_equal_op): Likewise. * lib.c (nreverse, acons_new, aconsql_new, sort_list): Use rplaca and rplacd. * match.c (dest_set, v_gather, v_collect, v_flatten, v_cat, v_output, v_filter): Likewise * parser.c (ensure_parser): Use sys_rplacd. * unwind.c (uw_register_subtype): Use rplacd.
* Revising out-of-memory handling.Kaz Kylheku2017-08-181-0/+1
| | | | | | | | | | | | | | | | | | | | | We don't want to be aborting on OOM, but throwing an exception. * lib.c (alloc_error_s): New symbol variable. (oom_realloc): Global variable removed. (oom): New static function. (chk_malloc, chk_malloc_gc_more, chk_calloc, chk_realloc): Call oom instead of removed oom_realloc handler. (env): Throw alloc-error rather than error by calling oom. (obj_init): Initialize alloc_error_s. (init): Drop function pointer argument; do not initialize removed oom_realloc. * lib.h (alloc_error_s): Declared. (oom_realloc): Declaration removed. (init): Declaration updated. * txr.1: Type tree diagram includes alloc-error.
* Get continuations working on aarch64.Kaz Kylheku2017-08-161-14/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | | | * unwind.c (UW_CONT_FRAME_BEFORE, UW_CONT_FRAME_AFTER): New preprocessor symbols. (revive_cont): The "frame slack" zero-filled padding logic is replaced by capturing an actual part of the real stack before the uw_stack unwind frame. On aarch64, there is content there we must actually capture. Experiment shows that exactly 128 bytes is enough, and that corresponds to the frame_slack value. (capture_cont): Capture UW_CONT_FRAME_BEFORE bytes before the uw_stack unwind frame location. Also, the "capture_extra" is replaced by UW_CONT_FRAME_AFTER constant, to harmonize. * unwind.h (UW_FRAME_ALIGN): New preprocessor symbol. (union uw_frame): On aarch64, we ask the compiler, via a GCC-specific attribute syntax, to align the address of frame objects to a 16 byte boundary. This solves a crash in the continuation code. Continuation capture is keyed to unwind frame addresses. When a captured continuation is revived onto the stack, the delta between its original address and the revive address must be a multiple of 16. The reason is that this preserves the stack and frame pointer alignment. Certain instructions on the aarch64, require the stack pointer to be 16 byte aligned. There are other ways we could achieve this, but the easiest is to align the original frames to 16 bytes.
* cobj: rename poorly named default operation.Kaz Kylheku2017-05-151-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Renaming cobj_hash_op to cobj_eq_hash_op. This function is only appropriate to use with COBJ objects which use eq as their equal funtion. I've spotted one instance of an inappropriate use which have to be addressed by a different commit: the equal function is other than eq, but cobj_hash_op is used for the equal hash. * lib.h (cobj_hash_op): Declaration renamed to cobj_eq_hash_op. * hash.c (cobj_hash_op): Renamed to cobj_eq_hash_op. (hash_iter_ops): Refer to renamed cobj_hash_eq_op. * ffi.c (ffi_type_builtin_ops, ffi_type_struct_ops, ffi_type_ptr_ops, ffi-closure_ops, ffi_call_desc_ops): Likewise. * lib.c (cptr_ops): Likewise. * parser.c (parser_ops): Likewise. * rand.c (random_state_ops): Likewise. * regex.c (char_set_ops, regex_obj_ops): Likewise. * socket.c (dgram_strm_ops): Likewise. * stream.c (null_ops, stdio_ops, tail_ops, pipe_ops, dir_ops, string_in_ops, byte_in_ops, strlist_in_ops, string_out_ops, strlist_out_ops, cat_stream_ops, record_adapter_ops): Likewise. * struct.c (struct_type_ops): Likewise. * sysif.c (cptr_dl_ops): Likewise. * syslog.c (syslog_strm_ops): Likewise. * unwind.c (cont_ops): Likewise.
* Restore package and package alist in handlers.Kaz Kylheku2017-03-181-0/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | When setting up a handler frame, we note down the current package alist and package in the frame. Then when invoking the handler, we rebind the *package* and *package-alist* special variables. This is a needed security measure for sandboxing. Since handlers do not unwind (and therefore do not restore special variables) a handler in sandboxed code could catch an exception from non-sandboxed code that has changed *package* or *package-alist*, and take advantage of those changed values to escape from the sandbox. * unwind.c (uw_push_handler): Store current package and package-alist into new fields in the handler frame. (invoke_handler): Set up a new dynamic environment and bind *package* and *package-alist* around the handler call, to the values noted in the frame. Thus the handler executes with whatever package context was current when the handler was established. * unwind.h (struct uw_handler): New members, package and package_alist. * txr.1: Add paragraph to Exception Handling about this issue.
* Rename badly named default_bool_argKaz Kylheku2017-03-171-3/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * lib.h (default_bool_arg): Inline function renamed to default_null_arg. * eval.c (if_fun, pad, ginterate, giterate, range_star, range, constantp, macroexpand_1, macro_form_p, expand_with_free_refs, do_expand, eval_intrinsic, func_get_name, make_env_intrinsic): Follow rename. * arith.c (lognot): Likewise. * gc.c (gc_finalize): Likewise. * glob.c (glob_wrap): Likewise. * hash.c (group_reduce, gethash_n): Likewise. * lib.c (print, multi_sort, lazy_str, vector, iff, tok_str, split_str_keep, search_str, remove_if, val): Likewise. * match.c (match_fun): Likewise. * parser.c (lisp_parse_impl, regex_parse): Likewise. * rand.c (make_random_state): Likewise. * regex.c (read_until_match, search_regex, regex_compile): Likewise. * socket.c (sock_accept, sock_connect): Likewise. * stream.c (open_files_star, open_files, run, open_process, open_tail, get_string, record_adapter): Likewise. * struct.c (static_slot_ensure, static_slot_ens_rec, clear_struct, make_struct_type): Likewise. * sysif.c (exec_wrap, errno_wrap, cobj_ops_init): Likewise. * unwind.c (uw_capture_cont, uw_find_frames_impl): Likewise.
* Use non-hacky representation for deferrable warnings.Kaz Kylheku2017-02-101-12/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Deferrable warnings now get their own subtype, defr-warning. The tag is a regular argument: no funny dotted argument list. * eval.c (eval_defr_warn): Throw new style deferrable warning. (me_op, no_warn_expand): Catch defr-warning rather than warning. Use uw_muffle_warning to suppress it. (gather_free_refs): Parse new representation of deferrable warning. (expand_with_free_refs): Catch defr-warning rather than warning. * lib.c (defr_warning_s): New symbol variable defined. (obj_init): Initialize defr_warning_s. * lib.h (defr_warning_s): Declared. * share/txr/stdlib/error.tl (compile-defr-warning): Throw new-style deferrable warning. * unwind.c (uw_muffle_deferrable_warning): Function removed. (uw_throw): Bugfix: handle warnings by checking by subtype rather than exactly for the warning type. Distinguish deferrable warnings by subtype rather than argument list shape. (uw_defer_warning): Take the new style args and reconstruct the (msg . tag) representation for a deferred warning, so the other functions don't have to change. (uw_late_init): Register defr-warning as exception subtype of warning. * unwind.h (uw_muffle_deferrable_warning): Decl removed. * txr.1: Adjusted all documentation touching on the subject of the representation of deferrable warnings.
* Better way for releasing deferred warnings.Kaz Kylheku2017-02-101-0/+22
| | | | | | | | | | | | | | | | | | | | We should be re-throwing deferred warnings as ordinary warnings, not dumping them to a stream. * eval.c (eval_exception): Use uw_release_deferred_warnings instead of uw_dupm_deferred_warnings. (load): Likewise. * parser.c (read_eval_ret_last): Likewise. * txr.c (txr_main): Likewise. * unwind.c (uw_release_deferred_warnings): New function. * unwind.h (uw_release_deferred_warnings): Declared. * txr.1: Documented release-deferred-warnings and updated documentation for dump-deferred-warnings.
* Muffle only deferrable warnings in sys:expand.Kaz Kylheku2017-02-091-0/+8
| | | | | | | | | | | | | | | | | The problem is that if some macrology is performing its own expansion with sys:expand, and if all warnings are muffled in sys:expand, it means that some warnings will never be seen. Expansion is the last chance to produce warnings issued by macros. Once they are expanded, a redundant expansion pass won't issue the warnings any more. * eval.c (no_warn_expand); Use the uw_muffle_deferrable_warning handler isntead of uw_muffle_warnings. * unwind.c (uw_muffle_deferrable_warning): New function. * unwind.h (uw_muffle_deferrable_warning): Declared.
* Expose defer-warning and dump-deferred-warnings.Kaz Kylheku2017-01-261-0/+2
| | | | | | | * unwind.c (uw_late_init): Register defer-warning and dump-deferred-warnings intrinsics. * txr.1: Documented.
* Registering tentative def must purge warning.Kaz Kylheku2017-01-251-0/+1
| | | | | | | | * match.c (match_reg_var): No need to call uw_purge_deferred_warning here any more. * unwind.c (uw_register_tentative_def): Purge any deferred warnings for the tag.
* Bump copyright year to 2017.Kaz Kylheku2017-01-231-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | * LICENSE, LICENSE-CYG, METALICENSE, Makefile, args.c, args.h, arith.c, arith.h, cadr.c, cadr.h, combi.c, combi.h, configure, debug.c, debug.h, eval.c, eval.h, filter.c, filter.h, ftw.c, ftw.h, gc.c, gc.h, glob.c, glob.h, hash.c, hash.h, jmp.S, lib.c, lib.h, lisplib.c, lisplib.h, match.c, match.h, parser.c, parser.h, parser.l, parser.y, rand.c, rand.h, regex.c, regex.h, signal.c, signal.h, stream.c, stream.h, struct.c, struct.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, share/txr/stdlib/awk.tl, share/txr/stdlib/build.tl, share/txr/stdlib/cadr.tl, share/txr/stdlib/conv.tl, share/txr/stdlib/except.tl, share/txr/stdlib/getopts.tl, share/txr/stdlib/getput.tl, share/txr/stdlib/hash.tl, share/txr/stdlib/ifa.tl, share/txr/stdlib/package.tl, share/txr/stdlib/path-test.tl, share/txr/stdlib/place.tl, share/txr/stdlib/socket.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: Add 2017 to all copyright headers and strings.
* Extend deferred warnings system with tentative defs.Kaz Kylheku2017-01-151-3/+19
| | | | | | | | | | | | | | | | | | | | Tentative defs record the fact that some definition has been seen at expansion time, even though that definition has not been put into effect. They suppress warnings. * unwind.c (tentative_defs): New static variable. (uw_defer_warning): Throw away the warning if it matches a tentative def. (uw_register_tentative_def, uw_tentative_def_exists): New functions. (uw_dump_deferred_warnings): Purge the tag from the list of deferred defs also. (uw_init): gc-protect tentative_defs. Register intrinsics register-tentative-def and tentative-def-exists. * unwind.h (uw_register_tentative_def, uw_tentative_def_exists): Declared.
* Functions for error reporting out of macros.Kaz Kylheku2017-01-151-0/+2
| | | | | | | | | | | | | | | | | * eval.c (eval_init): Register sys:ctx-form and sys:ctx-name intrinsics. * lisplib.c (error_set_entries, error_instantiate): New static functions. (lisplib_init): Register autoloading of error.tl via new functions. * share/txr/stdlib/error.tl: New file. * struct.c (make_struct_type): Purge deferred warnings. * unwind.c (uw_late_init): Register purge-deferred-warning intrinsic.
* Deferred warnings.Kaz Kylheku2017-01-131-2/+31
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Warnings about undefined functions and variables are now deferred during loading, so forward references do not generate nuisance diagnostics. * eval.c (load_recursive_s): New symbol variable. (eval_defr_warn): New static function. (op_defvarl, op_defun): Purge any deferred warning about the given function or variable not being defined. (load): Rebind the sys:*load-recursive* special var to true around the load. After the load, dump deferred warnings if the prior binding of sys:*load-recursive* is false. Discard deferred warnings in the case of termination by a nonlocal control transfer. (do_expand): Treat unbound vars and functions as deferrable warnings, specially tagged for individual purging frkm the deferred list. (eval_init): Intern sys:*load-recursive* and initialize load_recursive_s variable. * eval.h (load_recursive_s): Declared. * parse.c (repl_warning): Accept variable arguments. Check whether we are loading and if so, defer deferrable (repl): Adjustment for altered signature of repl_warning. warnings. * txr.c (txr_main): dump deferred warnings after evaluating Lisp stream. * unwind.c (deferred_warnings): New static variable. (uw_throw): When a deferrable warning is caught, suppress the usual message and add it to the deferred_warnings list. (uw_defer_warning, uw_dump_deferred_warnings, uw_dump_deferred_warnings, uw_purge_deferred_warnings): New functions. (uw_late_init): gc-protect deferred_warnings. * unwind.h (uw_defer_warning, uw_dump_deferred_warnings, uw_dump_deferred_warnings, uw_purge_deferred_warnings): New functions declared.
* New function: find-frames.Kaz Kylheku2016-12-201-3/+17
| | | | | | | | | | | | | * unwind.c (uw_find_frames_impl): New static function, made from uw_find_frame. (uw_find_frame): Reduced to wrapper around uw_find_frames_impl. (uw_find_frames): New function. (uw_late_init): Register find-frames intrinsic. * unwind.h (uw_find_frames): Declared. * txr.1: Documented.
* Eliminate duplicated warning-suppressing function.Kaz Kylheku2016-11-281-0/+7
| | | | | | | | | | | | | | * eval.c (warning_continue): Static function removed. (no_warn_expand): Use uw_muffle_warning instead of removed function. * parser.y (warning_continue): Static function removed. (parse_once): Use uw_muffle_warning instead of removed function. * unwind.c (uw_muffle_warning): New function. * unwind.h (uw_muffle_warning): Declared.
* New function to access exception subtype map.Kaz Kylheku2016-11-261-0/+6
| | | | | | | | | | * uwind.c (exception_subtype_map): New static function. (uw_late_init): Register exception-subtype-map intrinsic function. * txr.1: Exception types are described in more detail. A complete diagram of the existing hierarchyis given, and the exception-subtype-map funtion is documented.
* Expander warns about unbound variables.Kaz Kylheku2016-11-261-4/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * eval.c (eval_exception): New static function. (eval_error): Reduced to wrapper around eval_exception. (eval_warn): New function. (me_op): Bind the rest symbol in a shadowing env to suppress watnings about unbound rest. (do_expand): Throw a warning when a bindable symbol is traversed that has no binding. (expand): Don't install atoms as last_form_expanded. * lib.c (warning_s, restart_s, continue_s): New symbol variables. (obj_init): Initialize new symbol variables. * lib.h (warning_s, restart_s, continue_s): Declared. * lisplib.c (except_set_entries): New entries for ignwarn and macro-time-ignwarn. * parser.c (repl_warning): New static function. (repl): Use repl_warning function as a handler for warning exceptions: to print their message and then continue by throwing a continue exception. * parser.y (warning_continue): New static function. (parse_once): Use warning_continue to ignore warnings. In other words, we suppress warnings from Lisp that is mixed into TXR pattern language code, because this produces too many false positives. * share/txr/stdlib/except.tl (ignwarn, macro-time-ignwarn): New macros. * share/txr/stdlib/place.tl (call-update-expander, call-clobber-expander, call-delete-expander): Ignore warnings around calls to sys:expand, because of some gensym-related false positives (we expand code into which we inserted some gensyms, without having inserted the constructs which bind them. * tests/011/macros-2.txr: Suppress unbound variable warnings from a test case. * tests/012/ifa.tl: Bind unbound x y variables in one test case. * tests/012/struct.tl: Suppress unbound variable warnings in some test cases. * uwind.c (uw_throw): If a warning is unhandled, then print its message with a "warning" prefix and then throw a continue exception. (uw_register_subtype): Eliminate the check for sub already being a subtype of sup. This allows us to officially register new types against t. (uw_late_init): Register continue exception type as a subtype of the restart type. Formally register warning type. * txr.1: Documented ignwarn.
* Move unwind intrinsics from eval.c to unwind.c.Kaz Kylheku2016-11-231-0/+26
| | | | | | | | | | | | | | | | * eval.c (reg_mac): Static function changed to extern. (me_defex, register_exception_subtypes): Static function removed here; relocated into unwind.c. (eval_init): Registrations of defex, throw, throwf, error, register-exception-subtypes and exception-subtype-p removed. * eval.h (reg_mac): Declared. * unwind.c (me_defex, register_exception_subtypes): Static function moved here. (uw_late_init): Registrations of defex, throw, throwf, error, register-exception-subtypes and exception-subtype-p moved here.
* Flush *stdout* upon unhandled exception.Kaz Kylheku2016-10-311-0/+1
| | | | | | | | * unwind.c (uw_unwind_to_exit_point): Prior to printing diagnostics related to an unhandled exception to std_error, flush std_output. This clarifies the output in situations when both std_error and std_output go to the same destination, and the exception occurred while producing output on std_output.
* Let guard frames optionally pass through unwinding.Kaz Kylheku2016-10-261-1/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | We have a bug in that when an exception occurs in a context called from obj_print, the guard for stopping continuation captures across obj_print also unintentially blocks the unwinding. Let's make the unwinding blockage optional * unwind.c (uw_unwind_to_exit_point): If a UW_GUARD is encountered, do not abort if the uw_ok flag is set; keep unwinding. (uw_push_guard): New uw_ok argument, initializes the uw_ok member of a guard frame. * unwind.h (struct uw_guard): New struct type. (union uw_frame): New member gu of type struct uw_guard. (uw_push_guard): Declaration updated. * ftw.c (ftw_callback): Pass zero as new uw_push_guard argument: no unwinding across the POSIX library function ftw. * glob.c (errfunc_thunk): Likewise, no unwinding across the library function glob. * lib.c (obj_print): Pass 1 as new uw_push_guard argument: continuations can't be captured, but unwinding is okay.
* nuke trailing newlines from exception messages.Kaz Kylheku2016-10-071-1/+1
| | | | | | | | | * signal.c (set_signal_handler, get_sign_handler): Eliminate newline in exception messages. * stream.c (unimpl, formatv): Likewise. * unwind.c (uw_block_abscond): Likewise.
* Synchronize license comments with LICENSE.Kaz Kylheku2016-10-011-16/+17
| | | | | | | | | | | | | | | | | | | | * Makefile, args.c, args.h, arith.c, arith.h, cadr.c, cadr.h, combi.c, combi.h, configure, debug.c, debug.h, eval.c, eval.h, filter.c, filter.h, ftw.c, ftw.h, gc.c, gc.h, glob.c, glob.h, hash.c, hash.h, jmp.S, lib.c, lib.h, lisplib.c, lisplib.h, match.c, match.h, parser.c, parser.h, parser.l, parser.y, 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/except.tl, share/txr/stdlib/hash.tl, share/txr/stdlib/ifa.tl, share/txr/stdlib/path-test.tl, share/txr/stdlib/place.tl, share/txr/stdlib/socket.tl, share/txr/stdlib/struct.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, 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: Revert to verbatim 2-Clause BSD.
* Adding panic macro, which throws a panic exception.Kaz Kylheku2016-05-071-0/+1
| | | | | | | | | | | * lib.c (panic_s): New symbol variable. (obj_init): Initialize panic_s. * lib.h (panic_s): Declared. * unwind.c (uw_init): Register panic exception. * unwind.h (panic): New macro.
* Valgrind support in continuations.Kaz Kylheku2016-04-161-1/+18
| | | | | | | * unwind.c (revive_cont): When scanning the stack of the revived continuation to fix up pointers, we can save the Valgrind validity bits of each word, mark it defined, and then restore the validity bits.
* Block absconds across foreign frames.Kaz Kylheku2016-04-161-0/+4
| | | | | * unwind.c (uw_block_abscond): If a UW_GUARD frame occurs in the search for the abscond point, throw an error.
* Remove frame popping action from uw_continue.Kaz Kylheku2016-04-111-2/+1
| | | | | | | | | | | | * unwind.c (uw_continue): Don't take the current frame as an argument and consequently don't pop the current frame. This function currently has only one use, the uw_catch_end macro. * unwind.h (uw_continue): Declaration updated. (uw_catch_end): Slight code rearrangement: pop the frame unconditionally before the test for whether uw_continue must be called.
* Typo in comment.Kaz Kylheku2016-04-111-1/+1
| | | | | * unwind.c (uw_unwind_to_exit_point): Misspelled "execute".
* New frame type to block bad unwinding and cont capture.Kaz Kylheku2016-04-081-3/+30
| | | | | | | | | | | | | | | | | | If some external function is invoked which can call back into TXR Lisp, we should guard against the called-back code from capturing a continuation across the external stack frames, and also from unwinding across those frames. This patch prepares a mechanism for this. * unwind.c (uw_unwind_to_exit_point): Abort with message on standard error if attempt is made to unwind across UW_GUARD frame. (uw_push_guard): New function. (uw_capture_cont): If the frame search encounters a UW_GUARD block, an exception is thrown. * unwind.h (enum uw_frtype): New enum constant, UW_GUARD. (uw_push_guard): Declared.