Hi Eliot,
On Tue, 26 Apr 2011, Eliot Miranda wrote:
Hmm... the above behavior is intentional and correct in that to speed up context-to-stack mapping Cog makes no guarantee to preserve the values of temporary values after a context has returned. You'll notice that the entire closure scheme is centered around this, in that temporaries that must outlive their dynamic extent for the correct working of blocks are either copied into blocks (as copied values) or stored into remote temp vectors, hence breaking any dependence on the temporaries in enclosing contexts.
it's probably just the lack of my knowledge about VMs, but I don't see why an existing object's slots can't be copied by primitive 148. Here's an example:
| context | context := MethodContext newForMethod: Object >> #yourself. context stackp: 3. 1 to: 3 do: [ :index | context at: index put: index ]. { context. context copy } explore
The forged contexts in the above example never returned (because they weren't executed), but the copied context lacks the temps of the original.
If you can live with this restriction then instead of stating "Cog doesn't copy the temps properly, so copy them here." in your reimplementation of copyTo: it would be more accurate to state "Cog doesn't preserve non-closed-over temps beyond their dynamic extent, so copy them here." or some such.
That's acceptable, but I think that loop is superfluous, see below.
Note that Cog /does/ preserve arguments. However, I've clearly still got some bug because look at the following. In the copy the arguments ba1 & ba2 (1 & 2) are in the wrong place on the stack. Sigh...
[:ba1 :ba2| | context a b c d e | context := thisContext copy. a := b := c := d := e := context. { context. context copy } explore. { a. b. c. d. e } "This is here to avoid compiler complaints."] value: 1 value: 2
I think that this bug causes the problem with both #copyTo: and the above example. When this is fixed, then there will be no need to copy the temps slots in #copyTo:. The temp slots are copied in the next example, but they are off by 6 (the number of fixed slots):
| context | context := MethodContext newForMethod: Object >> #yourself. context stackp: 16. 1 to: 3 do: [ :index | context at: index put: index ]. { context. context copy} explore
Cheers, Levente
Levente
thanks!
best, Eliot