diff options
author | Andy Wingo <wingo@pobox.com> | 2013-11-21 21:15:58 +0100 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2013-11-21 21:15:58 +0100 |
commit | dd1c7decccd35dc37950310b403b8e45a658fea4 (patch) | |
tree | 04b7f835bdcc185d61d7bf6b28b2b3166a10e796 /libguile/vm-engine.c | |
parent | bd63e5b2c3e28cc6db0b0bdc7ea9103b5688e085 (diff) | |
download | guile-dd1c7decccd35dc37950310b403b8e45a658fea4.tar.gz |
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).
Diffstat (limited to 'libguile/vm-engine.c')
-rw-r--r-- | libguile/vm-engine.c | 37 |
1 files changed, 13 insertions, 24 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), ¤t_thread->dynstack, - ®isters); + 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), ®isters); + 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, - ®isters); + registers); NEXT (3); } |