* libguile/vm-builtins.h (FOR_EACH_VM_BUILTIN): Add arity information.
(enum scm_vm_builtins):
* libguile/vm.c (scm_vm_builtin_ref):
(scm_vm_builtin_name_to_index):
(scm_vm_builtin_index_to_name): Adapt to macro interface change.
(scm_init_vm_builtin_properties): New helper, sets procedure
properties on builtins.
(scm_bootstrap_vm): Just define the builtins here. Later in the
bootstrap we set their properties.
(scm_sym_apply): Move definition here from expand.c.
* libguile/procprop.c (scm_init_procprop): Call
scm_init_vm_builtin_properties.
* libguile/vm-engine.c (br-if-npos-gt): New instruction (sigh!). For
case-lambda* dispatching on the number of positional args, as the
manual describes. Renumber other opcodes.
* libguile/gsubr.h:
* libguile/gsubr.c (scm_i_primitive_call_ip):
* libguile/programs.c (scm_primitive_call_ip): Adapt to return an
absolute address.
* module/system/vm/assembler.scm (write-arity-headers): Adapt to write
byte addresses (relative to the text base).
* module/system/vm/debug.scm (arity-low-pc, arity-high-pc): Return
absolute addresses, instead of word offsets relative to the text
base.
(find-first-arity): Adapt for absolute addresses.
* module/system/vm/program.scm (program-arguments-alist): Adapt for
arity-low-pc / arity-high-pc absolute addresses.
* libguile/frames.c (scm_frame_source): Instead of assuming that
scm_frame_procedure is correct, use the IP to get the source.
(scm_frame_instruction_pointer): Return an absolute value instead of
assuming that slot 0 is correct. (It isn't, when preparing for a tail
call.)
* libguile/programs.h:
* libguile/programs.c (scm_find_source_for_addr): New internal helper.
* module/system/repl/debug.scm (print-registers): Readably print
absolute instruction pointers.
* module/system/vm/coverage.scm: Complete rewrite to use absolute IP's.
We can't assume that frame-procedure is cheap if it is correct, or
correct if it is cheap. Anyway using the address is better anyway.
(coverage-data->lcov): Disable per-function info temporarily.
(loaded-modules, module-procedures, closest-source-line)
(closed-over-procedures): Remove these. Instead of going from
procedures to source info, now we go from ELF image to source info.
* module/system/vm/debug.scm (debug-context-length): New interface.
* module/system/vm/program.scm (source-for-addr): New internal helper.
* module/system/vm/objcode.scm:
* libguile/objcodes.c (scm_all_mapped_elf_images): New proc.
* module/system/vm/debug.scm (fold-all-debug-contexts):
(fold-source-locations): New public interfaces.
* libguile/arrays.c (scm_from_contiguous_typed_array):
* libguile/bytevectors.c (scm_uniform_array_to_bytevector): For
bitvectors, round up the length to 32-bit units, as they are stored
internally. Otherwise I think this probably does the wrong thing for
the last word on big-endian systems.
* libguile/bitvectors.c (BITVECTOR_LENGTH, BITVECTOR_BITS):
(scm_c_make_bitvector): Reorder the length and pointer words to match
the layout of bytevectors.
* module/language/cps/primitives.scm (*branching-primcall-arities*):
* module/system/vm/assembler.scm (br-if-bitvector):
* module/system/vm/disassembler.scm (code-annotation): Add bitvector
test support.
* module/system/vm/assembler.scm (<uniform-vector-backing-store>): Add
an element-size field.
(intern-constant): Adapt make-uniform-vector-backing-store call. Use
uniform-array->bytevector, as the old compiler did.
(link-data): Add bitvector cases.
* libguile/vm.c (vm_return_to_continuation): The RTL VM saves the
registers for the caller of call/cc, but the caller will expect values
in the normal MV return location: above the frame. Make it so, number
four!
* libguile/memoize.h (SCM_M_CAPTURE_MODULE)
* libguile/memoize.c (MAKMEMO_CAPTURE_MODULE, capture_env):
(maybe_makmemo_capture_module, memoize): Determine when to capture the
module on the environment chain at compile-time, instead of at
runtime. Introduces a new memoized expression type, capture-module.
(scm_memoized_expression): Start memoizing with #f as the
environment.
(unmemoize): Add unmemoizer.
(scm_memoize_variable_access_x): Cope with #f as module, and treat as
the root module (captured before modules were booted).
* libguile/eval.c (eval):
* module/ice-9/eval.scm (primitive-eval): Adapt.
* libguile/procs.c (scm_make_procedure_with_setter): Don't set the name
of the procedure. Instead rely on procedure-name to look it up from
the wrapped procedure as needed.
* libguile/procprop.c (scm_procedure_name): If there was no override and
the procedure is a procedure-with-setter, recurse on the procedure.
* libguile/vm-engine.c (define!): Rename from define.
* module/language/cps/arities.scm (fix-clause-arities): If a prim
aliases an RTL instruction with a different name and we reify a
primcall, reify the instruction name.
* module/language/cps/compile-rtl.scm (emit-rtl-sequence): Update
emit-define! for new name.
* module/language/cps/primitives.scm (*rtl-instruction-aliases*): Add
bytevector native accessors.
* libguile/uniform.h:
* libguile/uniform.c (scm_uniform_vector_element_type_code): New
interface, returns a type code as an integer.
* module/system/vm/assembler.scm (<uniform-vector-backing-store>)
(simple-vector?, uniform-array?, statically-allocatable?)
(intern-constant, link-data, link-constants): Support uniform arrays,
and punt on vectors aren't contiguous from 0. Support for general
arrays will come later.
* test-suite/tests/rtl.test ("load-constant"): Add tests.
* libguile/vm-engine.c (static-patch!): Replace link-procedure! with
this more versatile primitive.
* module/system/vm/assembler.scm (intern-constant): Emit static-patch!
for static procedures and for strings.
* module/system/vm/disassembler.scm (code-annotation): Remove annotation
for link-procedure!. There can be no annotation for static-patch!, as
neither operand is guaranteed to be a SCM value.
* libguile/vm-engine.c (receive-values): Bugfix for the case where we
want an exact number of values.
(abort): Advance the IP before capturing. The captured SP is fp - 1,
not fp.
* libguile/vm.c (vm_reinstate_partial_continuation): Don't push on a
number-of-values marker.
* libguile/Makefile.am:
* libguile/vm-builtins.h: New header, declaring stubs needed by the
compiler like values, apply, and abort-to-prompt.
* libguile/vm.c: Adapt the apply and values stubs to conform to a
standard interface. Add an abort-to-prompt stub. Add call/cc and
call-with-values stubs.
(scm_vm_builtin_ref): New helper, for the builtin-ref opcode.
(scm_vm_builtin_name_to_index)
(scm_vm_builtin_index_to_name): New helpers, for the compiler and
disassembler, respectively.
(scm_init_vm_builtins, scm_bootstrap_vm): Allow the compiler helpers
to be loaded later into a module.
* module/language/rtl.scm: Export builtin-index->name and
builtin-name->index.
* libguile/vm-engine.c (RETURN_VALUE_LIST): Update to use new names of
"apply" and "values".
(tail-call/shuffle): New opcode.
(abort): Update to be a tail VM op, and reorder and renumber other
ops.
(builtin-ref): New opcode.
* libguile/continuations.h:
* libguile/continuations.c (scm_i_call_with_current_continuation):
Move this to vm.[ch], implemented as a builtin.
* module/language/tree-il/compile-cps.scm (convert): Convert to
'abort-to-prompt calls, possibly with 'apply, effectively undoing the
tree-il transformation.
* module/language/cps/reify-primitives.scm (builtin-ref): New helper.
(reify-primitives): Convert builtin primitives to builtin-ref.
* module/language/cps/dfg.scm (constant-needs-allocation?):
* module/language/cps/compile-rtl.scm (emit-rtl-sequence): Add support
for compiling builtin-ref.
* module/system/vm/disassembler.scm (code-annotation): Add annotation
for builtin-ref.
* libguile/control.c: Implement partial continuations as RTL programs.
* libguile/programs.c (scm_i_rtl_program_minimum_arity): Add partial
continuation case.
* libguile/vm-engine.c (compose-continuation): Fix to look for vm_cont
from the free variables.
* libguile/vm-i-system.c (abort): Poison continuations captured in the
stack VM, as the can't be rewound by the RTL stubs.
* libguile/memoize.c (MAKMEMO): Memoized objects are pairs now, not
SMOBs. This lets eval.scm destructure them more efficiently.
(scm_print_memoized, scm_memoized_p, scm_memoized_expression_typecode)
(scm_memoized_expression_data): Remove these interfaces.
(unmemoize, scm_memoize_variable_access_x): Remove SMOB type checks.
(scm_init_memoize): Remove SMOB type definition.
* libguile/memoize.h (scm_tc16_memoized, SCM_MEMOIZED_P)
(scm_memoized_expression_typecode, scm_memoized_expression_data)
(scm_memoized_p): Remove declarations.
* libguile/validate.h (SCM_VALIDATE_MEMOIZED): Remove declaration.
* libguile/eval.c (eval): Remove memoized type check, and inline the
inum unpacking.
* module/ice-9/eval.scm (memoized-expression-case): Use car and cdr to
destructure memoized expressions. A big win!
* libguile/vm-engine.c (rtl_vm_engine): Add make-vector and
constant-make-vector instructions and renumber.
* module/language/cps/compile-rtl.scm (emit-rtl-sequence): Emit
constant-make-vector and make-vector as appropriate.
* module/language/cps/dfg.scm (constant-needs-allocation?): In some
cases, make-vector doesn't need to allocate its index.
* module/language/tree-il/primitives.scm
(*interesting-primitive-names*, *primitive-constructors*): Add
make-vector.
* libguile/vm-engine.c (rtl_vm_engine): Add constant-vector-set!
instruction and renumber.
* module/language/cps/compile-rtl.scm (emit-rtl-sequence): Emit
constant-vector-ref and constant-vector-set! as appropriate.
* module/language/cps/dfg.scm (constant-needs-allocation?): In some
cases, vector-ref and vector-set! don't need to allocate their index.
* libguile/vm-engine (box-ref, box-set!): Instead of aborting if a box
isn't a var, call out to vm_error_not_a_variable. This makes these
instructions equivalent to variable-ref/variable-set!.
(vector-set!): Rename from vector-set.
* module/language/cps/compile-rtl.scm (emit-rtl-sequence): Add
variable-set! case, and adapt vector-set!.
* module/language/cps/primitives.scm (*rtl-instruction-aliases*): Add
variable-ref / variable-set! aliases to box-ref / box-set!.
* libguile/strings.h:
* libguile/strings.c (scm_i_print_stringbuf):
* libguile/print.c (iprin1): Add a printer for stringbufs. The
disassembler can print a stringbuf.
* libguile/procprop.c (scm_procedure_properties, scm_procedure_property)
(scm_set_procedure_properties_x, scm_set_procedure_property_x)
(scm_procedure_name, scm_procedure_documentation): Rework to treat the
overrides table as complementary to the RTL program properties. In
this way setting a procedure property doesn't require loading up
the (system vm debug) module.
* libguile/memoize.c (MAKMEMO_LAMBDA, memoize): Instead of passing the
docstring in the memoized lambda, pass the meta as-is. That way we
get all procedure properties, including "name".
* module/ice-9/eval.scm (primitive-eval): Set procedure properties when
making lambdas. Don't set the name when defining toplevel variables
-- before we did so only if the procedure didn't have a name
property, but I would like to avoid calls to procedure-property in
eval, because getting the name for an RTL function requires loading up
other modules.
* libguile/memoize.c (MAKMEMO_LEX_REF, MAKMEMO_LEX_SET): Change to
address lexicals by depth and width.
(try_lookup_rib, lookup_rib, make_pos): New helpers.
(lookup): Adapt to return a pair.
(memoize, unmemoize_bindings, unmemoize_lexical): Adapt.
* libguile/eval.c (eval, prepare_boot_closure_env_for_eval):
(prepare_boot_closure_env_for_apply):
* module/ice-9/eval.scm (make-fixed-closure, make-general-closure)
(eval): Adapt to new environment.
This is currently a slight win for C, and a slight lose for Scheme --
because the lookup loop is so poorly compiled by the stack VM. I expect
that the RTL-compiled eval will fix this.
* libguile/continuations.h:
* libguile/continuations.c: Reimplement continuations and the call_cc
stub as RTL programs.
* libguile/programs.c (scm_i_rtl_program_minimum_arity): Add a case for
continuations.
* libguile/vm-engine.c (rtl_vm_debug_engine): Always call the abort
continuation hook with the number of non-procedure locals. Fix
compose-continuation argument count. Enable call/cc.
* libguile/foreign.c: Convert to using RTL stubs. Because RTL code has
different GC characteristics than objcode -- it's mostly assumed that
RTL code will never go away -- we go ahead and pre-generate code for
100 arguments. This is actually less memory than the stack VM code,
and doesn't require any relocations at load-time: bonus! We'll cross
the >=100 args bridge if we ever come to it.
(get_foreign_stub_code) New function.
(scm_i_foreign_arity): New helper, like scm_i_primitive_arity.
(cif_to_procedure): Rework to make RTL programs.
* libguile/foreign.h: Declare scm_pointer_to_scm and
scm_scm_to_pointer. Declare new internal helpers.
* libguile/gsubr.c (create_subr): Refactor to set the flags when the
object is allocated.
* libguile/instructions.h: Define SCM_PACK_RTL_12_12.
* libguile/programs.c (scm_i_rtl_program_minimum_arity): Dispatch to
scm_i_foreign_arity if the procedure has the FOREIGN flag.
* libguile/programs.h (SCM_F_PROGRAM_IS_FOREIGN)
(SCM_PROGRAM_IS_FOREIGN): New interfaces.
* test-suite/tests/foreign.test ("procedure->pointer"): Add a test for
foreign arities.
* 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.
* libguile/vm.c (scm_c_vm_run): Directly dispatch to the RTL VM for RTL
programs.
(scm_bootstrap_vm): Initialize the RTL program stubs early, and mark
the RTL boot program with the boot flag.
* libguile/vm-engine.c (bind-rest): If the sp is below the dst reg,
alloc the frame to ensure there is enough space, and to fill in
intermediate values with SCM_UNDEFINED.
* libguile/vm-engine.c (prompt): Adapt to explicitly set the saved SP so
we know how many incoming values the handler will receive, and to make
escape-only? a flag.
* module/language/cps/compile-rtl.scm (emit-rtl-sequence): $prompt
should only be found in a "seq" context, as it just pushes on a prompt
and doesn't bind any values. On the other hand it should emit
appropriate code for the handler to bind its values, so do that.
* module/language/cps/slot-allocation.scm ($cont-allocation): Add a note
that proc-slot is used by prompts as well.
(allocate-slots): Compute the allocation of a prompt handler's args.
* module/language/tree-il/compile-cps.scm (convert): Use "unwind"
instead of the nonexistent "pop-prompt".
* module/system/vm/disassembler.scm (code-annotation): Adapt to change
in prompt VM op.
* libguile/vm-engine.c (receive-values): Add an ALLOW-EXTRA? flag in
unused bits of the third word. Without it, receive-values will check
for the exact number of incoming values.
* libguile/vm.c (vm_error_wrong_number_of_values): New error case.
* module/language/cps/compile-rtl.scm (emit-rtl-sequence): Adapt to add
the ALLOW-EXTRA? flag.
* libguile/dynstack.h (scm_t_dynstack_prompt_flags): New flag,
SCM_F_DYNSTACK_PROMPT_PUSH_NARGS, set if the continuation expects the
number of args to be pushed on the top of the stack.
* libguile/control.c (scm_c_abort): Only push nargs if requested.
* libguile/eval.c (eval):
* libguile/throw.c (pre_init_catch):
* libguile/vm-i-system.c (prompt): Set
SCM_F_DYNSTACK_PROMPT_PUSH_NARGS.
* libguile/frames.c (scm_frame_source, scm_frame_instruction_pointer):
Fix to work with RTL programs.
* module/system/vm/debug.scm (find-debug-context): Allow for the
possibility of there being no ELF image.
(find-program-debug-info, find-program-arities)
(program-minimum-arity, find-program-docstring)
(find-program-properties, find-source-for-addr)
(find-program-die, find-program-sources): Don't bail if we couldn't
get the debug context.
* module/system/vm/frame.scm (frame-next-source)
(frame-call-representation): Allow RTL programs.
* module/system/vm/program.scm (program-arguments-alist): Placeholder
implementation for RTL programs.
(program-arguments-alists): Don't bail if we couldn't get the
arities.
* libguile/programs.c (scm_program_sources): Define as %program-sources,
and let Scheme export the program-sources proper.
(scm_program_source): Call out to Scheme.
* module/system/vm/program.scm: Convert to use match instead of pmatch.
Adapt existing callers.
(program-sources, program-source): New Scheme implementations of these
functions.
(program-sources-pre-retire): Add RTL program case.