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