mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-03 21:30:29 +02:00
Setjmp before calling into the VM
* libguile/vm-engine.c (CACHE_REGISTER): Remove an unneeded cast. (VM_NAME): * libguile/vm.c (scm_call_n): Setjmp out here. This leaves the VM without any initialization work to do. It also makes it possible to restart the VM in another mode (with hooks, for example).
This commit is contained in:
parent
bd63e5b2c3
commit
dd1c7deccc
2 changed files with 26 additions and 26 deletions
|
@ -214,7 +214,7 @@
|
||||||
|
|
||||||
#define CACHE_REGISTER() \
|
#define CACHE_REGISTER() \
|
||||||
do { \
|
do { \
|
||||||
ip = (scm_t_uint32 *) vp->ip; \
|
ip = vp->ip; \
|
||||||
fp = vp->fp; \
|
fp = vp->fp; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
@ -424,7 +424,8 @@
|
||||||
((scm_t_uintptr) (ptr) % alignof_type (type) == 0)
|
((scm_t_uintptr) (ptr) % alignof_type (type) == 0)
|
||||||
|
|
||||||
static SCM
|
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
|
/* Instruction pointer: A pointer to the opcode that is currently
|
||||||
running. */
|
running. */
|
||||||
|
@ -438,9 +439,6 @@ VM_NAME (scm_i_thread *current_thread, struct scm_vm *vp)
|
||||||
/* Current opcode: A cache of *ip. */
|
/* Current opcode: A cache of *ip. */
|
||||||
register scm_t_uint32 op;
|
register scm_t_uint32 op;
|
||||||
|
|
||||||
/* Cached variables. */
|
|
||||||
scm_i_jmp_buf registers; /* used for prompts */
|
|
||||||
|
|
||||||
#ifdef HAVE_LABELS_AS_VALUES
|
#ifdef HAVE_LABELS_AS_VALUES
|
||||||
static const void **jump_table_pointer = NULL;
|
static const void **jump_table_pointer = NULL;
|
||||||
register const void **jump_table JT_REG;
|
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;
|
jump_table = jump_table_pointer;
|
||||||
#endif
|
#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. */
|
/* Load VM registers. */
|
||||||
CACHE_REGISTER ();
|
CACHE_REGISTER ();
|
||||||
|
|
||||||
VM_HANDLE_INTERRUPTS;
|
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:
|
apply:
|
||||||
while (!SCM_PROGRAM_P (SCM_FRAME_PROGRAM (fp)))
|
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),
|
vm_reinstate_partial_continuation (vp, vmcont, FRAME_LOCALS_COUNT_FROM (1),
|
||||||
LOCAL_ADDRESS (1),
|
LOCAL_ADDRESS (1),
|
||||||
¤t_thread->dynstack,
|
¤t_thread->dynstack,
|
||||||
®isters);
|
registers);
|
||||||
CACHE_REGISTER ();
|
CACHE_REGISTER ();
|
||||||
NEXT (0);
|
NEXT (0);
|
||||||
}
|
}
|
||||||
|
@ -1004,7 +993,7 @@ VM_NAME (scm_i_thread *current_thread, struct scm_vm *vp)
|
||||||
ip++;
|
ip++;
|
||||||
SYNC_IP ();
|
SYNC_IP ();
|
||||||
vm_abort (vp, LOCAL_REF (1), nlocals - 2, LOCAL_ADDRESS (2),
|
vm_abort (vp, LOCAL_REF (1), nlocals - 2, LOCAL_ADDRESS (2),
|
||||||
SCM_EOL, LOCAL_ADDRESS (0), ®isters);
|
SCM_EOL, LOCAL_ADDRESS (0), registers);
|
||||||
|
|
||||||
/* vm_abort should not return */
|
/* vm_abort should not return */
|
||||||
abort ();
|
abort ();
|
||||||
|
@ -2013,7 +2002,7 @@ VM_NAME (scm_i_thread *current_thread, struct scm_vm *vp)
|
||||||
fp - vp->stack_base,
|
fp - vp->stack_base,
|
||||||
LOCAL_ADDRESS (proc_slot) - vp->stack_base,
|
LOCAL_ADDRESS (proc_slot) - vp->stack_base,
|
||||||
ip + offset,
|
ip + offset,
|
||||||
®isters);
|
registers);
|
||||||
NEXT (3);
|
NEXT (3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -706,7 +706,8 @@ initialize_default_stack_size (void)
|
||||||
#undef VM_USE_HOOKS
|
#undef VM_USE_HOOKS
|
||||||
#undef VM_NAME
|
#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] =
|
static const scm_t_vm_engine vm_engines[SCM_VM_NUM_ENGINES] =
|
||||||
{ vm_regular_engine, vm_debug_engine };
|
{ vm_regular_engine, vm_debug_engine };
|
||||||
|
@ -809,6 +810,8 @@ scm_call_n (SCM proc, SCM *argv, size_t nargs)
|
||||||
struct scm_vm *vp;
|
struct scm_vm *vp;
|
||||||
SCM *base;
|
SCM *base;
|
||||||
ptrdiff_t base_frame_size;
|
ptrdiff_t base_frame_size;
|
||||||
|
/* Cached variables. */
|
||||||
|
scm_i_jmp_buf registers; /* used for prompts */
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
thread = SCM_I_CURRENT_THREAD;
|
thread = SCM_I_CURRENT_THREAD;
|
||||||
|
@ -845,7 +848,15 @@ scm_call_n (SCM proc, SCM *argv, size_t nargs)
|
||||||
vp->fp = &base[5];
|
vp->fp = &base[5];
|
||||||
vp->sp = &SCM_FRAME_LOCAL (vp->fp, nargs);
|
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, ®isters, resume);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Scheme interface */
|
/* Scheme interface */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue