#833: Exception from :init sub in PIR compreg causes problems
-------------------------+--------------------------------------------------
Reporter: whiteknight | Owner:
Type: RFC | Status: new
Priority: major | Milestone:
Component: core | Version: 1.3.0
Severity: medium | Keywords: inferior runloop
Lang: | Patch:
Platform: all |
-------------------------+--------------------------------------------------
Actually, this is just one more example of the inferior runloops problem,
although pmichaud++ has been able to narrow it down to a pure-PIR test
case:
{{{
.sub main
$S0 = <<'END'
.sub 'abc' :load :init
say 'run abc'
.end
.sub 'def' :load :init
die 'died in def'
.end
.sub 'ghi' :load :init
say 'run ghi'
.end
.sub 'main' :main
say 'run main'
.end
END
$P0 = compreg 'PIR'
push_eh trap1
$P0($S0)
trap1:
pop_eh
push_eh trap2
$P0($S0)
trap2:
pop_eh
.end
}}}
What happens, in a nutshell, is this: The :init functions from the
compiled code string are executed immediately in an child runloop.
function 'def' throws an exception which is handled by a handler from
outside the compiled code string. Execution continues in the child runloop
until the end of the program. Once that terminates, the C stack is unwound
back up to the parent runloop and execution continues, but now with a
corrupted context.
This isn't just a problem with IMCC, although the problem does manifest
inside IMCC in this case. It's a problem any time we mix child runloops
with exceptions.
We now know what causes this problem, and there are a handful of examples
of manifestations of it throughout the Trac and RT ticket queues by
various names. Resolving this issue won't be difficult if we can agree on
a sane way to do it.
Here's my proposal, which could easily be made to work for this particular
case but would require more planning and implementation effort to make it
work for the larger class of all related failures: Instead of executing
the :init functions in a new runloop from IMCC, we add them to the
scheduler and schedule them to execute in the parent runloop after IMCC
returns (in this case, directly after the invokecc opcode on the PIR
compreg). In this way we integrate this better with the scheduler and
prevent ever creating a child runloop, which prevents problems from multi-
runloop interaction.
This type of solution could also be extended to almost every other case
where a child runloop is created such as in vtable overrides for Object
PMC instead of calling the override directly, we add it to the scheduler
and execute some sort of continuation that takes us into the override and
then returns to the point in the parent control flow where the vtable was
called). Again, more details needed to be worked out for this idea to
become a reality.
Once we decide how we want to resolve this problem (and there are other
options besides the one I mention here), it should be straight-forward to
resolve it. I would like to hear ideas from people so we can start
planning a path forward.
--
Ticket URL: <https://trac.parrot.org/parrot/ticket/833>
Parrot <https://trac.parrot.org/parrot/>
Parrot Development
_______________________________________________
parrot-tickets mailing list
[email protected]
http://lists.parrot.org/mailman/listinfo/parrot-tickets