Hi Stef,<br><br><div class="gmail_quote">On Wed, Feb 13, 2013 at 11:40 AM, Stéphane Ducasse <span dir="ltr">&lt;<a href="mailto:stephane.ducasse@inria.fr" target="_blank">stephane.ducasse@inria.fr</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div>I repost the mail to the mailing-list since I do not see it in the vm-dev</div></div>
</blockquote><div><br></div><div>did you post to vm-dev?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><br></div>
<div>Stef</div><div><br><blockquote type="cite"><br><div style="word-wrap:break-word"><div>Hi </div><div><br></div><div>I was reading the following method in the VM code and I have a couple of questions:</div><div><br></div>
<div>- I do not understand why lookupMethodInClass: may return a class. I was thinking that it would return a method.</div></div></blockquote></div></div></blockquote><div><br></div><div>It doesn&#39;t matter what it returns as it&#39;s return value is always ignored.  It assigns to newMethod.  I suspect it returns currentClass because a) the return type was always sqInt because Slang didn&#39;t support void functions, and b) currentClass is a value in hand so probably in a register and hence cheap to return.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><blockquote type="cite"><div style="word-wrap:break-word"><div>- what is the invariant? </div>
<div><span style="white-space:pre-wrap">        </span>that currentclass always point to the currently looked up class and </div><div><span style="white-space:pre-wrap">        </span>newMethod is the found method?</div></div></blockquote>
</div></div></blockquote><div><br></div><div>The input arguments are messageSelector, argumentCount and its argument, class.  The VM suffers somewhat from being cluttered with global variables, which is I think a legacy of the blue-book specification (the Smalltalk code that was used to implement Interpreter in VMMaker) being derived from the Alto and Dorado implementations in microcode.  It would be nicer if there were fewer variables, but e.g. supplying argumentCount as a parameter throughout all the message handling routines can be difficult, especially when things like perform: and MNU change the argumentCount during message send.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><blockquote type="cite"><div style="word-wrap:break-word"><div>- why lookupMethodFor: selector InDictionary: dictionary is defined in StackInterpreter but never used</div>
<div>only in CoInterpreter?</div></div></blockquote></div></div></blockquote><div><br></div><div>Well, it belongs in StackInterpreter and could be used in the other lookup methods.  I was probably considering rewriting the other lookup routines to use  lookupMethodFor: InDictionary: but didn&#39;t get round to it.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><blockquote type="cite"><div style="word-wrap:break-word"><div><br>
</div><div>Thanks</div><div><br></div><div><br></div><div>lookupMethodInClass: class</div><div><span style="white-space:pre-wrap">        </span>| currentClass dictionary found |</div><div><span style="white-space:pre-wrap">        </span>&lt;inline: false&gt;</div>
<div><span style="white-space:pre-wrap">        </span>self assert: class ~= objectMemory nilObject.</div><div><span style="white-space:pre-wrap">        </span>currentClass := class.</div><div><span style="white-space:pre-wrap">        </span>[currentClass ~= objectMemory nilObject]</div>
<div><span style="white-space:pre-wrap">                </span>whileTrue:</div><div><span style="white-space:pre-wrap">                </span>[dictionary := objectMemory fetchPointer: MethodDictionaryIndex ofObject: currentClass.</div><div><br></div>
<div><span style="white-space:pre-wrap">                </span>*** trick with the cannotInterpret ***</div><div><span style="white-space:pre-wrap">                </span>dictionary = objectMemory nilObject ifTrue:</div><div><span style="white-space:pre-wrap">                        </span>[&quot;MethodDict pointer is nil (hopefully due a swapped out stub)</div>
<div><span style="white-space:pre-wrap">                                </span>-- raise exception #cannotInterpret:.&quot;</div><div><span style="white-space:pre-wrap">                        </span>self createActualMessageTo: class.</div><div><span style="white-space:pre-wrap">                        </span>messageSelector := objectMemory splObj: SelectorCannotInterpret.</div>
<div><span style="white-space:pre-wrap">                        </span>self sendBreak: messageSelector + BaseHeaderSize</div><div><span style="white-space:pre-wrap">                                </span>point: (objectMemory lengthOf: messageSelector)</div><div><span style="white-space:pre-wrap">                                </span>receiver: nil.</div>
<div><span style="white-space:pre-wrap">                        </span>^self lookupMethodInClass: (self superclassOf: currentClass)].</div><div><span style="white-space:pre-wrap">                </span>*** trick with the cannotInterpret end ***</div><div><br>
</div><div><span style="white-space:pre-wrap">                </span>found := self lookupMethodInDictionary: dictionary.</div><div><span style="white-space:pre-wrap">                </span>found ifTrue: [^currentClass].</div><div><span style="white-space:pre-wrap">                        </span>^^^^^^^^^^^^^^^^^^^^^^^^^</div>
<div><br></div><div><span style="white-space:pre-wrap">                </span>currentClass := self superclassOf: currentClass].</div><div><br></div><div><span style="white-space:pre-wrap">        </span>&quot;Could not find #doesNotUnderstand: -- unrecoverable error.&quot;</div>
<div><span style="white-space:pre-wrap">        </span>messageSelector = (objectMemory splObj: SelectorDoesNotUnderstand) ifTrue:</div><div><span style="white-space:pre-wrap">                </span>[self error: &#39;Recursive not understood error encountered&#39;].</div>
<div><br></div><div><span style="white-space:pre-wrap">        </span>&quot;Cound not find a normal message -- raise exception #doesNotUnderstand:&quot;</div><div><span style="white-space:pre-wrap">        </span>self createActualMessageTo: class.</div>
<div><span style="white-space:pre-wrap">        </span>messageSelector := objectMemory splObj: SelectorDoesNotUnderstand.</div><div><span style="white-space:pre-wrap">        </span>self sendBreak: messageSelector + BaseHeaderSize</div>
<div><span style="white-space:pre-wrap">                </span>point: (objectMemory lengthOf: messageSelector)</div><div><span style="white-space:pre-wrap">                </span>receiver: nil.</div><div><span style="white-space:pre-wrap">        </span>^self lookupMethodInClass: class</div>
<div><br></div><div><br></div><div><div style="margin:0px;font-size:11px;font-family:Menlo"><span style="color:rgb(187,44,162)">if</span> (found) {</div><div style="margin:0px;font-size:11px;font-family:Menlo"><span style="color:rgb(187,44,162)"><span style="white-space:pre-wrap">        </span>return</span> currentClass;</div>
<div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">        </span>}</div></div><div><br></div><div><br></div><div><div style="margin:0px;font-size:11px;font-family:Menlo"><span style="color:#bb2ca2">static</span> sqInt</div>
<div style="margin:0px;font-size:11px;font-family:Menlo">lookupMethodInClass(sqInt class)</div><div style="margin:0px;font-size:11px;font-family:Menlo">{</div><div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(0,132,0)">
<span><span style="white-space:pre-wrap">        </span></span>// StackInterpreter&gt;&gt;#lookupMethodInClass:   DECL_MAYBE_SQ_GLOBAL_STRUCT</div><div style="margin:0px;font-size:11px;font-family:Menlo">    sqInt currentClass;</div>
<div style="margin:0px;font-size:11px;font-family:Menlo">    sqInt dictionary;</div><div style="margin:0px;font-size:11px;font-family:Menlo">    sqInt found;</div><div style="margin:0px;font-size:11px;font-family:Menlo">    sqInt header;</div>
<div style="margin:0px;font-size:11px;font-family:Menlo">    sqInt index;</div><div style="margin:0px;font-size:11px;font-family:Menlo">    sqInt length;</div><div style="margin:0px;font-size:11px;font-family:Menlo">    sqInt mask;</div>
<div style="margin:0px;font-size:11px;font-family:Menlo">    sqInt methodArray;</div><div style="margin:0px;font-size:11px;font-family:Menlo">    sqInt nextSelector;</div><div style="margin:0px;font-size:11px;font-family:Menlo">
    sqInt sz;</div><div style="margin:0px;font-size:11px;font-family:Menlo">    sqInt wrapAround;</div><div style="margin:0px;font-size:11px;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;font-family:Menlo">
<span style="white-space:pre-wrap">        </span>assert(class != (nilObject()));</div><div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">        </span>currentClass = class;</div><div style="margin:0px;font-size:11px;font-family:Menlo">
<span style="white-space:pre-wrap">        </span><span style="color:#bb2ca2">while</span> (currentClass != GIV(nilObj)) {</div><div style="margin:0px;font-size:11px;font-family:Menlo">dictionary = longAt((currentClass + BaseHeaderSize) + (MethodDictionaryIndex &lt;&lt; ShiftForWord));</div>
<div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">                </span><span style="color:#bb2ca2">if</span> (dictionary == GIV(nilObj)) {</div><div style="margin:0px;font-size:11px;font-family:Menlo;min-height:13px">
<br></div><div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(0,132,0)"><span><span style="white-space:pre-wrap">                        </span></span>/* ifTrue: */</div><div style="margin:0px;font-size:11px;font-family:Menlo;min-height:13px">
<br></div><div style="margin:0px;font-size:11px;font-family:Menlo">createActualMessageTo(class);</div><div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">                        </span>GIV(messageSelector) = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SelectorCannotInterpret &lt;&lt; ShiftForWord));</div>
<div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">                        </span>sendBreakpointreceiver(GIV(messageSelector) + BaseHeaderSize, lengthOf(GIV(messageSelector)), null);</div><div style="margin:0px;font-size:11px;font-family:Menlo">
<span style="white-space:pre-wrap">                        </span><span style="color:#bb2ca2">return</span> lookupMethodInClass(longAt((currentClass + BaseHeaderSize) + (SuperclassIndex &lt;&lt; ShiftForWord)));</div><div style="margin:0px;font-size:11px;font-family:Menlo">
<span style="white-space:pre-wrap">                </span>}</div><div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(0,132,0)"><span><span style="white-space:pre-wrap">                </span></span>/* begin lookupMethodInDictionary: */</div>
<div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(0,132,0)">/* begin fetchWordLengthOf: */</div><div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(0,132,0)">/* begin sizeBitsOf: */</div><div style="margin:0px;font-size:11px;font-family:Menlo">
header = longAt(dictionary);</div><div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">                </span>sz = ((header &amp; TypeMask) == HeaderTypeSizeAndClass</div><div style="margin:0px;font-size:11px;font-family:Menlo">
<span style="white-space:pre-wrap">                        </span>? (longAt(dictionary - (BytesPerWord * <span style="color:#272ad8">2</span>))) &amp; LongSizeMask</div><div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">                        </span>: header &amp; SizeMask);</div>
<div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">                </span>length = ((usqInt) (sz - BaseHeaderSize)) &gt;&gt; ShiftForWord;</div><div style="margin:0px;font-size:11px;font-family:Menlo">
<span style="white-space:pre-wrap">                </span>mask = (length - SelectorStart) - <span style="color:#272ad8">1</span>;</div><div style="margin:0px;font-size:11px;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(0,132,0)">
<span><span style="white-space:pre-wrap">                </span></span>/* messageSelector */</div><div style="margin:0px;font-size:11px;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;font-family:Menlo">
index = SelectorStart + (mask &amp; (((GIV(messageSelector) &amp; <span style="color:#272ad8">1</span>)</div><div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">        </span>? (GIV(messageSelector) &gt;&gt; <span style="color:#272ad8">1</span>)</div>
<div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">        </span>: (((usqInt) (longAt(GIV(messageSelector)))) &gt;&gt; HashBitsOffset) &amp; HashMaskUnshifted)));</div><div style="margin:0px;font-size:11px;font-family:Menlo">
<span style="white-space:pre-wrap">                </span>wrapAround = <span style="color:#272ad8">0</span>;</div><div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">                </span><span style="color:#bb2ca2">while</span> (<span style="color:#272ad8">1</span>) {</div>
<div style="margin:0px;font-size:11px;font-family:Menlo">nextSelector = longAt((dictionary + BaseHeaderSize) + (index &lt;&lt; ShiftForWord));</div><div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">                        </span><span style="color:#bb2ca2">if</span> (nextSelector == GIV(nilObj)) {</div>
<div style="margin:0px;font-size:11px;font-family:Menlo">found = <span style="color:#272ad8">0</span>;</div><div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">                                </span><span style="color:#bb2ca2">goto</span> l1;</div>
<div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">                        </span>}</div><div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">                        </span><span style="color:#bb2ca2">if</span> (nextSelector == GIV(messageSelector)) {</div>
<div style="margin:0px;font-size:11px;font-family:Menlo">methodArray = longAt((dictionary + BaseHeaderSize) + (MethodArrayIndex &lt;&lt; ShiftForWord));</div><div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">                                </span>GIV(newMethod) = longAt((methodArray + BaseHeaderSize) + ((index - SelectorStart) &lt;&lt; ShiftForWord));</div>
<div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">                                </span>found = <span style="color:#272ad8">1</span>;</div><div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">                                </span><span style="color:#bb2ca2">goto</span> l1;</div>
<div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">                        </span>}</div><div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">                        </span>index += <span style="color:#272ad8">1</span>;</div>
<div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">                        </span><span style="color:#bb2ca2">if</span> (index == length) {</div><div style="margin:0px;font-size:11px;font-family:Menlo">
<span style="color:#bb2ca2">if</span> (wrapAround) {</div><div style="margin:0px;font-size:11px;font-family:Menlo">found = <span style="color:#272ad8">0</span>;</div><div style="margin:0px;font-size:11px;font-family:Menlo">
<span style="white-space:pre-wrap">                                        </span><span style="color:#bb2ca2">goto</span> l1;</div><div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">                                </span>}</div><div style="margin:0px;font-size:11px;font-family:Menlo">
<span style="white-space:pre-wrap">                                </span>wrapAround = <span style="color:#272ad8">1</span>;</div><div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">                                </span>index = SelectorStart;</div>
<div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">                        </span>}</div><div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">                </span>}</div><div style="margin:0px;font-size:11px;font-family:Menlo">
found = <span style="color:#272ad8">0</span>;</div><div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(0,132,0)"><span><span style="white-space:pre-wrap">        </span>l1:<span style="white-space:pre-wrap">        </span></span>/* end lookupMethodInDictionary: */<span>;</span></div>
<div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">                </span><span style="color:#bb2ca2">if</span> (found) {</div><div style="margin:0px;font-size:11px;font-family:Menlo"><span style="color:#bb2ca2">return</span> currentClass;</div>
<div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">                </span>}</div><div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">                </span>currentClass = longAt((currentClass + BaseHeaderSize) + (SuperclassIndex &lt;&lt; ShiftForWord));</div>
<div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">        </span>}</div><div style="margin:0px;font-size:11px;font-family:Menlo"><span style="color:#bb2ca2">if</span> (GIV(messageSelector) == (longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SelectorDoesNotUnderstand &lt;&lt; ShiftForWord)))) {</div>
<div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(209,47,27)"><span><span style="white-space:pre-wrap">                </span>error(</span>&quot;Recursive not understood error encountered&quot;<span>);</span></div><div style="margin:0px;font-size:11px;font-family:Menlo">
<span style="white-space:pre-wrap">        </span>}</div><div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">        </span>createActualMessageTo(class);</div><div style="margin:0px;font-size:11px;font-family:Menlo">
<span style="white-space:pre-wrap">        </span>GIV(messageSelector) = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SelectorDoesNotUnderstand &lt;&lt; ShiftForWord));</div><div style="margin:0px;font-size:11px;font-family:Menlo">
<span style="white-space:pre-wrap">        </span>sendBreakpointreceiver(GIV(messageSelector) + BaseHeaderSize, lengthOf(GIV(messageSelector)), null);</div><div style="margin:0px;font-size:11px;font-family:Menlo"><span style="white-space:pre-wrap">        </span><span style="color:#bb2ca2">return</span> lookupMethodInClass(class);</div>
<div style="margin:0px;font-size:11px;font-family:Menlo">}</div></div><div><br></div><div><br></div><div><br></div><div><br></div></div></blockquote></div><br></div></blockquote></div><br><br clear="all"><div><br></div>-- <br>
best,<div>Eliot</div>