1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-30 20:00:19 +02:00
Commit graph

159 commits

Author SHA1 Message Date
Andy Wingo
e5dc27b86d increase range of relative jumps by aligning blocks to 8-byte boundaries
* libguile/objcodes.c (OBJCODE_COOKIE): Bump again, as our jump offsets
  are now multiplied by 8.

* libguile/vm-i-system.c (BR): Interpret the 16-bit offset as a relative
  jump to the nearest 8-byte-aligned block -- increasing relative jump
  range from +/-32K to +/-240K.
  (mvra): Do the same for the mvra jump.

* libguile/vm.c (really_make_boot_program): Align the mvra.

* module/language/assembly.scm (align-block): New export, for aligning
  blocks.

* module/language/assembly/compile-bytecode.scm (write-bytecode): Emit
  jumps to the nearest 8-byte-aligned block. Effectively our range is 18
  bits in either direction. I would like to do this differently -- have
  long-br and long-br-if, and all the other br instructions go to 8 bits
  only. But the assembler doesn't have an appropriate representation to
  allow me to do this yet, so for now this is what we have.

* module/language/assembly/decompile-bytecode.scm (decode-load-program):
  Decode the 19-bit jumps.
2009-07-26 14:01:56 +02:00
Andy Wingo
28b119ee3d make sure all programs are 8-byte aligned
* libguile/objcodes.c (OBJCODE_COOKIE): Bump objcode cookie, as we added
  to struct scm_objcode.
* libguile/objcodes.h (struct scm_objcode): Add a uint32 after metalen
  and before base, so that if the structure has 8-byte alignment, base
  will have 8-byte alignment too. (Before, base was 12 bytes from the
  start of the structure, now it's 16 bytes.)

* libguile/vm-engine.h (ASSERT_ALIGNED_PROCEDURE): Add a check that can
  be turned on with VM_ENABLE_PARANOID_ASSERTIONS.
  (CACHE_PROGRAM): Call ASSERT_ALIGNED_PROCEDURE.

* libguile/vm-i-system.c (long-local-ref): Add a missing semicolon.

* libguile/vm.c (really_make_boot_program): Rework to operate directly
  on a malloc'd buffer, so that the program will be 8-byte aligned.

* module/language/assembly.scm (*program-header-len*): Add another 4 for
  the padding.
  (object->assembly): Fix case in which we would return (make-int8 0)
  instead of (make-int8:0). This would throw off compile-assembly.scm's
  use of addr+.

* module/language/assembly/compile-bytecode.scm (write-bytecode): Write
  out the padding int.

* module/language/assembly/decompile-bytecode.scm (decode-load-program):
  And pop off the padding int too.

* module/language/glil/compile-assembly.scm (glil->assembly): Don't pack
  the assembly, assume that assembly.scm has done it for us. If a
  program has a meta, pad out the program so that meta will be aligned.

* test-suite/tests/asm-to-bytecode.test: Adapt to expect programs to
  have the extra 4-byte padding int.
2009-07-26 12:57:11 +02:00
Andy Wingo
80545853d5 compiler support for nlocs >= 256
* libguile/vm-i-system.c (long-local-ref, long-local-set)
  (make-variable): New intructions, for handling nlocs >= 256.
* module/language/glil/compile-assembly.scm (glil->assembly): Compile
  <glil-lexical> with support for nlocs >= 256.
2009-07-24 11:00:32 +02:00
Andy Wingo
57ab0671d7 rename "closure-ref" to "free-ref"; s/vars/variables/ in some names
* libguile/programs.h:
* libguile/programs.c: (SCM_PROGRAM_FREE_VARIABLES): Rename from
  SCM_PROGRAM_FREE_VARS. Callers changed.
* libguile/programs.c (scm_make_program): Rename arg to
  "free_variables".
  (scm_program_free_variables): Rename from program-free-vars.

* libguile/vm-engine.h:
* libguile/vm-engine.c (VM_CHECK_FREE_VARIABLES): Rename from
  VM_CHECK_CLOSURE.
  (vm_engine, CACHE_PROGRAM): Rename closure and closure_count to free_vars and
  free_vars_vount.

* libguile/vm-i-system.c (FREE_VARIABLE_REF): Rename from CLOSURE_REF.
  (free-ref, free-boxed-ref, free-boxed-set): Rename from closure-ref,
  closure-boxed-ref, closure-boxed-set.
  (make-closure): Renamed from make-closure2.

* module/language/glil/compile-assembly.scm (glil->assembly): Hack to
  never write out the the old "make-closure" instruction. Will fix
  better later. Change to emit free-ref etc instead of closure-ref.

* module/language/tree-il/compile-glil.scm (flatten): Emit make-closure
  instead of make-closure2, now that the old make-closure is gone.

* module/system/vm/program.scm (system): Rename program-free-vars to
  program-free-variables.

* test-suite/tests/tree-il.test ("lambda"): Update for make-closure.
2009-07-23 17:15:17 +02:00
Andy Wingo
20d47c3915 remove "externals" from the vm
* libguile/frames.c (scm_frame_external_link): Removed.
* libguile/frames.h: No need to have the "external link" in the stack
  frame -- update macros to take the new situation into account.

* libguile/objcodes.h (struct scm_objcode): Rename the nexts field to
  "unused". In the future we can use it for nlocs, I think.
  (SCM_OBJCODE_NEXTS): removed.

* libguile/programs.h:
* libguile/programs.c (scm_make_program): Expect the third argument to
  be a vector of free variables, not a list of free variables.
  SCM_BOOL_F indicates no free variables, not SCM_EOL.
  (program_mark): Adapt.
  (scm_program_arity): No more nexts.
  (scm_program_free_vars): Replaces scm_program_externals.

* libguile/vm-engine.c (VM_CHECK_EXTERNAL)
  (vm_engine): No need for the "external" var.
* libguile/vm-engine.h (CACHE_PROGRAM): Update for SCM_PROGRAM_FREE_VARS
  instead of SCM_PROGRAM_EXTERNALS.
  (NEW_FRAME): Update for new frame size, and no need to cons up
  externals. Yay :)

