resume/cc can grow the current stack if the continuation is larger

(as could happen resuming a continuation from a separate thread)
This commit is contained in:
Alex Shinn 2011-02-27 18:14:22 +09:00
parent ece6500f99
commit 01dd712a50
2 changed files with 32 additions and 19 deletions

View file

@ -444,8 +444,12 @@
#define SEXP_INIT_BCODE_SIZE 128
#endif
#ifndef SEXP_INIT_STACK_SIZE
#if SEXP_USE_CHECK_STACK
#define SEXP_INIT_STACK_SIZE 1024
#else
#define SEXP_INIT_STACK_SIZE 8192
#endif
#endif
#ifndef SEXP_MAX_STACK_SIZE
#define SEXP_MAX_STACK_SIZE SEXP_INIT_STACK_SIZE*1000
#endif

47
vm.c
View file

@ -482,24 +482,6 @@ static sexp make_opcode_procedure (sexp ctx, sexp op, sexp_uint_t i) {
/*********************** the virtual machine **************************/
static sexp sexp_save_stack (sexp ctx, sexp *stack, sexp_uint_t to) {
sexp res, *data;
sexp_uint_t i;
res = sexp_make_vector(ctx, sexp_make_fixnum(to), SEXP_VOID);
data = sexp_vector_data(res);
for (i=0; i<to; i++)
data[i] = stack[i];
return res;
}
static sexp_uint_t sexp_restore_stack (sexp saved, sexp *current) {
sexp_uint_t len = sexp_vector_length(saved), i;
sexp *from = sexp_vector_data(saved);
for (i=0; i<len; i++)
current[i] = from[i];
return len;
}
#if SEXP_USE_CHECK_STACK
static int sexp_grow_stack (sexp ctx) {
sexp stack, *from, *to;
@ -523,6 +505,31 @@ static int sexp_grow_stack (sexp ctx) {
}
#endif
static sexp sexp_save_stack (sexp ctx, sexp *stack, sexp_uint_t to) {
sexp res, *data;
sexp_uint_t i;
res = sexp_make_vector(ctx, sexp_make_fixnum(to), SEXP_VOID);
data = sexp_vector_data(res);
for (i=0; i<to; i++)
data[i] = stack[i];
return res;
}
static sexp sexp_restore_stack (sexp ctx, sexp saved) {
sexp_uint_t len = sexp_vector_length(saved), i;
sexp *from = sexp_vector_data(saved), *to;
#if SEXP_USE_CHECK_STACK
if ((len+64 >= sexp_stack_length(sexp_context_stack(ctx)))
&& !sexp_grow_stack(ctx))
return sexp_global(ctx, SEXP_G_OOS_ERROR);
#endif
to = sexp_stack_data(sexp_context_stack(ctx));
for (i=0; i<len; i++)
to[i] = from[i];
sexp_context_top(ctx) = len;
return SEXP_VOID;
}
#define _ARG1 stack[top-1]
#define _ARG2 stack[top-2]
#define _ARG3 stack[top-3]
@ -679,7 +686,9 @@ sexp sexp_vm (sexp ctx, sexp proc) {
case SEXP_OP_RESUMECC:
sexp_context_top(ctx) = top;
tmp1 = stack[fp-1];
top = sexp_restore_stack(sexp_vector_ref(cp, 0), stack);
tmp2 = sexp_restore_stack(ctx, sexp_vector_ref(cp, 0));
if (sexp_exceptionp(tmp2)) {_ARG1 = tmp2; goto call_error_handler;}
top = sexp_context_top(ctx);
fp = sexp_unbox_fixnum(_ARG1);
self = _ARG2;
bc = sexp_procedure_code(self);