summaryrefslogtreecommitdiff
path: root/libguile/gsubr.c
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2016-11-17 22:13:53 +0100
committerAndy Wingo <wingo@pobox.com>2016-11-17 22:13:53 +0100
commit4985ef13e68c83adf3e83f2c981205806ed9b621 (patch)
treeb5027ca3f4c0ce3c904c1e015ddae6d924db2c56 /libguile/gsubr.c
parentca74e3fae52dd23f8e8f12194d07041e207f68e7 (diff)
downloadguile-4985ef13e68c83adf3e83f2c981205806ed9b621.tar.gz
Explicit interrupt handling in VM
* libguile/foreign.c (CODE, get_foreign_stub_code): Add explicit handle-interrupts and return-values calls, as foreign-call will fall through. * libguile/gsubr.c (A, B, C, AB, AC, BC, ABC, SUBR_STUB_CODE) (scm_i_primitive_call_ip): Same. * libguile/vm-engine.c (VM_HANDLE_INTERRUPTS): Inline into handle-interrupts. (RETURN_ONE_VALUE, RETURN_VALUE_LIST): Inline into callers, and fall through instead of returning. (BR_BINARY, BR_UNARY, BR_ARITHMETIC, BR_U64_ARITHMETIC): Remove conditional VM_HANDLE_INTERRUPTS, as the compiler already inserted the handle-interrupts calls if needed. (vm_engine): Remove VM_HANDLE_INTERRUPTS invocations except in the handle-interrupts instruction.
Diffstat (limited to 'libguile/gsubr.c')
-rw-r--r--libguile/gsubr.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/libguile/gsubr.c b/libguile/gsubr.c
index b456b220a..e22d16363 100644
--- a/libguile/gsubr.c
+++ b/libguile/gsubr.c
@@ -75,6 +75,8 @@
#define A(nreq) \
SCM_PACK_OP_24 (assert_nargs_ee, nreq + 1), \
SCM_PACK_OP_24 (subr_call, 0), \
+ SCM_PACK_OP_24 (handle_interrupts, 0), \
+ SCM_PACK_OP_24 (return_values, 0), \
0, \
0
@@ -82,11 +84,15 @@
SCM_PACK_OP_24 (assert_nargs_le, nopt + 1), \
SCM_PACK_OP_24 (alloc_frame, nopt + 1), \
SCM_PACK_OP_24 (subr_call, 0), \
+ SCM_PACK_OP_24 (handle_interrupts, 0), \
+ SCM_PACK_OP_24 (return_values, 0), \
0
#define C() \
SCM_PACK_OP_24 (bind_rest, 1), \
SCM_PACK_OP_24 (subr_call, 0), \
+ SCM_PACK_OP_24 (handle_interrupts, 0), \
+ SCM_PACK_OP_24 (return_values, 0), \
0, \
0
@@ -94,17 +100,23 @@
SCM_PACK_OP_24 (assert_nargs_ge, nreq + 1), \
SCM_PACK_OP_24 (assert_nargs_le, nreq + nopt + 1), \
SCM_PACK_OP_24 (alloc_frame, nreq + nopt + 1), \
- SCM_PACK_OP_24 (subr_call, 0)
+ SCM_PACK_OP_24 (subr_call, 0), \
+ SCM_PACK_OP_24 (handle_interrupts, 0), \
+ SCM_PACK_OP_24 (return_values, 0)
#define AC(nreq) \
SCM_PACK_OP_24 (assert_nargs_ge, nreq + 1), \
SCM_PACK_OP_24 (bind_rest, nreq + 1), \
SCM_PACK_OP_24 (subr_call, 0), \
+ SCM_PACK_OP_24 (handle_interrupts, 0), \
+ SCM_PACK_OP_24 (return_values, 0), \
0
#define BC(nopt) \
SCM_PACK_OP_24 (bind_rest, nopt + 1), \
SCM_PACK_OP_24 (subr_call, 0), \
+ SCM_PACK_OP_24 (handle_interrupts, 0), \
+ SCM_PACK_OP_24 (return_values, 0), \
0, \
0
@@ -112,6 +124,8 @@
SCM_PACK_OP_24 (assert_nargs_ge, nreq + 1), \
SCM_PACK_OP_24 (bind_rest, nreq + nopt + 1), \
SCM_PACK_OP_24 (subr_call, 0), \
+ SCM_PACK_OP_24 (handle_interrupts, 0), \
+ SCM_PACK_OP_24 (return_values, 0), \
0
@@ -212,7 +226,7 @@ static const scm_t_uint32 subr_stub_code[] = {
/* (nargs * nargs) + nopt + rest * (nargs + 1) */
#define SUBR_STUB_CODE(nreq,nopt,rest) \
&subr_stub_code[((nreq + nopt + rest) * (nreq + nopt + rest) \
- + nopt + rest * (nreq + nopt + rest + 1)) * 4]
+ + nopt + rest * (nreq + nopt + rest + 1)) * 6]
static const scm_t_uint32*
get_subr_stub_code (unsigned int nreq, unsigned int nopt, unsigned int rest)
@@ -265,12 +279,16 @@ scm_i_primitive_code_p (const scm_t_uint32 *code)
scm_t_uintptr
scm_i_primitive_call_ip (SCM subr)
{
+ size_t i;
const scm_t_uint32 *code = SCM_PROGRAM_CODE (subr);
- /* A stub is 4 32-bit words long, or 16 bytes. The call will be one
+ /* A stub is 6 32-bit words long, or 24 bytes. The call will be one
instruction, in either the fourth, third, or second word. Return a
byte offset from the entry. */
- return (scm_t_uintptr)(code + (code[3] ? 3 : code[2] ? 2 : 1));
+ for (i = 1; i < 4; i++)
+ if ((code[i] & 0xff) == scm_op_subr_call)
+ return (scm_t_uintptr) (code + i);
+ abort ();
}
SCM