* libguile/vm-i-loader.c (load-program): Update for scm_make_program.

* libguile/vm-i-system.c (external-ref, external-set): No more.
  (make-closure): No more.
  (goto/args): No need to re-cons externals here. Update for new stack
  frame size.
  (mv-call, return, return/values): Update for new frame size. No need
  to reinstate externals on return.

* libguile/vm.c (really_make_boot_program, scm_load_compiled_with_vm):
  Update for scm_make_program.
* module/language/objcode/spec.scm (objcode-env-externals): Treat '() as
  #f, for the externals. Need to clean this up later...
* module/system/vm/program.scm (arity:nexts): Remove. Rename
  program-external to program-free-vars.
2009-07-23 17:15:13 +02:00
Andy Wingo
8d90b35656 vm support for display closures
* libguile/vm-i-system.c (box, empty-box): Boxing values and storing
  them in local variables.
  (local-boxed-ref, local-boxed-set): A combination of local-ref then
  variable-ref/set.
  (make-closure2, closure-ref, closure-boxed-ref, closure-boxed-set):
  New ops. The idea is to migrate Guile over to using flat dispay
  closures. See the paper "Three Implementation Models for Scheme" by
  Kent Dybvig for more details; this is the "stack-based" model.

* libguile/vm-engine.c:
* libguile/vm-engine.h: Add the necessary infrastructure to keep track
  of a "closure" variable, like our "externals" in semantics, but
  minimal, flat, and O(1) in implementation.
2009-07-22 00:13:52 +02:00
Andy Wingo
a5cfddd560 renumber vm ops (objcode cookie bumped)
* libguile/objcodes.c (OBJCODE_COOKIE): Bump.

* libguile/vm-i-loader.c:
* libguile/vm-i-scheme.c:
* libguile/vm-i-system.c: Renumber instructions, so I can have a bit
  more space to work.
