This post originated from an RSS feed registered with Agile Buzz
by James Robertson.
Original Post: Debugging VMless continuations
Feed Title: Michael Lucas-Smith
Feed URL: http://www.michaellucassmith.com/site.atom
Feed Description: Smalltalk and my misinterpretations of life
I thought I'd explore some of the ideas that are required of a really flash Smalltalk system. Firstly, debugging! But before I get on to the first thing, I'll insert a zeroth thing.
How do continuations and continuations passing style gel? In CPS, this is called "Call with Current Continuation". In an non-CPS system, you are required to take a copy of the whole stack. Since there's no stack in CPS, you need but remember the arguments you're passing to a method call as your Continuations, then enact that when you wish to run that continuation. That's about as much state as is involved with a closure. One might even call closures a 'call with current continuation'.
Back to debugging. Since I'm focusing on a VMless system (which it may not end up being) I thought I'd try and consider how it is you'd get a debugger in there. First off, you could use a debugger like C uses - an assembly level debugger which uses CPU features to control execution. Thanks but no thanks.. I was talking about a really flash Smalltalk system after all.
So! We want an advanced interactive Smalltalk debugger. What does that entail? Well, it means you need to have a stack (hee hee) so that you can drop back a stack frame and resume from there after changing some code. No big ask, except that we have no stack. Oops.
Let's extend our ideas a little further. Imagine the compiler inserts an audit call before every call you make in your program. This is about as costly as creating a stack frame for every call you make. Or perhaps it costs a little more, but since we've lost most of our cost already, it's safe to add some back in for development time.
The audit information can stay in memory, or perhaps be swapped out to disk. But a noteable feature of this audit information is that it's the entire execution path - not just the current stack branch of execution!. That's right, you can see what code truely made your instance variables go fooey.
Instead of having a list of stack frames in the debugger, you'd have a tree, with the current stack branch expanded automatically. The audit information writes out CallCC's (call with current continuations, as described above) for each call you would have made, so that the call can be made again. "Dropping back to a stack frame" is merely activating the continuation you want to go to.
Let's say this is too much audit information for you, no problem, the audit collector can act as a stack by itself and trim the audit information as it goes. A tool for a tool in effect, instead of a tool on a premise, where that premise is that you will have a stack.
One last thought: if the audit information does trim (or perhaps it does both jobs, stores all and trims) then the classic Smalltalk Stack and Process can be supported in a call-auditing system. For a fast system you'd want to turn all the audit information off, which would make it non ST-80 compliant.
Given how rare it is to use previous stack frames in production code, I doubt there will be many people up in arms over this non-compliance. In fact, the only example I've seen of using the smalltalk stack in executable code is: a) the debugger and b) Travis Grigg's silly 'Goto' package :)