From 9b709b0fe1ec5a71903e07d21006441d15e0c1ed Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Tue, 15 Mar 2011 23:33:32 +0100 Subject: fix frame dynamic linkage in the face of partial continuation application * libguile/vm-i-system.c (new-frame): Though it was appealing to set the dynamic link here on the incomplete frame, we no longer do that, for the reasons mentioned in the code. (call, mv-call): Adapt to set the frame's dynamic link. * libguile/vm-engine.c (vm_engine): Don't set dynamic link here, even for boot program. * libguile/frames.c (scm_frame_num_locals, scm_frame_local_ref) (scm_frame_local_set_x): Fix up not-yet-active frame detection. --- libguile/vm-i-system.c | 49 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 13 deletions(-) (limited to 'libguile/vm-i-system.c') diff --git a/libguile/vm-i-system.c b/libguile/vm-i-system.c index 57712cabd..980d22afe 100644 --- a/libguile/vm-i-system.c +++ b/libguile/vm-i-system.c @@ -756,9 +756,14 @@ VM_DEFINE_INSTRUCTION (52, new_frame, "new-frame", 0, 0, 3) { /* NB: if you change this, see frames.c:vm-frame-num-locals */ /* and frames.h, vm-engine.c, etc of course */ - PUSH ((SCM)fp); /* dynamic link */ - PUSH (0); /* mvra */ - PUSH (0); /* ra */ + + /* We don't initialize the dynamic link here because we don't actually + know that this frame will point to the current fp: it could be + placed elsewhere on the stack if captured in a partial + continuation, and invoked from some other context. */ + PUSH (0); /* dynamic link */ + PUSH (0); /* mvra */ + PUSH (0); /* ra */ NEXT; } @@ -790,11 +795,20 @@ VM_DEFINE_INSTRUCTION (53, call, "call", 1, -1, 1) } CACHE_PROGRAM (); - fp = sp - nargs + 1; - ASSERT (SCM_FRAME_RETURN_ADDRESS (fp) == 0); - ASSERT (SCM_FRAME_MV_RETURN_ADDRESS (fp) == 0); - SCM_FRAME_SET_RETURN_ADDRESS (fp, ip); - SCM_FRAME_SET_MV_RETURN_ADDRESS (fp, 0); + + { + SCM *old_fp = fp; + + fp = sp - nargs + 1; + + ASSERT (SCM_FRAME_DYNAMIC_LINK (fp) == 0); + ASSERT (SCM_FRAME_RETURN_ADDRESS (fp) == 0); + ASSERT (SCM_FRAME_MV_RETURN_ADDRESS (fp) == 0); + SCM_FRAME_SET_DYNAMIC_LINK (fp, old_fp); + SCM_FRAME_SET_RETURN_ADDRESS (fp, ip); + SCM_FRAME_SET_MV_RETURN_ADDRESS (fp, 0); + } + ip = SCM_C_OBJCODE_BASE (bp); PUSH_CONTINUATION_HOOK (); APPLY_HOOK (); @@ -1091,11 +1105,20 @@ VM_DEFINE_INSTRUCTION (62, mv_call, "mv-call", 4, -1, 1) } CACHE_PROGRAM (); - fp = sp - nargs + 1; - ASSERT (SCM_FRAME_RETURN_ADDRESS (fp) == 0); - ASSERT (SCM_FRAME_MV_RETURN_ADDRESS (fp) == 0); - SCM_FRAME_SET_RETURN_ADDRESS (fp, ip); - SCM_FRAME_SET_MV_RETURN_ADDRESS (fp, mvra); + + { + SCM *old_fp = fp; + + fp = sp - nargs + 1; + + ASSERT (SCM_FRAME_DYNAMIC_LINK (fp) == 0); + ASSERT (SCM_FRAME_RETURN_ADDRESS (fp) == 0); + ASSERT (SCM_FRAME_MV_RETURN_ADDRESS (fp) == 0); + SCM_FRAME_SET_DYNAMIC_LINK (fp, old_fp); + SCM_FRAME_SET_RETURN_ADDRESS (fp, ip); + SCM_FRAME_SET_MV_RETURN_ADDRESS (fp, mvra); + } + ip = SCM_C_OBJCODE_BASE (bp); PUSH_CONTINUATION_HOOK (); APPLY_HOOK (); -- cgit v1.2.3 From 6f2ff78299f54b1fde9f2ff85cbabf876bea85b8 Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Sat, 19 Mar 2011 23:12:40 +0100 Subject: fix new-frame push in call/cc * libguile/vm-i-system.c (call/cc): Whoops, fix the new-frame push here. A little birdie tells me a test case is coming soon. --- libguile/vm-i-system.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libguile/vm-i-system.c') diff --git a/libguile/vm-i-system.c b/libguile/vm-i-system.c index 980d22afe..71c5281c8 100644 --- a/libguile/vm-i-system.c +++ b/libguile/vm-i-system.c @@ -1179,7 +1179,7 @@ VM_DEFINE_INSTRUCTION (65, call_cc, "call/cc", 0, 1, 1) cont = scm_i_make_continuation (&first, vm, vm_cont); if (first) { - PUSH ((SCM)fp); /* dynamic link */ + PUSH (0); /* dynamic link */ PUSH (0); /* mvra */ PUSH (0); /* ra */ PUSH (proc); -- cgit v1.2.3