
[Christian Tismer]
I tried the most simple thing, and this seemed to be duplicating the current state of the machine. The frame holds the stack, and references to all objects. By chance, the locals are not in a dict, but unpacked into the frame. (Sometimes I agree with Guido, that optimization is considered harmful :-)
I don't see that the locals are a problem here -- provided you simply leave them alone <wink>.
The Python stack, besides its intermingledness with the machine stack, is basically its chain of frames.
Right.
The value stack pointer still hides in the machine stack, but that's easy to change.
I'm not sure what "value stack" means here, or "machine stack". The latter means the C stack? Then I don't know which values you have in mind that are hiding in it (the locals are, as you say, unpacked in the frame, and the evaluation stack too). By "evaluation stack" I mean specifically f->f_valuestack; the current *top* of stack pointer (specifically stack_pointer) lives in the C stack -- is that what we're talking about? Whichever, when we're talking about the code, let's use the names the code uses <wink>.
So the real Scheme-like part is this chain, methinks, with the current bytecode offset and value stack info.
Curiously, f->f_lasti is already materialized every time we make a call, in order to support tracing. So if capturing a continuation is done via a function call (hard to see any other way it could be done <wink>), a bytecode offset is already getting saved in the frame object.
Making a copy of this in a restartable way means to increase the refcount of all objects in a frame.
You later had a vision of splitting the frame into two objects -- I think. Whichever part the locals live in should not be copied at all, but merely have its (single) refcount increased. The other part hinges on details of your approach I don't know. The nastiest part seems to be f->f_valuestack, which conceptually needs to be (shallow) copied in the current frame and in all other frames reachable from the current frame's continuation (the chain rooted at f->f_back today); that's the sum total (along with the same frames' bytecode offsets) of capturing the control flow state.
Would it be correct to undo the effect of fast locals before splitting, and redoing it on activation?
Unsure what splitting means, but in any case I can't conceive of a reason for doing anything to the locals. Their values aren't *supposed* to get restored upon continuation invocation, so there's no reason to do anything with their values upon continuation creation either. Right? Or are we talking about different things? almost-as-good-as-pantomimem<wink>-ly y'rs - tim