[squeak-dev] Implementing control operators

Frank Shearar frank.shearar at angband.za.org
Wed Apr 13 22:42:36 UTC 2011


On 2011/04/13 23:19, Eliot Miranda wrote:
> Hi Frank,
>
>      you're committing a category error.  The space of bytecodes is
> disjoint from the space of numbered primitives and they are entirely
> unrelated.  The implementation of primitive 199 is given in e.g.
> Interpreter class>>initializePrimitiveTable and is
> primitiveMarkHandlerMethod, which itself is implemented as
> primitiveFail, since (as the comment says) primitive 199 is only used to
> mark a method as being an unwind-protect, not to change its invocation
> semantics.  Bytecode 199 is indeed bytecodePrimClass and causes the VM
> to fetch the class of the receiver (i.e. it is short-hand for sending
> #class to the receiver, except that the message isn't looked up, and so
> can't be overridden).  The sace of bytecodes is defined by e.g.
> Interpreter class>>intiializeBytecodeTable.  Compare e.g. primitive 60
> to bytecode 60 and the distinction should become clearer.

Ah! That was a silly mistake. I found initializeBytecodeTable by 
searching for methods containing '199', and leapt to my great confusion.

> BTW, you should focus your understanding on how contexts work
> (ContextPart & MethodContext). That's the fundamental, and above
> contexts exceptions are implemented.  Anyone have a pointer to Peter
> Deutsch's article on contexts ion the 1981 Byte issue?  That's a good
> place to start.  Another place is the Blue Book's implementation chapter.

I have a fair idea on how contexts work, although I still need to figure 
out/find out how (and when) contexts are actually created. (More reading 
of VMMaker source is required.)

(At any rate, I know enough to have implemented a rough working 
implementation of shift/reset.)

Randal mentions 
https://gforge.inria.fr/frs/download.php/26600/PBE2-Exceptions-2010-03-02.pdf 
and indeed, on page 24 I see what I _should_ have been looking at, 
namely _primitive_ 199, not _bytecode_ 199.

I see that, for instance, using primitives to search for the handler 
context won't create more contexts in the call stack. When you're 
manipulating the current call stack that can be quite important, I would 
imagine?

But I suppose I'm really asking this: is it _necessary_ to use primitive 
199, or could one in _principle_ implement exception handling solely by 
in-image stack manipulation?

frank

> On Wed, Apr 13, 2011 at 3:07 PM, Frank Shearar
> <frank.shearar at angband.za.org <mailto:frank.shearar at angband.za.org>> wrote:
>
>     I'm playing around with Danvy and Filinski's shift/reset operators,
>     which allow a nice (lexically scoped) syntax for capturing partial
>     continuations.
>
>     In particular, reset marks the stack in some way, and a later shift
>     reifies the call stack between itself and reset as a function.
>
>     To that end, I'm delving into the guts of how exceptions work. I've
>     a few questions:
>
>     First, I know that VMMaker (especially Interpreter
>     class>>initializeBytecodeTable) lists all the known numbered
>     primitives. In particular, BlockClosure>>on:do: uses <primitive: 199>.
>
>     on: exception do: handlerAction
>     "Evaluate the receiver in the scope of an exception handler."
>
>             | handlerActive |
>     <primitive: 199> "just a marker, fail and execute the following"
>             handlerActive := true.
>             ^ self value
>
>     and
>
>     bytecodePrimClass
>             | rcvr |
>             rcvr := self internalStackTop.
>             self internalPop: 1 thenPush: (self fetchClassOf: rcvr).
>             self fetchNextBytecode.
>
>     is the implementation of that bytecode.
>
>     But what's this really doing? Or, rather, how is what it's doing
>     connected with marking a context so as to find an exception handler?
>
>     If it's purely a marker, could one use another primitive? (Other
>     than "that's how we do it, and Things Will Break if something
>     changes the primitive number". I can only find
>     MethodContext>>isHandlerContext caring about the particular
>     primitive number)
>
>     Could one, in principle at least, lose the primitive invocation and
>     have an instvar isHandlerContext on ContextPart (MethodContext, more
>     likely), and just repeatedly walk down the stack to find the handler
>     rather than using another primitive to find the handler?
>
>     Secondly, what's handlerActive for in #on:do:? It's a local variable
>     set and then never referenced. (No other method has 'handlerActive'
>     in its source, in the base image.)
>
>     Thanks!
>
>     frank
>
>
>
>
>




More information about the Squeak-dev mailing list