Matt Fowles <[EMAIL PROTECTED]> wrote: > All~ > I must admit I am a little confused as to what the problem is. Given > that any continuation which was originally created as a return > continuation will restore its registers, all code which uses P/S > registers will work as expected. Furthermore, I/N registers will be > usable accross function calls, it is just that continuations will > cause the same to computate as before to be repeated (which is really > not that much of a spanner in the works).
> Please don't draw the same diagrams and claim that registers life is > secretly extended. That is not the case, as the invocation of the > (once) return continuation will restore the register allocation to the > correct state that code after it is expecting. Ok. I'll try to summarize, where I see the problem. No diagrams, just code :) $I0 = 42 # set I16, 42 42 $N0 = 2.5 # set N16, 2.5 ..101... $S0 = "a" # set S16, "a" 0x1004 -> "a" $P0 = "a" # set P16, "a" 0x2008 -> "a" loop: foo() # set P0, ...; invokecc We have some temporary variables and a function call. Variables are used beyond that point, so the register allocator puts these in the preserved register range. The function C<foo()> might or might not capture the continuation created by the C<invokecc> opcode. Let's assume, it is captured, and stored into a global, if it wasn't already, i.e. the first time. According to Dan's plan, the function return restores the register contents to the state of the creation of the return continuation, which is shown in the right column. $I0 += 1 # add I16, 1 43 $N0 *= 2.0 # mul N16, 2.0 .101.... $S0 .= "b" # concat S16, "b" 0x1008 -> "ab" inc $P0 # inc P16 0x2008 -> "b" dec a # dec P17 0x200c -> 1 if a goto loop # if P17, loop A note WRT strings: the concat might or might not assign a new string to S16. It depends on the capacity of the string buffer. But generally: string operations do create new string headers with a different memory address like shown here. While S registers hold pointers, they have value semantics. Now we loop once over the function call. This creates a new return continuation and on function return registers are restored to their new values (44, 10.0, "abb", "c"). All fine till here. The loop counter "a" reaches zero. Now the next instruction is another function call. bar() # set P0, ... invokecc The "bar()" function extracts the return continuation captured in the first call to "foo()" from the global and invokes it. Control flow continues right after the "invokecc" opcode that called "foo()". This would restore the register contents to the first state shown above. That is, not only I and N registers would be clobbered also S registers are involved. Above code could only use P registers. Or in other words: I, N, and S registers are almost[1] useless. Perl6 syntax like "my int $i;" would need PMCs. Extracting an integer from an array that stores natural ints would need a PMC. And further: to achieve this functionality of restoring registers, there must AFAIK be some copying involved (probably when the return continuation is captured and converted into a real continuation). This would make the usage of continuations again very expensive and very likely unusable for backtracking in the rules engine or such. [1] What about I,S,N register usage between function calls or in leaf functions (that don't call further)? A piece of code like: $I0 = 10 loop: $P0 = shift ar dec $I0 if $I0 goto loop would look reasonable sane with a loop counter in an I register. But what happens if the "shift" extracts values from the array and the array creates these values lazily with a generator function? You never know if there is a continuation involved. To me this all smells like a huge change of the Parrot architecture. Please correct me, if any of my assumptions is wrong. leo