Reported by Daniel Kraft <d@domob.eu>.
* libguile/frames.c, libguile/vm.c: Include <stdlib.h>, use `size_t'
instead of `scm_sizet'.
* libguile/objcodes.c, libguile/programs.c, libguile/vm-engine.c,
libguile/vm-i-loader.c, libguile/vm-i-system.c: Use `scm_list_X ()'
instead of the deprecated `SCM_LISTX ()'.
* libguile/vm-engine.c (VM_PUSH_DEBUG_FRAMES): New knob, if true we much
with the scm_i_last_debug_frame when entering the VM, because sometimes
the evaluator doesn't do it for us.
(VM_ENGINE): Plug through debug frame fondling. Now, program exit comes
back to the main text. Rename err_args to finish_args, and reuse for
the return value.
* libguile/vm-engine.h (PUSH_LIST):
* libguile/vm-i-loader.c:
* libguile/vm-i-scheme.c:
* libguile/vm-i-system.c: Update for finish_args.
(halt): goto vm_done, now, instead of returning directly.
* libguile/objcodes.c (scm_bytecode_to_objcode): Check that the length of
the vector matches the length embedded in the bytecode.
* libguile/programs.c (scm_program_meta): Call through to
scm_objcode_meta, instead of looking in the object table. Avoids
consing up a program+objcode slice for the meta until the meta is
actually called.
* libguile/vm-i-loader.c (load-program): Step past the metadata too.
* module/language/glil/compile-assembly.scm (make-meta): Just return the
load-program form, or #f.
(assoc-ref-or-acons, object-index-and-alist, make-object-table): Don't
write the meta into the object table.
(glil->assembly): Instead write the meta into the load-program form.
* gdbinit: Untested attempts to get the stack fondling macros to deal
with the new program representation.
* libguile/frames.c (scm_vm_frame_arguments, scm_vm_frame_source)
(scm_vm_frame_local_ref, scm_vm_frame_local_set_x): SCM_PROGRAM_DATA is
a struct scm_objcode*.
* libguile/instructions.h:
* libguile/instructions.c: Hide the instruction table and the struct
scm_instruction structure; all access to instructions now goes through
procedures. This is because instructions are no longer in a packed
array indexed by opcode. Also, declare a mask that all instructions
should fit in.
* libguile/objcodes.h:
* libguile/objcodes.c: Rewrite so that object code directly maps its
arity and length from its bytecode. This makes it unnecessary to keep
this information in programs, allowing programs to be simple conses
between the code (objcodes) and data (the object table and the closure
variables).
* libguile/programs.c (scm_make_program): Rework so that make-program
takes objcode, an object table, and externals as arguments. It's much
clearer this way, and we avoid malloc().
* libguile/stacks.c (is_vm_bootstrap_frame): Update for program/objcode
changes.
* libguile/vm-engine.c (vm_run): Initialize the jump table on the first
run, with the opcodes declared in the instruction sources, and with bad
instructions raising an error instead of wandering off into the
Unknown.
* libguile/vm-engine.h (FETCH_LENGTH): Always represent lengths as 3
bytes. The old code was too error-prone.
(NEXT_JUMP): Mask the instruction with SCM_VM_INSTRUCTION_MASK.
(NEW_FRAME): Update for program/objcode changes.
* libguile/vm-expand.h (VM_DEFINE_FUNCTION, VM_DEFINE_INSTRUCTION)
(VM_DEFINE_LOADER): Update so that we explicitly specify opcodes, so
that we have a stable bytecode API.
* libguile/vm-i-loader.c: Update license to LGPLv2+. Explicitly declare
opcodes.
(load-integer): Use an int instead of a long as the accumulator; still
need to revisit this code at some point, I think.
(load-program): Simplify, thankfully!! Just creates the objcode slice
and rolls with it.
* libguile/vm-i-scheme.c: Number the opcodes explicitly.
* libguile/vm-i-system.c: Update license to LGPLv2+. Explicitly declare
opcodes.
(make-closure): Update for new program API.
* libguile/vm.c (vm_make_boot_program): Update for new program/objcode
API. Still a bit ugly.
(scm_load_compiled_with_vm): Update for new program/objcode API.
* module/language/assembly.scm (byte-length): Fix byte-length calculation
for loaders, and load-program.
(code-pack, code-unpack): Start to move things from (system vm conv)
here.
(object->code, code->object): More things from conv.scm.
* module/language/glil.scm (<glil-program>): Add a new field,
closure-level.
(make-glil-program, compute-closure-level): Calculate the "closure
level" when making a glil program. This is the maximum depth of
external binding refs in this closure.
(unparse-glil): Fix label serialization.
* module/language/glil/compile-assembly.scm (make-meta): Prepend #f for
the meta's object table, though maybe in the future we can avoid
creating assembly in the first place.
(assoc-ref-or-acons, object-index-and-alist): GRRR! Caught again by the
different sets of arguments to assoc and assoc-ref!
(glil->assembly): Attempt to make the <glil-program> case more
readable, and fix the bugs. Sorry I don't know how to comment this
change any more than this.
(glil->assembly): For <glil-module> serialize the whole key, not just
the name.
(dump-object): subprogram-code is already a list. Serialize integers as
strings, not u8vectors. Fix the order of lists and vectors.
* module/language/glil/spec.scm (glil): Switch orders, so we prefer glil
-> assembly -> objcode. Actually glil->objcode doesn't work any more,
needs to be removed I think.
* module/language/objcode/spec.scm (objcode->value):
s/objcode->program/make-program/.
* module/language/scheme/inline.scm: Add acons inline.
* module/system/vm/conv.scm (make-byte-decoder): Skip the first 8 bytes,
they are header. Handle subprograms properly. Still needs help though.
(decode-length): Lengths are always 3 bytes now.
* module/system/vm/disasm.scm: Superficial changes to keep things
working. I'd like to fix this better in the future.
* module/system/vm/frame.scm (bootstrap-frame?): Fixes for
program-bytecode.
* module/system/vm/program.scm: Export make-program. It's program-objcode
now, no more program-bytecode.
* module/system/vm/vm.scm (vm-load): Use make-program.
* test-suite/tests/asm-to-bytecode.test: New test, very minimal.
* module/system/vm/objcode.scm: Export word-size, byte-order, and
write-objcode.
* libguile/programs.h (struct scm_program): Remove the module and meta
fields.
* libguile/programs.c (scm_c_make_program): Add a new argument, `objs'.
If it's a vector, we'll look for the module and the metadata in there,
instead of having them in the scm_program structure.
(scm_c_make_closure, program_mark, scm_program_meta)
(scm_c_program_source, scm_program_module): Adapt to the new program
representation.
* libguile/objcodes.c (scm_objcode_to_program): Pass #f as the object
table when making the program.
* libguile/vm-engine.h (CACHE_PROGRAM):
* libguile/vm-engine.c (vm_run): Rework to use the simple vector API for
getting the current object table. Call the helper,
vm_make_boot_program, to make the boot program.
* libguile/vm-i-loader.c (load-program): Set the current module and the
meta in the object vector, which we pass to scm_c_make_program.
* libguile/vm-i-system.c (toplevel-ref, toplevel-set): Adapt to the new
program representation.
* module/language/glil/compile-objcode.scm (codegen): Clarify.
* libguile/vm-engine.h (CHECK_STACK_LEAK, NULLSTACK): Add a new mode,
VM_ENABLE_STACK_NULLING, that tries to ensure that all stack data past
the top of the stack is NULL. This helps to verify the VM's
consistency. If VM_ENABLE_STACK_NULLING is not defined, there is no
overhead.
(DROP, DROPN): Hook into NULLSTACK.
(POP_LIST): Hoo, fix a good bug: if CONS triggered a GC, the elements
of the list that had not yet been consed would not be marked, because
the sp was already below them.
(NEXT): Hook into CHECK_STACK_LEAK.
(INIT_ARGS): Add a note that consing the rest arg can cause GC.
(NEW_FRAME): Cons up the external data after initializing the frame, so
that if GC is triggered, the precise marker sees a well-formed frame.
* libguile/vm-i-loader.c (load-program): In the four-integers case, use
the POP macro so that we can hook into NULLSTACK (if necessary).
* libguile/vm-i-scheme.c (ARGS2, ARGS3): Hook into NULLSTACK.
* libguile/vm-i-system.c (halt): Null the nvalues. Rework some asserts
into using ASSERT, and null the stack when we free the frame.
(variable-set): Use DROPN instead of sp -= 2.
(BR): Hook into NULLSTACK.
(goto/args): Hook into NULLSTACK. In the non-self case, delay updating
the frame until after INIT_ARGS so that GC sees a well-formed frame.
Delay consing the externals until after the frame is set up, as in
NEW_FRAME.
(call/cc): Add some asserts.
(return): Rework some asserts into ASSERT, and hook into NULLSTACK.
(return/values): Hook into NULLSTACK, and use ASSERT.
(return/values*) Use ASSERT.
* libguile/vm.c (VM_ENABLE_ASSERTIONS, VM_ENABLE_STACK_NULLING): These
are the variables that control assertions and nulling. Perhaps we can
do these per-engine when we start compiling the debug engine separate
from a speedy engine.
(vm_mark_stack): Add a precise stack marker. Yay!
(vm_cont_mark): Mark the continuation stack precisely.
(capture_vm_cont): Record the difference from the vp's stack_base too,
so that we can translate the dynamic links when marking the
continuation stack. Memset the stack to NULL if we are doing nulling.
(reinstate_vm_cont): If we are nulling, null out the relevant part
of the stack.
(vm_reset_stack): When resetting sp due to a nonlocal exit, null out
the stack too.
(vm_mark): If we are nulling, assert that there are no extra values on
the stack. Mark the stack precisely.
* libguile/vm-engine.c (vm_run): Add new error case for resolving @ or @@
references, but there is no such module. Possible if
module-public-interface returns #f.
* libguile/vm-i-loader.c (link-now): Allow the stack arg to be a sym, as
before, or a list, indicating an absolute reference. Could be two
separate instructions, but I'm lazy.
* libguile/vm-i-system.c (late-variable-ref, late-variable-set): As in
link-now, allow the lazy reference to be a list, for @ and @@.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile @ and @@, and set! forms for both of them. This will ease the
non-hygienic pain for exported macros.
* module/system/il/compile.scm (make-glil-var): Translate public and
private module variable references into glil-module variables.
* module/system/il/ghil.scm (ghil-var-at-module!): New function, resolves
a variable for @ or @@.
* module/system/il/glil.scm (<glil-module>): Revival of <glil-module>,
this time with the semantics that it really links to a particular
module.
* module/system/vm/assemble.scm (<vlink-now>, <vlink-later>): Redefine as
taking a "key" as the argument, which may be a sym or a list; see the
notes on link-now for more details.
(codegen): Compile <glil-module> appropriately. Some duplication here,
probably could use some cleanup later.
* 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/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.
* 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?