summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libguile/vm-engine.c37
-rw-r--r--libguile/vm.c15
2 files changed, 26 insertions, 26 deletions
diff --git a/libguile/vm-engine.c b/libguile/vm-engine.c
index 1343bbf2c..4e1d4f83f 100644
--- a/libguile/vm-engine.c
+++ b/libguile/vm-engine.c
@@ -214,7 +214,7 @@
#define CACHE_REGISTER() \
do { \
- ip = (scm_t_uint32 *) vp->ip; \
+ ip = vp->ip; \
fp = vp->fp; \
} while (0)
@@ -424,7 +424,8 @@
((scm_t_uintptr) (ptr) % alignof_type (type) == 0)
static SCM
-VM_NAME (scm_i_thread *current_thread, struct scm_vm *vp)
+VM_NAME (scm_i_thread *current_thread, struct scm_vm *vp,
+ scm_i_jmp_buf *registers, int resume)
{
/* Instruction pointer: A pointer to the opcode that is currently
running. */
@@ -438,9 +439,6 @@ VM_NAME (scm_i_thread *current_thread, struct scm_vm *vp)
/* Current opcode: A cache of *ip. */
register scm_t_uint32 op;
- /* Cached variables. */
- scm_i_jmp_buf registers; /* used for prompts */
-
#ifdef HAVE_LABELS_AS_VALUES
static const void **jump_table_pointer = NULL;
register const void **jump_table JT_REG;
@@ -461,27 +459,18 @@ VM_NAME (scm_i_thread *current_thread, struct scm_vm *vp)
jump_table = jump_table_pointer;
#endif
- if (SCM_I_SETJMP (registers))
- {
- /* Non-local return. The values are on the stack, on a new frame
- set up to call `values' to return the values to the handler.
- Cache the VM registers back from the vp, and dispatch to the
- body of `values'.
-
- Note, at this point, we must assume that any variable local to
- vm_engine that can be assigned *has* been assigned. So we need
- to pull all our state back from the ip/fp/sp.
- */
- CACHE_REGISTER ();
- ABORT_CONTINUATION_HOOK ();
- NEXT (0);
- }
-
/* Load VM registers. */
CACHE_REGISTER ();
VM_HANDLE_INTERRUPTS;
+ /* Usually a call to the VM happens on application, with the boot
+ continuation on the next frame. Sometimes it happens after a
+ non-local exit however; in that case the VM state is all set up,
+ and we have but to jump to the next opcode. */
+ if (SCM_UNLIKELY (resume))
+ NEXT (0);
+
apply:
while (!SCM_PROGRAM_P (SCM_FRAME_PROGRAM (fp)))
{
@@ -886,7 +875,7 @@ VM_NAME (scm_i_thread *current_thread, struct scm_vm *vp)
vm_reinstate_partial_continuation (vp, vmcont, FRAME_LOCALS_COUNT_FROM (1),
LOCAL_ADDRESS (1),
&current_thread->dynstack,
- &registers);
+ registers);
CACHE_REGISTER ();
NEXT (0);
}
@@ -1004,7 +993,7 @@ VM_NAME (scm_i_thread *current_thread, struct scm_vm *vp)
ip++;
SYNC_IP ();
vm_abort (vp, LOCAL_REF (1), nlocals - 2, LOCAL_ADDRESS (2),
- SCM_EOL, LOCAL_ADDRESS (0), &registers);
+ SCM_EOL, LOCAL_ADDRESS (0), registers);
/* vm_abort should not return */
abort ();
@@ -2013,7 +2002,7 @@ VM_NAME (scm_i_thread *current_thread, struct scm_vm *vp)
fp - vp->stack_base,
LOCAL_ADDRESS (proc_slot) - vp->stack_base,
ip + offset,
- &registers);
+ registers);
NEXT (3);
}
diff --git a/libguile/vm.c b/libguile/vm.c
index dfd0d1983..3c28c1789 100644
--- a/libguile/vm.c
+++ b/libguile/vm.c
@@ -706,7 +706,8 @@ 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);
+typedef SCM (*scm_t_vm_engine) (scm_i_thread *current_thread, struct scm_vm *vp,
+ scm_i_jmp_buf *registers, int resume);
static const scm_t_vm_engine vm_engines[SCM_VM_NUM_ENGINES] =
{ vm_regular_engine, vm_debug_engine };
@@ -809,6 +810,8 @@ scm_call_n (SCM proc, SCM *argv, size_t nargs)
struct scm_vm *vp;
SCM *base;
ptrdiff_t base_frame_size;
+ /* Cached variables. */
+ scm_i_jmp_buf registers; /* used for prompts */
size_t i;
thread = SCM_I_CURRENT_THREAD;
@@ -845,7 +848,15 @@ scm_call_n (SCM proc, SCM *argv, size_t nargs)
vp->fp = &base[5];
vp->sp = &SCM_FRAME_LOCAL (vp->fp, nargs);
- return vm_engines[vp->engine](thread, vp);
+ {
+ int resume = SCM_I_SETJMP (registers);
+
+ if (SCM_UNLIKELY (resume))
+ /* Non-local return. */
+ vm_dispatch_abort_hook (vp);
+
+ return vm_engines[vp->engine](thread, vp, &registers, resume);
+ }
}
/* Scheme interface */