This test reproduces the error from <https://bugs.gnu.org/56493>, and
passes with the workaround which was merged in commit
c7fa78fc75.
* test-suite/tests/eval.test ("avoid frame-local-ref out of range"): New
test.
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
* libguile/exceptions.c:
* libguile/exceptions.h: New files.
* libguile.h: Add exceptions.h.
* libguile/Makefile.am (libguile_@GUILE_EFFECTIVE_VERSION@_la_SOURCES):
(DOT_X_FILES, DOT_DOC_FILES, modinclude_HEADERS): Add exceptions.c and
exceptions.h.
* libguile/init.c (scm_i_init_guile): Initialize exceptions.
* libguile/threads.c (scm_spawn_thread): Use new names for
scm_i_make_catch_handler and scm_c_make_thunk.
* libguile/throw.c: Rewrite to be implemented in terms of
with-exception-handler / raise-exception.
* libguile/throw.h: Use data types from exceptions.h. Move
scm_report_stack_overflow and scm_report_out_of_memory to
exceptions.[ch].
* module/ice-9/boot-9.scm (&error, &programming-error)
(&non-continuable, make-exception-from-throw, raise-exception)
(with-exception-handler): New top-level definitions.
(throw, catch, with-throw-handler): Rewrite in terms of
with-exception-handler and raise-exception.
: New top-level definitions.
* module/ice-9/exceptions.scm: Adapt to re-export &error,
&programming-error, &non-continuable, raise-exception, and
with-exception-handler from boot-9.
(make-quit-exception, guile-quit-exception-converter): New exception
converters.
(make-exception-from-throw): Override core binding.
* test-suite/tests/eval.test ("inner trim with prompt tag"): Adapt to
"with-exception-handler" being the procedure on the stack.
("outer trim with prompt tag"): Likewise.
* test-suite/tests/exceptions.test (throw-test): Use pass-if-equal.
* module/srfi/srfi-34.scm: Reimplement in terms of core exceptions, and
make "guard" actually re-raise continuations with the original "raise"
continuation.
* module/system/vm/frame.scm (frame-call-representation): Fix to work
for primitives.
* test-suite/tests/eval.test ("stacks"): Update expected result for
substring.
* module/ice-9/boot-9.scm (for-each): Fix detection of not-a-list in the
unrolled one-argument case.
* test-suite/tests/eval.test ("for-each"): Add a test.
* libguile/vm.h:
* libguile/vm.c:
(scm_vm_apply_hook, scm_vm_push_continuation_hook,
scm_vm_pop_continuation_hook, scm_vm_abort_continuation_hook,
scm_vm_restore_continuation_hook, scm_vm_next_hook,
scm_vm_trace_level, scm_set_vm_trace_level_x, scm_vm_engine,
scm_set_vm_engine_x, scm_c_set_vm_engine_x): The VM argument is now
implicit: the VM for the current thread.
* doc/ref/api-debug.texi (VM Hooks): Try to adapt.
* module/ice-9/command-line.scm:
* module/statprof.scm:
* module/system/vm/coverage.scm:
* module/system/vm/trace.scm:
* module/system/vm/trap-state.scm:
* module/system/vm/traps.scm:
* test-suite/tests/control.test:
* test-suite/tests/eval.test: Adapt users that set hooks or ensure that
we have a debug engine.
* libguile/gsubr.c: Define RTL stubs instead of stack VM stubs.
(SUBR_STUB_CODE, get_subr_stub_code): Adapt to return a uint32_t*
pointer instead of a SCM value.
(create_subr): Create RTL procedures instead of stack VM procedures.
For RTL procedures, the function pointer, name, and generic address
pointer go inline to the procedure, as free variables.
(scm_i_primitive_arity, scm_i_primitive_call_ip): New helpers.
(scm_c_make_gsubr, scm_c_define_gsubr, scm_c_make_gsubr_with_generic)
(scm_c_define_gsubr_with_generic): Adapt to create_gsubr being renamed
to create_subr.
Remove gsubr test code.
* libguile/gsubr.h (SCM_PRIMITIVE_P, SCM_PRIMITIVE_GENERIC_P): Only RTL
programs can be primitives now.
(SCM_SUBRF, SCM_SUBR_NAME, SCM_SUBR_GENERIC): These fields are now in
the RTL free variables, not the object table.
* libguile/programs.c (scm_i_rtl_program_name):
(scm_i_rtl_program_documentation):
(scm_i_rtl_program_properties):
(scm_i_rtl_program_minimum_arity): Implement these appropriately for
primitives, which lack debugging information.
(scm_primitive_p, scm_primitive_call_ip): New helpers.
* libguile/snarf.h: Remove static allocation for subrs. Since there is
nothing to allocate besides the program itself, which needs runtime
relocation, static allocation is not a win.
* system/vm/program.scm: Fix up various arity-related things for
primitives, which don't use ELF arity info.
* test-suite/tests/eval.test ("stack involving a primitive"): Add an
XFAIL until we get just one VM.
Fixes <http://bugs.gnu.org/12173>.
Reported by Ian Price <ianprice90@googlemail.com>.
* libguile/memoize.c (MAKMEMO_LAMBDA): New `docstring' parameter. Add
it as the second argument of `SCM_M_LAMBDA'. Update caller.
(memoize)[SCM_M_LAMBDA]: Extract docstring from EXP; when `memoize'
returns, add the docstring to the lambda's arguments.
(unmemoize)[SCM_M_LAMBDA]: Adjust to new argument layout of
`SCM_M_LAMBDA'.
* libguile/eval.c (BOOT_CLOSURE_NUM_REQUIRED_ARGS,
BOOT_CLOSURE_HAS_REST_ARGS, BOOT_CLOSURE_IS_REST,
BOOT_CLOSURE_PARSE_FULL): Adjust to new argument layout of
`SCM_M_LAMBDA'.
* module/ice-9/eval.scm (primitive-eval)[make-general-closure]:
Likewise.
[eval]: When EXP is a lambda, match its docstring; when the docstring
is not #f, add it to the closures procedure properties.
* test-suite/tests/eval.test ("docstrings"): New test prefix.
* libguile/procs.c (sym_documentation): Rename to...
(scm_sym_documentation): ... this. Make it global.
* libguile/procs.h (scm_sym_documentation): New declaration.
* libguile/stacks.c: update make-stack and narrow_stack to handle
prompt tags that are not symbols.
* test-suite/tests/eval.test: add tests for trimming a stack with
a prompt tag.
* module/ice-9/local-eval.scm (local-wrap): Fix the (module? e) case, to
reference the expression 'x' instead of the non-existent variable
'exp', as was previously done. Also use quasisyntax instead of
quasiquote, so that the introduced 'lambda' is an identifier instead
of a bare symbol, so that this will work in modules that have rebound
'lambda' to something else.
* test-suite/tests/eval.test (local-eval): Make sure to test both
'local-eval' and 'local-compile' when the specified environment is a
module.
* module/ice-9/local-eval.scm: New module (ice-9 local-eval) which
exports `the-environment', `local-eval', and `local-compile'.
* libguile/debug.c (scm_local_eval): New C function that calls the
Scheme implementation of `local-eval' in (ice-9 local-eval).
* libguile/debug.h (scm_local_eval): Add prototype.
* doc/ref/api-evaluation.texi (Local Evaluation): Add documentation.
* test-suite/tests/eval.test (local evaluation): Add tests.
* test-suite/standalone/test-loose-ends.c (test_scm_local_eval):
Add test.
* module/Makefile.am: Add ice-9/local-eval.scm.
Based on a patch by Mark H Weaver <mhw@netris.org>.
* test-suite/tests/eval.test ("stacks"): Enable another test, fix to use
with-throw-handler, and remove a duplicate test, now that there is no
difference between subrs and gsubrs.
These tests had been disabled as part of
b7742c6b71 ("new evaluator, y'all").
* test-suite/tests/eval.test ("define set procedure-name")["closure"]:
Change to `pass-if' since it now works, as a result of
ee15aa46e3 ("set names of functions
defined at the toplevel from `eval'").
("stacks")["arguments of a gsubr stack frame"]: Remove (throw
'unresolved).
* module/ice-9/boot-9.scm (map, for-each): Implement in Scheme instead
of C. There are boot versions before `cond' is defined.
(map-in-order): Define this alias here instead of in evalext.h.
* libguile/eval.c: Stub out the map and for-each definitions to just
call into Scheme.
* libguile/evalext.c: Remove map-in-order definition.
* module/srfi/srfi-1.scm: Replace all calls to map1 with calls to map.
(map, for-each): Define implementations here, in Scheme, instead of in
C.
* test-suite/tests/eval.test (exception:wrong-length, "map"): Update the
expected exception for mapping over lists of different lengths.
* libguile/srfi-1.h:
* libguile/srfi-1.c: Remove map and for-each definitions. Remove the
bit that extended the core `map' primitive with another method: the
right way to do that is with modules.
* libguile/vm.h (scm_c_vm_run): Make internal.
* libguile/vm.c (vm_default_engine): New static global variable.
(make_vm): Set vp->engine based on
(scm_vm_apply): Remove in favor of call-with-vm.
(scm_thread_vm, scm_set_thread_vm_x): Remove these, as they did not
have a well-defined meaning, and were dangerous to call on other
threads.
(scm_the_vm): Reinstate previous definition.
(symbol_to_vm_engine, vm_engine_to_symbol)
(vm_has_pending_computation): New helpers.
(scm_vm_engine, scm_set_vm_engine_x, scm_c_set_vm_engine_x): New
accessors for VM engines.
(scm_c_set_default_vm_engine_x, scm_set_default_vm_engine_x): New
setters for the default VM engine.
(scm_call_with_vm): New function, applies a procedure to arguments in
a context in which a given VM is current.
* libguile/eval.c (eval, scm_apply): VM dispatch goes through
scm_call_with_vm.
* test-suite/tests/control.test ("the-vm"):
* module/system/vm/coverage.scm (with-code-coverage): Use call-with-vm.
* module/system/vm/vm.scm: Update exports.
* test-suite/vm/run-vm-tests.scm (run-vm-program):
* test-suite/tests/compiler.test ("current-reader"): Just rely on the
result of make-program being an applicable.
* test-suite/tests/eval.test ("stack overflow"): Add a note that this
test does not test what it should.
* libguile/vm-engine.c (VM_NAME)[vm_error_stack_overflow]: Increase
`vp->stack_limit' when possible.
* libguile/vm.c (VM_STACK_RESERVE_SIZE): New macro.
* test-suite/lib.scm (exception:vm-error): New variable.
* test-suite/tests/eval.test ("stack overflow"): New test prefix.
* libguile/deprecated.h:
* libguile/deprecated.c (scm_internal_lazy_catch, scm_lazy_catch):
Deprecate, and print out a nasty warning that people should change to
with-throw-handler.
* libguile/throw.h:
* libguile/throw.c (scm_c_with_throw_handler): Deprecate the use of the
lazy_catch_p argument, printing out a nasty warning if someone
actually passes 1 as that argument. The combination of the pre-unwind
and post-unwind handlers should be sufficient.
* test-suite/tests/exceptions.test: Remove lazy-catch tests, as they are
deprecated. Two of them fail:
* throw/catch: effect of lazy-catch unwinding on throw to another key
* throw/catch: repeat of previous test but with lazy-catch
Hopefully people are not depending on this behavior, and the warning is
sufficiently nasty for people to switch. We will see.
* test-suite/tests/eval.test ("promises"): Use with-throw-handler
instead of lazy-catch.
* doc/ref/api-debug.texi:
* doc/ref/api-control.texi: Update to remove references to lazy-catch,
folding in the useful bits to with-throw-handler.
* libguile/eval.c: So, ladies & gents, a new evaluator. It's similar to
the old one, in that we memoize and then evaluate, but in this
incarnation, memoization of an expression happens before evaluation,
not lazily as the expression is evaluated. This makes the evaluation
itself much cleaner, in addition to being threadsafe. In addition,
since this C evaluator will in the future just serve to bootstrap the
Scheme evaluator, we don't have to pay much concern for debugging
conveniences. So the environment is just a list of values, and the
memoizer pre-computes where it's going to find each individual value
in the environment.
Interface changes are commented below, with eval.h.
(scm_evaluator_traps): No need to reset the debug mode after rnning te
traps thing. But really, the whole traps system needs some love.
* libguile/memoize.h:
* libguile/memoize.c: New memoizer, which runs before evaluation,
checking all syntax before evaluation begins. Significantly, no
debugging information is left for lexical variables, which is not so
great for interactive debugging; perhaps we should change this to have
a var list in the future as per the classic interpreters. But it's
quite fast, and the resulting code is quite good. Also note that it
doesn't produce ilocs, memoized code is a smob whose type is in the
first word of the smob itself.
* libguile/eval.h (scm_sym_and, scm_sym_begin, scm_sym_case)
(scm_sym_cond, scm_sym_define, scm_sym_do, scm_sym_if, scm_sym_lambda)
(scm_sym_let, scm_sym_letstar, scm_sym_letrec, scm_sym_quote)
(scm_sym_quasiquote, scm_sym_unquote, scm_sym_uq_splicing, scm_sym_at)
(scm_sym_atat, scm_sym_atapply, scm_sym_atcall_cc)
(scm_sym_at_call_with_values, scm_sym_delay, scm_sym_eval_when)
(scm_sym_arrow, scm_sym_else, scm_sym_apply, scm_sym_set_x)
(scm_sym_args): Remove public declaration of these symbols.
(scm_ilookup, scm_lookupcar, scm_eval_car, scm_eval_body)
(scm_eval_args, scm_i_eval_x, scm_i_eval): Remove public declaration
of these functions.
(scm_ceval, scm_deval, scm_ceval_ptr): Remove declarations of these
deprecated functions.
(scm_i_print_iloc, scm_i_print_isym, scm_i_unmemocopy_expr)
(scm_i_unmemocopy_body): Remove declarations of these internal
functions.
(scm_primitive_eval_x, scm_eval_x): Redefine as macros for their less
destructive siblings.
* libguile/Makefile.am: Add memoize.[ch] to the build.
* libguile/debug.h (scm_debug_mode_p, scm_check_entry_p)
(scm_check_apply_p, scm_check_exit_p, scm_check_memoize_p)
(scm_debug_eframe_size): Remove these vars that were tied to the old
evaluator's execution model.
(SCM_RESET_DEBUG_MODE): Remove, no more need for this.
(SCM_MEMOIZEDP, SCM_MEMOIZED_EXP, SCM_MEMOIZED_ENV): Remove macros
referring to old memoized code representation.
(scm_local_eval, scm_procedure_environment, scm_memoized_environment)
(scm_make_memoized, scm_memoized_p): Remove functions operating on old
memoized code representation.
(scm_memcons, scm_mem_to_proc, scm_proc_to_mem): Remove debug-only
code for old evaluator.
* libguile/debug.c: Remove code to correspond with debug.h removals.
(scm_debug_options): No need to set the debug mode or frame limit
here, as we don't have C stack limits any more. Perhaps this is a bug,
but as long as we can compile eval.scm, we should be fine.
* libguile/init.c (scm_i_init_guile): Init memoize.c.
* libguile/modules.c (scm_top_level_env, scm_env_top_level)
(scm_env_module, scm_system_module_env_p): Remove these functions.
* libguile/print.c (iprin1): No more need to handle isyms. Adapt to new
form of interpreted procedures.
* libguile/procprop.c (scm_i_procedure_arity): Adapt to new form of
interpreted procedures.
* libguile/procs.c (scm_thunk_p): Adapt to new form of interpreted
procedures.
* libguile/procs.h (SCM_CLOSURE_FORMALS): Removed, this exists no more.
(SCM_CLOSURE_NUM_REQUIRED_ARGS, SCM_CLOSURE_HAS_REST_ARGS): New
accessors.
* libguile/srcprop.c (scm_source_properties, scm_source_property)
(scm_set_source_property_x): Remove special cases for memoized code.
* libguile/stacks.c (read_frame): Remove a source-property case for
interpreted code.
(NEXT_FRAME): Remove a case that I don't fully understand, that seems
to be designed to skip over apply frames. Will be obsolete in the
futures.
(read_frames): Default source value for interpreted frames to #f.
(narrow_stack): Don't pay attention to the system_module thing.
* libguile/tags.h: Remove isyms and ilocs. Whee!
* libguile/validate.h (SCM_VALIDATE_MEMOIZED): Fix to use the new
MEMOIZED_P formulation.
* module/ice-9/psyntax-pp.scm (do, quasiquote, case): Adapt for these no
longer being primitive macros.
* module/ice-9/boot-9.scm: Whitespace change, but just a poke to force a
rebuild due to and/or/cond/... not being primitives any more.
* module/ice-9/deprecated.scm (unmemoize-expr): Deprecate, it's
unmemoize-expression now.
* test-suite/tests/eval.test ("define set procedure-name"): XFAIL a
couple of tests here; I don't know what to do about them. I reckon the
expander should ensure that defined values are named.
* test-suite/tests/chars.test ("basic char handling"): Fix expected
exception when trying to apply a char.
* libguile.h:
* libguile/Makefile.am
* libguile/init.c (scm_i_init_guile): Add trees.[ch] to the build.
* libguile/eval.c:
* libguile/eval.h: Remove scm_copy_tree and scm_cons_source...
* libguile/trees.h:
* libguile/trees.c:
* libguile/srcprop.h:
* libguile/srcprop.c: ... factoring them out here and here,
respectively.
* test-suite/tests/eval.test ("memoization"): Change expected exception
for circular data structures, given new copy-tree location.
This fixes a bug introduced in e20d7001c3
and reported by Neil.
* libguile/eval.i.c (CEVAL)[DEVAL]: Don't duplicate ARG1 in
`debug.info->a.args' for gsubr stack frames.
(scm_apply): Likewise.
* test-suite/tests/eval.test ("stacks")["arguments of a gsubr stack
frame"]: New test.
* module/ice-9/psyntax.scm (chi-lambda-clause): Strip the docstring
before passing it on to the continuation.
* module/ice-9/psyntax-pp.scm: Regenerated.
* test-suite/tests/eval.test (exception:failed-match): New exception, for
syntax-case failed matches.
("evaluator"): Fix macro-as-parameter tests. They pass now :)
* libguile/procs.c (scm_make_procedure_with_setter): Patch through the
getter's procedure name to the procedure-with-setter. Fixes part of the
srfi-17 test, as the VM doesn't set procedure-name on define -- but
perhaps that is the bug that should be fixed. In any case this patching
is cheap.
* test-suite/tests/eval.test: Change so that (define name pws) is
initially passed an anonymous procedure-with-setter, as was the case
before the procs.c change.
with-debugging-evaluator.
* lib.scm (with-debugging-evaluator*, with-debugging-evaluator):
New utilities.
* standalone/test-use-srfi: Use -q to avoid picking up the user's
~/.guile file.
* tests/eval.test (promises)[unmemoizing a promise]: New test.
from the memoization part of the file.
(copy_tree): New static function
(scm_copy_tree): Rewritten to fix two kinds or bugs: First, cyclic
structures are detected now and will lead to an exception instead
of forcing guile to run in an endless loop, using up all the
system's memory. Second, arrays in the cdr of an improper list
are now copied. See the new test cases in eval.test.
* test-suite/tests/eval.test: Added tests which reflect the recent
fixes to copy-tree.
* tests/dynamic-scope.test, tests/eval.test,
tests/r5rs_pitfall.test, tests/srfi-17.test, tests/syncase.test:
Wrap tests in module (test-suite test-<file-name without .test>),
following a practice that was used on a couple of files already.
* tests/dynamic-scope.test (exception:duplicate-binding,
exception:bad-binding): New.
* tests/dynamic-scope.test, tests/srfi-17.test, tests/syntax.test:
Execute syntactically wrong tests using eval. With the upcoming
new memoizer this is necessary in order to postpone the syntax
check to the actual evaluation of the syntactically wrong form.
* tests/syntax.test: Added some test cases and modified one test
case.