Piers Cawley <[EMAIL PROTECTED]> wrote: > Further to my last response. If you have things set up so that you can > return multiple times from the same function invocation then the return > continuation should have been replaced with a full continuation before > the first return, so even the first return will use copying semantics, > and the registers will always be restored to the state they were in when > the function was first called, which is absolutely the right thing to > do.
Here is again the example I've brought recently. Please go through it and tell me what's wrong with my conclusion. $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. leo