1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-03 05:20:16 +02:00
Commit graph

13 commits

Author SHA1 Message Date
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
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
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
da320011a3 add a multiple values return address to stack frames
* 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.
2008-09-13 19:22:28 +02:00
Andy Wingo
28106f547d inline frame replacement in tail-call
* 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.
2008-09-13 15:41:43 +02:00
Andy Wingo
f13c269b7f inline FREE_FRAME in return, sync stack_base in CACHE_REGISTER
* libguile/vm-engine.h (CACHE_REGISTER): Sync stack_base too.

* libguile/vm-i-system.c (return): Inline FREE_FRAME here,
  micro-optimizing a wee bit. Sounds silly, but it's to enable some
  refactoring.
2008-09-13 14:30:57 +02:00
Andy Wingo
2cdb8cdc0d clean up NEW_FRAME macro
* libguile/vm-engine.h (NEW_FRAME): Clean up this macro.
2008-09-13 14:19:30 +02:00
Andy Wingo
93d197be98 readability improvement in vm-i-scheme
* libguile/vm-engine.h:
* libguile/vm-i-scheme.c: Move some helper macros closer to their use
  sites.
2008-09-13 14:19:30 +02:00
Andy Wingo
83495480e8 merge guile-vm into libguile itself
* 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?
2008-08-21 18:39:30 -07:00
Renamed from src/vm_engine.h (Browse further)