chromatic (via RT) wrote:
Invoking a RetContinuation requires freeing the current context (or at least
decreasing its reference count). The problem is that the PCCMETHOD code
doesn't set the current context in the RetContinuation PMC.
Note that setting the current context is awfully ugly.
Not to mention confusing, this stuff took me ages to get my head around
and I'm still not sure I'm completely there.
The attached patch fixes the problem for me, but I'm not sure it's completely
correct. src/sub.c:174 says:
cc->from_ctx = NULL; /* filled in during a call */
I can't track down where that actually happens.
Happens in sub.pmc's invoke vtable method, I believe.
Still, the current patch identifies the problem and makes the test pass without
breaking anything else.
Yup, though I'm not sure it does the right thing.
- ctx->current_cont = ret_cont;
+ ctx->current_cont = ret_cont;
+ PMC_cont(ret_cont)->from_ctx = caller_ctx;
PMC_cont(ret_cont)->to_ctx is the context you end up in when you invoke
the continuation. This is set when you create a new return continuation
- it captures the current context. That is when we do:
PMC* ret_cont = new_ret_continuation_pmc(interp, NULL);
Then after that we create a new context for the current sub.
parrot_context_t *ctx = Parrot_push_context(interp, n_regs_used);
Note that to_ctx now refers to the caller, which is what you'd expect
since that's where we expect to go when we invoke a return continuation.
from_ctx is the current sub's context - that is, the one we just created
- so I think the correct thing to do here is:
PMC_cont(ret_cont)->from_ctx = ctx;
That is, set it to the context for this sub, since that's the context
we're returning from.
I did this change and it resolved the segfault. It was also needed in a
couple of other places. I'm smoking the changes at the moment, and
provided that doesn't show up any problems I'll check this in.
Thanks for tracking this one down!
Jonathan