2001-04-16 03:43:48 +00:00
|
|
|
|
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
2000-08-22 15:54:19 +00:00
|
|
|
|
*
|
|
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
|
|
|
|
* any later version.
|
|
|
|
|
|
*
|
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
|
*
|
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
|
* along with this software; see the file COPYING. If not, write to
|
|
|
|
|
|
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
|
|
|
|
|
* Boston, MA 02111-1307 USA
|
|
|
|
|
|
*
|
|
|
|
|
|
* As a special exception, the Free Software Foundation gives permission
|
|
|
|
|
|
* for additional uses of the text contained in its release of GUILE.
|
|
|
|
|
|
*
|
|
|
|
|
|
* The exception is that, if you link the GUILE library with other files
|
|
|
|
|
|
* to produce an executable, this does not by itself cause the
|
|
|
|
|
|
* resulting executable to be covered by the GNU General Public License.
|
|
|
|
|
|
* Your use of that executable is in no way restricted on account of
|
|
|
|
|
|
* linking the GUILE library code into it.
|
|
|
|
|
|
*
|
|
|
|
|
|
* This exception does not however invalidate any other reasons why
|
|
|
|
|
|
* the executable file might be covered by the GNU General Public License.
|
|
|
|
|
|
*
|
|
|
|
|
|
* This exception applies only to the code released by the
|
|
|
|
|
|
* Free Software Foundation under the name GUILE. If you copy
|
|
|
|
|
|
* code from other Free Software Foundation releases into a copy of
|
|
|
|
|
|
* GUILE, as the General Public License permits, the exception does
|
|
|
|
|
|
* not apply to the code that you add in this way. To avoid misleading
|
|
|
|
|
|
* anyone as to the status of such modified files, you must delete
|
|
|
|
|
|
* this exception notice from them.
|
|
|
|
|
|
*
|
|
|
|
|
|
* If you write modifications of your own for GUILE, it is your choice
|
|
|
|
|
|
* whether to permit this exception to apply to your modifications.
|
|
|
|
|
|
* If you do not wish that, delete this exception notice. */
|
|
|
|
|
|
|
2008-05-20 11:46:52 +02:00
|
|
|
|
#if HAVE_CONFIG_H
|
|
|
|
|
|
# include <config.h>
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
|
#include <string.h>
|
2008-08-21 18:39:30 -07:00
|
|
|
|
#include "vm-bootstrap.h"
|
2001-04-22 02:13:48 +00:00
|
|
|
|
#include "frames.h"
|
2001-04-01 05:03:41 +00:00
|
|
|
|
#include "instructions.h"
|
2001-04-16 03:43:48 +00:00
|
|
|
|
#include "objcodes.h"
|
2001-04-22 02:13:48 +00:00
|
|
|
|
#include "programs.h"
|
2000-08-22 15:54:19 +00:00
|
|
|
|
#include "vm.h"
|
|
|
|
|
|
|
|
|
|
|
|
/* I sometimes use this for debugging. */
|
|
|
|
|
|
#define vm_puts(OBJ) \
|
|
|
|
|
|
{ \
|
enable inlining; speed!
* module/system/il/inline.scm: New module, implements generic inlining of
scheme functions. It even does the right thing regarding (define
arity:nopt caddr) and such. So now there are many more inlines: the
arithmetics, `apply', the caddr family, etc. This makes the benchmarks
*much* faster.
* module/language/scheme/translate.scm (trans): Remove the
%scheme-primitives code in favor of the generic (scheme il inline)
code. Adds inlining for +, -, =, etc.
* src/vm.c (vm_puts): Fix to work.
* module/system/base/compile.scm (system): Export load/compile also.
* module/system/il/compile.scm (optimize): Further debitrotting, but I
haven't tried this function yet. It seems that <ghil-inst> was what
<ghil-inline> is.
* module/system/il/ghil.scm (*core-primitives*, *macro-module*)
(ghil-primitive-macro?, ghil-macro-expander, ghil-primitive?): Remove
these unused things.
* module/system/il/macros.scm: Removed, replaced with inline.scm.
* module/system/vm/assemble.scm (stack->bytes): Before, the final
serialization code did an (apply u8vector (apply append (map
u8vector->list ...))). Aside from the misspelling of append-map, this
ends up pushing all elements of the u8vector on the stack -- assuredly
not what you want. But besides even that, I think that pushing more
than 32k arguments on the stack brings out some other bug that I think
was hidden before, because now we actually use the `apply' VM
instruction. Further testing is needed here, I think. Fixed the code to
be more efficient, which fixes the manifestation of this particular
bug: a failure to self-compile after inlining was enabled.
* module/system/vm/bootstrap.scm: New module, serves to bootstrap
boot-9's `load-compiled'. That way when we load (system vm core), we're
loading compiled code already.
* module/system/vm/core.scm: Use (system vm bootstrap).
* src/guilec.in: Use the bootstrap code, so that we really are compiling
with an entirely compiled compiler.
* module/system/repl/repl.scm (default-catch-handler): An attempt at
making the repl print a backtrace; more work needed here.
* module/system/vm/frame.scm (make-frame-chain): Fix some misspellings --
I think, anyway.
2008-05-25 13:13:15 +02:00
|
|
|
|
scm_display (OBJ, scm_current_error_port ()); \
|
|
|
|
|
|
scm_newline (scm_current_error_port ()); \
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
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
|
|
|
|
/* The VM has a number of internal assertions that shouldn't normally be
|
|
|
|
|
|
necessary, but might be if you think you found a bug in the VM. */
|
|
|
|
|
|
#define VM_ENABLE_ASSERTIONS
|
|
|
|
|
|
|
|
|
|
|
|
/* We can add a mode that ensures that all stack items above the stack pointer
|
|
|
|
|
|
are NULL. This is useful for checking the internal consistency of the VM's
|
|
|
|
|
|
assumptions and its operators, but isn't necessary for normal operation. It
|
|
|
|
|
|
will ensure that assertions are enabled. */
|
|
|
|
|
|
#define VM_ENABLE_STACK_NULLING
|
|
|
|
|
|
|
|
|
|
|
|
#if defined (VM_ENABLE_STACK_NULLING) && !defined (VM_ENABLE_ASSERTIONS)
|
|
|
|
|
|
#define VM_ENABLE_ASSERTIONS
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* VM Continuation
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2005-04-22 11:07:06 +00:00
|
|
|
|
scm_t_bits scm_tc16_vm_cont;
|
2001-04-01 05:03:41 +00:00
|
|
|
|
|
2008-09-24 17:04:14 +02:00
|
|
|
|
struct scm_vm_cont {
|
|
|
|
|
|
scm_byte_t *ip;
|
|
|
|
|
|
scm_t_ptrdiff sp;
|
|
|
|
|
|
scm_t_ptrdiff fp;
|
|
|
|
|
|
scm_t_ptrdiff stack_size;
|
|
|
|
|
|
SCM *stack_base;
|
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
|
|
|
|
scm_t_ptrdiff reloc;
|
2008-09-24 17:04:14 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
|
|
|
|
|
|
|
#define SCM_VM_CONT_P(OBJ) SCM_SMOB_PREDICATE (scm_tc16_vm_cont, OBJ)
|
2008-09-24 17:04:14 +02:00
|
|
|
|
#define SCM_VM_CONT_DATA(CONT) ((struct scm_vm_cont *) SCM_CELL_WORD_1 (CONT))
|
|
|
|
|
|
|
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
|
|
|
|
static void
|
|
|
|
|
|
vm_mark_stack (SCM *base, scm_t_ptrdiff size, SCM *fp, scm_t_ptrdiff reloc)
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM *sp, *upper, *lower;
|
|
|
|
|
|
sp = base + size - 1;
|
|
|
|
|
|
|
|
|
|
|
|
while (sp > base && fp)
|
|
|
|
|
|
{
|
|
|
|
|
|
upper = SCM_FRAME_UPPER_ADDRESS (fp);
|
|
|
|
|
|
lower = SCM_FRAME_LOWER_ADDRESS (fp);
|
|
|
|
|
|
|
|
|
|
|
|
for (; sp >= upper; sp--)
|
|
|
|
|
|
if (SCM_NIMP (*sp))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (scm_in_heap_p (*sp))
|
|
|
|
|
|
scm_gc_mark (*sp);
|
|
|
|
|
|
else
|
|
|
|
|
|
fprintf (stderr, "BADNESS: crap on the stack: %p\n", *sp);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* skip ra, mvra */
|
|
|
|
|
|
sp -= 2;
|
|
|
|
|
|
|
|
|
|
|
|
/* update fp from the dynamic link */
|
|
|
|
|
|
fp = (SCM*)*sp-- + reloc;
|
|
|
|
|
|
|
|
|
|
|
|
/* mark from the hl down to the lower address */
|
|
|
|
|
|
for (; sp >= lower; sp--)
|
|
|
|
|
|
if (*sp && SCM_NIMP (*sp))
|
|
|
|
|
|
scm_gc_mark (*sp);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2008-09-24 17:04:14 +02:00
|
|
|
|
static SCM
|
|
|
|
|
|
vm_cont_mark (SCM obj)
|
|
|
|
|
|
{
|
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
|
|
|
|
struct scm_vm_cont *p = SCM_VM_CONT_DATA (obj);
|
2008-09-24 17:04:14 +02:00
|
|
|
|
|
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
|
|
|
|
vm_mark_stack (p->stack_base, p->stack_size, p->stack_base + p->fp, p->reloc);
|
2008-09-24 17:04:14 +02:00
|
|
|
|
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static scm_sizet
|
|
|
|
|
|
vm_cont_free (SCM obj)
|
|
|
|
|
|
{
|
|
|
|
|
|
struct scm_vm_cont *p = SCM_VM_CONT_DATA (obj);
|
|
|
|
|
|
|
|
|
|
|
|
scm_gc_free (p->stack_base, p->stack_size * sizeof (SCM), "stack-base");
|
|
|
|
|
|
scm_gc_free (p, sizeof (struct scm_vm), "vm");
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
|
|
|
|
|
static SCM
|
2001-04-06 00:17:39 +00:00
|
|
|
|
capture_vm_cont (struct scm_vm *vp)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2008-09-24 17:04:14 +02:00
|
|
|
|
struct scm_vm_cont *p = scm_gc_malloc (sizeof (*p), "capture_vm_cont");
|
|
|
|
|
|
p->stack_size = vp->sp - vp->stack_base + 1;
|
2005-04-22 16:00:33 +00:00
|
|
|
|
p->stack_base = scm_gc_malloc (p->stack_size * sizeof (SCM),
|
|
|
|
|
|
"capture_vm_cont");
|
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
|
|
|
|
#ifdef VM_ENABLE_STACK_NULLING
|
|
|
|
|
|
memset (p->stack_base, 0, p->stack_size * sizeof (SCM));
|
|
|
|
|
|
#endif
|
2001-04-06 00:17:39 +00:00
|
|
|
|
p->ip = vp->ip;
|
2008-09-24 17:04:14 +02:00
|
|
|
|
p->sp = vp->sp - vp->stack_base;
|
|
|
|
|
|
p->fp = vp->fp - vp->stack_base;
|
|
|
|
|
|
memcpy (p->stack_base, vp->stack_base, p->stack_size * sizeof (SCM));
|
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
|
|
|
|
p->reloc = p->stack_base - vp->stack_base;
|
2001-04-01 05:03:41 +00:00
|
|
|
|
SCM_RETURN_NEWSMOB (scm_tc16_vm_cont, p);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
2001-04-06 00:17:39 +00:00
|
|
|
|
reinstate_vm_cont (struct scm_vm *vp, SCM cont)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2008-09-24 17:04:14 +02:00
|
|
|
|
struct scm_vm_cont *p = SCM_VM_CONT_DATA (cont);
|
2001-04-06 00:17:39 +00:00
|
|
|
|
if (vp->stack_size < p->stack_size)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2001-04-01 05:03:41 +00:00
|
|
|
|
/* puts ("FIXME: Need to expand"); */
|
2000-08-22 15:54:19 +00:00
|
|
|
|
abort ();
|
|
|
|
|
|
}
|
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
|
|
|
|
#ifdef VM_ENABLE_STACK_NULLING
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_t_ptrdiff nzero = (vp->sp - vp->stack_base) - p->sp;
|
|
|
|
|
|
if (nzero > 0)
|
|
|
|
|
|
memset (vp->stack_base + p->stack_size, 0, nzero);
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
2001-04-06 00:17:39 +00:00
|
|
|
|
vp->ip = p->ip;
|
2008-09-24 17:04:14 +02:00
|
|
|
|
vp->sp = vp->stack_base + p->sp;
|
|
|
|
|
|
vp->fp = vp->stack_base + p->fp;
|
|
|
|
|
|
memcpy (vp->stack_base, p->stack_base, p->stack_size * sizeof (SCM));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* In theory, a number of vm instances can be active in the call trace, and we
|
|
|
|
|
|
only want to reify the continuations of those in the current continuation
|
|
|
|
|
|
root. I don't see a nice way to do this -- ideally it would involve dynwinds,
|
|
|
|
|
|
and previous values of the *the-vm* fluid within the current continuation
|
|
|
|
|
|
root. But we don't have access to continuation roots in the dynwind stack.
|
|
|
|
|
|
So, just punt for now -- take the current value of *the-vm*.
|
|
|
|
|
|
|
|
|
|
|
|
While I'm on the topic, ideally we could avoid copying the C stack if the
|
|
|
|
|
|
continuation root is inside VM code, and call/cc was invoked within that same
|
|
|
|
|
|
call to vm_run; but that's currently not implemented.
|
|
|
|
|
|
*/
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_vm_capture_continuations (void)
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM vm = scm_the_vm ();
|
|
|
|
|
|
return scm_acons (vm, capture_vm_cont (SCM_VM_DATA (vm)), SCM_EOL);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
scm_vm_reinstate_continuations (SCM conts)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (; conts != SCM_EOL; conts = SCM_CDR (conts))
|
|
|
|
|
|
reinstate_vm_cont (SCM_VM_DATA (SCM_CAAR (conts)), SCM_CDAR (conts));
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
fix stack corruption on vm-save-stack; more robust with nonlocal exits
* module/system/repl/command.scm: Coerce rationals to floats.
* module/system/vm/program.scm (program-documentation): Fix a typo, doh!
* src/vm.c (vm_reset_stack, struct vm_unwind_data): Add unwind handler to
reset vp->sp, vp->fp, and vp->this_frame when performing a nonlocal
exit from a vm_run.
(vm_heapify_frames_1): Don't repack the stack, it causes stack
corruption. I think we need spaghetti stacks to handle continuations,
not separate heap frames. I don't think call/cc is working now.
(vm-save-stack): Don't call heapify_frames, that modifies the stack
that we're copying. Instead call its helper, heapify_1.
* src/vm_engine.c (vm_run): Set up the vm_reset_stack unwind handler.
* src/vm_engine.h (IP_REG, SP_REG, FP_REG): If we got through all of the
checks without having these macros defined, define them as empty.
Happens on x86-64.
* src/vm_system.c (halt): End the dynwind before we return from the VM.
* src/vm_scheme.c (REL): Sync the regs before calling scm_lt_p et al,
cause they can do a nonlocal exit.
2008-08-07 19:04:25 +02:00
|
|
|
|
struct vm_unwind_data
|
|
|
|
|
|
{
|
|
|
|
|
|
struct scm_vm *vp;
|
|
|
|
|
|
SCM *sp;
|
|
|
|
|
|
SCM *fp;
|
|
|
|
|
|
SCM this_frame;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
vm_reset_stack (void *data)
|
|
|
|
|
|
{
|
|
|
|
|
|
struct vm_unwind_data *w = data;
|
|
|
|
|
|
|
|
|
|
|
|
w->vp->sp = w->sp;
|
|
|
|
|
|
w->vp->fp = w->fp;
|
|
|
|
|
|
w->vp->this_frame = w->this_frame;
|
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
|
|
|
|
#ifdef VM_ENABLE_STACK_NULLING
|
|
|
|
|
|
memset (w->vp->sp + 1, 0, w->vp->stack_size - (w->vp->sp + 1 - w->vp->stack_base));
|
|
|
|
|
|
#endif
|
fix stack corruption on vm-save-stack; more robust with nonlocal exits
* module/system/repl/command.scm: Coerce rationals to floats.
* module/system/vm/program.scm (program-documentation): Fix a typo, doh!
* src/vm.c (vm_reset_stack, struct vm_unwind_data): Add unwind handler to
reset vp->sp, vp->fp, and vp->this_frame when performing a nonlocal
exit from a vm_run.
(vm_heapify_frames_1): Don't repack the stack, it causes stack
corruption. I think we need spaghetti stacks to handle continuations,
not separate heap frames. I don't think call/cc is working now.
(vm-save-stack): Don't call heapify_frames, that modifies the stack
that we're copying. Instead call its helper, heapify_1.
* src/vm_engine.c (vm_run): Set up the vm_reset_stack unwind handler.
* src/vm_engine.h (IP_REG, SP_REG, FP_REG): If we got through all of the
checks without having these macros defined, define them as empty.
Happens on x86-64.
* src/vm_system.c (halt): End the dynwind before we return from the VM.
* src/vm_scheme.c (REL): Sync the regs before calling scm_lt_p et al,
cause they can do a nonlocal exit.
2008-08-07 19:04:25 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* VM Internal functions
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2008-09-02 00:27:59 -07:00
|
|
|
|
static SCM sym_vm_run;
|
|
|
|
|
|
static SCM sym_vm_error;
|
|
|
|
|
|
static SCM sym_debug;
|
2001-04-01 05:03:41 +00:00
|
|
|
|
|
|
|
|
|
|
static scm_byte_t *
|
|
|
|
|
|
vm_fetch_length (scm_byte_t *ip, size_t *lenp)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2001-04-06 23:15:53 +00:00
|
|
|
|
/* NOTE: format defined in system/vm/conv.scm */
|
2001-04-01 05:03:41 +00:00
|
|
|
|
*lenp = *ip++;
|
|
|
|
|
|
if (*lenp < 254)
|
|
|
|
|
|
return ip;
|
|
|
|
|
|
else if (*lenp == 254)
|
2001-04-05 05:48:59 +00:00
|
|
|
|
{
|
|
|
|
|
|
int b1 = *ip++;
|
|
|
|
|
|
int b2 = *ip++;
|
|
|
|
|
|
*lenp = (b1 << 8) + b2;
|
|
|
|
|
|
}
|
2001-04-01 05:03:41 +00:00
|
|
|
|
else
|
2001-04-05 05:48:59 +00:00
|
|
|
|
{
|
|
|
|
|
|
int b1 = *ip++;
|
|
|
|
|
|
int b2 = *ip++;
|
|
|
|
|
|
int b3 = *ip++;
|
|
|
|
|
|
int b4 = *ip++;
|
|
|
|
|
|
*lenp = (b1 << 24) + (b2 << 16) + (b3 << 8) + b4;
|
|
|
|
|
|
}
|
2001-04-01 05:03:41 +00:00
|
|
|
|
return ip;
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2001-04-23 04:28:13 +00:00
|
|
|
|
static SCM
|
2001-04-23 06:17:52 +00:00
|
|
|
|
vm_heapify_frames_1 (struct scm_vm *vp, SCM *fp, SCM *sp, SCM **destp)
|
2001-04-23 04:28:13 +00:00
|
|
|
|
{
|
2001-04-23 06:17:52 +00:00
|
|
|
|
SCM frame;
|
2001-04-23 04:28:13 +00:00
|
|
|
|
SCM *dl = SCM_FRAME_DYNAMIC_LINK (fp);
|
2008-08-20 14:32:36 -07:00
|
|
|
|
#if 0
|
2001-04-23 06:17:52 +00:00
|
|
|
|
SCM *src = SCM_FRAME_UPPER_ADDRESS (fp);
|
2008-08-20 14:32:36 -07:00
|
|
|
|
#endif
|
2001-04-23 06:17:52 +00:00
|
|
|
|
SCM *dest = SCM_FRAME_LOWER_ADDRESS (fp);
|
2001-04-23 04:28:13 +00:00
|
|
|
|
|
|
|
|
|
|
if (!dl)
|
|
|
|
|
|
{
|
|
|
|
|
|
/* The top frame */
|
|
|
|
|
|
frame = scm_c_make_heap_frame (fp);
|
|
|
|
|
|
fp = SCM_HEAP_FRAME_POINTER (frame);
|
|
|
|
|
|
SCM_FRAME_HEAP_LINK (fp) = SCM_BOOL_T;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2001-04-23 06:17:52 +00:00
|
|
|
|
/* Child frames */
|
2001-04-23 04:28:13 +00:00
|
|
|
|
SCM link = SCM_FRAME_HEAP_LINK (dl);
|
|
|
|
|
|
if (!SCM_FALSEP (link))
|
2001-04-23 06:17:52 +00:00
|
|
|
|
link = SCM_FRAME_LOWER_ADDRESS (dl)[-1]; /* self link */
|
2001-04-23 04:28:13 +00:00
|
|
|
|
else
|
2001-04-23 06:17:52 +00:00
|
|
|
|
link = vm_heapify_frames_1 (vp, dl, dest - 1, &dest);
|
2001-04-23 04:28:13 +00:00
|
|
|
|
frame = scm_c_make_heap_frame (fp);
|
|
|
|
|
|
fp = SCM_HEAP_FRAME_POINTER (frame);
|
2008-10-09 12:17:51 +02:00
|
|
|
|
/* FIXME: I don't think we should be storing heap links on the stack. */
|
2001-04-23 04:28:13 +00:00
|
|
|
|
SCM_FRAME_HEAP_LINK (fp) = link;
|
2005-11-01 21:29:04 +00:00
|
|
|
|
SCM_FRAME_SET_DYNAMIC_LINK (fp, SCM_HEAP_FRAME_POINTER (link));
|
2001-04-23 04:28:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
fix stack corruption on vm-save-stack; more robust with nonlocal exits
* module/system/repl/command.scm: Coerce rationals to floats.
* module/system/vm/program.scm (program-documentation): Fix a typo, doh!
* src/vm.c (vm_reset_stack, struct vm_unwind_data): Add unwind handler to
reset vp->sp, vp->fp, and vp->this_frame when performing a nonlocal
exit from a vm_run.
(vm_heapify_frames_1): Don't repack the stack, it causes stack
corruption. I think we need spaghetti stacks to handle continuations,
not separate heap frames. I don't think call/cc is working now.
(vm-save-stack): Don't call heapify_frames, that modifies the stack
that we're copying. Instead call its helper, heapify_1.
* src/vm_engine.c (vm_run): Set up the vm_reset_stack unwind handler.
* src/vm_engine.h (IP_REG, SP_REG, FP_REG): If we got through all of the
checks without having these macros defined, define them as empty.
Happens on x86-64.
* src/vm_system.c (halt): End the dynwind before we return from the VM.
* src/vm_scheme.c (REL): Sync the regs before calling scm_lt_p et al,
cause they can do a nonlocal exit.
2008-08-07 19:04:25 +02:00
|
|
|
|
/* Apparently the intention here is to be able to have a frame on the heap,
|
|
|
|
|
|
but data on the stack, so that you can push as much as you want on the
|
|
|
|
|
|
stack; but I think that it's currently causing borkage with nonlocal exits
|
|
|
|
|
|
and the unwind handler, which reinstates the sp and fp, but it's no longer
|
|
|
|
|
|
pointing at a valid stack frame. So disable for now, we'll get back to
|
|
|
|
|
|
this later. */
|
|
|
|
|
|
#if 0
|
2001-04-23 04:28:13 +00:00
|
|
|
|
/* Move stack data */
|
2001-04-23 06:17:52 +00:00
|
|
|
|
for (; src <= sp; src++, dest++)
|
|
|
|
|
|
*dest = *src;
|
|
|
|
|
|
*destp = dest;
|
fix stack corruption on vm-save-stack; more robust with nonlocal exits
* module/system/repl/command.scm: Coerce rationals to floats.
* module/system/vm/program.scm (program-documentation): Fix a typo, doh!
* src/vm.c (vm_reset_stack, struct vm_unwind_data): Add unwind handler to
reset vp->sp, vp->fp, and vp->this_frame when performing a nonlocal
exit from a vm_run.
(vm_heapify_frames_1): Don't repack the stack, it causes stack
corruption. I think we need spaghetti stacks to handle continuations,
not separate heap frames. I don't think call/cc is working now.
(vm-save-stack): Don't call heapify_frames, that modifies the stack
that we're copying. Instead call its helper, heapify_1.
* src/vm_engine.c (vm_run): Set up the vm_reset_stack unwind handler.
* src/vm_engine.h (IP_REG, SP_REG, FP_REG): If we got through all of the
checks without having these macros defined, define them as empty.
Happens on x86-64.
* src/vm_system.c (halt): End the dynwind before we return from the VM.
* src/vm_scheme.c (REL): Sync the regs before calling scm_lt_p et al,
cause they can do a nonlocal exit.
2008-08-07 19:04:25 +02:00
|
|
|
|
#endif
|
2001-04-23 04:28:13 +00:00
|
|
|
|
|
|
|
|
|
|
return frame;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static SCM
|
|
|
|
|
|
vm_heapify_frames (SCM vm)
|
|
|
|
|
|
{
|
|
|
|
|
|
struct scm_vm *vp = SCM_VM_DATA (vm);
|
|
|
|
|
|
if (SCM_FALSEP (SCM_FRAME_HEAP_LINK (vp->fp)))
|
|
|
|
|
|
{
|
2001-04-23 06:17:52 +00:00
|
|
|
|
SCM *dest;
|
|
|
|
|
|
vp->this_frame = vm_heapify_frames_1 (vp, vp->fp, vp->sp, &dest);
|
2001-04-23 04:28:13 +00:00
|
|
|
|
vp->fp = SCM_HEAP_FRAME_POINTER (vp->this_frame);
|
2001-04-23 06:17:52 +00:00
|
|
|
|
vp->sp = dest - 1;
|
2001-04-23 04:28:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
return vp->this_frame;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* VM
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2001-04-07 11:54:36 +00:00
|
|
|
|
#define VM_DEFAULT_STACK_SIZE (16 * 1024)
|
2001-04-01 05:03:41 +00:00
|
|
|
|
|
|
|
|
|
|
#define VM_REGULAR_ENGINE 0
|
|
|
|
|
|
#define VM_DEBUG_ENGINE 1
|
|
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
#define VM_NAME vm_regular_engine
|
|
|
|
|
|
#define VM_ENGINE VM_REGULAR_ENGINE
|
2008-08-21 18:39:30 -07:00
|
|
|
|
#include "vm-engine.c"
|
2001-04-01 05:03:41 +00:00
|
|
|
|
#undef VM_NAME
|
|
|
|
|
|
#undef VM_ENGINE
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#define VM_NAME vm_debug_engine
|
|
|
|
|
|
#define VM_ENGINE VM_DEBUG_ENGINE
|
2008-08-21 18:39:30 -07:00
|
|
|
|
#include "vm-engine.c"
|
2001-04-01 05:03:41 +00:00
|
|
|
|
#undef VM_NAME
|
|
|
|
|
|
#undef VM_ENGINE
|
|
|
|
|
|
|
2005-04-22 11:07:06 +00:00
|
|
|
|
scm_t_bits scm_tc16_vm;
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
2008-09-24 11:47:25 +02:00
|
|
|
|
SCM scm_the_vm_fluid;
|
2001-04-06 05:00:10 +00:00
|
|
|
|
|
2000-08-22 15:54:19 +00:00
|
|
|
|
static SCM
|
2001-04-01 05:03:41 +00:00
|
|
|
|
make_vm (void)
|
|
|
|
|
|
#define FUNC_NAME "make_vm"
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2001-04-01 05:03:41 +00:00
|
|
|
|
int i;
|
2005-04-22 16:00:33 +00:00
|
|
|
|
struct scm_vm *vp = scm_gc_malloc (sizeof (struct scm_vm), "vm");
|
|
|
|
|
|
|
2001-04-06 00:17:39 +00:00
|
|
|
|
vp->stack_size = VM_DEFAULT_STACK_SIZE;
|
2005-04-22 16:00:33 +00:00
|
|
|
|
vp->stack_base = scm_gc_malloc (vp->stack_size * sizeof (SCM),
|
|
|
|
|
|
"stack-base");
|
2001-04-07 09:39:38 +00:00
|
|
|
|
vp->stack_limit = vp->stack_base + vp->stack_size - 3;
|
|
|
|
|
|
vp->ip = NULL;
|
|
|
|
|
|
vp->sp = vp->stack_base - 1;
|
|
|
|
|
|
vp->fp = NULL;
|
2001-04-06 00:17:39 +00:00
|
|
|
|
vp->time = 0;
|
|
|
|
|
|
vp->clock = 0;
|
|
|
|
|
|
vp->options = SCM_EOL;
|
2001-04-23 04:28:13 +00:00
|
|
|
|
vp->this_frame = SCM_BOOL_F;
|
2001-04-22 02:13:48 +00:00
|
|
|
|
vp->last_frame = SCM_BOOL_F;
|
improve source loc info in nonlocal exits and backtraces
* module/system/il/compile.scm (codegen): The currently-executing
instruction is actually the one right before the instruction pointer;
so for purposes of assv to find a source location for an ip, put the
source after the code, as it was before.
* module/system/vm/debug.scm (vm-backtrace): Move more code to frame.scm.
* module/system/vm/frame.scm (make-frame-chain): Include all frames, even
the bootstrap one. For a reentrant backtrace we'll have boostrap
programs anyway. Probably should check for objcode[2] == scm_op_halt,
to not show those frames in the trace.
(frame-line-number, frame-file): New helpers.
(print-frame): Print out the line number too.
(frame-call-representation): Code from print-frame-call moved here.
(print-frame-chain-as-backtrace): A backtrace printer, yays.
(program-name): Check link validity before calling frame-address on it.
* module/system/vm/program.scm (source:addr, source:line, source:column)
(source:file): New accessors for the elements of program-sources.
* module/system/vm/vm.scm (vm:last-ip): New export.
(vm-last-frame-chain): Use vm:last-ip in making the frame chain.
* src/vm.h (struct scm_vm):
* src/vm.c (make_vm, scm_vm_last_ip, scm_vm_save_stack): Save the last
instruction pointer when saving the stack. Really though, we should be
saving all of the stack data on a spaghetti stack.
* src/vm_system.c (late-variable-ref): Pointless s/REGISTER/BEFORE_GC/.
2008-08-08 12:55:57 +02:00
|
|
|
|
vp->last_ip = NULL;
|
2001-04-01 05:03:41 +00:00
|
|
|
|
for (i = 0; i < SCM_VM_NUM_HOOKS; i++)
|
2001-04-06 00:17:39 +00:00
|
|
|
|
vp->hooks[i] = SCM_BOOL_F;
|
|
|
|
|
|
SCM_RETURN_NEWSMOB (scm_tc16_vm, vp);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
2001-04-01 05:03:41 +00:00
|
|
|
|
#undef FUNC_NAME
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
|
|
|
|
|
static SCM
|
2001-04-01 05:03:41 +00:00
|
|
|
|
vm_mark (SCM obj)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2001-04-01 05:03:41 +00:00
|
|
|
|
int i;
|
2001-04-06 00:17:39 +00:00
|
|
|
|
struct scm_vm *vp = SCM_VM_DATA (obj);
|
2001-04-01 05:03:41 +00:00
|
|
|
|
|
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
|
|
|
|
#ifdef VM_ENABLE_STACK_NULLING
|
|
|
|
|
|
if (vp->sp >= vp->stack_base)
|
|
|
|
|
|
if (!vp->sp[0] || vp->sp[1])
|
|
|
|
|
|
abort ();
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
/* mark the stack, precisely */
|
|
|
|
|
|
vm_mark_stack (vp->stack_base, vp->sp + 1 - vp->stack_base, vp->fp, 0);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
2001-04-23 04:28:13 +00:00
|
|
|
|
/* mark other objects */
|
2001-04-01 05:03:41 +00:00
|
|
|
|
for (i = 0; i < SCM_VM_NUM_HOOKS; i++)
|
2001-04-06 00:17:39 +00:00
|
|
|
|
scm_gc_mark (vp->hooks[i]);
|
2001-04-23 04:28:13 +00:00
|
|
|
|
scm_gc_mark (vp->this_frame);
|
2001-04-22 02:13:48 +00:00
|
|
|
|
scm_gc_mark (vp->last_frame);
|
2001-04-06 00:17:39 +00:00
|
|
|
|
return vp->options;
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
|
static scm_sizet
|
|
|
|
|
|
vm_free (SCM obj)
|
|
|
|
|
|
{
|
2001-04-06 00:17:39 +00:00
|
|
|
|
struct scm_vm *vp = SCM_VM_DATA (obj);
|
2005-04-22 16:00:33 +00:00
|
|
|
|
|
|
|
|
|
|
scm_gc_free (vp->stack_base, vp->stack_size * sizeof (SCM),
|
|
|
|
|
|
"stack-base");
|
|
|
|
|
|
scm_gc_free (vp, sizeof (struct scm_vm), "vm");
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
2001-04-01 05:03:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_vm_apply (SCM vm, SCM program, SCM args)
|
|
|
|
|
|
#define FUNC_NAME "scm_vm_apply"
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2001-04-01 05:03:41 +00:00
|
|
|
|
SCM_VALIDATE_PROGRAM (1, program);
|
2001-04-11 20:57:44 +00:00
|
|
|
|
return vm_run (vm, program, args);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
2001-04-01 05:03:41 +00:00
|
|
|
|
#undef FUNC_NAME
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
|
|
|
|
|
/* Scheme interface */
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_vm_version, "vm-version", 0, 0, 0,
|
2001-04-01 05:03:41 +00:00
|
|
|
|
(void),
|
|
|
|
|
|
"")
|
2000-08-22 15:54:19 +00:00
|
|
|
|
#define FUNC_NAME s_scm_vm_version
|
|
|
|
|
|
{
|
2008-08-02 12:17:27 +02:00
|
|
|
|
return scm_from_locale_string (PACKAGE_VERSION);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2001-04-06 05:00:10 +00:00
|
|
|
|
SCM_DEFINE (scm_the_vm, "the-vm", 0, 0, 0,
|
2008-08-20 14:32:36 -07:00
|
|
|
|
(void),
|
2001-04-06 05:00:10 +00:00
|
|
|
|
"")
|
|
|
|
|
|
#define FUNC_NAME s_scm_the_vm
|
|
|
|
|
|
{
|
2008-09-25 11:04:35 +02:00
|
|
|
|
SCM ret;
|
|
|
|
|
|
|
|
|
|
|
|
if (SCM_NFALSEP ((ret = scm_fluid_ref (scm_the_vm_fluid))))
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
|
|
ret = make_vm ();
|
|
|
|
|
|
scm_fluid_set_x (scm_the_vm_fluid, ret);
|
|
|
|
|
|
return ret;
|
2001-04-06 05:00:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
|
2000-08-22 15:54:19 +00:00
|
|
|
|
SCM_DEFINE (scm_vm_p, "vm?", 1, 0, 0,
|
|
|
|
|
|
(SCM obj),
|
2001-04-01 05:03:41 +00:00
|
|
|
|
"")
|
2000-08-22 15:54:19 +00:00
|
|
|
|
#define FUNC_NAME s_scm_vm_p
|
|
|
|
|
|
{
|
|
|
|
|
|
return SCM_BOOL (SCM_VM_P (obj));
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_make_vm, "make-vm", 0, 0, 0,
|
2001-04-01 05:03:41 +00:00
|
|
|
|
(void),
|
|
|
|
|
|
"")
|
|
|
|
|
|
#define FUNC_NAME s_scm_make_vm,
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2001-04-01 05:03:41 +00:00
|
|
|
|
return make_vm ();
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
|
SCM_DEFINE (scm_vm_ip, "vm:ip", 1, 0, 0,
|
2000-08-22 15:54:19 +00:00
|
|
|
|
(SCM vm),
|
2001-04-01 05:03:41 +00:00
|
|
|
|
"")
|
|
|
|
|
|
#define FUNC_NAME s_scm_vm_ip
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
|
|
|
|
|
SCM_VALIDATE_VM (1, vm);
|
2005-05-02 16:32:32 +00:00
|
|
|
|
return scm_from_ulong ((unsigned long) SCM_VM_DATA (vm)->ip);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_vm_sp, "vm:sp", 1, 0, 0,
|
|
|
|
|
|
(SCM vm),
|
2001-04-01 05:03:41 +00:00
|
|
|
|
"")
|
2000-08-22 15:54:19 +00:00
|
|
|
|
#define FUNC_NAME s_scm_vm_sp
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_VALIDATE_VM (1, vm);
|
2005-05-02 16:32:32 +00:00
|
|
|
|
return scm_from_ulong ((unsigned long) SCM_VM_DATA (vm)->sp);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_vm_fp, "vm:fp", 1, 0, 0,
|
|
|
|
|
|
(SCM vm),
|
2001-04-01 05:03:41 +00:00
|
|
|
|
"")
|
2000-08-22 15:54:19 +00:00
|
|
|
|
#define FUNC_NAME s_scm_vm_fp
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_VALIDATE_VM (1, vm);
|
2005-05-02 16:32:32 +00:00
|
|
|
|
return scm_from_ulong ((unsigned long) SCM_VM_DATA (vm)->fp);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
|
#define VM_DEFINE_HOOK(n) \
|
|
|
|
|
|
{ \
|
2001-04-06 00:17:39 +00:00
|
|
|
|
struct scm_vm *vp; \
|
2001-04-01 05:03:41 +00:00
|
|
|
|
SCM_VALIDATE_VM (1, vm); \
|
2001-04-06 00:17:39 +00:00
|
|
|
|
vp = SCM_VM_DATA (vm); \
|
|
|
|
|
|
if (SCM_FALSEP (vp->hooks[n])) \
|
2005-04-28 15:45:59 +00:00
|
|
|
|
vp->hooks[n] = scm_make_hook (SCM_I_MAKINUM (1)); \
|
2001-04-06 00:17:39 +00:00
|
|
|
|
return vp->hooks[n]; \
|
2001-04-01 05:03:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_vm_boot_hook, "vm-boot-hook", 1, 0, 0,
|
2000-08-22 15:54:19 +00:00
|
|
|
|
(SCM vm),
|
2001-04-01 05:03:41 +00:00
|
|
|
|
"")
|
|
|
|
|
|
#define FUNC_NAME s_scm_vm_boot_hook
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2001-04-01 05:03:41 +00:00
|
|
|
|
VM_DEFINE_HOOK (SCM_VM_BOOT_HOOK);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
|
SCM_DEFINE (scm_vm_halt_hook, "vm-halt-hook", 1, 0, 0,
|
|
|
|
|
|
(SCM vm),
|
|
|
|
|
|
"")
|
|
|
|
|
|
#define FUNC_NAME s_scm_vm_halt_hook
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2001-04-01 05:03:41 +00:00
|
|
|
|
VM_DEFINE_HOOK (SCM_VM_HALT_HOOK);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
|
SCM_DEFINE (scm_vm_next_hook, "vm-next-hook", 1, 0, 0,
|
2000-08-22 15:54:19 +00:00
|
|
|
|
(SCM vm),
|
2001-04-01 05:03:41 +00:00
|
|
|
|
"")
|
|
|
|
|
|
#define FUNC_NAME s_scm_vm_next_hook
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2001-04-01 05:03:41 +00:00
|
|
|
|
VM_DEFINE_HOOK (SCM_VM_NEXT_HOOK);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2001-05-02 15:05:05 +00:00
|
|
|
|
SCM_DEFINE (scm_vm_break_hook, "vm-break-hook", 1, 0, 0,
|
|
|
|
|
|
(SCM vm),
|
|
|
|
|
|
"")
|
|
|
|
|
|
#define FUNC_NAME s_scm_vm_break_hook
|
|
|
|
|
|
{
|
|
|
|
|
|
VM_DEFINE_HOOK (SCM_VM_BREAK_HOOK);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
|
SCM_DEFINE (scm_vm_enter_hook, "vm-enter-hook", 1, 0, 0,
|
|
|
|
|
|
(SCM vm),
|
|
|
|
|
|
"")
|
|
|
|
|
|
#define FUNC_NAME s_scm_vm_enter_hook
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2001-04-01 05:03:41 +00:00
|
|
|
|
VM_DEFINE_HOOK (SCM_VM_ENTER_HOOK);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
|
SCM_DEFINE (scm_vm_apply_hook, "vm-apply-hook", 1, 0, 0,
|
|
|
|
|
|
(SCM vm),
|
|
|
|
|
|
"")
|
|
|
|
|
|
#define FUNC_NAME s_scm_vm_apply_hook
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2001-04-01 05:03:41 +00:00
|
|
|
|
VM_DEFINE_HOOK (SCM_VM_APPLY_HOOK);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
|
SCM_DEFINE (scm_vm_exit_hook, "vm-exit-hook", 1, 0, 0,
|
2000-08-22 15:54:19 +00:00
|
|
|
|
(SCM vm),
|
2001-04-01 05:03:41 +00:00
|
|
|
|
"")
|
|
|
|
|
|
#define FUNC_NAME s_scm_vm_exit_hook
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2001-04-01 05:03:41 +00:00
|
|
|
|
VM_DEFINE_HOOK (SCM_VM_EXIT_HOOK);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
|
SCM_DEFINE (scm_vm_return_hook, "vm-return-hook", 1, 0, 0,
|
2000-08-22 15:54:19 +00:00
|
|
|
|
(SCM vm),
|
2001-04-01 05:03:41 +00:00
|
|
|
|
"")
|
|
|
|
|
|
#define FUNC_NAME s_scm_vm_return_hook
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2001-04-01 05:03:41 +00:00
|
|
|
|
VM_DEFINE_HOOK (SCM_VM_RETURN_HOOK);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
|
SCM_DEFINE (scm_vm_option, "vm-option", 2, 0, 0,
|
|
|
|
|
|
(SCM vm, SCM key),
|
|
|
|
|
|
"")
|
|
|
|
|
|
#define FUNC_NAME s_scm_vm_option
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
|
|
|
|
|
SCM_VALIDATE_VM (1, vm);
|
2001-04-01 05:03:41 +00:00
|
|
|
|
return scm_assq_ref (SCM_VM_DATA (vm)->options, key);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
|
SCM_DEFINE (scm_set_vm_option_x, "set-vm-option!", 3, 0, 0,
|
|
|
|
|
|
(SCM vm, SCM key, SCM val),
|
|
|
|
|
|
"")
|
|
|
|
|
|
#define FUNC_NAME s_scm_set_vm_option_x
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
|
|
|
|
|
SCM_VALIDATE_VM (1, vm);
|
2001-04-01 05:03:41 +00:00
|
|
|
|
SCM_VM_DATA (vm)->options
|
|
|
|
|
|
= scm_assq_set_x (SCM_VM_DATA (vm)->options, key, val);
|
|
|
|
|
|
return SCM_UNSPECIFIED;
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
|
SCM_DEFINE (scm_vm_stats, "vm-stats", 1, 0, 0,
|
2000-08-22 15:54:19 +00:00
|
|
|
|
(SCM vm),
|
2001-04-01 05:03:41 +00:00
|
|
|
|
"")
|
|
|
|
|
|
#define FUNC_NAME s_scm_vm_stats
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2001-04-01 05:03:41 +00:00
|
|
|
|
SCM stats;
|
|
|
|
|
|
|
2000-08-22 15:54:19 +00:00
|
|
|
|
SCM_VALIDATE_VM (1, vm);
|
2001-04-01 05:03:41 +00:00
|
|
|
|
|
2005-04-29 14:12:12 +00:00
|
|
|
|
stats = scm_make_vector (SCM_I_MAKINUM (2), SCM_UNSPECIFIED);
|
|
|
|
|
|
scm_vector_set_x (stats, SCM_I_MAKINUM (0),
|
2005-04-22 11:07:06 +00:00
|
|
|
|
scm_from_ulong (SCM_VM_DATA (vm)->time));
|
2005-04-29 14:12:12 +00:00
|
|
|
|
scm_vector_set_x (stats, SCM_I_MAKINUM (1),
|
2005-04-22 11:07:06 +00:00
|
|
|
|
scm_from_ulong (SCM_VM_DATA (vm)->clock));
|
2001-04-01 05:03:41 +00:00
|
|
|
|
|
|
|
|
|
|
return stats;
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
|
#define VM_CHECK_RUNNING(vm) \
|
|
|
|
|
|
if (!SCM_VM_DATA (vm)->ip) \
|
|
|
|
|
|
SCM_MISC_ERROR ("Not running", SCM_LIST1 (vm))
|
|
|
|
|
|
|
2001-04-23 04:28:13 +00:00
|
|
|
|
SCM_DEFINE (scm_vm_this_frame, "vm-this-frame", 1, 0, 0,
|
2000-08-22 15:54:19 +00:00
|
|
|
|
(SCM vm),
|
2001-04-01 05:03:41 +00:00
|
|
|
|
"")
|
2001-04-23 04:28:13 +00:00
|
|
|
|
#define FUNC_NAME s_scm_vm_this_frame
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
|
|
|
|
|
SCM_VALIDATE_VM (1, vm);
|
2001-04-23 04:28:13 +00:00
|
|
|
|
return SCM_VM_DATA (vm)->this_frame;
|
2001-04-22 02:13:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_vm_last_frame, "vm-last-frame", 1, 0, 0,
|
|
|
|
|
|
(SCM vm),
|
|
|
|
|
|
"")
|
|
|
|
|
|
#define FUNC_NAME s_scm_vm_last_frame
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_VALIDATE_VM (1, vm);
|
|
|
|
|
|
return SCM_VM_DATA (vm)->last_frame;
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
improve source loc info in nonlocal exits and backtraces
* module/system/il/compile.scm (codegen): The currently-executing
instruction is actually the one right before the instruction pointer;
so for purposes of assv to find a source location for an ip, put the
source after the code, as it was before.
* module/system/vm/debug.scm (vm-backtrace): Move more code to frame.scm.
* module/system/vm/frame.scm (make-frame-chain): Include all frames, even
the bootstrap one. For a reentrant backtrace we'll have boostrap
programs anyway. Probably should check for objcode[2] == scm_op_halt,
to not show those frames in the trace.
(frame-line-number, frame-file): New helpers.
(print-frame): Print out the line number too.
(frame-call-representation): Code from print-frame-call moved here.
(print-frame-chain-as-backtrace): A backtrace printer, yays.
(program-name): Check link validity before calling frame-address on it.
* module/system/vm/program.scm (source:addr, source:line, source:column)
(source:file): New accessors for the elements of program-sources.
* module/system/vm/vm.scm (vm:last-ip): New export.
(vm-last-frame-chain): Use vm:last-ip in making the frame chain.
* src/vm.h (struct scm_vm):
* src/vm.c (make_vm, scm_vm_last_ip, scm_vm_save_stack): Save the last
instruction pointer when saving the stack. Really though, we should be
saving all of the stack data on a spaghetti stack.
* src/vm_system.c (late-variable-ref): Pointless s/REGISTER/BEFORE_GC/.
2008-08-08 12:55:57 +02:00
|
|
|
|
SCM_DEFINE (scm_vm_last_ip, "vm:last-ip", 1, 0, 0,
|
|
|
|
|
|
(SCM vm),
|
|
|
|
|
|
"")
|
|
|
|
|
|
#define FUNC_NAME s_scm_vm_last_ip
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_VALIDATE_VM (1, vm);
|
|
|
|
|
|
return scm_from_ulong ((unsigned long) SCM_VM_DATA (vm)->last_ip);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2008-08-07 13:51:45 +02:00
|
|
|
|
SCM_DEFINE (scm_vm_save_stack, "vm-save-stack", 1, 0, 0,
|
|
|
|
|
|
(SCM vm),
|
|
|
|
|
|
"")
|
|
|
|
|
|
#define FUNC_NAME s_scm_vm_save_stack
|
|
|
|
|
|
{
|
fix stack corruption on vm-save-stack; more robust with nonlocal exits
* module/system/repl/command.scm: Coerce rationals to floats.
* module/system/vm/program.scm (program-documentation): Fix a typo, doh!
* src/vm.c (vm_reset_stack, struct vm_unwind_data): Add unwind handler to
reset vp->sp, vp->fp, and vp->this_frame when performing a nonlocal
exit from a vm_run.
(vm_heapify_frames_1): Don't repack the stack, it causes stack
corruption. I think we need spaghetti stacks to handle continuations,
not separate heap frames. I don't think call/cc is working now.
(vm-save-stack): Don't call heapify_frames, that modifies the stack
that we're copying. Instead call its helper, heapify_1.
* src/vm_engine.c (vm_run): Set up the vm_reset_stack unwind handler.
* src/vm_engine.h (IP_REG, SP_REG, FP_REG): If we got through all of the
checks without having these macros defined, define them as empty.
Happens on x86-64.
* src/vm_system.c (halt): End the dynwind before we return from the VM.
* src/vm_scheme.c (REL): Sync the regs before calling scm_lt_p et al,
cause they can do a nonlocal exit.
2008-08-07 19:04:25 +02:00
|
|
|
|
struct scm_vm *vp;
|
|
|
|
|
|
SCM *dest;
|
2008-08-07 13:51:45 +02:00
|
|
|
|
SCM_VALIDATE_VM (1, vm);
|
fix stack corruption on vm-save-stack; more robust with nonlocal exits
* module/system/repl/command.scm: Coerce rationals to floats.
* module/system/vm/program.scm (program-documentation): Fix a typo, doh!
* src/vm.c (vm_reset_stack, struct vm_unwind_data): Add unwind handler to
reset vp->sp, vp->fp, and vp->this_frame when performing a nonlocal
exit from a vm_run.
(vm_heapify_frames_1): Don't repack the stack, it causes stack
corruption. I think we need spaghetti stacks to handle continuations,
not separate heap frames. I don't think call/cc is working now.
(vm-save-stack): Don't call heapify_frames, that modifies the stack
that we're copying. Instead call its helper, heapify_1.
* src/vm_engine.c (vm_run): Set up the vm_reset_stack unwind handler.
* src/vm_engine.h (IP_REG, SP_REG, FP_REG): If we got through all of the
checks without having these macros defined, define them as empty.
Happens on x86-64.
* src/vm_system.c (halt): End the dynwind before we return from the VM.
* src/vm_scheme.c (REL): Sync the regs before calling scm_lt_p et al,
cause they can do a nonlocal exit.
2008-08-07 19:04:25 +02:00
|
|
|
|
vp = SCM_VM_DATA (vm);
|
2008-08-11 18:35:58 +02:00
|
|
|
|
|
|
|
|
|
|
if (vp->fp)
|
|
|
|
|
|
{
|
2008-10-09 12:17:51 +02:00
|
|
|
|
#ifdef VM_ENABLE_STACK_NULLING
|
|
|
|
|
|
if (vp->sp >= vp->stack_base)
|
|
|
|
|
|
if (!vp->sp[0] || vp->sp[1])
|
|
|
|
|
|
abort ();
|
|
|
|
|
|
#endif
|
2008-08-11 18:35:58 +02:00
|
|
|
|
vp->last_frame = vm_heapify_frames_1 (vp, vp->fp, vp->sp, &dest);
|
|
|
|
|
|
vp->last_ip = vp->ip;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
vp->last_frame = SCM_BOOL_F;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
fix stack corruption on vm-save-stack; more robust with nonlocal exits
* module/system/repl/command.scm: Coerce rationals to floats.
* module/system/vm/program.scm (program-documentation): Fix a typo, doh!
* src/vm.c (vm_reset_stack, struct vm_unwind_data): Add unwind handler to
reset vp->sp, vp->fp, and vp->this_frame when performing a nonlocal
exit from a vm_run.
(vm_heapify_frames_1): Don't repack the stack, it causes stack
corruption. I think we need spaghetti stacks to handle continuations,
not separate heap frames. I don't think call/cc is working now.
(vm-save-stack): Don't call heapify_frames, that modifies the stack
that we're copying. Instead call its helper, heapify_1.
* src/vm_engine.c (vm_run): Set up the vm_reset_stack unwind handler.
* src/vm_engine.h (IP_REG, SP_REG, FP_REG): If we got through all of the
checks without having these macros defined, define them as empty.
Happens on x86-64.
* src/vm_system.c (halt): End the dynwind before we return from the VM.
* src/vm_scheme.c (REL): Sync the regs before calling scm_lt_p et al,
cause they can do a nonlocal exit.
2008-08-07 19:04:25 +02:00
|
|
|
|
return vp->last_frame;
|
2008-08-07 13:51:45 +02:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
|
SCM_DEFINE (scm_vm_fetch_code, "vm-fetch-code", 1, 0, 0,
|
|
|
|
|
|
(SCM vm),
|
|
|
|
|
|
"")
|
|
|
|
|
|
#define FUNC_NAME s_scm_vm_fetch_code
|
|
|
|
|
|
{
|
|
|
|
|
|
int i;
|
|
|
|
|
|
SCM list;
|
|
|
|
|
|
scm_byte_t *ip;
|
|
|
|
|
|
struct scm_instruction *p;
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
|
SCM_VALIDATE_VM (1, vm);
|
|
|
|
|
|
VM_CHECK_RUNNING (vm);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
|
ip = SCM_VM_DATA (vm)->ip;
|
|
|
|
|
|
p = SCM_INSTRUCTION (*ip);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
|
list = SCM_LIST1 (scm_str2symbol (p->name));
|
|
|
|
|
|
for (i = 1; i <= p->len; i++)
|
2005-04-29 14:12:12 +00:00
|
|
|
|
list = scm_cons (SCM_I_MAKINUM (ip[i]), list);
|
2001-04-01 05:03:41 +00:00
|
|
|
|
return scm_reverse_x (list, SCM_EOL);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_vm_fetch_stack, "vm-fetch-stack", 1, 0, 0,
|
|
|
|
|
|
(SCM vm),
|
|
|
|
|
|
"")
|
|
|
|
|
|
#define FUNC_NAME s_scm_vm_fetch_stack
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2001-04-07 09:39:38 +00:00
|
|
|
|
SCM *sp;
|
|
|
|
|
|
SCM ls = SCM_EOL;
|
|
|
|
|
|
struct scm_vm *vp;
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
|
|
|
|
|
SCM_VALIDATE_VM (1, vm);
|
2001-04-01 05:03:41 +00:00
|
|
|
|
VM_CHECK_RUNNING (vm);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
2001-04-07 09:39:38 +00:00
|
|
|
|
vp = SCM_VM_DATA (vm);
|
2001-04-23 04:28:13 +00:00
|
|
|
|
for (sp = vp->stack_base; sp <= vp->sp; sp++)
|
2001-04-07 09:39:38 +00:00
|
|
|
|
ls = scm_cons (*sp, ls);
|
|
|
|
|
|
return ls;
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2001-04-01 05:03:41 +00:00
|
|
|
|
* Initialize
|
2000-08-22 15:54:19 +00:00
|
|
|
|
*/
|
|
|
|
|
|
|
big reorg of scheme modules -- e.g. programs.c -> (system vm program)
This reorganization kills the ugly module-export-all hacks in
bootstrap.scm and core.scm. In fact, it gets rid of core.scm entirely,
breaking out its functionality into separate files.
* module/system/vm/trace.scm:
* module/system/vm/profile.scm:
* module/system/vm/disasm.scm:
* module/system/vm/debug.scm:
* module/system/vm/conv.scm:
* module/system/vm/assemble.scm:
* module/system/repl/repl.scm:
* module/system/repl/common.scm:
* module/system/base/compile.scm:
* module/system/repl/command.scm: Update for changes, and fix a bug in
procedure-documentation.
* module/system/vm/bootstrap.scm: Just call scm_bootstrap_vm, which
handles setting load-compiled for us.
* module/system/vm/core.scm: Removed, functionality folded into other
modules.
* module/system/vm/frame.scm: Export the C frame procedures here; also
move scheme functions from core.scm here.
* module/system/vm/instruction.scm: New file, exports procedures from
instructions.c.
* module/system/vm/objcode.scm: New file, exports procedures from
objcodes.c.
* module/system/vm/program.scm: New file, exports procedures from
programs.c, and some scheme functions originally from core.scm.
* module/system/vm/vm.scm: New file, from vm.c and core.scm.
* src/Makefile.am (libguile_vm_la_SOURCES): Add bootstrap.h.
* src/bootstrap.h: New file, prototypes scm_bootstrap_vm (), which the
scm_init_* functions call.
* src/frames.h:
* src/frames.c (scm_init_frames):
* src/frames.c (scm_bootstrap_frames):
* src/vm.h:
* src/instructions.h:
* src/instructions.c (scm_init_instructions):
* src/instructions.c (scm_bootstrap_instructions):
* src/objcodes.h:
* src/objcodes.c (scm_bootstrap_objcodes):
* src/objcodes.c (scm_init_objcodes):
* src/programs.h:
* src/programs.c (scm_bootstrap_programs):
* src/programs.c (scm_init_programs):
* src/vm.c (scm_bootstrap_vm):
* src/vm.c (scm_init_vm): Call scm_bootstrap_vm() before doing anything
in an init function. Bootstrap_vm will call bootstrap_instructions(),
etc to initialize types, then set load-compiled to point to
load-compiled/vm.
* src/vm.c (scm_load_compiled_with_vm): Code to load .go files, if
they're present.
2008-08-07 13:11:27 +02:00
|
|
|
|
SCM scm_load_compiled_with_vm (SCM file)
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM program = scm_objcode_to_program (scm_load_objcode (file));
|
|
|
|
|
|
|
2008-09-24 11:47:25 +02:00
|
|
|
|
return vm_run (scm_the_vm (), program, SCM_EOL);
|
big reorg of scheme modules -- e.g. programs.c -> (system vm program)
This reorganization kills the ugly module-export-all hacks in
bootstrap.scm and core.scm. In fact, it gets rid of core.scm entirely,
breaking out its functionality into separate files.
* module/system/vm/trace.scm:
* module/system/vm/profile.scm:
* module/system/vm/disasm.scm:
* module/system/vm/debug.scm:
* module/system/vm/conv.scm:
* module/system/vm/assemble.scm:
* module/system/repl/repl.scm:
* module/system/repl/common.scm:
* module/system/base/compile.scm:
* module/system/repl/command.scm: Update for changes, and fix a bug in
procedure-documentation.
* module/system/vm/bootstrap.scm: Just call scm_bootstrap_vm, which
handles setting load-compiled for us.
* module/system/vm/core.scm: Removed, functionality folded into other
modules.
* module/system/vm/frame.scm: Export the C frame procedures here; also
move scheme functions from core.scm here.
* module/system/vm/instruction.scm: New file, exports procedures from
instructions.c.
* module/system/vm/objcode.scm: New file, exports procedures from
objcodes.c.
* module/system/vm/program.scm: New file, exports procedures from
programs.c, and some scheme functions originally from core.scm.
* module/system/vm/vm.scm: New file, from vm.c and core.scm.
* src/Makefile.am (libguile_vm_la_SOURCES): Add bootstrap.h.
* src/bootstrap.h: New file, prototypes scm_bootstrap_vm (), which the
scm_init_* functions call.
* src/frames.h:
* src/frames.c (scm_init_frames):
* src/frames.c (scm_bootstrap_frames):
* src/vm.h:
* src/instructions.h:
* src/instructions.c (scm_init_instructions):
* src/instructions.c (scm_bootstrap_instructions):
* src/objcodes.h:
* src/objcodes.c (scm_bootstrap_objcodes):
* src/objcodes.c (scm_init_objcodes):
* src/programs.h:
* src/programs.c (scm_bootstrap_programs):
* src/programs.c (scm_init_programs):
* src/vm.c (scm_bootstrap_vm):
* src/vm.c (scm_init_vm): Call scm_bootstrap_vm() before doing anything
in an init function. Bootstrap_vm will call bootstrap_instructions(),
etc to initialize types, then set load-compiled to point to
load-compiled/vm.
* src/vm.c (scm_load_compiled_with_vm): Code to load .go files, if
they're present.
2008-08-07 13:11:27 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
|
void
|
big reorg of scheme modules -- e.g. programs.c -> (system vm program)
This reorganization kills the ugly module-export-all hacks in
bootstrap.scm and core.scm. In fact, it gets rid of core.scm entirely,
breaking out its functionality into separate files.
* module/system/vm/trace.scm:
* module/system/vm/profile.scm:
* module/system/vm/disasm.scm:
* module/system/vm/debug.scm:
* module/system/vm/conv.scm:
* module/system/vm/assemble.scm:
* module/system/repl/repl.scm:
* module/system/repl/common.scm:
* module/system/base/compile.scm:
* module/system/repl/command.scm: Update for changes, and fix a bug in
procedure-documentation.
* module/system/vm/bootstrap.scm: Just call scm_bootstrap_vm, which
handles setting load-compiled for us.
* module/system/vm/core.scm: Removed, functionality folded into other
modules.
* module/system/vm/frame.scm: Export the C frame procedures here; also
move scheme functions from core.scm here.
* module/system/vm/instruction.scm: New file, exports procedures from
instructions.c.
* module/system/vm/objcode.scm: New file, exports procedures from
objcodes.c.
* module/system/vm/program.scm: New file, exports procedures from
programs.c, and some scheme functions originally from core.scm.
* module/system/vm/vm.scm: New file, from vm.c and core.scm.
* src/Makefile.am (libguile_vm_la_SOURCES): Add bootstrap.h.
* src/bootstrap.h: New file, prototypes scm_bootstrap_vm (), which the
scm_init_* functions call.
* src/frames.h:
* src/frames.c (scm_init_frames):
* src/frames.c (scm_bootstrap_frames):
* src/vm.h:
* src/instructions.h:
* src/instructions.c (scm_init_instructions):
* src/instructions.c (scm_bootstrap_instructions):
* src/objcodes.h:
* src/objcodes.c (scm_bootstrap_objcodes):
* src/objcodes.c (scm_init_objcodes):
* src/programs.h:
* src/programs.c (scm_bootstrap_programs):
* src/programs.c (scm_init_programs):
* src/vm.c (scm_bootstrap_vm):
* src/vm.c (scm_init_vm): Call scm_bootstrap_vm() before doing anything
in an init function. Bootstrap_vm will call bootstrap_instructions(),
etc to initialize types, then set load-compiled to point to
load-compiled/vm.
* src/vm.c (scm_load_compiled_with_vm): Code to load .go files, if
they're present.
2008-08-07 13:11:27 +02:00
|
|
|
|
scm_bootstrap_vm (void)
|
2001-04-01 05:03:41 +00:00
|
|
|
|
{
|
big reorg of scheme modules -- e.g. programs.c -> (system vm program)
This reorganization kills the ugly module-export-all hacks in
bootstrap.scm and core.scm. In fact, it gets rid of core.scm entirely,
breaking out its functionality into separate files.
* module/system/vm/trace.scm:
* module/system/vm/profile.scm:
* module/system/vm/disasm.scm:
* module/system/vm/debug.scm:
* module/system/vm/conv.scm:
* module/system/vm/assemble.scm:
* module/system/repl/repl.scm:
* module/system/repl/common.scm:
* module/system/base/compile.scm:
* module/system/repl/command.scm: Update for changes, and fix a bug in
procedure-documentation.
* module/system/vm/bootstrap.scm: Just call scm_bootstrap_vm, which
handles setting load-compiled for us.
* module/system/vm/core.scm: Removed, functionality folded into other
modules.
* module/system/vm/frame.scm: Export the C frame procedures here; also
move scheme functions from core.scm here.
* module/system/vm/instruction.scm: New file, exports procedures from
instructions.c.
* module/system/vm/objcode.scm: New file, exports procedures from
objcodes.c.
* module/system/vm/program.scm: New file, exports procedures from
programs.c, and some scheme functions originally from core.scm.
* module/system/vm/vm.scm: New file, from vm.c and core.scm.
* src/Makefile.am (libguile_vm_la_SOURCES): Add bootstrap.h.
* src/bootstrap.h: New file, prototypes scm_bootstrap_vm (), which the
scm_init_* functions call.
* src/frames.h:
* src/frames.c (scm_init_frames):
* src/frames.c (scm_bootstrap_frames):
* src/vm.h:
* src/instructions.h:
* src/instructions.c (scm_init_instructions):
* src/instructions.c (scm_bootstrap_instructions):
* src/objcodes.h:
* src/objcodes.c (scm_bootstrap_objcodes):
* src/objcodes.c (scm_init_objcodes):
* src/programs.h:
* src/programs.c (scm_bootstrap_programs):
* src/programs.c (scm_init_programs):
* src/vm.c (scm_bootstrap_vm):
* src/vm.c (scm_init_vm): Call scm_bootstrap_vm() before doing anything
in an init function. Bootstrap_vm will call bootstrap_instructions(),
etc to initialize types, then set load-compiled to point to
load-compiled/vm.
* src/vm.c (scm_load_compiled_with_vm): Code to load .go files, if
they're present.
2008-08-07 13:11:27 +02:00
|
|
|
|
static int strappage = 0;
|
|
|
|
|
|
|
|
|
|
|
|
if (strappage)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
scm_bootstrap_frames ();
|
|
|
|
|
|
scm_bootstrap_instructions ();
|
|
|
|
|
|
scm_bootstrap_objcodes ();
|
|
|
|
|
|
scm_bootstrap_programs ();
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
|
scm_tc16_vm_cont = scm_make_smob_type ("vm-cont", 0);
|
|
|
|
|
|
scm_set_smob_mark (scm_tc16_vm_cont, vm_cont_mark);
|
|
|
|
|
|
scm_set_smob_free (scm_tc16_vm_cont, vm_cont_free);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
|
scm_tc16_vm = scm_make_smob_type ("vm", 0);
|
|
|
|
|
|
scm_set_smob_mark (scm_tc16_vm, vm_mark);
|
|
|
|
|
|
scm_set_smob_free (scm_tc16_vm, vm_free);
|
|
|
|
|
|
scm_set_smob_apply (scm_tc16_vm, scm_vm_apply, 1, 0, 1);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
2008-09-24 11:47:25 +02:00
|
|
|
|
scm_the_vm_fluid = scm_permanent_object (scm_make_fluid ());
|
|
|
|
|
|
scm_fluid_set_x (scm_the_vm_fluid, make_vm ());
|
|
|
|
|
|
scm_c_define ("*the-vm*", scm_the_vm_fluid);
|
2001-04-06 05:00:10 +00:00
|
|
|
|
|
2008-08-21 18:39:30 -07:00
|
|
|
|
scm_c_define ("load-compiled",
|
|
|
|
|
|
scm_c_make_gsubr ("load-compiled/vm", 1, 0, 0,
|
|
|
|
|
|
scm_load_compiled_with_vm));
|
big reorg of scheme modules -- e.g. programs.c -> (system vm program)
This reorganization kills the ugly module-export-all hacks in
bootstrap.scm and core.scm. In fact, it gets rid of core.scm entirely,
breaking out its functionality into separate files.
* module/system/vm/trace.scm:
* module/system/vm/profile.scm:
* module/system/vm/disasm.scm:
* module/system/vm/debug.scm:
* module/system/vm/conv.scm:
* module/system/vm/assemble.scm:
* module/system/repl/repl.scm:
* module/system/repl/common.scm:
* module/system/base/compile.scm:
* module/system/repl/command.scm: Update for changes, and fix a bug in
procedure-documentation.
* module/system/vm/bootstrap.scm: Just call scm_bootstrap_vm, which
handles setting load-compiled for us.
* module/system/vm/core.scm: Removed, functionality folded into other
modules.
* module/system/vm/frame.scm: Export the C frame procedures here; also
move scheme functions from core.scm here.
* module/system/vm/instruction.scm: New file, exports procedures from
instructions.c.
* module/system/vm/objcode.scm: New file, exports procedures from
objcodes.c.
* module/system/vm/program.scm: New file, exports procedures from
programs.c, and some scheme functions originally from core.scm.
* module/system/vm/vm.scm: New file, from vm.c and core.scm.
* src/Makefile.am (libguile_vm_la_SOURCES): Add bootstrap.h.
* src/bootstrap.h: New file, prototypes scm_bootstrap_vm (), which the
scm_init_* functions call.
* src/frames.h:
* src/frames.c (scm_init_frames):
* src/frames.c (scm_bootstrap_frames):
* src/vm.h:
* src/instructions.h:
* src/instructions.c (scm_init_instructions):
* src/instructions.c (scm_bootstrap_instructions):
* src/objcodes.h:
* src/objcodes.c (scm_bootstrap_objcodes):
* src/objcodes.c (scm_init_objcodes):
* src/programs.h:
* src/programs.c (scm_bootstrap_programs):
* src/programs.c (scm_init_programs):
* src/vm.c (scm_bootstrap_vm):
* src/vm.c (scm_init_vm): Call scm_bootstrap_vm() before doing anything
in an init function. Bootstrap_vm will call bootstrap_instructions(),
etc to initialize types, then set load-compiled to point to
load-compiled/vm.
* src/vm.c (scm_load_compiled_with_vm): Code to load .go files, if
they're present.
2008-08-07 13:11:27 +02:00
|
|
|
|
|
2008-09-02 00:27:59 -07:00
|
|
|
|
sym_vm_run = scm_permanent_object (scm_from_locale_symbol ("vm-run"));
|
|
|
|
|
|
sym_vm_error = scm_permanent_object (scm_from_locale_symbol ("vm-error"));
|
|
|
|
|
|
sym_debug = scm_permanent_object (scm_from_locale_symbol ("debug"));
|
|
|
|
|
|
|
big reorg of scheme modules -- e.g. programs.c -> (system vm program)
This reorganization kills the ugly module-export-all hacks in
bootstrap.scm and core.scm. In fact, it gets rid of core.scm entirely,
breaking out its functionality into separate files.
* module/system/vm/trace.scm:
* module/system/vm/profile.scm:
* module/system/vm/disasm.scm:
* module/system/vm/debug.scm:
* module/system/vm/conv.scm:
* module/system/vm/assemble.scm:
* module/system/repl/repl.scm:
* module/system/repl/common.scm:
* module/system/base/compile.scm:
* module/system/repl/command.scm: Update for changes, and fix a bug in
procedure-documentation.
* module/system/vm/bootstrap.scm: Just call scm_bootstrap_vm, which
handles setting load-compiled for us.
* module/system/vm/core.scm: Removed, functionality folded into other
modules.
* module/system/vm/frame.scm: Export the C frame procedures here; also
move scheme functions from core.scm here.
* module/system/vm/instruction.scm: New file, exports procedures from
instructions.c.
* module/system/vm/objcode.scm: New file, exports procedures from
objcodes.c.
* module/system/vm/program.scm: New file, exports procedures from
programs.c, and some scheme functions originally from core.scm.
* module/system/vm/vm.scm: New file, from vm.c and core.scm.
* src/Makefile.am (libguile_vm_la_SOURCES): Add bootstrap.h.
* src/bootstrap.h: New file, prototypes scm_bootstrap_vm (), which the
scm_init_* functions call.
* src/frames.h:
* src/frames.c (scm_init_frames):
* src/frames.c (scm_bootstrap_frames):
* src/vm.h:
* src/instructions.h:
* src/instructions.c (scm_init_instructions):
* src/instructions.c (scm_bootstrap_instructions):
* src/objcodes.h:
* src/objcodes.c (scm_bootstrap_objcodes):
* src/objcodes.c (scm_init_objcodes):
* src/programs.h:
* src/programs.c (scm_bootstrap_programs):
* src/programs.c (scm_init_programs):
* src/vm.c (scm_bootstrap_vm):
* src/vm.c (scm_init_vm): Call scm_bootstrap_vm() before doing anything
in an init function. Bootstrap_vm will call bootstrap_instructions(),
etc to initialize types, then set load-compiled to point to
load-compiled/vm.
* src/vm.c (scm_load_compiled_with_vm): Code to load .go files, if
they're present.
2008-08-07 13:11:27 +02:00
|
|
|
|
strappage = 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
scm_init_vm (void)
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_bootstrap_vm ();
|
|
|
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
|
#ifndef SCM_MAGIC_SNARFER
|
2000-08-22 15:54:19 +00:00
|
|
|
|
#include "vm.x"
|
2001-04-01 05:03:41 +00:00
|
|
|
|
#endif
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
2001-04-01 05:03:41 +00:00
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
Local Variables:
|
|
|
|
|
|
c-file-style: "gnu"
|
|
|
|
|
|
End:
|
|
|
|
|
|
*/
|