<div dir="ltr">Hi John, Hi Esteban,<div class="gmail_extra"><br><div class="gmail_quote">On Tue, Oct 20, 2015 at 2:48 PM, John McIntosh <span dir="ltr">&lt;<a href="mailto:johnmci@smalltalkconsulting.com" target="_blank">johnmci@smalltalkconsulting.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><div dir="ltr">Sure but I see the follow use cases, which are best confusing, and just curious if they work as you think they should? <div>Does clang optimize out the  (value &gt;= 0) if value is a unsigned type? <br><br>/* begin maybeInlinePositive32BitIntegerFor: */<br><br>assert(!((hasSixtyFourBitImmediates())));<br><br>if ((stackPtr &gt;= 0)<br><br>&amp;&amp; ((stackPtr ^ (stackPtr &lt;&lt; 1)) &gt;= 0)) {<br><br>((stackPtr &lt;&lt; 1) | 1);<br><br>goto l2;<br><br>}<br>where stackPtr is <br>sendInvokeCallbackStackRegistersJmpbuf(sqInt thunkPtr, sqInt stackPtr, sqInt regsPtr, sqInt jmpBufPtr)<br><br> or  where integerValue is saint  btw  so casting to usqInt then back to saint is &#39;magic handwaving?&#39; </div><div><br>integerValue = ((usqInt)usecs);<br><br>/* begin maybeInlinePositive32BitIntegerFor: */<br><br>assert(!((hasSixtyFourBitImmediates())));<br><br>if ((integerValue &gt;= 0)<br><br>&amp;&amp; ((integerValue ^ (integerValue &lt;&lt; 1)) &gt;= 0)) {<br><br>v1 = ((integerValue &lt;&lt; 1) | 1);<br><br>goto l1;<br><br>}<br><br><br>or this where value is declared as &#39;unsigned long&#39; versus a squeak data type <div><br></div><div><br>value = ((usqInt)((vmCallbackContext-&gt;thunkp)));<br><br>/* begin positive32BitIntegerFor: */<br><br>/* begin maybeInlinePositive32BitIntegerFor: */<br><br>assert(!((hasSixtyFourBitImmediates())));<br><br>if ((value &gt;= 0)<br><br>&amp;&amp; ((value ^ (value &lt;&lt; 1)) &gt;= 0)) {<br><br>((value &lt;&lt; 1) | 1);<br><br>goto l2;<br><br>}<br></div></div></div></blockquote><div><br></div><div>So first of all, this code is out of date.  This method should read the following; notice the use of positiveMachineIntegerValueOf:, not positive32BitIntegerFor:</div><div><br></div><div>sendInvokeCallback: thunkPtr Stack: stackPtr Registers: regsPtr Jmpbuf: jmpBufPtr</div><div><span class="" style="white-space:pre">        </span>&quot;Send the 4 argument callback message invokeCallback:stack:registers:jmpbuf:</div><div><span class="" style="white-space:pre">        </span> to Alien class with the supplied args.  The arguments are raw C addresses</div><div><span class="" style="white-space:pre">        </span> and are converted to integer objects on the way.&quot;</div><div><span class="" style="white-space:pre">        </span>&lt;export: true&gt;</div><div><span class="" style="white-space:pre">        </span>| classTag |</div><div><span class="" style="white-space:pre">        </span>classTag := self fetchClassTagOfNonImm: (self splObj: ClassAlien).</div><div><span class="" style="white-space:pre">        </span>messageSelector := self splObj: SelectorInvokeCallback.</div><div><span class="" style="white-space:pre">        </span>argumentCount := 4.</div><div><span class="" style="white-space:pre">        </span>(self lookupInMethodCacheSel: messageSelector classTag: classTag) ifFalse:</div><div><span class="" style="white-space:pre">        </span> <span class="" style="white-space:pre">        </span>[(self lookupOrdinaryNoMNUEtcInClass: (objectMemory classForClassTag: classTag)) ~= 0 ifTrue:</div><div><span class="" style="white-space:pre">                        </span>[^false]].</div><div><span class="" style="white-space:pre">        </span>((self argumentCountOf: newMethod) = 4</div><div><span class="" style="white-space:pre">        </span>and: [primitiveFunctionPointer = 0]) ifFalse:</div><div><span class="" style="white-space:pre">                </span>[^false].</div><div><span class="" style="white-space:pre">        </span>self push: (self splObj: ClassAlien). &quot;receiver&quot;</div><div><span class="" style="white-space:pre">        </span>self push: (self positiveMachineIntegerFor: thunkPtr).</div><div><span class="" style="white-space:pre">        </span>self push: (self positiveMachineIntegerFor: stackPtr).</div><div><span class="" style="white-space:pre">        </span>self push: (self positiveMachineIntegerFor: regsPtr).</div><div><span class="" style="white-space:pre">        </span>self push: (self positiveMachineIntegerFor: jmpBufPtr).</div><div><span class="" style="white-space:pre">        </span>self ifAppropriateCompileToNativeCode: newMethod selector: messageSelector.</div><div><span class="" style="white-space:pre">        </span>self justActivateNewMethod.</div><div><span class="" style="white-space:pre">        </span>(self isMachineCodeFrame: framePointer) ifFalse:</div><div><span class="" style="white-space:pre">                </span>[self maybeFlagMethodAsInterpreted: newMethod].</div><div><span class="" style="white-space:pre">        </span>self externalWriteBackHeadFramePointers.</div><div><span class="" style="white-space:pre">        </span>self handleStackOverflow.</div><div><span class="" style="white-space:pre">        </span>self enterSmalltalkExecutiveFromCallback.</div><div><span class="" style="white-space:pre">        </span>&quot;not reached&quot;</div><div><span class="" style="white-space:pre">        </span>^true</div><div><br></div><div>Second of all, this whole method is obsolete.  It&#39;s there for old-style Alien callbacks.  You should be using new-style Alien callbacks that use invokeCallbackContext: and sendInvokeCallbackContext:.</div><div><br></div><div><div>sendInvokeCallbackContext: vmCallbackContext</div><div><span class="" style="white-space:pre">        </span>&quot;Send the calllback message to Alien class with the supplied arg(s).  Use either the</div><div><span class="" style="white-space:pre">        </span> 1 arg invokeCallbackContext: or the 4 arg invokeCallback:stack:registers:jmpbuf:</div><div><span class="" style="white-space:pre">        </span> message, depending on what selector is installed in the specialObjectsArray.</div><div><span class="" style="white-space:pre">        </span> Note that if invoking the legacy invokeCallback:stack:registers:jmpbuf: we pass the</div><div><span class="" style="white-space:pre">        </span> vmCallbackContext as the jmpbuf argument (see reestablishContextPriorToCallback:).</div><div><span class="" style="white-space:pre">        </span> The arguments are raw C addresses and are converted to integer objects on the way.&quot;</div><div><span class="" style="white-space:pre">        </span>&lt;export: true&gt;</div><div><span class="" style="white-space:pre">        </span>&lt;var: #vmCallbackContext type: #&#39;VMCallbackContext *&#39;&gt;</div><div><span class="" style="white-space:pre">        </span>| classTag |</div><div><span class="" style="white-space:pre">        </span>classTag := self fetchClassTagOfNonImm: (self splObj: ClassAlien).</div><div><span class="" style="white-space:pre">        </span>messageSelector := self splObj: SelectorInvokeCallback.</div><div><span class="" style="white-space:pre">        </span>(self lookupInMethodCacheSel: messageSelector classTag: classTag) ifFalse:</div><div><span class="" style="white-space:pre">        </span> <span class="" style="white-space:pre">        </span>[(self lookupOrdinaryNoMNUEtcInClass: (objectMemory classForClassTag: classTag)) ~= 0 ifTrue:</div><div><span class="" style="white-space:pre">                        </span>[^false]].</div><div><span class="" style="white-space:pre">        </span>primitiveFunctionPointer ~= 0 ifTrue:</div><div><span class="" style="white-space:pre">                </span>[^false].</div><div><span class="" style="white-space:pre">        </span>self saveCStackStateForCallbackContext: vmCallbackContext.</div><div><span class="" style="white-space:pre">        </span>self push: (self splObj: ClassAlien). &quot;receiver&quot;</div><div><span class="" style="white-space:pre">        </span>(self argumentCountOf: newMethod) = 4 ifTrue:</div><div><span class="" style="white-space:pre">                </span>[self push: (self positiveMachineIntegerFor: vmCallbackContext thunkp asUnsignedInteger).</div><div><span class="" style="white-space:pre">                </span> self push: (self positiveMachineIntegerFor: vmCallbackContext stackp asUnsignedInteger).</div><div><span class="" style="white-space:pre">                </span> self push: (self positiveMachineIntegerFor: vmCallbackContext intregargsp asUnsignedInteger)].</div><div><span class="" style="white-space:pre">        </span>self push: (self positiveMachineIntegerFor: vmCallbackContext asUnsignedInteger).</div><div><span class="" style="white-space:pre">        </span>self ifAppropriateCompileToNativeCode: newMethod selector: messageSelector.</div><div><span class="" style="white-space:pre">        </span>self justActivateNewMethod.</div><div><span class="" style="white-space:pre">        </span>(self isMachineCodeFrame: framePointer) ifFalse:</div><div><span class="" style="white-space:pre">                </span>[self maybeFlagMethodAsInterpreted: newMethod].</div><div><span class="" style="white-space:pre">        </span>self externalWriteBackHeadFramePointers.</div><div><span class="" style="white-space:pre">        </span>self handleStackOverflow.</div><div><span class="" style="white-space:pre">        </span>self enterSmalltalkExecutiveFromCallback.</div><div><span class="" style="white-space:pre">        </span>&quot;not reached&quot;</div><div><span class="" style="white-space:pre">        </span>^true</div></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"><div dir="ltr"><div><div></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Oct 20, 2015 at 2:34 PM, Eliot Miranda <span dir="ltr">&lt;<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.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><div dir="ltr">Hi John,<div class="gmail_extra"><br><div class="gmail_quote">On Tue, Oct 20, 2015 at 1:59 PM, John McIntosh <span dir="ltr">&lt;<a href="mailto:johnmci@smalltalkconsulting.com" target="_blank">johnmci@smalltalkconsulting.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><div dir="ltr">Ok, you know you are using maybeInlinePositive32BitIntegerFor for BOTH unsigned and signed integers? That to me rings alarm bells, so do you need maybeInlinePositive32BitIntegerForSignedInteger or maybeInlinePositive32BitIntegerForUnSignedInteger  or always cast the incoming value to an unsigned integer, or is it signed? If so are you sure you understand the math involved and the possible input values? </div></blockquote><div><br></div><div>No, we don&#39;t need this.  Looking at the code, it is OK for positive32BitIntegerFor: to truncate to 32-bits.  But if one wants to pass in a 32-bit value form a long one should write</div><div><br></div><div>    ^self positive32BitIntegerFor: (value bitAnd: 16rFFFFFFFF)</div><div><br></div><div>If one wants a value which is as big as a pointer one should use</div><div><br></div><div> ^self positiveMachineIntegerFor: (value bitAnd: 16rFFFFFFFF)<br></div><div><br></div><div>Only use the 32Bit conversion routines when you want a 32-bit result.  There are now 32-bit, 64-bit and machine versions of the conversion routines.  The machine versions answer 32 or 64 bit results as appropriate.</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"><div dir="ltr"><div><br><div><br></div><div><br></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Oct 19, 2015 at 9:31 AM, Esteban Lorenzano <span dir="ltr">&lt;<a href="mailto:estebanlm@gmail.com" target="_blank">estebanlm@gmail.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><div style="word-wrap:break-word"><div>Hi, </div><div><br></div><div>Does anyone tested Alien on Spur and &quot;El capitan&quot;? specifically callbacks?</div><div>For me, a completely broken :(</div><div><br></div><div>1) this structure (in maybeInlinePositive32BitIntegerFor: and others): </div><div><br></div><div><div><span style="white-space:pre-wrap">        </span>(integerValue &gt;= 0</div><div><span style="white-space:pre-wrap">        </span> and: [objectMemory isIntegerValue: integerValue]) ifTrue:</div><div><span style="white-space:pre-wrap">                </span>[^objectMemory integerObjectOf: integerValue].</div></div><div><br></div><div>Does not works if “integer value” is an unsigned long, because compiler assumes it will always be true, then remove the if, then answers a wrong value. </div><div><br></div><div>2) <span style="color:rgb(120,73,42);font-family:Menlo;font-size:11px">assertCStackWellAligned </span>always fail. No idea why because if does not says anything, just jmp back to the regular flow. </div><div><br></div><div>3) finally, <span style="color:rgb(79,129,135);font-family:Menlo;font-size:11px">ceCaptureCStackPointers </span>also fails… this can be because (2) or because other reasons (it also jmps back so no clue) (method generateCaptureCStackPointers: clarifies is a hack, so I suppose it stopped to work). </div><div><br></div><div>I guess solution of (1) is easy: argument number just has to be a sqLong instead an unsigned long. </div><div><br></div><div>But for 2 and 3 I have no idea where to start.</div><div><br></div><div>Does anyone has an idea?</div><div><br></div><div>Esteban</div><div><br></div></div><br></blockquote></div><br><br clear="all"><div><br></div>-- <br><div><div dir="ltr"><div><div dir="ltr">===========================================================================<br>John M. McIntosh. Corporate Smalltalk Consulting Ltd <a href="https://www.linkedin.com/in/smalltalk" target="_blank">https://www.linkedin.com/in/smalltalk</a><br>===========================================================================<br></div></div></div></div>
</div>
<br></blockquote></div><br><br clear="all"><div><br></div>-- <br><div><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div>
</div></div>
<br></blockquote></div><br><br clear="all"><div><br></div>-- <br><div><div dir="ltr"><div><div dir="ltr">===========================================================================<br>John M. McIntosh. Corporate Smalltalk Consulting Ltd <a href="https://www.linkedin.com/in/smalltalk" target="_blank">https://www.linkedin.com/in/smalltalk</a><br>===========================================================================<br></div></div></div></div>
</div>
<br></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div>
</div></div>