[squeak-dev] About on:do:

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

[squeak-dev] About on:do:

stephane ducasse
Hello

I would like to know how the VM defines on:do:

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


I'm on a rather non existent internet connexion and I do not have the
vm code and I would like to know where how the exception and  
handlerAction block
are stored.

I was imagining that may be the vm stores them in the previous context.

Stef

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] About on:do:

Lukas Renggli
>  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

199 is a primitive that marks the context (it just sets a bit in the
context object) and always fails. The fallback code is then evaluated
that causes the receiving block to evaluate. That's all.

In case of an exception the VM can quickly find marked contexts.

Cheers,
Lukas

--
Lukas Renggli
http://www.lukas-renggli.ch

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] About on:do:

David T. Lewis
On Mon, Jul 21, 2008 at 12:46:15PM +0200, Lukas Renggli wrote:

> >  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
>
> 199 is a primitive that marks the context (it just sets a bit in the
> context object) and always fails. The fallback code is then evaluated
> that causes the receiving block to evaluate. That's all.
>
> In case of an exception the VM can quickly find marked contexts.

And the implementation of primitive 199 in class Interpreter is just this:

primitiveMarkHandlerMethod
        "Primitive. Mark the method for exception handling. The primitive must fail after marking the context so that the regular code is run."
        self inline: false.
        ^self primitiveFail

Or in C:

/* Primitive. Mark the method for exception handling. The primitive must fail after marking the context so that the regular code is run. */

sqInt primitiveMarkHandlerMethod(void) {
        /* begin primitiveFail */
        foo->successFlag = 0;
        return null;
}




Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] About on:do:

Eliot Miranda-2
In reply to this post by stephane ducasse


On Sun, Jul 20, 2008 at 11:59 AM, stephane ducasse <[hidden email]> wrote:
Hello

I would like to know how the VM defines on:do:

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


I'm on a rather non existent internet connexion and I do not have the
vm code and I would like to know where how the exception and handlerAction block
are stored.

As the other posters have pointed out primitive 199 is simply a primitive that aways fails.  So exception and handlerAction are stored in the activation of on:do: in its first and second argument, e.g. see
        | exception handler |
        [exception := thisContext sender at: 1.
         handler := thisContext sender at: 2.
         1 / 0]
             on: Error
             do: [:ex| ].
         { exception. handler }

The primitive doesn't set any bits in the context.  It merely fails, ad the method is activated exactly as if on:do: did not have a primitive.

The VM finds activations of on:do: by examining the header of each context's compiled method (no bits are set in the context).  Methods with primitives have the primitive number stored in a field in the method header.  The VM's primitive is merely an optimization of the Smalltalk code you see:

findNextHandlerContextStarting
"Return the next handler marked context, returning nil if there
         is none.  Search starts with self and proceeds up to nil."

| ctx |
<primitive: 197>
ctx := self.
[ctx isHandlerContext ifTrue:[^ctx].
(ctx := ctx sender) == nil ] whileFalse.
^nil

isHandlerContext
        "is this context for  method that is marked?"
^method primitive = 199

and similarly for finding unwind contexts (marked with primitive 198).

BTW, this is a really nice implementation by Andreas and Dan.  In VW there are bits in the method header because primitives are not stored in the method header but in the bytecode.  But this means we need a little bit more machinery.  Using the primitive field is very simple and just as effective



I was imagining that may be the vm stores them in the previous context.

Stef




Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] About on:do:

timrowledge

On 21-Jul-08, at 7:13 AM, Eliot Miranda wrote:
>
> The primitive doesn't set any bits in the context.  It merely fails,  
> ad the method is activated exactly as if on:do: did not have a  
> primitive.
>
> The VM finds activations of on:do: by examining the header of each  
> context's compiled method (no bits are set in the context).  Methods  
> with primitives have the primitive number stored in a field in the  
> method header.
[snip]
> BTW, this is a really nice implementation by Andreas and Dan.  In VW  
> there are bits in the method header because primitives are not  
> stored in the method header but in the bytecode.  But this means we  
> need a little bit more machinery.  Using the primitive field is very  
> simple and just as effective
Actually I'm pretty sure that was me. Certainly I did all the  
exception handling stuff in the VM and old email implies we came up  
with using a prim number as a flag in order to make it simple to both  
interpret and support the old J3 attempt with minimal changes. This  
was  all done back in august 200 or so. There was of course  
considerable back and forth about various details, lasting for several  
months IIRC.

tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
Useful random insult:- One chicken short of a henhouse.



Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] About on:do:

Randal L. Schwartz
>>>>> "tim" == tim Rowledge <[hidden email]> writes:

tim> [...] This  was  all done back in august 200 or
tim> so. [...]

Wow, I realize Smalltalk has been around for a while, but...
was it lost during the Dark Ages? :)

--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<[hidden email]> <URL:http://www.stonehenge.com/merlyn/>
Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc.
See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion

Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: About on:do:

Andreas.Raab
In reply to this post by Eliot Miranda-2
Eliot Miranda wrote:
> BTW, this is a really nice implementation by Andreas and Dan.

As much as I like to take credit, in this case it wasn't me. I don't
quite remember but I think Tim came up with it (was this one of the
adopted Interval changes?)

Cheers,
   - Andreas

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: About on:do:

Eliot Miranda-2


On Mon, Jul 21, 2008 at 8:58 AM, Andreas Raab <[hidden email]> wrote:
Eliot Miranda wrote:
BTW, this is a really nice implementation by Andreas and Dan.

As much as I like to take credit, in this case it wasn't me. I don't quite remember but I think Tim came up with it (was this one of the adopted Interval changes?)

I'm sorry.  I misunderstood a conversation we had recently.  Apologies Tim  And its great to hear you sounding so chipper at 1808 years old.
 


Cheers,
 - Andreas




Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: About on:do:

timrowledge

On 21-Jul-08, at 9:51 AM, Eliot Miranda wrote:

>
>
> On Mon, Jul 21, 2008 at 8:58 AM, Andreas Raab <[hidden email]>  
> wrote:
> Eliot Miranda wrote:
> BTW, this is a really nice implementation by Andreas and Dan.
>
> As much as I like to take credit, in this case it wasn't me. I don't  
> quite remember but I think Tim came up with it (was this one of the  
> adopted Interval changes?)
>
> I'm sorry.  I misunderstood a conversation we had recently.  
> Apologies Tim  And its great to hear you sounding so chipper at 1808  
> years old.
>
Well, as I was saying to Lucius Septimus Severus back then , "Emp", I  
said, "Emp - we need to put a flag in some primitive". Of course he  
misunderstood and took a legion or two off to impale some barbarians.

Note the method involved -
Interpreter>isUnwindMarked: aContext
        "Is this a MethodContext whose meth has a primitive number of 198?"
        | header meth pIndex |
        "NB: the use of a primitive number for marking the method is pretty  
grungy, but it is simple to use for a test sytem, not too expensive  
and we don't actually have the two spare method header bits we need.  
We can probably obtain them when the method format is changed
        NB 2: actually, the jitter will probably implement the prim to  
actually mark the volatile frame by changing the return function  
pointer."
        self inline: true.
        header := self baseHeader: aContext.
        (self isMethodContextHeader: header) ifFalse: [^false].
        meth := self fetchPointer: MethodIndex ofObject: aContext.
        pIndex := self primitiveIndexOf: meth.
        ^pIndex == 198
... and particularly the two NBs.
I think it's a pretty poor implementation all in all but it was the  
best compromise we could develop at the time and given the belief we  
would have a working JIT Real Soon Now to replace the interpreter. A  
mere eight years later we still don't have a cleaned up image format,  
jitter, closures, host windows etc etc in actual use[1]. Sigh.

tim
[1] Yes, I know all of them have been developed in some form - I've  
worked on all of them - but are they in actual use?
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
Strange OpCodes: WDS: Warp Drive, Scotty!



Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: About on:do:

