* 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>.
* 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?