<div dir="ltr"><br><br><div class="gmail_quote">On Sun, Jul 20, 2008 at 11:59 AM, stephane ducasse <<a href="mailto:stephane.ducasse@free.fr">stephane.ducasse@free.fr</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Hello<br>
<br>
I would like to know how the VM defines on:do:<br>
<br>
on: exception do: handlerAction<br>
"Evaluate the receiver in the scope of an exception handler."<br>
<br>
| handlerActive |<br>
<primitive: 199> "just a marker, fail and execute the following"<br>
handlerActive _ true.<br>
^ self value<br>
<br>
<br>
I'm on a rather non existent internet connexion and I do not have the<br>
vm code and I would like to know where how the exception and handlerAction block<br>
are stored.</blockquote><div><br></div><div>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</div>
<div> | exception handler |</div><div> [exception := thisContext sender at: 1.</div><div> handler := thisContext sender at: 2.</div><div> 1 / 0]</div><div> on: Error</div><div> do: [:ex| ].</div>
<div> { exception. handler }</div><div><br></div><div>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.</div><div><br>
</div><div>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:</div>
<div><br></div><div><div><div>findNextHandlerContextStarting</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>"Return the next handler marked context, returning nil if there</div><div> is none. Search starts with self and proceeds up to nil."</div>
<div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>| ctx |</div><div><span class="Apple-tab-span" style="white-space:pre">        </span><primitive: 197></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>ctx := self.</div>
<div><span class="Apple-tab-span" style="white-space:pre">                </span>[ctx isHandlerContext ifTrue:[^ctx].</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>(ctx := ctx sender) == nil ] whileFalse.</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>^nil</div><div><br></div><div><div>isHandlerContext</div><div> "is this context for method that is marked?"</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>^method primitive = 199</div>
<div><br></div><div>and similarly for finding unwind contexts (marked with primitive 198).</div><div><br></div><div>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</div>
</div></div><div><div><br></div></div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><br>
<br>
I was imagining that may be the vm stores them in the previous context.<br>
<br>
Stef<br>
<br>
</blockquote></div><br></div>