Leopold Toetsch <[EMAIL PROTECTED]> writes:

> Piers Cawley <[EMAIL PROTECTED]> wrote:
>
>> The thing is, 'pushtop' is almost certainly the wrong thing to do. You
>> should only push the registers you care about onto the register
>> stacks.
>
> Yes:
>
> $ time parrot -j  oofib.imc
> fib(28) = 317811 3.050051s
>
> real    0m3.077s
>
> $ time parrot -j -Oc  oofib.imc
> fib(28) = 317811 2.234049s
>
> real    0m2.262s
>
> C<savetop> becomes C<pushtopp> if only P-registers are used. Saving only
> 3 or 5 registers isn't possible yet. We have no opcodes for that.

  save Pn
  save Pm
  ...
  restore Pm
  restore Pn

Admittedly we don't have opcodes for storing multiple registers at a
time, and having them would be a useful optimization...

>> The catch is that, whilst I know which registers *I* care about, I don't
>> know which registers IMCC cares about. So maybe IMCC's 'newcont' should
>> expand to:
>
>>      save 'imcc_magic_register1'
>>      save 'imcc_magic_register2'
>>      target = newsub .Continuation, dest
>>      restore 'imcc_magic_register2'
>>      restore 'imcc_magic_register1'
>
>> Notice how making a continuation looks remarkably like making a function
>> call.
>
> The usage of above Continuation would be to pass it on into a subroutine
> and eventually return through it to an alternate position? 

Have you looked at the parrotunit code that I (finally) posted? That
creates a continuation and calls a method to set it as an object
attribute. If you could fix whatever I'm doing wrong there I'd be
obscenely grateful btw.

Incidentally, the latest rewrite has the continuation created and saved
on the object using:

     savetop
     P5 = new Continuation
     set_addr P5, catch0
     I0 = 1
     I1 = 0
     I2 = 0
     I3 = 1
     I4 = 0
     S0 = "setFailureHandler"
     callmethodcc
     restoretop

     ...
   finally:
     thisObject."tearDown"() # thisObject is self in a high register...
     .pcc_begin_return
     .pcc_end_return

   catch0:
     restoretop
     ...
     branch finally
  .end   

and the continuation is invoked using 'handler("a string") rather than
simply invoking it. Catch is, 'finally' gets jumped to twice.

Other usages include stuffing the continuation into a
global. 


> If yes, then the Continuation should be created inside the call
> sequence to avoid duplicate register saving and restoring code:
>
>   res = subroutine(args, NEWCONT)



> But that's only one side of the business. The code at the return label
> C<dest>) has to restore the same registers too.
>
> If the target of the Continuation isn't the function return, it has to
> look somethin like this:
>
>       goto around_cont_ret
>   cont_ret_target:
>       restoretop   # or whatever was saved
>   around_cont_ret:

Oh yes, I'm fine with that. The problem I have at the moment is that I
don't know *what* to save and restore. It appears that IMCC uses at
least one register in P16-32 to save a copy of P1 so that it'll be
caught by a savetop and, in the cases where I was saving individual
registers, creating the continuation, and restoring the registers, I
was failing to save the current continuation because I didn't know
where it was (this is why I want P1 to be invariant over function
calls/continuation creation). Presumably, because IMCC knows that
cont_ret is a continuation target, it can create the appropriate
real_cont_ret and add the appropriate stack manipulation code in there?
This would be really cool.

>> If the destination of the continuation is within the current
>> compilation unit (which it probably should be, or things get *very*
>> weird) then, potentially, IMCC knows what registers the continuation
>> target cares about and can automagically save the current .locals as
>> well.
>
> Yes.
>
>> Would it be possible to arrange things so that
>
>>      $P0 = new .Continuation
>>      $P0 = P1 # The current RetContinuation
>
>> makes $P0 into a full continuation equivalent to the RetContinuation?
>
> Sure. It depends on what part of the context should be copied into the
> Continuation:
>
>   get_addr Idest, P1
>   set_addr $P0, Idest   # assign dest - implemented
>
> or
>
>   assign $P0, P1       # vtable->set_pmc  (N/Y)

Assign would be good. I can't really think of an occasion when you'd
want to copy anything less than the full context held by the
continuation. 

>
> which could do whatever is appropriate.
>
> ($P0 = P1 just aliases the two and isn't usable for assignment)

D'oh.

Reply via email to