summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--unwind.c11
-rw-r--r--unwind.h1
-rw-r--r--vm.c1
3 files changed, 11 insertions, 2 deletions
diff --git a/unwind.c b/unwind.c
index 0032493d..a1f0989d 100644
--- a/unwind.c
+++ b/unwind.c
@@ -191,6 +191,7 @@ void uw_push_block(uw_frame_t *fr, val tag)
fr->bl.tag = tag;
fr->bl.result = nil;
fr->bl.up = uw_stack;
+ fr->bl.cont_bottom = 0;
uw_stack = fr;
}
@@ -906,8 +907,10 @@ static val revive_cont(val dc, val arg)
word = *wordptr;
if (word >= orig_start - UW_CONT_FRAME_BEFORE &&
- word < orig_end && is_ptr(coerce(val, word)))
+ word <= orig_end && is_ptr(coerce(val, word)))
+ {
*wordptr = word + delta;
+ }
#if HAVE_VALGRIND
if (opt_vg_debug)
@@ -959,7 +962,11 @@ static val capture_cont(val tag, val fun, uw_frame_t *block)
bug_unless (uw_stack < block);
{
- mem_t *lim = coerce(mem_t *, block + 1) + UW_CONT_FRAME_AFTER;
+ mem_t *basic_lim = coerce(mem_t *, block + 1) + UW_CONT_FRAME_AFTER;
+ mem_t *lim = block->bl.cont_bottom
+ ? (block->bl.cont_bottom > basic_lim
+ ? block->bl.cont_bottom : basic_lim)
+ : basic_lim;
cnum bloff = coerce(mem_t *, block) - coerce(mem_t *, stack);
cnum size = coerce(mem_t *, lim) - coerce(mem_t *, stack);
mem_t *stack_copy = chk_malloc(size);
diff --git a/unwind.h b/unwind.h
index 34853223..0a7d20d3 100644
--- a/unwind.h
+++ b/unwind.h
@@ -42,6 +42,7 @@ struct uw_block {
val tag;
val result;
val protocol;
+ mem_t *cont_bottom;
extended_jmp_buf jb;
};
diff --git a/vm.c b/vm.c
index e5489c2c..4d041fce 100644
--- a/vm.c
+++ b/vm.c
@@ -643,6 +643,7 @@ static void vm_block(struct vm *vm, vm_word_t insn)
int saved_lev = vm->lev;
uw_block_begin (vm_get(vm->dspl, blname), result);
+ uw_blk.bl.cont_bottom = coerce(mem_t *, vm + 1);
result = vm_execute(vm);
uw_block_end;