Diffs between last version checked in and current workfile(s): Index: include/parrot/interpreter.h =================================================================== --- include/parrot/interpreter.h (revision 14695) +++ include/parrot/interpreter.h (working copy) @@ -213,6 +213,7 @@ struct Stack_Chunk *user_stack; /* Base of the scratch stack */ struct Stack_Chunk *control_stack; /* Base of the flow control stack */ + struct Stack_Chunk *return_stack; /* Base of the bsr/jsr/ret stack */ PMC *lex_pad; /* LexPad PMC */ struct Parrot_Context *outer_ctx; /* outer context, if a closure */ UINTVAL warns; /* Keeps track of what warnings Index: src/register.c =================================================================== --- src/register.c (revision 14695) +++ src/register.c (working copy) @@ -234,6 +234,9 @@ ctx->current_method = NULL; /* XXX who clears it? */ ctx->current_object = NULL; /* XXX who clears it? */ ctx->current_HLL = 0; + /* each context gets its own return stack, but we may not be able to + initialize it yet if we're still in create_initial_context. */ + ctx->return_stack = NULL; if (old) { /* some items should better be COW copied */ ctx->constants = old->constants; @@ -393,6 +396,12 @@ ptr = ctxp; slot = ctxp->regs_mem_size >> 3; + if (ctxp->return_stack) { + /* [stack_destroy is currently a noop. -- rgr, 23-Sep-06.] */ + stack_destroy(ctxp->return_stack); + ctxp->return_stack = NULL; + } + assert(slot < interpreter->ctx_mem.n_free_slots); *(void **)ptr = interpreter->ctx_mem.free_list[slot]; interpreter->ctx_mem.free_list[slot] = ptr; Index: src/inter_create.c =================================================================== --- src/inter_create.c (revision 14695) +++ src/inter_create.c (working copy) @@ -416,8 +416,13 @@ /* deinit op_lib */ (void) PARROT_CORE_OPLIB_INIT(0); + /* [stack_destroy is currently a noop, otherwise these would probably fail, + as the entries are shared with other contexts. -- rgr, 23-Sep-06.] + */ stack_destroy(CONTEXT(interpreter->ctx)->user_stack); stack_destroy(CONTEXT(interpreter->ctx)->control_stack); + if (CONTEXT(interpreter->ctx)->control_stack) + stack_destroy(CONTEXT(interpreter->ctx)->control_stack); destroy_context(interpreter); Index: src/ops/core.ops =================================================================== --- src/ops/core.ops (revision 14695) +++ src/ops/core.ops (working copy) @@ -203,7 +203,13 @@ =cut inline op bsr (label INT) :base_core,check_event { - stack_push(interpreter, &CONTEXT(interpreter->ctx)->control_stack, + struct Parrot_Context *context = CONTEXT(interpreter->ctx); + if (! context->return_stack) { + /* this is necessary in order to work around strange context + initiation rites. -- rgr, 21-Sep-06. */ + context->return_stack = new_stack(interpreter, "Return"); + } + stack_push(interpreter, &context->return_stack, expr NEXT(), STACK_ENTRY_DESTINATION, STACK_CLEANUP_NULL); goto OFFSET($1); } @@ -230,7 +236,13 @@ inline op jsr(label INT) :base_core,check_event { opcode_t * loc; - stack_push(interpreter, &CONTEXT(interpreter->ctx)->control_stack, + struct Parrot_Context *context = CONTEXT(interpreter->ctx); + if (! context->return_stack) { + /* this is necessary in order to work around strange context + initiation rites. -- rgr, 21-Sep-06. */ + context->return_stack = new_stack(interpreter, "Return"); + } + stack_push(interpreter, &context->return_stack, expr NEXT(), STACK_ENTRY_DESTINATION, STACK_CLEANUP_NULL); loc = INTVAL2PTR(opcode_t *, $1); goto ADDRESS(loc); Index: src/stacks.c =================================================================== --- src/stacks.c (revision 14695) +++ src/stacks.c (working copy) @@ -363,7 +363,13 @@ /* We don't mind the extra call, so we do this: (previous comment * said we *do* mind, but I say let the compiler decide) */ void *dest; - (void)stack_pop(interpreter, &CONTEXT(interpreter->ctx)->control_stack, + struct Parrot_Context *context = CONTEXT(interpreter->ctx); + + if (! context->return_stack) { + real_exception(interpreter, NULL, INVALID_OPERATION, + "Return address stack is empty."); + } + (void)stack_pop(interpreter, &CONTEXT(interpreter->ctx)->return_stack, &dest, STACK_ENTRY_DESTINATION); return dest; } Index: src/sub.c =================================================================== --- src/sub.c (revision 14695) +++ src/sub.c (working copy) @@ -40,6 +40,8 @@ mark_stack(interpreter, ctx->user_stack); mark_stack(interpreter, ctx->control_stack); + if (ctx->return_stack) + mark_stack(interpreter, ctx->return_stack); mark_register_stack(interpreter, ctx->reg_stack); obj = (PObj*)ctx->current_sub; if (obj) End of diffs.