summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
...
* compiler: bug: lambda body uses inappropriate output reg.Kaz Kylheku2018-03-191-3/+5
| | | | | | | | | | * share/txr/stdlib/compiler.tl (compiler comp-lambda): The incoming oreg, which indicates where the surrounding context would like to put the closure, cannot be used for the output location of the lambda body. Because then when the closure is called, its return value will overwrite the location where the closure was placed. We must allocate a a new temporary register for this, and be sure to free it.
* compiler: bugfix: misused assoc in function lookup.Kaz Kylheku2018-03-191-1/+1
| | | | | * share/txr/stdlib/compiler.tl (sys:env lookup-fun): Fix swapped args in assoc call.
* vm: function table for faster calls.Kaz Kylheku2018-03-185-34/+176
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The vm now supports gcall and gapply opcodes which index numerically (using an immediate integer field in the instruction word) into a table of pre-resolved global function bindings. * share/txr/stdlib/asm.tl (op-gcall, op-gapply): New opcodes. (disassemble-c-d): Take the function vector as an argument and dump it too. (usr:disassemble): Extract function vector from VM description and pass it to disassemble-c-d. * share/txr/stdlib/compiler.tl (usr:compile-toplevel): Pass empty function symbol vector to vm-make-desc; it's now a required argument. * vm.c (struct vm_desc): New members funvec and ftab. (struct vm_ftent): New struct type. (vm_make_desc): New argument, funvec. Store funvec in the descriptor. Allocate a table of vm_ftent structures equal in number of elements to the function table, and populate it with resolved bindings. (vm_desc_funvec, vm_desc_destroy): New static functions. (vm_desc_mark): Mark the captured bindings in vd->ftab. (vm_gcall, vm_gapply): New static functions. (vm_execute): Handle GCALL and GAPPLY opcodes. (vm_desc_ops): Wire vm_desc_destroy in place of cobj_destroy_free_op. (vm_init): Add argument to vm-make-desc intrinsic. Register vm-desc-funvec intrinsic. * vm.h (vm_make_desc): Declaration updated. * vmop.h: Regenerated
* vm: free display memory when closure reclaimed.Kaz Kylheku2018-03-181-1/+8
| | | | | | * vm.c (vm_closure_destroy): New static function. (vm_closure_ops): Use vm_closure_destroy rather than generic cobj_destroy_free_op.
* compiler: change in output register protocol.Kaz Kylheku2018-03-181-108/+107
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | With this change we get better code, as well fewer situations in which tregs are manually released. There are some subtleties. Previously, a compiled fragment of code would dictate the identity of the location into which it has placed output; then the higher level compile had to work with that location. The new protocol is that the caller specifies a suggested output register to the recursive compile call. If the recursive compile requires a temporary register for the output, it uses the suggested one. If it doesn't require a temporary register, it specifies its own output (for instance a (v x y) entry in the display). The caller has to deal with the output not being in the suggested register. The binding constructs lambda and let also have to deal with the possibility that the body specifies an output which is going out of scope, rather than the suggested register, and in that case must generate a move instruction to transfer from there to the suggested register before the (end ...). * share/txr/stdlib/compiler.tl (sys:env out-of-scope): New method. (compiler compile): Restructured handling of atom forms. Function takes output register argument and passes it down to the special form compile methods. (compiler comp-atom): Bugfix: this must handle nil by returning (t 0) rather than wastefully interning nil into the data table. (quote nil) triggered this. We no longer need to allocate a temporary register in this function; we just use oreg when we need it. (compiler comp-var): Don't alloc temporary, use oreg. (compiler comp-setq): We don't have to free the temporary register from compiling the value expression. When the target is a lexical variable, we pass its location to the sub-compile, so the result is placed in the variable directly. Thus we don't have to generate an additional mov instruction any more, except if that compile wasn't able to use the suggested location. (compiler comp-block): Pass oreg to compile of block bodies. Then use whatever register that block specifies as the block output. (compiler comp-let): Binding of variables is streamlined with oreg in a manner similar to assignment in comp-setq. The body is compiled with the suggested oreg as its output. Because it may put the output in a location that is going out of scope, we have to do the scope check and insert a mov. (compiler comp-lambda): Similar changes as in comp-let. (compiler comp-progn): Just use the incoming oreg as the destination for every form. Use the actual output register of the last frag as the output register, unless there were no frags in which case the nil register is specified as the output. (compiler comp-prog1): Allocate a register for the ignored values of the second and subsequent forms. Use oreg for compiling the first form. (compiler comp-quasi): Take oreg param and pass down. (compiler comp-call): Now allocates a batch of suggested registers for each of the argument compiles, and passes each down to its corresponding argument compile. These registers are freed, and the actual output are used in generating the call. The output of the call goes into oreg; no need to allocate. (compiler comp-for): Mostly the obvious changes here. (usr:compile-toplevel): Here we need to allocate an output register for the top-level call into the compiler.
* compiler: use mac-param-bindKaz Kylheku2018-03-171-15/+15
| | | | | | | | | | | | It's better to use mac-param-bind than tree-bind because it provides diagnostics related to the form being destructured. * share/txr/stdlib/compiler.tl (compiler compile): Pass the whole form rather than (cdr form) to a number of special form handlers. (compiler comp-seq, compiler comp-block, compiler comp-let, compiler comp-lambda, compiler comp-for): Destructure arguments with mac-param-bind.
* listener: fix poor regex handling in balance check.Kaz Kylheku2018-03-171-1/+33
| | | | | | | * parser.c (is_balanced_line): Introduce the ST_RGXC state to which we switch when we encounter a regex character class. Also introduce ST_RGXE for regex subexpressions. In these states, do not recognize / as the regex terminator.
* compiler: replace invalid compound form message.Kaz Kylheku2018-03-171-1/+1
| | | | | | * share/txr/stdlib/compiler.tl (compiler compile): The message will show (car form) followed by a colon, so the wording should refer to that object rather than the entire form.
* compile-toplevel: expand with warnings.Kaz Kylheku2018-03-172-1/+2
| | | | | | | | * eval.c (eval_init): Expose raw expand function as sys:expand*, since sys:expand squelches warnings. * share/txr/stdlib/compiler.tl (usr:compile-toplevel): Use expand* instead of expand.
* compiler: compile string quasiliterals.Kaz Kylheku2018-03-171-0/+84
| | | | | | | | * share/txr/stdlib/compiler.tl (compiler compile): Add sys:quasi case, dispatching new comp-quasi method. (compiler comp-quasi): New method. (expand-quasi-mods, expand-quasi-args, expand-quasi): New functions.
* vm: handle FVM function type thorughout run-time.Kaz Kylheku2018-03-162-2/+51
| | | | | | | | | | | | | | | | * gc.c (mark_obj): Recognize FVM functions and mark their vm_desc. * lib.c (equal): Handle equality for FVM. If the environment pointers are equal, consider the functions equal. (funcall, funcall1, funcall2, funcall3, funcall4): Recognize and call FVM functions. However, there is a lack of robustness here that needs to be addressed: vm_execute_closure doesn't check whether there are too many or not enough arguments. Interpreted functions have a run-time check inside bind_args. (obj_print_impl): Don't print VM functions as #<intrinsic fun...> but rather #<vm fun>.
* quasi: factor out repeated code.Kaz Kylheku2018-03-161-19/+24
| | | | | | | | * eval.c (fmt_tostring, fmt_cat): New static functions. (do_format_field): Replace code block with call to fmt_cat. (fmt_simple, fmt_flex): Insert needed call to fmt_tostring. (subst_vars): Replace blocks of code with calls to fmt_tostring and fmt_cat.
* quasilit: expose access to field formatting.Kaz Kylheku2018-03-161-0/+35
| | | | | | | | | | | | | | | | | | | | | | | | | This is the second round of changes in perparation for compiling the string quasiliterals special form. Having split format_fields into a lower level do_format_field and format_field, we now provide two functions which allow Lisp code to call do_format_field. The sys:fmt-simple function has fixed arguments for the field width/alignment, indexing/slicing, separator and plist. Any of them can be defaulted with nil. This function will be useful when the quasiliteral specifies modifiers that are simple literals or constant expressions. The sys:fmt-flex function takes a variable number of arguments, after the object and the plist. This function has to scan through the arguments and classify them by type: a string is a separator, an integer is a width and left/right alignment and so on. The compiler will use sys:flex when format field modifiers are present whose arguments contain expressions that get evaluated. * eval.c (fmt_simple, fmt_flex): New static functions. (eval_init): sys:fmt-simple and sys:fmt-flex registered.
* compiler: closure bug: (dframe ...) without (end ...).Kaz Kylheku2018-03-161-0/+2
| | | | | | * share/txr/stdlib/compiler.tl (compiler comp-lambda): When we have specials we must generate an extra (end ...), to terminate the (dframe ...) that we inserted.
* compiler: fix wrong, undersized frame size in closure.Kaz Kylheku2018-03-161-3/+3
| | | | | | | | | | | * share/txr/stdlib/compiler.tl (compiler comp-lambda): Frame size can't be calculated from nfixed, because that doesn't account for the extra variables in optional parameters. It can't be calculated from the number of lexical variables either, because parameters that are special variables consume vXXYY frame entries without being counted as lexicals. Rather, the accurate frame size is given to us by the value of the counter in the newly created environment.
* Adding compiler.Kaz Kylheku2018-03-162-0/+425
| | | | | | | | | * lisplib.c (compiler_instantiate, compiler_set_entries): New static functions. (lisplib_init): Register auto-load for compiler via new functions. * share/txr/stdlib/compiler.tl: New file.
* asm: add copyright header.Kaz Kylheku2018-03-161-0/+26
| | | | | * share/txr/stdlib/asm.tl: block comment with copyright and BSD license added.
* quasilit: split format_field into two functions.Kaz Kylheku2018-03-161-46/+55
| | | | | | | | | | | | | | | | | | | | | | | | The objective of this work is to isolate the field-formatting logic so we can target it in the compiler. Currently, the sys:quasi special operator relies on calling subst_vars, which calls format_field. Both subst_vars and format_field perform dynamic evaluation, requiring an environment. In the compiler, this will be replaced by macro-generated logic; but we would like to obtain the use of the lower-level field formatting as a pure function. * eval.c (do_format_field): New static function. Does the field formatting previously done in format_field. Also performs the indexing on the object implied by the numeric or range modifier; but the range or index is already computed and comes in as a parameter. (format_field): Perform the modifier parsing only, requiring the dynamic evaluations via eval_fun, and then call do_format_field on the extracted data. The range indexing on the input sequence is no longer done during the parsing of the modifiers. That unfortunately changes some behaviors that are possible but are fortunately obscure and undocumented.
* vm: bugfix: wrong setup of closure param counts.Kaz Kylheku2018-03-151-1/+1
| | | | | | * lib.c (func_vm): The fixparam argument is the total number of fixed parameters, including optionals. That argument must be stored in the same-named member of the function structure.
* asm: close opcode checks no of registers.Kaz Kylheku2018-03-151-0/+2
| | | | | | * share/txr/stdlib/asm.tl (op-close asm): Check that the list of registers has the right number of registers indicated by the previous operands.
* asm/vm: add ifq and ifql instructions.Kaz Kylheku2018-03-153-17/+64
| | | | | | | | | | * share/txr/stdlib/asm.tl (op-ifq, op-ifql): New opcode types. * vm.c (vm_ifq, vm_ifql): New static functions. (vm_execute): Handle IFQ and IFQL opcodes. * vmop.h (vm_op_t): Regenerated.
* structs: spurious hiding of defmeth: fix needed.Kaz Kylheku2018-03-141-1/+1
| | | | | | | | | | * eval.c (op_defun): There is a hidden reference to the sys:defmeth function here, which should have been updated in commit 0ae617f463290ff4463db2e479604808f940cc76 that renamed the function to define-method! Caught this by incidental code inspection, browsing through special forms in the context of working on the compiler.
* eval: remove eval_initing, which does nothing.Kaz Kylheku2018-03-141-11/+0
| | | | | | | | | | | None of the statements which are conditional on eval_initing are ever executed, because no code is interpreted during eval init time; all intrisinc functions are C functions defined using reg_fun. * eval.c (eval_initing): Global variable removed. (op_defun, op_defmacro, eval_init): References to eval_initing and code conditional on it are removed.
* push can safely use alet rather than rlet.Kaz Kylheku2018-03-141-1/+1
| | | | | | | | | | | push doesn't unconditionally require a temporary location for operational correctness; a temporary is used only for evaluation order. Therefore it is safe to use alet to eliminate the temporary when (after all expansion) the item is a trivial symbolic expression. * share/txr/stdlib/place.tl (push): Use alet to bind the temp which holds the new item.
* asm: block and catch need dest op constraint.Kaz Kylheku2018-03-141-2/+2
| | | | | | | * share/txr/stdlib/asm.tl (op-block, op-catch): Some operands that are destinations need to be parsed as "d", so the assembler diagnoses invalid destinations. Otherwise we don't catch the problem until VM run time.
* asm: wrong labels-outside-of-code test.Kaz Kylheku2018-03-141-1/+1
| | | | | | * share/txr/stdlib/asm.tl (assembler asm): Allow instruction 0 to have a label L labeled by checking for the range 0 <= L < N.
* vm: bugfix: handle empty data vector.Kaz Kylheku2018-03-141-1/+2
| | | | | | * vm.c (vm_make_desc): We can't call vecref_l on an empty vector, because it has no index zero. Let's use a null location in this case.
* asm: bugfix: correct value of (v x y) operands.Kaz Kylheku2018-03-141-1/+1
| | | | | | * share/txr/stdlib/asm.tl (parse-compound-operand): Add the forgotten increment by two to the level number of the v operand, since (v 0 n) is in the third display level.
* expander bug: sequential vars with no init forms.Kaz Kylheku2018-03-131-1/+2
| | | | | | | | | | | | | | | | The test case for this is (let* (a (b a))) which raises suspicion by diagnosing an "unbound variable a" error against the (b a) var-init pair. The error goes away if we make it (let* ((a nil) (b a))), a perfectly equivalent form. The diagnostic is just a symptom; the problem is that in the case when a doesn't have an initform, the (b a) var-init pair is being incorrectly expanded in an environment that hasn't been extended with the a variable. * eval.c (expand_vars): In the sequential binding situation (let*), we must extend the environment for each variable in the no-init-form case exactly as we do in the with-init-form case.
* higher level disassemble function.Kaz Kylheku2018-03-133-4/+32
| | | | | | | | | | | | | | | | * lisplib.c (asm_set_entries): Autoload on usr:disassemble. * share/txr/stdlib/asm.tl (assembler): Drop initializer from bstr slot. Requires complex initialization for the case when the buf is supplied by the constructor caller for the sake of disassembling existing code. (assembler :postinit): Handle cases when only one of buf or bstr are set, and when both are not set, for the greatest flexibility. (disassemble-c-d, disassemble): New functions. * vm.c (vm_desc_datavec): New static function. (vm_init): Registered vm-desc-datavec intrinsic.
* asm: no package qualifiers in textual disassembly.Kaz Kylheku2018-03-131-1/+1
| | | | | | | * share/txr/stdlib/asm.tl (assembler dis-listing): Use tostringp when converting the opcode and arguments to text, so package prefixes won't be shown when the current package isn't sys.
* asm: fix nonworking setv.Kaz Kylheku2018-03-131-2/+3
| | | | | | | * share/txr/stdlib/asm.tl (parse-args): Include the type spec in the diagnostic for invalid type spec. (op-setv): Fix use of invalid type spec s, which should be rs.
* regression: excess args not diagnosed.Kaz Kylheku2018-03-131-1/+1
| | | | | | | | | | | This was caused by the recent work to reduce consing in generic_funcall. * lib.c (generic_funcall): Correct test for too many arguments. Because we don't normalize the argument list to the exact number of fixed args, but to at least the fixed args, the excess args can possibly be part of the fill rather than part of the list.
* vm: rename vm-interpret-toplevel function.Kaz Kylheku2018-03-131-1/+1
| | | | | * vm.c (vm_init): Register vm_execute_toplevel as vm-execute-toplevel rather than vm-interpret-toplevel.
* asm: move method definitions outside defstruct.Kaz Kylheku2018-03-131-150/+150
| | | | | | * share/txr/stdlib/asm.tl (assembler): All :method definitions and the :postinit become defmeth forms outside of the defstruct.
* structs: spurious hiding of usr symbol by sys symbol.Kaz Kylheku2018-03-131-3/+3
| | | | | | | | * share/txr/stdlib/struct.tl (sys:defmeth): Rename function to sys:define-method. Otherwise it hides usr:defmethod when the current package is sys. (defmeth): Refer to sys:define-method rather than sys:defmeth.
* asm: allow compound syntax reg operands.Kaz Kylheku2018-03-121-0/+15
| | | | | | | | | | | | In additon to the encoded notation like t13 and v013f, we allow forms like (t 19) and (v 1 63) which mean the same thing. These are a much more convenient representation for a compiler. * share/txr/stdlib/asm.tl (assembler parse-operand): Recognize a compound expression as an operand, and handle via parse-compound-operand function. (parse-compound-operand): New function.
* asm: support gensym labels.Kaz Kylheku2018-03-121-4/+9
| | | | | | | | | | | Remove restriction that labels are keywords; a compiler cannot pollute the keyword space to generate labels. We allow them to be uninterned symbols also. * share/txr/stdlib/asm.tl (assembler parse-args, assembler asm-one): Use is-label instead of keywordp. (is-label): New function. (op-label): Use is-label test.
* vm: introduce sframe instruction.Kaz Kylheku2018-03-123-32/+48
| | | | | | | | | | | | | | | | | | | | This is for allocating a new frame purely on the stack. The frame will not be captured by lexical closures, and so can only be used for non-shared variables and additional compiler-generated temporaries (if registers run out, for instance). * share/txr/stdlib/asm.tl (op-sframe, sframe): New opcode class and opcode. * vm.c (vm_do_frame): New static function for the common implementation of frame and sframe. (vm_frame): Now just a call with vm_do_frame, passing the flag indicating that closure capture is enabled for this environment frame. (vm_sframe): New static function. * vmop.h: Regenerated.
* genvmop: fix broken script.Kaz Kylheku2018-03-121-1/+1
| | | | | | | | | | | | This broke when I moved asm.tl into the library directory and set it up for auto-load. * genvmop.txr: We must not include "asm" any more. But then there is no auto-load on any other feature of the assembler other than the class name. The @(mdo) directive comes in handy; at expansion time we can trigger auto-load by doing a lookup on the sys:assembler struct name.
* vm: use memcpy for copying environment.Kaz Kylheku2018-03-121-4/+2
| | | | | | * vm.c (vm_make_closure): When copying captured environment from stack to heap, use memcpy instead of a loop with assignments.
* 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.
* New: virtual machine with assembler.Kaz Kylheku2018-03-1011-37/+1585
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit is the start of compiler work to make TXR Lisp execute faster. In six days of part time work, we now have a register-style virtual machine with 32 instructions, handling exceptions, unwind-protect, lexical closures, and global environment access/mutation. We have a complete assembler and disassembler for this machine. The assembler supports labels with forward referencing with backpatching, and features pseudo-ops: for instance the (mov ...) pseudo-instruction chooses one of three kinds of specific move instruction based on the operands. * Makelfile (OBJS): Add vm.o. * eval.c (lookup_sym_lisp1): Static function becomes external; the virtual machine needs to use this to support that style of lookup. * genvmop.txr: New file. This is the generator for the "vmop.h" header. * lib.c (func_vm): New function. (generic_funcall): Handle the FVM function type via new vm_execute_closure function. In the variadic case, we want to avoid the argument copying which we do for the sake of C functions that get their fixed arguments directly, and then just the trailing arguments. Thus the code is restructured a bit in order to switch twice on the function type. (init): Call vm_init. * lib.h (functype_t): New enum member FVM. (struct func): New member in the .f union: vm_desc. (func_vm): Declared. * lisplib.c (set_dlt_entries_impl): New static function, formed from set_dlt_entries. (set_dlt_entries): Reduced to wrapper for set_dlt_entries_impl, passing in the user package. (set_dlt_entries_sys): New static function: like set_dlt_entries but targetting the sys package. (asm_instantiate, asm_set_entries): New static functions. (lisplib_init): Auto-load the sys:assembler class. * share/txr/stdlib/asm.tl: New file. * vm.c, vm.h, vmop.h: New files.
* sys package fall back on usr.Kaz Kylheku2018-03-091-0/+2
| | | | | | | | | * lib.c (obj_init): Give the system package a fallback list consisting of one element: the user package. This will make it easier to develop some library features that have lots of internal symbols that ought to be hidden in the system package, without having to put sys: on everything. That code will just switch to the system package.
* packages: drop no-fallback-list interning restriction.Kaz Kylheku2018-03-092-44/+7
| | | | | | | | | | | | | Removing the restriction that qualified pkg:sym syntax may not cause interning to take place if pkg has a nonempty fallback list. This serves no purpose, only hindering the flexibility of the package system. * parser.y (sym_helper): When processing a qualified symbol, if the package exists, just intern it. * txr.1: Revise all text which touched on the removed rule, to remove all traces of it from the documentation.
* args: overhaul for clarity and reduced consing.Kaz Kylheku2018-03-096-34/+39
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * 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.
* bugfix: broken single-digit bignum multiplication.Kaz Kylheku2018-03-081-18/+9
| | | | | | | | | | | | * mpi/mpi.c (s_mp_mul_d): The test used for deciding whether or not the multiplication will carry, and possibly needs another digit of space, is broken. There are situations in which a carry occurs (k > 0) in spite of the test being negative. We code this the way it should have been done in the first place: resize the object when carry actually occurs. This still avoids calling s_mp_pad unless absolutely necessary, as the removed comment says. Also, in the carry case, we need not try to clamp away leading zeros.
* code review: switch case breaks.Kaz Kylheku2018-03-082-0/+4
| | | | | | | | | | * arith.c (c_unum): Add fallthrough comment. (minus): Add missing break after case that handles char minus heap object.. This luckily isn't a bug because type(anum) isn't RNG, and so when it falls through, the next case also falls through. * lib.c (car): Add missing fallthrough comment.
* New function: bignum-len.Kaz Kylheku2018-03-063-0/+46
| | | | | | | | | * arith.c (bignum_len): Wew function. (arith_init): Register bignum-len intrinsic. * arith.h (bignum_len): Declared. * txr.1: Documented.
* trace: bugfix in method redefinition check.Kaz Kylheku2018-03-011-2/+5
| | | | | | | | | | | | | | | If the trace module has been loaded, we can't define methods. Repro: 1> (trace) nil 2> (defmeth time foo (me)) ** static-slot-home: #<struct-type time> has no static slot named foo * struct.c (static_slot_ensure): Do the trace_check after calling static_slot_ens_rec so that the slot exists. If the slot doesn't exist, an exception occurs when sys:trace-canonicalize-name calls static-slot-home.