<div dir="ltr"><div><div>Hi David,<br></div>do you realize that Eliot is (ab)using this in COG in order to eliminate some direct cCode: &#39;...&#39; inclusion?<br></div>So setFoo: is not an option (or i misunderstood something)<br>
</div><div class="gmail_extra"><br><br><div class="gmail_quote">2014-02-10 21:51 GMT+01:00 David T. Lewis <span dir="ltr">&lt;<a href="mailto:lewis@mail.msen.com" target="_blank">lewis@mail.msen.com</a>&gt;</span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
I was looking at the trunk VMM yesterday and found that most of the issues<br>
were just caused by accessor methods, where #foo and #foo: generate<br>
conflicting foo(void) and foo(aParameter). In most cases, a convention of<br>
#setFoo: rather than #foo: takes care of the problem. There were a few<br>
other miscellaneous issues as well, but nothing that looked serious.<br>
<br>
The variable &#39;memory&#39; is a challenge because it is used extensively both<br>
directly and through #memory and #memory:. I was considering changing the<br>
variable name to something like memoryBase, and leaving the accessors<br>
alone though I&#39;m not sure that would be a very good idea.<br>
<br>
I ran out of time yesterday and did not pursue it beyond this.<br>
<br>
Dave<br>
<br>
&gt;<br>
&gt;<br>
&gt; On 10-02-2014, at 11:53 AM, Eliot Miranda &lt;<a href="mailto:eliot.miranda@gmail.com">eliot.miranda@gmail.com</a>&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt; I *think* the issue is the internal/external split brought abut by the<br>
&gt;&gt; introduction of the localFoo variables, such as localSP and localIP.<br>
&gt;<br>
&gt; It&rsquo;s really hard to be sure but I suspect that this isn&rsquo;t the (only)<br>
&gt; issue. IIRC we used to be able to make non-inlined VMs at one point and<br>
&gt; that was well after the internalFoo code was added.<br>
&gt;<br>
&gt; OK, some quick email searching reveals some work done in &rsquo;03 by johnMcI,<br>
&gt; Craig &amp; me.<br>
&gt; Craig found the following code helped -<br>
&gt;<br>
&gt; !&#39;From Squeak3.6alpha of &#39;&#39;17 March 2003&#39;&#39; [latest update: #5325] on 21<br>
&gt; July 2003 at 1:11:25 pm&#39;!<br>
&gt;<br>
&gt; !Interpreter methodsFor: &#39;contexts&#39; stamp: &#39;crl 7/19/2003 15:59&#39;!<br>
&gt; primitiveFindNextUnwindContext<br>
&gt; &nbsp; &nbsp; &nbsp; &quot;Primitive. Search up the context stack for the next method context<br>
&gt; marked for unwind handling from the receiver up to but not including the<br>
&gt; argument. Return nil if none found.&quot;<br>
&gt; &nbsp; &nbsp; &nbsp; | thisCntx nilOop aContext isUnwindMarked header meth pIndex |<br>
&gt; &nbsp; &nbsp; &nbsp; aContext _ self popStack.<br>
&gt; &nbsp; &nbsp; &nbsp; thisCntx _ self fetchPointer: SenderIndex ofObject: self popStack.<br>
&gt; &nbsp; &nbsp; &nbsp; nilOop _ nilObj.<br>
&gt;<br>
&gt; &nbsp; &nbsp; &nbsp; [(thisCntx = aContext) or: [thisCntx = nilOop]] whileFalse: [<br>
&gt;<br>
&gt; &nbsp; &nbsp; &nbsp; header _ self baseHeader: aContext.<br>
&gt;<br>
&gt; &nbsp; &nbsp; &nbsp; (self isMethodContextHeader: header)<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ifTrue: [<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; meth _ self fetchPointer: MethodIndex ofObject: aContext.<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pIndex _ self primitiveIndexOf: meth.<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; isUnwindMarked _ pIndex == 198]<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ifFalse: [isUnwindMarked _ false].<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; isUnwindMarked ifTrue:[<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self push: thisCntx.<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ^nil].<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; thisCntx _ self fetchPointer: SenderIndex ofObject: thisCntx].<br>
&gt;<br>
&gt; &nbsp; &nbsp; &nbsp; ^self push: nilOop! !<br>
&gt;<br>
&gt; !Interpreter methodsFor: &#39;interpreter shell&#39; stamp: &#39;crl 7/19/2003 15:33&#39;!<br>
&gt; interpret<br>
&gt; &nbsp; &nbsp; &nbsp; &quot;This is the main interpreter loop. It normally loops forever, fetching<br>
&gt; and executing bytecodes. When running in the context of a browser plugin<br>
&gt; VM, however, it must return control to the browser periodically. This<br>
&gt; should done only when the state of the currently running Squeak thread is<br>
&gt; safely stored in the object heap. Since this is the case at the moment<br>
&gt; that a check for interrupts is performed, that is when we return to the<br>
&gt; browser if it is time to do so. Interrupt checks happen quite<br>
&gt; frequently.&quot;<br>
&gt;<br>
&gt; &nbsp; &nbsp; &nbsp; &quot;record entry time when running as a browser plug-in&quot;<br>
&gt; &nbsp; &nbsp; &nbsp; &quot;self browserPluginInitialiseIfNeeded&quot;<br>
&gt; &nbsp; &nbsp; &nbsp; self internalizeIPandSP.<br>
&gt; &nbsp; &nbsp; &nbsp; self fetchNextBytecode.<br>
&gt; &nbsp; &nbsp; &nbsp; [true] whileTrue: [self dispatchOn: currentBytecode in: BytecodeTable].<br>
&gt; &nbsp; &nbsp; &nbsp; localIP _ localIP - 1. &nbsp;&quot;undo the pre-increment of IP before returning&quot;<br>
&gt; &nbsp; &nbsp; &nbsp; self externalizeIPandSP.<br>
&gt; ! !<br>
&gt;<br>
&gt; !Interpreter methodsFor: &#39;return bytecodes&#39; stamp: &#39;crl 7/19/2003 16:05&#39;!<br>
&gt; returnValueTo<br>
&gt; &nbsp; &nbsp; &nbsp; &quot;Note: Assumed to be inlined into the dispatch loop.&quot;<br>
&gt;<br>
&gt; &nbsp; &nbsp; &nbsp; | nilOop thisCntx contextOfCaller localCntx localVal isUnwindMarked<br>
&gt; header meth pIndex |<br>
&gt; &nbsp; &nbsp; &nbsp; self inline: true.<br>
&gt; &nbsp; &nbsp; &nbsp; self sharedCodeNamed: &#39;commonReturn&#39; inCase: 120.<br>
&gt;<br>
&gt; &nbsp; &nbsp; &nbsp; nilOop _ nilObj. &quot;keep in a register&quot;<br>
&gt; &nbsp; &nbsp; &nbsp; thisCntx _ activeContext.<br>
&gt; &nbsp; &nbsp; &nbsp; localCntx _ cntx.<br>
&gt; &nbsp; &nbsp; &nbsp; localVal _ val.<br>
&gt;<br>
&gt; &nbsp; &nbsp; &nbsp; &quot;make sure we can return to the given context&quot;<br>
&gt; &nbsp; &nbsp; &nbsp; ((localCntx = nilOop) or:<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp;[(self fetchPointer: InstructionPointerIndex ofObject: localCntx) =<br>
&gt; nilOop]) ifTrue: [<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &quot;error: sender&#39;s instruction pointer or context is nil; cannot return&quot;<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ^self internalCannotReturn: localVal].<br>
&gt;<br>
&gt; &nbsp; &nbsp; &nbsp; &quot;If this return is not to our immediate predecessor (i.e. from a method<br>
&gt; to its sender, or from a block to its caller), scan the stack for the<br>
&gt; first unwind marked context and inform this context and let it deal with<br>
&gt; it. This provides a chance for ensure unwinding to occur.&quot;<br>
&gt; &nbsp; &nbsp; &nbsp; thisCntx _ self fetchPointer: SenderIndex ofObject: activeContext.<br>
&gt;<br>
&gt; &nbsp; &nbsp; &nbsp; &quot;Just possibly a faster test would be to compare the homeContext and<br>
&gt; activeContext - they are of course different for blocks. Thus we might be<br>
&gt; able to optimise a touch by having a different returnTo for the<br>
&gt; blockreteurn (since we know that must return to caller) and then if<br>
&gt; active ~= home we must be doing a non-local return. I think. Maybe.&quot;<br>
&gt; &nbsp; &nbsp; &nbsp; [thisCntx = localCntx] whileFalse: [<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; thisCntx = nilObj ifTrue:[<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &quot;error: sender&#39;s instruction pointer or context is nil; cannot return&quot;<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ^self internalCannotReturn: localVal].<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &quot;Climb up stack towards localCntx. Break out to a send of<br>
&gt; #aboutToReturn:through: if an unwind marked context is found&quot;<br>
&gt; &nbsp; &nbsp; &nbsp; header _ self baseHeader: thisCntx.<br>
&gt;<br>
&gt; &nbsp; &nbsp; &nbsp; (self isMethodContextHeader: header)<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ifTrue: [<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; meth _ self fetchPointer: MethodIndex ofObject: thisCntx.<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pIndex _ self primitiveIndexOf: meth.<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; isUnwindMarked _ pIndex == 198]<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ifFalse: [isUnwindMarked _ false].<br>
&gt;<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; isUnwindMarked ifTrue:[<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &quot;context is marked; break out&quot;<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ^self internalAboutToReturn: localVal through: thisCntx].<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; thisCntx _ self fetchPointer: SenderIndex ofObject: thisCntx.<br>
&gt; ].<br>
&gt;<br>
&gt; &nbsp; &nbsp; &nbsp; &quot;If we get here there is no unwind to worry about. Simply terminate the<br>
&gt; stack up to the localCntx - often just the sender of the method&quot;<br>
&gt; &nbsp; &nbsp; &nbsp; thisCntx _ activeContext.<br>
&gt; &nbsp; &nbsp; &nbsp; [thisCntx = localCntx]<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; whileFalse:<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [&quot;climb up stack to localCntx&quot;<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; contextOfCaller _ self fetchPointer: SenderIndex ofObject: thisCntx.<br>
&gt;<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &quot;zap exited contexts so any future attempted use will be caught&quot;<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self storePointerUnchecked: SenderIndex ofObject: thisCntx withValue:<br>
&gt; nilOop.<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self storePointerUnchecked: InstructionPointerIndex ofObject: thisCntx<br>
&gt; withValue: nilOop.<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; reclaimableContextCount &gt; 0 ifTrue:<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [&quot;try to recycle this context&quot;<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; reclaimableContextCount _ reclaimableContextCount - 1.<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self recycleContextIfPossible: thisCntx].<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; thisCntx _ contextOfCaller].<br>
&gt;<br>
&gt; &nbsp; &nbsp; &nbsp; activeContext _ thisCntx.<br>
&gt; &nbsp; &nbsp; &nbsp; (thisCntx &lt; youngStart) ifTrue: [ self beRootIfOld: thisCntx ].<br>
&gt;<br>
&gt; &nbsp; &nbsp; &nbsp; self internalFetchContextRegisters: thisCntx. &nbsp;&quot;updates local IP and SP&quot;<br>
&gt; &nbsp; &nbsp; &nbsp; self fetchNextBytecode.<br>
&gt; &nbsp; &nbsp; &nbsp; self internalPush: localVal.<br>
&gt; ! !<br>
&gt;<br>
&gt; Shortly after that I released the VMMaker3.6 with a note that it couldn&rsquo;t<br>
&gt; produce a completely non-inlined VM because of a problem in fetchByte if<br>
&gt; globalstruct was enabled, and some odd problems in B2DPlugin. When<br>
&gt; VMMaker3.7 was released a year late (march 04) I apparently thought it<br>
&gt; could make the core vm non-inlined. Since this is all a bazillion years<br>
&gt; ago I can&rsquo;t remember any context to help extend the history.<br>
&gt;<br>
&gt; tim<br>
<span class="HOEnZb"><font color="#888888">&gt; --<br>
&gt; tim Rowledge; <a href="mailto:tim@rowledge.org">tim@rowledge.org</a>; <a href="http://www.rowledge.org/tim" target="_blank">http://www.rowledge.org/tim</a><br>
&gt; Science is imagination equipped with grappling hooks.<br>
&gt;<br>
<br>
<br>
</font></span></blockquote></div><br></div>