Eliot Miranda-2
Well, as I was saying to Lucius Septimus Severus back then , "Emp", I said, "Emp - we need to put a flag in some primitive". Of course he misunderstood and took a legion or two off to impale some barbarians.

ROTFL!


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: About on:do:

timrowledge

On 21-Jul-08, at 10:47 AM, Eliot Miranda wrote:

> Well, as I was saying to Lucius Septimus Severus back then , "Emp",  
> I said, "Emp - we need to put a flag in some primitive". Of course  
> he misunderstood and took a legion or two off to impale some  
> barbarians.
>
> ROTFL!
>
Actually it was SUAPWIA[*] ;-)

tim
[*]Stuck Up A Pole Wriggling In Agony
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
Strange OpCodes: DPN: Double Precision No-op



Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] About on:do:

stephane ducasse
In reply to this post by Eliot Miranda-2
>
Thanks for all these explanation.
I like Smalltalk because I can learn a lot.
I'm writing some columns and chapters on exception-handling in  
Smalltalk for the next volume of Squeak
by Example (volume two) and I will make them public and call for  
feedback when they are more than a draft.


> I'm on a rather non existent internet connexion and I do not have the
> vm code and I would like to know where how the exception and  
> handlerAction block
> are stored.
>
> As the other posters have pointed out primitive 199 is simply a  
> primitive that aways fails.  So exception and handlerAction are  
> stored in the activation of on:do: in its first and second argument,  
> e.g. see
>        | exception handler |
>        [exception := thisContext sender at: 1.
>         handler := thisContext sender at: 2.
>         1 / 0]
>             on: Error
>             do: [:ex| ].
>         { exception. handler }

Excellent!

> The primitive doesn't set any bits in the context.  It merely fails,  
> ad the method is activated exactly as if on:do: did not have a  
> primitive.
>
> The VM finds activations of on:do: by examining the header of each  
> context's compiled method (no bits are set in the context).  Methods  
> with primitives have the primitive number stored in a field in the  
> method header.

Ok I see so when there is an error the VM look in the activation stack  
for 199Matching activation and then check if the raised error is a  
kind of "thisContext sender at: 1" and in such as case evaluate  
"thisContext sender at: 2"


> The VM's primitive is merely an optimization of the Smalltalk code  
> you see:
>
> findNextHandlerContextStarting
> "Return the next handler marked context, returning nil if there
>         is none.  Search starts with self and proceeds up to nil."
>
> | ctx |
> <primitive: 197>
> ctx := self.
> [ctx isHandlerContext ifTrue:[^ctx].
> (ctx := ctx sender) == nil ] whileFalse.
> ^nil
>
> isHandlerContext
>        "is this context for  method that is marked?"
> ^method primitive = 199
>
> and similarly for finding unwind contexts (marked with primitive 198).

this looks simple when reading the code.

> BTW, this is a really nice implementation by Andreas and Dan.  In VW  
> there are bits in the method header because primitives are not  
> stored in the method header but in the bytecode.  But this means we  
> need a little bit more machinery.  Using the primitive field is very  
> simple and just as effective

Thanks.!



Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: About on:do:

Paolo Bonzini-2

>> BTW, this is a really nice implementation by Andreas and Dan.  In VW
>> there are bits in the method header because primitives are not stored
>> in the method header but in the bytecode.  But this means we need a
>> little bit more machinery.  Using the primitive field is very simple
>> and just as effective
>
> Thanks.!

Just to chime in, GNU Smalltalk also uses a similar trick but with
pragmas.  Methods with pragmas are marked with a special flag value, and
the #scanForAttribute:ifFound: method on ContextPart looks for that flag
value before looking for a pragma in the method.  It is probably less
efficient than Squeak, but applies to all pragmas (at some point I had
an idea about using pragmas to support security policies).

The handling of unwind methods instead is completely different, 99% of
it residing in the implementation of the VM's return-from-method bytecode.

Paolo