summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2013-11-21 19:05:43 +0100
committerAndy Wingo <wingo@pobox.com>2013-11-21 19:05:43 +0100
commitbd63e5b2c3e28cc6db0b0bdc7ea9103b5688e085 (patch)
treec2dea25a0abd66fdee3b9de60fba374da3f46258
parentb85cd20f80c94e4bd8e62363cf509cc9e2f6ede9 (diff)
downloadguile-bd63e5b2c3e28cc6db0b0bdc7ea9103b5688e085.tar.gz
scm_call_n sets up boot continuation frame for VM
* libguile/vm-engine.c: * libguile/vm.c (scm_call_n): Move boot continuation setup to scm_call_n, so that vm-engine takes all of its state from the vp.
-rw-r--r--libguile/vm-engine.c45
-rw-r--r--libguile/vm.c38
2 files changed, 38 insertions, 45 deletions
diff --git a/libguile/vm-engine.c b/libguile/vm-engine.c
index 72bdd53aa..1343bbf2c 100644
--- a/libguile/vm-engine.c
+++ b/libguile/vm-engine.c
@@ -424,8 +424,7 @@
((scm_t_uintptr) (ptr) % alignof_type (type) == 0)
static SCM
-VM_NAME (scm_i_thread *current_thread, struct scm_vm *vp,
- SCM program, SCM *argv, size_t nargs_)
+VM_NAME (scm_i_thread *current_thread, struct scm_vm *vp)
{
/* Instruction pointer: A pointer to the opcode that is currently
running. */
@@ -478,49 +477,11 @@ VM_NAME (scm_i_thread *current_thread, struct scm_vm *vp,
NEXT (0);
}
- /* Load previous VM registers. */
+ /* Load VM registers. */
CACHE_REGISTER ();
VM_HANDLE_INTERRUPTS;
- /* Initialization */
- {
- SCM *base;
- ptrdiff_t base_frame_size;
-
- /* Check that we have enough space: 3 words for the boot
- continuation, 3 + nargs for the procedure application, and 3 for
- setting up a new frame. */
- base_frame_size = 3 + 3 + nargs_ + 3;
- vp->sp += base_frame_size;
- CHECK_OVERFLOW ();
- base = vp->sp + 1 - base_frame_size;
-
- /* Since it's possible to receive the arguments on the stack itself,
- and indeed the regular VM invokes us that way, shuffle up the
- arguments first. */
- {
- int i;
- for (i = nargs_ - 1; i >= 0; i--)
- base[6 + i] = argv[i];
- }
-
- /* Initial frame, saving previous fp and ip, with the boot
- continuation. */
- base[0] = SCM_PACK (fp); /* dynamic link */
- base[1] = SCM_PACK (ip); /* ra */
- base[2] = vm_boot_continuation;
- fp = &base[2];
- ip = (scm_t_uint32 *) vm_boot_continuation_code;
-
- /* MV-call frame, function & arguments */
- base[3] = SCM_PACK (fp); /* dynamic link */
- base[4] = SCM_PACK (ip); /* ra */
- base[5] = program;
- fp = vp->fp = &base[5];
- RESET_FRAME (nargs_ + 1);
- }
-
apply:
while (!SCM_PROGRAM_P (SCM_FRAME_PROGRAM (fp)))
{
@@ -2141,7 +2102,7 @@ VM_NAME (scm_i_thread *current_thread, struct scm_vm *vp,
if (scm_is_eq (val, SCM_UNDEFINED))
val = SCM_I_FLUID_DEFAULT (fluid);
VM_ASSERT (!scm_is_eq (val, SCM_UNDEFINED),
- vm_error_unbound_fluid (program, fluid));
+ vm_error_unbound_fluid (SCM_FRAME_PROGRAM (fp), fluid));
LOCAL_SET (dst, val);
}
diff --git a/libguile/vm.c b/libguile/vm.c
index 0430a0558..dfd0d1983 100644
--- a/libguile/vm.c
+++ b/libguile/vm.c
@@ -706,8 +706,7 @@ initialize_default_stack_size (void)
#undef VM_USE_HOOKS
#undef VM_NAME
-typedef SCM (*scm_t_vm_engine) (scm_i_thread *current_thread, struct scm_vm *vp,
- SCM program, SCM *argv, size_t nargs);
+typedef SCM (*scm_t_vm_engine) (scm_i_thread *current_thread, struct scm_vm *vp);
static const scm_t_vm_engine vm_engines[SCM_VM_NUM_ENGINES] =
{ vm_regular_engine, vm_debug_engine };
@@ -808,12 +807,45 @@ scm_call_n (SCM proc, SCM *argv, size_t nargs)
{
scm_i_thread *thread;
struct scm_vm *vp;
+ SCM *base;
+ ptrdiff_t base_frame_size;
+ size_t i;
thread = SCM_I_CURRENT_THREAD;
vp = thread_vm (thread);
SCM_CHECK_STACK;
- return vm_engines[vp->engine](thread, vp, proc, argv, nargs);
+
+ /* Check that we have enough space: 3 words for the boot
+ continuation, 3 + nargs for the procedure application, and 3 for
+ setting up a new frame. */
+ base_frame_size = 3 + 3 + nargs + 3;
+ vp->sp += base_frame_size;
+ if (vp->sp >= vp->stack_limit)
+ vm_error_stack_overflow (vp);
+ base = vp->sp + 1 - base_frame_size;
+
+ /* Since it's possible to receive the arguments on the stack itself,
+ shuffle up the arguments first. */
+ for (i = nargs; i > 0; i--)
+ base[6 + i - 1] = argv[i - 1];
+
+ /* Push the boot continuation, which calls PROC and returns its
+ result(s). */
+ base[0] = SCM_PACK (vp->fp); /* dynamic link */
+ base[1] = SCM_PACK (vp->ip); /* ra */
+ base[2] = vm_boot_continuation;
+ vp->fp = &base[2];
+ vp->ip = (scm_t_uint32 *) vm_boot_continuation_code;
+
+ /* The pending call to PROC. */
+ base[3] = SCM_PACK (vp->fp); /* dynamic link */
+ base[4] = SCM_PACK (vp->ip); /* ra */
+ base[5] = proc;
+ vp->fp = &base[5];
+ vp->sp = &SCM_FRAME_LOCAL (vp->fp, nargs);
+
+ return vm_engines[vp->engine](thread, vp);
}
/* Scheme interface */