* libguile/continuations.c (continuation_mark): Mark the vm
continuations.
* libguile/vm.c (vm_cont_mark): Fix the marking function.
(vm_mark): Fix this one too -- the size is a number of STACKITEMS,
which we foolishly assume are the same size as SCM.
* test-suite/tests/ftw.test: Make our stat hacks verifyable without
assuming that they are interpreted.
* test-suite/tests/r5rs_pitfall.test: Re-indent.
* ice-9/boot-9.scm (start-stack): Define as a defmacro instead of an acro
in C. We have a way to delay evaluation of the exp, after all: putting
it in a thunk is sufficient.
* libguile/debug.h:
* libguile/debug.c (scm_sys_start_stack): Renamed from scm_start_stack,
and exposed to the user. Takes a thunk instead of an expression +
environment.
(scm_m_start_stack): Remove this acro.
* module/language/scheme/translate.scm (custom-transformer-table): Remove
the start-stack special case.
* libguile/eval.h:
* libguile/eval.c (scm_make_promise): Rename from `scm_makprom', and
export as the scheme procedure, `make-promise'.
* libguile/eval.i.c (CEVAL): s/makprom/make_promise/.
* libguile/vm-i-system.c (call, goto/args): Add a FIXME for handling the
case in which a call to the interpreter returns a values object.
(call/cc, goto/cc): Flesh out, and handle full continuations (with the
C stack also).
* module/language/scheme/translate.scm (custom-transformer-table):
Compile call-with-current-continuation. This is necessary so that the
called procedure is called in tail position.
* module/system/il/compile.scm (codegen): Translate apply to goto/apply,
call/cc to goto/cc, etc when in tail position.
* libguile/vm.c (the-vm): If the dynamic binding of *the-vm* is false,
make a new vm. Fixes multiple threads with the vm since the *the-vm*
fluid changes.
* libguile/continuations.c (scm_make_continuation): Capture VM
continuations as well, as their stack is outside the C stack.
(copy_stack): Reinstate VM stacks with the C stack.
* libguile/continuations.h (scm_t_contregs): Add a pointer for VM stacks.
A binary-incompatible change -- hopefully not too many people were
messing around with this struct, though.
* libguile/vm-engine.c (vm_run): Add a note about possibly maintaining a
stack of vms.
* libguile/vm.c (struct scm_vm_cont): New struct, distinct from scm_vm.
(vm_cont_mark, vm_cont_free, capture_vm_cont, reinstate_vm_cont):
Reorder some code, and fix some bad assumptions about what part of the
stack to copy; obviously this code was never used.
* libguile/vm.h:
* libguile/vm.c (scm_vm_capture_continuations)
(scm_vm_reinstate_continuations): New public functions, used by
continuations.c.
* module/system/vm/vm.scm:
* libguile/vm.h:
* libguile/vm.c: Make the `the-vm' procedure access a fluid, `*the-vm*'.
Export that fluid from vm.h and vm.scm.
* libguile/load.c (scm_init_load_path): If GUILE_SYSTEM_PATH is set, use
that instead of the compiled-in suffix to the load path. And, as a
special case, GUILE_SYSTEM_PATH= is interpreted as '(). A bit nasty.
* pre-inst-guile-env.in (top_builddir): Set GUILE_SYSTEM_PATH to the
empty string, if it is not set.
* libguile/vm-engine.c (vm_run): Add new error case,
vm_error_not_enough_values.
* libguile/vm-i-system.c (goto/nargs, call/nargs): So, in these cases, if
we get too many values, we don't truncate the values like we do in the
single-value continuation case, or in the mvbind case. What to do? I
guess we either truncate them here, or only allow the correct number of
values. Dunno. Mark the code as a fixme.
(truncate-values): New instruction, for mv-bind: checks that the number
of values on the stack is compatible with the number of bindings we
have arranged for them, truncating if necessary.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile receive as a primary form -- not so much because it is a
primary form, but more to test the mv-bind machinery. Also it's more
efficient, I think.
* module/system/il/compile.scm (lift-variables!): New helper, factored
out of `optimize'.
(optimize): Add a few more cases. Adapt `lambda' optimization, which
isn't much. I'm not happy with ghil as a mungeable language.
Add a case for call-with-values with the second argument is
a lambda: lift the lambda. Untested.
(codegen): Refactor the push-bindings! code. Compile mv-bind.
* module/system/il/ghil.scm (<ghil-mv-bind>): Add mv-bind construct,
along with its procedures.
* module/system/il/glil.scm (<glil-mv-bind>): Add mv-bind construct,
different from the high-level one. It makes sense in the source, I
think.
* module/system/vm/assemble.scm (codegen): Assemble glil-mv-bind by
pushing onto the bindings list, and actually push some code to truncate
the values.
* libguile/vm-engine.c (vm_run): Add another byte onto the bootstrap
program, as the offset passed to mv-call now takes two bytes.
* module/system/vm/frame.scm (bootstrap-frame?): Update for the new
bootstrap length. Really we should just check for 'halt though.
* libguile/vm-i-system.c (FETCH_OFFSET): New helper, used in BR().
(goto/nargs, call/nargs): Versions of goto/args and call, respectively,
that take the number of arguments from a value on the top of the stack.
(mv-call): Call FETCH_OFFSET to get the offset.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile call-with-values to <ghil-mv-call>. There is some trickery
because of the r4rs.scm call-with-values trampolines.
* module/system/il/ghil.scm: Add <ghil-mv-call> and accessors.
* module/system/il/compile.scm (codegen): Compile <ghil-mv-call>.
* module/system/il/glil.scm: Add <glil-mv-call>, which needs some special
assembly because of the label. Fix some typos.
* module/system/vm/assemble.scm (byte-length): New helper, factored out
and made more general.
(codegen): Assemble mv-call, including the label.
(check-length): New helper, makes sure that the addressing is
consistent within the produced object code.
(stack->bytes): Rewrite to be more generic -- now `br' instructions
aren't the only ones jumping around in the instruction stream.
* module/system/vm/conv.scm (make-byte-decoder): Return two values in the
#f case.
* module/system/vm/disasm.scm (disassemble-bytecode): Rewrite, because
the previous implementation depended on a guile interpreter quirk:
namely, that multiple values could be represented within one value, and
destructured later.
* libguile/vm-engine.c (vm_run): Move nvalues to the top level, to avoid
(spurious, it seems) gcc warnings about it being used uninitialized.
* libguile/vm-i-system.c (halt, return/values): Adapt to gcc silliness.
Deindent some of return/values.
(return/values*): New instruction, does what (apply values . args)
would do.
* module/language/scheme/translate.scm (custom-transformer-table): Move
the apply and @apply cases here from inline.scm, because we need some
more cleverness when dealing with cases like (apply values . args).
(lookup-apply-transformer): Define an eval transformer for `values',
turning it into ghil-values*.
* module/system/il/compile.scm (codegen): Compile <ghil-values*> into
return/values*.
* module/system/il/ghil.scm: Add <ghil-values*> and accessors.
(ghil-lookup): Add optional argument, define?, which if false tells us
not to actually cache the binding if it is not found in the toplevel.
* module/system/il/inline.scm: Remove apply clauses.
* module/system/vm/frame.scm (bootstrap-frame?): Update heuristic for
bootstrap-frame?, as the bootstrap frame is now 5 bytes since it
accepts multiple values.
* libguile/vm-engine.c (vm_run): The bootstrap program now uses mv_call,
so as to allow multiple values out of the VM. (It did before, because
multiple values were represented internally as single scm_values
objects, but now that values go on the stack, we need to note the boot
frame as accepting multiple values.)
(vm_error_no_values): New error, happens if you pass no values into a
single-value continuation. Passing more than one is OK though, it just
takes the first one.
* libguile/vm-i-system.c (halt): Assume that someone has pushed the
number of values onto the stack, and package up that number of values
as a scm_values() object, for communication with the interpreter.
(mv-call): New instruction, calls a procedure with a multiple-value
continuation, even handling calls out to the interpreter.
(return/values): New instruction, returns multiple values to the
continuation. If the continuation is single-valued, takes the first
value or errors if there are no values. Otherwise it returns to the
multiple-value return address, pushing the number of values on top of
the values.
* module/system/il/compile.scm (codegen): Compile <ghil-values> forms.
* module/system/il/ghil.scm (<ghil-values>) Add new GHIL data structure
and associated procedures.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile (values .. ) forms into <ghil-values>.
* libguile/vm-i-system.c (call): Rename continuation invocation from
`vm_call_cc' to `vm_call_continuation', because that's what it really
does. Add a note that it doesn't handle multiple values at the moment.
(goto/arg): Renamed from tail-call, in deference to the progenitors, on
Dale Smith's suggestion.
(goto/apply): New instruction, for `apply' in a tail context. Not yet
used, or vetted for that matter.
(call/cc): No need to pop the program, I don't think; although this
isn't tested either.
(goto/cc): New instruction, for call/cc in a tail context.
* module/language/scheme/translate.scm (*forbidden-primitives*): Rename
from %forbidden-primitives.
* module/system/il/compile.scm (codegen): Adapt to goto/args instead of
tail-call.
* module/system/il/inline.scm: Start inlining some macros used in
r4rs.scm -- not yet fully tested.
* ice-9/boot-9.scm: Allow load of a compiled r4rs file.
* libguile/frames.c (frame-mv-return-address): New accessor.
* libguile/frames.h: Update frame diagram.
(SCM_FRAME_UPPER_ADDRESS): Update for data area
growing by one pointer.
(SCM_FRAME_MV_RETURN_ADDRESS): New macro.
* libguile/vm-engine.h (NEW_FRAME): Update for frame getting bigger by a
pointer. In a normal NEW_FRAME, set the MV return address to NULL, to
indicate that this continuation does not accept multiple values.
* libguile/vm-i-system.c (tail-call): Update frame replacement code to
understand the MV return address.
(return): Make room for the MVRA.
* libguile/programs.c (program_print): Only try to lookup write-program
if the module system is booted.
* libguile/vm-engine.h (FREE_FRAME): Remove, it's now inlined everywhere.
* libguile/vm-i-system.c (tail-call): Inline FREE_FRAME, and implement
the calling bits here. Will make things more hackable.
* module/system/vm/program.scm (program-bindings-as-lambda-list): Handle
the bindings-is-null case too -- not sure how it comes about, though. A
thunk with no let, perhaps.
(write-program): Another default for the name: the source location at
which it was defined.
* libguile/programs.c (program_print): Add some "logic" to stop doing
detailed prints if one print had a nonlocal exit -- preventing
exceptions in backtraces.
* module/system/vm/frame.scm (frame-call-representation)
(frame-program-name): Rename program-name to frame-program-name, and
use the program-name if it is available.
* module/system/vm/program.scm (program-bindings): Return #f if there are
no bindings.
(program-name): New public procedure.
(program-bindings-as-lambda-list, write-program): A more useful writer
for programs.
* libguile/programs.c (scm_bootstrap_programs, program_print): Add a smob
printer for programs, which dispatches to `write-program'.
* libguile/programs.h (struct scm_program):
* libguile/programs.c (scm_c_make_program): Record the current module
when making a program. This replaces the per-late binding recorded
module in the generated code, which should be more efficient, both in
terms of garbage, and in not calling resolve-module.
(program-module): New accessor.
* module/system/vm/program.scm: Add program-module to exports.
* libguile/vm-i-loader.c (link-later): Remove this instruction, since now
the entry in the object table is just a symbol, and can be loaded with
load-symbol.
* libguile/vm-i-system.c (late-variable-ref, late-variable-set): Rework
so as to look up in the module of the current program. The logic could
be condensed quite a bit if scm_module_lookup () knew what to do with
mod==#f.
* module/system/vm/assemble.scm (dump-object!): Dump <vlink-later> just
as load-symbol, as mentioned in the note on link-later.
* module/system/il/ghil.scm: Update comment to reflect the new reality.
* module/system/vm/assemble.scm (make-meta, codegen): Hide the "meta"
information -- the names of the bindings, source info, procedure
properties, etc -- behind a lambda. This way, loading up a program
conses less, because the metadata stays as mmap'd code until it is
needed.
* libguile/vm-i-loader.c (load-program): Adjust load-program to expect
the metadata to be a program.
* module/system/vm/program.scm (program-bindings, program-sources)
(program-properties): Adjust to new meta format.
* libguile/modules.c (module-variable): If module is #f, access the
pre-modules-array. This is so that nested-ref can work before the
module system is booted, I think.
Of course all of these dependency lines during bootstrap are just to
make sure the system can be booted properly, either interpreted or
compiled, so there's no one right way: there are many ways that could
work.
* libguile/vm-i-system.c (late-variable-ref, late-variable-set): If the
module system isn't booted, do a simple scm_lookup. In the -ref case,
actually cache the variable location (doh!).
* libguile/load.h: Update scm_search_path prototype.
* libguile/load.c: Include vm.h for load-compiled/vm. Not sure if this is
bad wrt modularity.
(scm_c_string_has_an_ext): New private helper.
(scm_search_path): Add an extra optional arg, `require_exts'; if true,
require that the returned file name have one of the given extensions.
Changes the C API, but not the scheme API.
(scm_sys_search_load_path): Adapt to scm_search_path API change.
(primitive-load-path): Here is the craziness: load a compiled file if
found and newer than the corresponding (or not) source file.
(scm_init_load): Define %load-compiled-extensions as the list of
extensions denoting compiled files; defaults to '(".go").
* libguile/vm.c: Move 'vm-run, 'vm-error, 'debug sym initialization up to
the bootstrap phase, so they are ready if load-compiled/vm is called
before (system vm vm) is loaded.
* libguile/vm-i-loader.c (load-program):
* module/system/vm/assemble.scm (dump-object!): There are cases in which
we use the 16-bit representation for program params (nargs, nexts,
etc), but the actual 16-bit number actually fits into 8 bits -- which
is then misinterpreted by the loader as the 8-bit form. So ditch the
8-bit form entirely (it was never much of an optimization), and just
use the 16-bit form. Make sure to clear out all your .go files before
recompiling this one!
* libguile/vm-i-loader.c: A combination of superstition and a bugfix:
make sure that we treat bits as being of a type as wide as we think it
is, and, more importantly, allow for programs with 8 <= nargs < 16.
* libguile/vm-i-scheme.c (FUNC1): Remove, cause it's not used.
(FUNC2): Don't assume an inum can fit into an int, use scm_bits_t
instead. In reality though we should probably do use different checks,
i.e. for multiplication probably we overflow. (That would be a bug.)
Based on a patch by C. K. Jester-Young <cky944 <at> gmail.com>.
* ice-9/boot-9.scm: Only define load-compiled as #f if it's not already
defined, which won't normally be the case.
* libguile/guile-vm.c: Removed, there's no more guile-vm binary.
* libguile/frames.c: (with change frame? -> heap-frame?)
* libguile/frames.h:
* libguile/instructions.c:
* libguile/instructions.h:
* libguile/objcodes.c:
* libguile/objcodes.h:
* libguile/programs.c:
* libguile/programs.h:
* libguile/vm-bootstrap.h: (was bootstrap.h)
* libguile/vm-engine.c: (was vm_engine.c)
* libguile/vm-engine.h: (was vm_engine.h)
* libguile/vm-expand.h: (was vm_expand.h)
* libguile/vm-i-loader.c: (was vm_loader.c)
* libguile/vm-i-scheme.c: (was vm_scheme.c)
* libguile/vm-i-system.c: (was vm_system.c)
* libguile/vm.c:
* libguile/vm.h: These files moved here from src/, as guile-vm is now a
part of libguile.
* libguile/init.c: Bootstrap the VM. Yay!
* libguile/Makefile.am: The necessary chicanery here.
* module/system/vm/Makefile.am:
* module/system/vm/bootstrap.scm:
* module/system/vm/frame.scm:
* module/system/vm/instruction.scm:
* module/system/vm/objcode.scm:
* module/system/vm/program.scm:
* module/system/vm/vm.scm:
* pre-inst-guile-env.in: Add builddirs to the load path; add module/ to
the path in the empty-$GUILE_LOAD_PATH case as well.
* src/Makefile.am: Moved out everything except guilec and guile-disasm,
which probably should be moved to the scripts directory?
* testsuite/Makefile.am: Update to find guile-vm in the right place.
* module/system/vm/Makefile.am:
* module/system/vm/bootstrap.scm: Removed bootstrap.scm, scm_init_guile
handles the bootstrapping for us.
* module/system/vm/frame.scm:
* module/system/vm/instruction.scm:
* module/system/vm/objcode.scm:
* module/system/vm/program.scm:
* module/system/vm/vm.scm: Call the init functions in libguile; should
fix at some point to avoid the dlopen?