Piers Cawley <[EMAIL PROTECTED]> wrote:
> Leopold Toetsch <[EMAIL PROTECTED]> writes:

>> 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

Well, these are already used for pushing items onto the user stack. It
could be

   pushtopp 3   # save P16..P18
   savetop 4    # save 4 regs from all I16 ..., S16, N16, P16 ... P19

and so on.

>>> 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?

Yes (you must have missed a f'up with a small patch in it).

> ... 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.

Please mail me your current code.

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

Ok, code is fine.

>    catch0:
>      restoretop
>      ...
>      branch finally
>   .end

Should work.

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

Probably registers are still messed up.

> Other usages include stuffing the continuation into a
> global.

[ PIR syntax for Continuations ]

> 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).

P1 (and self) are saved in some registers in the range P16..P31 and
preserved by pushtopp (or savetop). On function return P16..P31 are
restored. The return continuation is put into P1 (or invoked) only
in the function return sequence:

  .pcc_begin_return
  .pcc_end_return

translates normally to:

   set P1, Px
   set I1, 1
   ...
   set I5, 0
   invoke P1

While the return continuation is preserved, you don't know where. Do you
need access to the current return continuation?

> ... 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.

The code for creating the continuation and the return must be in sync.
When you pass the continuation on into a subroutine and want to return
either normally or through the continuation, we need something like:

    $P0 = newcont dest_label FOR _invoker
    _invoker($P0)
    ...
  dest_label:
    ...

Creating correct code from that is a bit ugly, because the continuation
is created, before the actual call sequence is generated. So a bit more
verbose:

    .pcc_begin prototyped
    .arg_newcont dest_label
    .pcc_call _invoker
    .pcc_end
    ...

  .CONT_TARGET dest_label:

That's still complicated but doable. That would need searching the
current unit for subroutine calls that have a C<.arg_newcont> argument,
compare the labels and create finally the very same register
restore opcode(s) that the function call has.

OTOH storing a continuation inside a global can't prepare any code for
the continuation return, because nothing about the continuation's usage
is known.

>>   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.

What about:

  .sym pmc cont
  cont = newcont dest
  ...
  updatecc cont   # assign current P1's context to cont

With

  assign cont, P1

we need another syntax extension to actually get the real P1 register:

  assign cont, current_P1

or P1 is always restored immediately after function calls (like
currently P2).

I think, C<assign> and restoring P1 immediately would be the most useful
combination.

leo

Reply via email to