2009-07-21 22:22:38 +02:00
Daniel Kraft
4530432e01 Added make-nil instruction to VM and use it for Emacs' nil in the compiler.
* doc/ref/vm.texi: Document new instruction.
* libguile/vm-i-system.c: Add it to the VM.
* module/language/assembly.scm: Compile (const %nil) to (make-nil) assembly.
* module/language/glil/decompile-assembly.scm: Handle (make-nil)
* module/language/elisp/compile-tree-il.scm: Use (const %nil) for nil.
2009-06-29 13:16:27 +02:00
Neil Jerram
53befeb700 Change Guile license to LGPLv3+
(Not quite finished, the following will be done tomorrow.
   module/srfi/*.scm
   module/rnrs/*.scm
   module/scripts/*.scm
   testsuite/*.scm
   guile-readline/*
)
2009-06-17 00:22:09 +01:00
Andy Wingo
586cfdecfa new instructions: make-int64, make-uint64
* doc/ref/vm.texi (Loading Instructions): Remove references to
  load-integer and load-unsigned-integer -- they're still in the VM but
  will be removed at some point.
  (Data Control Instructions): Add make-int64 and make-uint64.

* libguile/vm-i-loader.c (load-unsigned-integer): Allow 8-byte values.
  But this instruction is on its way out, yo.

* libguile/vm-i-system.c (make-int64, make-uint64): New instructions.

* module/language/assembly.scm (object->assembly): Write out make-int64
  and make-uint64 instructions, using bytevectors to do the endianness
  conversion.
  (assembly->object): And pretty-print them back, for disassembly.

* module/language/glil/compile-assembly.scm: Don't generate load-integer
  / load-unsigned-integer instructions.
2009-06-07 00:53:48 +02:00
Andy Wingo
a9b0f876c1 add long-object-ref, long-toplevel-ref, long-toplevel-set
* libguile/vm-i-system.c (long-object-ref, long-toplevel-ref)
  (long-toplevel-set): Add new instructions, for accessing the object
  table with a 16-bit offset. HTMLprag defines a test program that has
  more than 256 constants, necessitating this addition.

* doc/ref/vm.texi: Mention the new instructions.

* module/language/glil/compile-assembly.scm: Emit long refs for object
  tables bigger than 256 entries.
2009-06-05 12:08:02 +02:00
Andy Wingo
b7393ea123 refactoring for toplevel-ref, toplevel-set, link-now
* libguile/vm-i-system.c (toplevel-ref, toplevel-set)
* libguile/vm-i-loader.c (link-now):
* libguile/vm.c (resolve_variable): Factor out common code to a static
  method. The compiler can still inline it, so it shouldn't have a
  significant performance effect.

* libguile/vm-engine.c (vm_error_no_such_module): Remove now-unused
  label.
2009-06-05 11:47:19 +02:00
Andy Wingo
81fd315299 update docs, clean up VM vestiges, macro docs, fix (/ a b c)
* doc/ref/api-procedures.texi (Compiled Procedures): Fix for API changes.

* doc/ref/compiler.texi (Compiling to the Virtual Machine): Replace GHIL
  docs with Tree-IL docs. Update the bits about the Scheme compiler to
  talk about Tree-IL and the expander instead of GHIL. Remove
  <glil-argument>. Add placeholder sections for assembly and bytecode.

* doc/ref/vm.texi: Update examples with what currently happens. Reword
  some things. Fix a couple errors.

* libguile/vm-i-system.c (externals): Remove this instruction, it's not
  used.

* module/ice-9/documentation.scm (object-documentation): If the object is
  a macro, try to return documentation on the macro transformer.

* module/language/assembly/disassemble.scm (disassemble-load-program):
  Fix problem in which we skipped the first element of the object vector,
  because of changes to procedure layouts a few months ago.

* module/language/scheme/spec.scm (read-file): Remove read-file
  definition.

* module/language/tree-il.scm: Reorder exports. Remove <lexical>, it was
  a compat shim to something that was never released. Fix `location'.

* module/language/tree-il/primitives.scm (/): Fix expander for more than
  two args to /.

* module/system/base/compile.scm (read-file-in): Remove unused
  definition.

* module/system/base/language.scm (system): Remove language-read-file.

* module/language/ecmascript/spec.scm (ecmascript): Remove read-file
  definition.
2009-05-24 13:09:01 +02:00
Andy Wingo
a1a482e0e9 and, or, cond etc use syntax-rules, compile scheme through tree-il
* libguile/vm-i-system.c:
* libguile/vm-engine.h (ASSERT_BOUND): New assertion, that a value is
  bound. Used by local-ref and external-ref in paranoid mode.

* module/ice-9/boot-9.scm (and, or, cond, case, do): Since we are
  switching to use psyntax as the first pass of the compiler, and perhaps
  soon of the interpreter too, we need to make sure it expands out all
  forms to primitive expressions. So define expanders for these derived
  syntax forms, as in the R5RS report.

* module/ice-9/psyntax-pp.scm: Regenerate, with core forms fully
  expanded.

* module/ice-9/psyntax.scm (build-void): New constructor, for making
  undefined values.
  (build-primref): Add in a hack so that primitive refs in the boot
  module expand out to toplevel refs, not module refs.
  (chi-void): Use build-void.
  (if): Define an expander for if that calls build-conditional.

* module/language/scheme/compile-tree-il.scm (compile-tree-il): Use let*
  so as not to depend on binding order for the result of
  (current-module).

* module/language/scheme/spec.scm (scheme): Switch over to tree-il as the
  primary intermediate language. Not yet fully tested, but at least it
  can compile psyntax-pp.scm.

* module/language/tree-il/analyze.scm (analyze-lexicals): Arguments don't
  count towards a function's nlocs.

* module/language/tree-il/compile-glil.scm (*comp-module*, compile-glil):
  Define a "compilation module" fluid.
  (flatten-lambda): Fix a call to make-glil-argument. Fix bug in
  heapifying arguments.
  (flatten): Fix number of arguments passed to apply instruction. Add a
  special case for `(values ...)'. If inlining primitive-refs fails,
  try expanding into toplevel-refs if the comp-module's variable is the
  same as the root variable.

* module/language/tree-il/optimize.scm (resolve-primitives!): Add missing
  src variable for <module-ref>.

* test-suite/tests/tree-il.test ("lambda"): Fix nlocs counts. Add a
  closure test case.
2009-05-20 11:15:22 +02:00
Andy Wingo
196b40932e fix handling of pre-modules errors in the vm
* libguile/vm-i-system.c (toplevel-ref, toplevel-set): Correct situation
  whereby we would not throw when toplevel vars were unbound, before
  modules had booted.
2009-04-17 15:20:18 +02:00
Ludovic Courtès
da8b47478e Avoid uses of deprecated forms in the VM code.
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 ()'.
2009-04-05 20:15:11 +02:00
Andy Wingo
2c0f99a28b fix nondeterminism in vm-i-system.c
* libguile/vm-i-system.c (br-if-eq, br-if-not-eq): Fix some
  nondeterminism caught by GCC 4.4.
2009-04-04 11:36:18 -07:00
Andy Wingo
4054d93183 fix variable not initialized spurious warnings
* libguile/vm-i-system.c: Work around some spurious "variable not
  initialized" messages on Etch's gcc.
2009-02-25 00:21:03 +01:00
Andy Wingo
81d677eb12 implement break and continue, work around overly recursive pmatch expansion
* libguile/vm-i-system.c (goto/args): On a tail call to a different
  procedure, init the locals to valid scheme values. Shouldn't matter for
  well-compiled scheme, but inspecting uninitialized locals could give
  garbage, or badly-compiled code could cause a crash.

* module/language/Makefile.am (NOCOMP_SOURCES): For the moment, don't
  compile compile-ghil.scm. I need to fix this.

* module/language/ecmascript/compile-ghil.scm (load-toplevel): Sigh, and
  disable stack checking in the evaluator too. Grr.
  (comp): Implement (unnamed) break and continue.

* module/language/ecmascript/parse.scm (parse-ecmascript): Fix var
  statements in `for' -- though it still doesn't work.
2009-02-21 20:28:28 +01:00
Andy Wingo
131f7d6c71 further ecmascript work
* libguile/vm-i-system.c (drop, return): Declare drop and return as
  popping one arg from the stack.

* module/language/ghil/compile-glil.scm:
* module/language/glil/compile-assembly.scm (make-meta): Adjust so that
  we declare 'drop and 'return calls as popping one arg from the stack.

* module/language/ecmascript/compile-ghil.scm (comp, comp-body): Flesh
  out a bit more. Most significantly, scoping within functions obeys
  javascript semantics better, modulo bits about with() forms.

* module/language/ecmascript/impl.scm: Define some runtime helper
  routines.
* module/language/Makefile.am (SOURCES): Add impl.scm.

* module/language/ecmascript/parse.scm (parse-ecmascript): Minor tweaks.

* module/language/ecmascript/tokenize.scm (read-identifier): Identifiers
  now read as symbols, not strings.
2009-02-19 13:55:55 +01:00
Andy Wingo
e06e857c8d in debug mode, make sure that calls to the vm can be captured via make-stack
* 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.
2009-02-05 12:28:19 +01:00
Andy Wingo
7edf200127 inline call to scm_make_program when making closures
* libguile/programs.c (scm_make_program): Add a comment.

* libguile/vm-engine.h (INIT_ARGS): Add a couple of UNLIKELY notes.

* libguile/vm-i-system.c (make-closure): Inline the call to
  scm_make_program, which avoids some redundant checks.
2009-02-05 00:20:51 +01:00
Andy Wingo
747a163532 make catch cache and restore vm regs, not the vm itself -- speedy speedy
* libguile/throw.c (scm_c_catch): Stash away the current vm's regs, and
  restore them if there's a nonlocal exit. There is a terrible case we
  have to handle if we catch from when the vm smob type isn't registered
  but the throw has the vm registered, but I think we handle this fine.

* libguile/vm-engine.c (vm_run):
* libguile/vm-i-system.c (halt): Don't make a dynwind context, so that
  entering the VM doesn't cons at all, except for the arg list. Maybe we
  can fix that bit too.

* libguile/vm.c (vm_reset_stack): Remove, as there is no more dynwind.
  (make_vm): Return #f if the tc16 hasn't yet been registered.
2009-02-04 00:09:38 +01:00
Andy Wingo
ef7e18683c inline dispatch to program cmethods, tick in return, remove old goops methods
* libguile/objects.c (scm_apply_generic): Inline the case when the
  generic is a program.

* libguile/vm-i-system.c (return): Tick when functions return.

* module/oop/goops.scm (object-eqv?, object-equal?): Remove these
  historical methods.
2009-02-03 21:13:01 +01:00
Andy Wingo
e311f5fa04 tick in calls, procedure-name works on compiled procedures
* module/system/vm/program.scm:
* libguile/programs.h:
* libguile/programs.c (scm_program_bindings, scm_program_bindings)
  (scm_program_properties, scm_program_name): Unfortunately, implement
  more procs in C, so that C can use them more easily.

* libguile/debug.c (scm_procedure_name): Dispatch to scm_program_name as
  appropriate.

* libguile/vm-i-system.c (call): Tick in a call.
2009-02-02 23:00:36 +01:00
Andy Wingo
5338b62b86 don't make intermediate garbage when making vectors in the vm
* libguile/vm-i-system.c (vector): Don't cons up a list just to make a
  vector. Saves a couple percent in total cell allocation when loading
  syncase. Probably not worth it, but foo!
2009-02-01 11:25:51 +01:00
Andy Wingo
53e28ed9b2 static opcodes; refactor program/objcode division; use new assembly pipeline
* 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.
2009-01-29 21:12:00 +01:00
Andy Wingo
2fda024221 move module and meta inside programs' object tables
* 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.
2009-01-17 16:42:53 +01:00
Andy Wingo
fb10a0084e allow `apply' on %nil-terminated lists
* libguile/vm-engine.h (PUSH_LIST): Add a parameter to check that the
  list was proper.

* libguile/vm-i-system.c: Adapt PUSH_LIST callsites to pass SCM_NULLP or
  SCM_NULL_OR_NIL_P, as appropriate. Add a check to return/values*.

* libguile/vm.c: Add lang.h header for SCM_NULL_OR_NIL_P.

* test-suite/tests/elisp.test: Fix XFAIL for elisp + apply.
2009-01-04 14:06:52 +01:00
Andy Wingo
b1b942b74c remove heap links in VM frames, incorporate vm frames into normal backtraces
* doc/ref/vm.texi (Stack Layout): Update to remove references to the
  "heap link".

* gdbinit: Update for "heap link" removal.

* libguile/frames.c:
* libguile/frames.h: Update macros and diagram for removal of "heap
  link". As part of this, we also remove "heap frames", replacing them
  with "vm frames", which are much like the interpreter's debug objects,
  but for VM stacks. That is to say, they don't actually hold the stack
  themselves, just the pointers into stack that's held by a continuation
  (either captured or current).

* libguile/stacks.c (stack_depth, read_frames): Since a "stack" object is
  really a copy of information that comes from somewhere else, it makes
  sense to copy over info from the VM, just as `make-stack' does from the
  evaluator. The tricky bit is to figure out how to interleave VM and
  interpreter frames. We do that by starting in the interpreter, and
  whenever the current frame's procedure is actually a program, we switch
  to the VM stack, switching back when we reach a "bootstrap frame". The
  last bit is hacky, but it does work...
  (is_vm_bootstrap_frame): Hacky predicate to see if a VM frame is a
  bootstrap frame.
  (scm_make_stack): Accept a VM frame in addition to debug frames.
  Probably has some bugs in this case. But in the case that the arg is
  #t (a common case), do the right thing, capturing the top VM frame as
  well, and interleaving those frames appropriately on the stack.

  As an accident, we lost the ability to limit the number of frames in
  the backtrace. We could add that back, but personally I always want
  *all* frames in the trace... Narrowing still works fine, though there
  are some hiccups sometimes -- e.g. an outer cut to a procedure that
  does a tail-call in VM code will never find the cut, as it no longer
  exists in the continuation.

* libguile/vm.h (struct scm_vm): So! Now that we have switched to save
  stacks in the normal make-stack, there's no more need for `this_frame'
  or `last_frame'. On the other hand, we can take this opportunity to fix
  tracing: when we're in a trace hook, we set `trace_frame' on the VM,
  so we know not to fire hooks when we're already in a hook.
  (struct scm_vm_cont): Expose this, as make-stack needs it to make VM
  frames from VM continuations.

* libguile/vm.c (scm_vm_trace_frame): New function, gets the current
  trace frame.
  (vm_mark, make_vm): Hook up the trace frame.
  (vm_dispatch_hook): New hook dispatcher, with a dynwind so it does the
  right thing if the hook exits nonlocally.

* libguile/vm-engine.c (vm_run): No more this_frame in the wind data.

* libguile/vm-engine.h (RUN_HOOK): Run hooks through the dispatcher.
  (ALIGN_AS_NON_IMMEDIATE, POP_LIST_ON_STACK): Remove unused code.
  (NEW_FRAME): Adapt for no HL in the frame.

* libguile/vm-i-system.c (goto/args, mv-call, return, return/values):
  Adapt for no HL in the frame.

* module/system/vm/frame.scm:
* module/system/vm/vm.scm: Beginnings of some reworkings, needs more
  thought.
2008-12-26 18:07:20 +01:00
Andy Wingo
f7e5296e04 late-variable-{ref,set} -> toplevel-{ref,set}
* benchmark/lib.scm:
* libguile/vm-i-system.c (toplevel-ref, toplevel-set):
* module/system/vm/assemble.scm (codegen):
* module/system/vm/disasm.scm (code-annotation):
  s/late-variable/toplevel/. It's just a better name.
2008-11-20 13:45:27 +01:00
Andy Wingo
9b10d0bcfd fix for (apply values '(1))
* libguile/vm-i-system.c (return/values): In the
  multiple-values-to-a-single-value-continuation (or MV but where N=1),
  null out the correct number of values from the stack. Fixes aborts on
  (apply values '(1)).

* testsuite/t-values.scm (call-with-values): Add a test.
2008-11-01 18:37:48 +01:00
Andy Wingo
42906d7406 fix multiple values coming from interpreted or C procedures
* libguile/vm-i-system.c (call, goto/args): Handle the case in which a
  non-program (i.e. interpreted program or a subr) returns multiple
  values.

* testsuite/t-values.scm: Add test case that exhibited this problem.
2008-11-01 18:19:19 +01:00
Andy Wingo
3de80ed52f recompiling with compile environments, fluid languages, cleanups
* ice-9/boot-9.scm (compile-time-environment): Remove definition from
  boot-9 -- instead, autoload it and `compile' from (system base
  compile).

* libguile/objcodes.h:
* libguile/objcodes.c (scm_objcode_to_program): Add an optional argument,
  `external', the external list to set on the returned program.

* libguile/vm-i-system.c (externals): New instruction, returns the
  external list. Only used by (compile-time-environment).

* libguile/vm.c (scm_load_compiled_with_vm): Adapt to
  scm_objcode_to_program change.

* module/language/scheme/translate.scm (translate): Actually pay
  attention to the environment passed as an argument.
  (custom-transformer-table): Expand out (compile-time-environment) to
  something that can be passed to `compile'.

* module/system/base/compile.scm (*current-language*): Instead of
  hard-coding `scheme' in various places, use a current language fluid,
  initialized to `scheme'.
  (compile-file, load-source-file): Adapt to *current-language*.
  (load-source-file): Ada
  (scheme-eval): Removed, no one used this.
  (compiled-file-name): Don't hard-code "scm" and "go"; instead use the
  %load-extensions and %load-compiled-extensions.
  (cenv-module, cenv-ghil-env, cenv-externals): Some accessors for
  compile-time environments.
  (compile-time-environment): Here we define (compile-time-environment)
  to something that will return #f; the compiler however produces
  different code as noted above.
  (compile): New function, compiles an expression into a thunk, then runs
  the thunk to get the value. Useful for procedures. The optional second
  argument can be either a module or a compile-time-environment; in the
  latter case, we can recompile even with lexical bindings.
  (compile-in): If the env specifies a module, set that module for the
  duration of the compilation.

* module/system/base/syntax.scm (%compute-initargs): Fix a bug where the
  default value for a field would always replace a user-supplied value.
  Whoops.

* module/system/il/ghil.scm (ghil-env-dereify): New function, takes the
  result of ghil-env-reify and turns it back into a GHIL environment.

* scripts/compile (compile): Remove some of the tricky error handling, as
  the library procedures handle this for us.

* test-suite/tests/compiler.test: Add a test for the dynamic compilation
  bits.
2008-10-30 10:57:36 +01:00
Andy Wingo
5e390de62f fix bug in self-tail-recursion with "external" variables; other sundries
* gdbinit (pp, inst): New commands.

* libguile/vm-engine.c (vm_error_not_a_pair): New error case.

* libguile/vm-i-scheme.c (VM_VALIDATE_CONS): New macro -- use this
  instead of SCM_VALIDATE_* because SCM_VALIDATE will exit nonlocally
  before we have a chance to sync the regs.
  (car, cdr, set-car, set-cdr): Use VM_VALIDATE_CONS.

* libguile/vm-i-system.c (goto/args): Bugfix: when doing a
  self-tail-recursion, allocate fresh externals. Fixes use of match.go.

* module/system/vm/assemble.scm (dump-object!): Add some checks that we
  aren't dumping out values that the VM can't handle.

* module/system/vm/disasm.scm (disassemble-externals): Fix rotten call to
  `print-info'.

* oop/goops/dispatch.scm: Add a FIXME.

* testsuite/Makefile.am (vm_test_files):
* testsuite/t-closure4.scm (extract-symbols): New test, distilled with
  much effort out of match.scm.

* ice-9/Makefile.am (NOCOMP_SOURCES): Re-enable compilation of match.scm.
  Yay!
2008-10-18 19:21:44 +02:00
Andy Wingo
1f40459f5c ensure that lists pushed onto the stack are proper
I saw this problem when running elisp.test -- it tries to apply a
function to an arglist ending in nil, which obviously is not null.

* libguile/vm-engine.h (PUSH_LIST): New helper macro, pushes the elements
  of a list onto the stack. Checks to make sure that the list is proper.

* libguile/vm-i-system.c (list-break, mv-call, apply, goto/apply)
  (goto/cc): Use LIST_BREAK.

* libguile/vm-engine.c (vm_error_improper_list): New error case.
2008-10-16 13:24:39 +02:00
Andy Wingo
28a2f57bde fix asyncs running in the vm; re-enable popen.scm compilation
* libguile/vm-i-system.c (goto/args): Sync the registers before doing the
  SCM_TICK. We probably need a different SCM_TICK that saves the regs
  only if necessary. This fixes GC problems with a compiled popen.scm.

* ice-9/Makefile.am: Re-enable popen.scm compilation.
2008-10-16 12:55:27 +02:00
Andy Wingo
27d43e3cf7 relax an assertion -- the test suite completes without aborting, whee
* libguile/vm-i-system.c (call/cc, goto/cc): Don't assert that ip matches
  vp->ip, because vp->ip is not restored by vm_reset_stack, and indeed
  it's re-set to 0 by `halt'. But still, perhaps reset_stack and halt
  should indeed reset vp->ip.
2008-10-11 12:01:25 +02:00
Andy Wingo
66db076ae1 NULLSTACK fixes for nonlocal exits in reentrant pre-wind handlers
* libguile/vm-i-system.c (goto/cc): Add some asserts here.

* libguile/vm.c (capture_vm_cont): Add some asserts here too.
  (reinstate_vm_cont): Null the correct number of bytes. Add a FIXME.
  (vm_reset_stack): Make the code a bit clearer. Null the correct number
  of bytes.

* libguile/vm-engine.h (NULLSTACK_FOR_NONLOCAL_EXIT): New macro, handles
  a very tricky case that took me days to find! Amply commented. Expands
  to nothing in the normal case.

* libguile/vm-i-system.c (call, goto/args, mv-call): Call
  NULLSTACK_FOR_NONLOCAL_EXIT in the right places. Fixes
  continuations.test.
2008-10-09 14:44:43 +02:00
Andy Wingo
11ea1aba9e precise stack marking, fix some missed references, still imperfect
* 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.
2008-10-03 16:00:30 +02:00
Andy Wingo
9a8cc8e7f7 be more like the interpreter in signalling wrong-num-args
* libguile/vm-engine.c: Call scm_wrong_num_args in the wrong-num-args
  case, to be more like the interpreter.

* libguile/vm-engine.h (ASSERT): New macro.

* libguile/vm-i-system.c (apply, goto/apply): Assert that nargs >= 2,
  because the compiler should always feed us correct instructions.
  (call/cc): If no values are returned to the continuation, signal
  no_values instead of wrong_num_args.
2008-10-02 11:00:55 +02:00
Andy Wingo
2bd859c81a fix compilation of quasiquote with splicing and improper lists
* libguile/vm-engine.h (POP_CONS_MARK): New macro, analagous to
  POP_LIST_MARK; used in quasiquote on improper lists.

* libguile/vm-i-system.c (cons-mark): New instruction. You know the
  drill, remove all your .go files please.

* module/system/il/compile.scm (codegen): Compile quasiquoted improper
  lists with splices correctly. Additionally check that we don't have
  slices in the CDR of an improper list.

* testsuite/t-quasiquote.scm: Add a test for unquote-splicing in improper
  lists.
2008-09-30 23:41:16 +02:00
Andy Wingo
887ce75ae8 fix some missed references when calling C functions
* gdbinit: Update to be a bit more useful.

* libguile/vm-i-system.c: Make sure that arguments to C procedures are
  visible on the stack so they get marked. Could be a source for the
  missed references.
2008-09-30 22:50:48 +02:00
Andy Wingo
fd3585753a compile @ and @@
* 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.
2008-09-30 00:31:17 +02:00
Andy Wingo
877ffa3f9c revert part of 7ff017002d that caused missed references
* libguile/programs.c (scm_c_make_closure): If the program is actually
  not a program, abort. This can happen if GC misses a reference, as
  currently seems to happen.

* libguile/vm.c (vm_mark): Revert part of
  7ff017002d, which changed the call to
  scm_mark_locations. I'm 99% *sure* this is wrong, but it seems to
  prevent missed references when recompiling the .go files in guile
  itself. Needs revisiting soon, but for the time being we can go back to
  where we were a couple of days ago.

* libguile/vm-i-system.c (halt, vector, vector-mark): Sync the registers
  before calling into C, as it may GC.
2008-09-28 23:08:14 +02:00
Andy Wingo
cd829416b2 fix handling of multiple values from c functions
* libguile/vm-i-system.c (mv-call, goto/cc): Fix handling of values
  returns from C or interpreted functions.
2008-09-25 12:08:54 +02:00
Andy Wingo
76282387ea compile call/cc, yee ha
* 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.
2008-09-25 11:07:54 +02:00
Andy Wingo
d51406fe87 lambda-lifting for (lambda () ...) as consumer of call-with-values
* 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.
2008-09-18 22:49:55 +02:00
Andy Wingo
efbd589204 compile call-with-values, woot!
* 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.
2008-09-16 00:26:22 +02:00
Andy Wingo
ef24c01bff add special case for (apply values ...)
* 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.
2008-09-15 00:04:34 +02:00