summaryrefslogtreecommitdiff
path: root/libguile/vm.c
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2012-03-07 10:27:16 +0100
committerAndy Wingo <wingo@pobox.com>2012-03-07 10:27:16 +0100
commit9d381ba4788b4d447acd3238c2fc8b86da4998b2 (patch)
tree5fd37ed1b9d73a20dbfadce6c4681bba8f05c75e /libguile/vm.c
parent3c12fc359561aedb179a524667ba03481333f482 (diff)
downloadguile-9d381ba4788b4d447acd3238c2fc8b86da4998b2.tar.gz
dynstack: pushing a prompt no longer allocates memory
* libguile/control.h: Remove scm_t_prompt_registers and scm_c_make_prompt_registers. (scm_c_abort): Take a pointer to a jmpbuf instead of a cookie. It will serve the same purpose. * libguile/control.c (reify_partial_continuation, scm_at_abort): Adapt to new prompt representation. * libguile/dynstack.h: * libguile/dynstack.c (scm_dynstack_push_prompt): Prompts now have 5 words instead of 2, as they now push the fp, sp, ip, and jmpbuf on the stack separately. This avoids allocation. (scm_dynstack_find_prompt): Likewise, add return values for fp, sp, etc. (scm_dynstack_wind_prompt): Replaces scm_dynstack_relocate_prompt. * libguile/eval.c (eval): * libguile/stacks.c (find_prompt): * libguile/throw.c (pre_init_catch): Adapt to the new prompt mechanism. * libguile/vm-engine.c (vm_engine): Setjmp an on-stack jmpbuf every time the VM enters. We can then re-use that jmpbuf for all prompts in that invocation. * libguile/vm-i-system.c (partial_cont_call): Adapt to change in prompt representation. We don't need to wind here any more, since we pass in the prompt's jmpbuf. (prompt): Adapt to scm_dynstack_push_prompt change. (abort): Adapt to vm_abort change. * libguile/vm.h (struct scm_vm): No more cookie. * libguile/vm.c (vm_abort): Adapt to scm_c_abort change. (vm_reinstate_partial_continuation): Rewind the dynamic stack here, now that we do have a valid jmpbuf. (make_vm): No need to initialize a cookie.
Diffstat (limited to 'libguile/vm.c')
-rw-r--r--libguile/vm.c44
1 files changed, 27 insertions, 17 deletions
diff --git a/libguile/vm.c b/libguile/vm.c
index a283857f0..4d32c9545 100644
--- a/libguile/vm.c
+++ b/libguile/vm.c
@@ -247,9 +247,11 @@ vm_dispatch_hook (SCM vm, int hook_num)
vp->trace_level = saved_trace_level;
}
-static void vm_abort (SCM vm, size_t n, scm_t_int64 cookie) SCM_NORETURN;
static void
-vm_abort (SCM vm, size_t n, scm_t_int64 vm_cookie)
+vm_abort (SCM vm, size_t n, scm_i_jmp_buf *current_registers) SCM_NORETURN;
+
+static void
+vm_abort (SCM vm, size_t n, scm_i_jmp_buf *current_registers)
{
size_t i;
ssize_t tail_len;
@@ -272,12 +274,13 @@ vm_abort (SCM vm, size_t n, scm_t_int64 vm_cookie)
/* NULLSTACK (n + 1) */
SCM_VM_DATA (vm)->sp -= n + 1;
- scm_c_abort (vm, tag, n + tail_len, argv, vm_cookie);
+ scm_c_abort (vm, tag, n + tail_len, argv, current_registers);
}
-static scm_t_ptrdiff
-vm_reinstate_partial_continuation (SCM vm, SCM cont,
- size_t n, SCM *argv, scm_t_int64 vm_cookie)
+static void
+vm_reinstate_partial_continuation (SCM vm, SCM cont, size_t n, SCM *argv,
+ scm_t_dynstack *dynstack,
+ scm_i_jmp_buf *registers)
{
struct scm_vm *vp;
struct scm_vm_cont *cp;
@@ -325,16 +328,24 @@ vm_reinstate_partial_continuation (SCM vm, SCM cont,
vp->sp++;
*vp->sp = scm_from_size_t (n);
- /* Finally, rewind the dynamic state. Unhappily, we have to do this
- in the vm_engine. If we do it here, the stack frame will likely
- have been stompled by some future call out of the VM, so we will
- return to some other part of the VM.
-
- We used to wind and relocate the prompts here, but that's bogus,
- because a rewinder would then be able to abort to a prompt with a
- stale jmpbuf. */
-
- return reloc;
+ /* The prompt captured a slice of the dynamic stack. Here we wind
+ those entries onto the current thread's stack. We also have to
+ relocate any prompts that we see along the way. */
+ {
+ scm_t_bits *walk;
+
+ for (walk = SCM_DYNSTACK_FIRST (cp->dynstack);
+ SCM_DYNSTACK_TAG (walk);
+ walk = SCM_DYNSTACK_NEXT (walk))
+ {
+ scm_t_bits tag = SCM_DYNSTACK_TAG (walk);
+
+ if (SCM_DYNSTACK_TAG_TYPE (tag) == SCM_DYNSTACK_TYPE_PROMPT)
+ scm_dynstack_wind_prompt (dynstack, walk, reloc, registers);
+ else
+ scm_dynstack_wind_1 (dynstack, walk);
+ }
+ }
#undef RELOC
}
@@ -522,7 +533,6 @@ make_vm (void)
vp->trace_level = 0;
for (i = 0; i < SCM_VM_NUM_HOOKS; i++)
vp->hooks[i] = SCM_BOOL_F;
- vp->cookie = 0;
return scm_cell (scm_tc7_vm, (scm_t_bits)vp);
}
#undef FUNC_NAME