#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

Reply via email to