<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Feb 11, 2014 at 11:05 AM, David T. Lewis <span dir="ltr">&lt;<a href="mailto:lewis@mail.msen.com" target="_blank">lewis@mail.msen.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><br>
OK thank you, I am aware of that trick so not a problem.<br>
<br>
(But you should not blame Eliot, I think I started abusing slang that way<br>
in OSProcessPlugin many years ago, so you can blame me just as well)<br></blockquote><div><br></div><div>Personally I fin it far less of an abuse than the horrible cCode: &#39;aString...&#39; idiom.  With &quot;self malloc: n&quot; I can look for senders etc, but more importantly I can actually implement it in the simulator.  You&#39;ll see in the Cog branch working implementations of str:n:cmp: mem:mo:ve: etc which are actually required by the simulator.  Let me plead for those of you writing VM code to avoid cCode: as much as possible.  Use it to include code that only the simulator should use by all means, but please try and generate your C calls from Smalltalk code.</div>
<div><br></div><div>Here&#39;s the kind of thing I mean.  This coerces an address into a simulator&#39;s CogMethod:</div><div><br></div><div><div>printCogMethod: cogMethod</div><div><span class="" style="white-space:pre">        </span>&lt;api&gt;</div>
<div><span class="" style="white-space:pre">        </span>&lt;var: #cogMethod type: #&#39;CogMethod *&#39;&gt;</div><div><span class="" style="white-space:pre">        </span>| address primitive |</div><div><span class="" style="white-space:pre">        </span>self cCode: &#39;&#39;</div>
<div><span class="" style="white-space:pre">                </span>inSmalltalk:</div><div><span class="" style="white-space:pre">                        </span>[self transcript ensureCr.</div><div><span class="" style="white-space:pre">                        </span> cogMethod isInteger ifTrue:</div>
<div><span class="" style="white-space:pre">                                </span>[^self printCogMethod: (self cCoerceSimple: cogMethod to: #&#39;CogMethod *&#39;)]].</div><div><span class="" style="white-space:pre">        </span>address := cogMethod asInteger.</div>
<div><span class="" style="white-space:pre">        </span>self printHex: address;</div><div><span class="" style="white-space:pre">                </span>print: &#39; &lt;-&gt; &#39;;</div><div><span class="" style="white-space:pre">                </span>printHex: address + cogMethod blockSize.</div>
<div><span class="" style="white-space:pre">        </span>cogMethod cmType = CMMethod ifTrue:</div></div><div>...</div><div><br></div><div>Here&#39;s the kind of thing to be avoided:</div><div><br></div><div><div><span class="" style="white-space:pre">        </span>interpreterProxy success:</div>
<div><span class="" style="white-space:pre">                </span>((interpreterProxy isBytes: oop)</div><div><span class="" style="white-space:pre">                </span> and: [(interpreterProxy slotSizeOf: oop) = (self cCode: &#39;sizeof(AsyncFile)&#39;)]).</div>
</div><div><br></div><div>It could be written as (and if so, simulated!!) </div><div><br></div><div><div><span class="" style="white-space:pre">        </span>interpreterProxy success:</div><div><span class="" style="white-space:pre">                </span>((interpreterProxy isBytes: oop)</div>
<div><span class="" style="white-space:pre">                </span> and: [(interpreterProxy slotSizeOf: oop) = (self sizeof: #AsyncFile)]).</div></div><div><br></div><div>cheers!</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

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