<div dir="ltr"><div><div><div>Yes, bad parenthesis...<br><br>#include &lt;stdio.h&gt;<br>int main()<br>{<br>  int a=0,b=11,c=22,d=33;<br>  int e;<br>  e=(a+b&lt;c+d)?(a=4),++b:(c=6),d++;<br>  printf(&quot;a=%d b=%d c=%d d=%d e=%d\n&quot;,a,b,c,d,e);<br>

  return 0;<br>}<br><br></div>prints a=4 b=12 c=22 d=34 e=12, so d++ is executed unconditionally.<br><br></div><div>while<br>  e=(a+b&lt;c+d)?(a=4),++b:((c=6),d++);<br></div>prints a=4 b=12 c=22 d=33 e=12.<br><br></div><div>
I will try and check if I can find a related change in COG.<br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">2013/4/6 Eliot Miranda <span dir="ltr">&lt;<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a>&gt;</span><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> <br>Hi Nicolas,<div><br></div><div>    I think this is bad parenthesization.  I think it&#39;s fixed in the Cog branch (at least I remember fixing it).  Try it in Cog.  Its late but I&#39;ll try and find the fix some time soon.<br>

<br><div class="gmail_quote">On Fri, Apr 5, 2013 at 1:52 PM, Nicolas Cellier <span dir="ltr">&lt;<a href="mailto:nicolas.cellier.aka.nice@gmail.com" target="_blank">nicolas.cellier.aka.nice@gmail.com</a>&gt;</span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> <br><div dir="ltr"><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div>Let me think aloud...<br>

<br>THE CONTEXT:<br><br>backport of LargeIntegersPlugin v2.0 (32 bit native word order) to Interpreter VM<br>
<br></div>THE BUG:<br><br></div>The Vm crashes with <a href="http://smalltalkhub.com/#!/~nice/NiceVMExperiments/versions/VMMaker-nice.315" target="_blank">http://smalltalkhub.com/#!/~nice/NiceVMExperiments/versions/VMMaker-nice.315</a><br>


<br></div>THE OFFENDING METHOD:<br><br>InterpreterPrimitives&gt;&gt;magnitude64BitIntegerFor: magnitude neg: isNegative<br>    &quot;Return a Large Integer object for the given integer magnitude and sign&quot;<br>    | newLargeInteger largeClass lowWord highWord sz isSmall smallVal highWord2 |<br>


    &lt;var: &#39;magnitude&#39; type: #usqLong&gt;<br>    &lt;var: &#39;lowWord&#39; type: #usqInt&gt;<br>    &lt;var: &#39;highWord&#39; type: #usqInt&gt;<br>    &lt;var: &#39;highWord2&#39; type: #usqInt&gt;<br><br>    isSmall := isNegative<br>


                ifTrue: [magnitude &lt;= 16r40000000]<br>                ifFalse: [magnitude &lt; 16r40000000].<br>    isSmall ifTrue:<br>        [smallVal := self cCoerceSimple: magnitude to: #sqInt.<br>        isNegative    ifTrue: [smallVal := 0 - smallVal].<br>


        ^objectMemory integerObjectOf: smallVal].<br>    largeClass := isNegative<br>        ifTrue:[self classLargeNegativeInteger]<br>        ifFalse:[self classLargePositiveInteger].<br>    lowWord := magnitude bitAnd: 16rFFFFFFFF.<br>


    highWord := magnitude &gt;&gt; 32.<br>    highWord = 0 <br>        ifTrue: [sz := 4] <br>        ifFalse:<br>            [sz := 5.<br>            (highWord2 := highWord &gt;&gt; 8) = 0 ifFalse: [sz := sz + 1].<br>            (highWord2 := highWord2 &gt;&gt; 8) = 0 ifFalse: [sz := sz + 1].<br>


            (highWord2 := highWord2 &gt;&gt; 8) = 0 ifFalse: [sz := sz + 1].].<br>    newLargeInteger := objectMemory instantiateClass: largeClass indexableSize:  sz.<br>    objectMemory storeLong32: 0 ofObject: newLargeInteger withValue: lowWord.<br>


    sz &gt; 4 ifTrue: [objectMemory storeLong32: 1 ofObject: newLargeInteger withValue: highWord].<br>    ^newLargeInteger<br><br></div>THE CORRECTED METHOD:<br><br></div>just replace the assignment<br><br>    isNegative<br>


        ifTrue:[    largeClass := self classLargeNegativeInteger]<br>        ifFalse:[    largeClass := self classLargePositiveInteger].<br><br></div>THE OFFENDING GENERATED CODE:<br><br></div><div>in src/vm/interp.c<br>

<br>
sqInt magnitude64BitIntegerForneg(usqLong magnitude, sqInt isNegative) {<br>register struct foo * foo = &amp;fum;<br>    usqInt highWord;<br>    usqInt highWord2;<br>    sqInt isSmall;<br>    sqInt largeClass;<br>    usqInt lowWord;<br>


    sqInt newLargeInteger;<br>    sqInt smallVal;<br>    sqInt sz;<br>    sqInt oop;<br>    sqInt oop1;<br><br>    isSmall = (isNegative<br>        ? magnitude &lt;= 1073741824<br>        : magnitude &lt; 1073741824);<br>


    if (isSmall) {<br>        smallVal = ((sqInt) magnitude);<br>        if (isNegative) {<br>            smallVal = 0 - smallVal;<br>        }<br>        return ((smallVal &lt;&lt; 1) | 1);<br>    }<br>    largeClass = (isNegative<br>


        ? /* begin fetchPointer:ofObject: */(oop = foo-&gt;specialObjectsOop),longAt((oop + (BASE_HEADER_SIZE)) + (ClassLargeNegativeInteger &lt;&lt; (SHIFT_FOR_WORD)))<br>        : /* begin fetchPointer:ofObject: */(oop1 = foo-&gt;specialObjectsOop),longAt((oop1 + (BASE_HEADER_SIZE)) + (ClassLargePositiveInteger &lt;&lt; (SHIFT_FOR_WORD))));<br>


    lowWord = magnitude &amp; 4294967295U;<br>    highWord = magnitude &gt;&gt; 32;<br>    if (highWord == 0) {<br>        sz = 4;<br>    } else {<br>        sz = 5;<br>        if (!(((highWord2 = ((usqInt) highWord) &gt;&gt; 8)) == 0)) {<br>


            sz += 1;<br>        }<br>        if (!(((highWord2 = ((usqInt) highWord2) &gt;&gt; 8)) == 0)) {<br>            sz += 1;<br>        }<br>        if (!(((highWord2 = ((usqInt) highWord2) &gt;&gt; 8)) == 0)) {<br>


            sz += 1;<br>        }<br>    }<br>    newLargeInteger = instantiateClassindexableSize(largeClass, sz);<br>    long32Atput((newLargeInteger + (BASE_HEADER_SIZE)) + (0 &lt;&lt; 2), lowWord);<br>    if (sz &gt; 4) {<br>


        long32Atput((newLargeInteger + (BASE_HEADER_SIZE)) + (1 &lt;&lt; 2), highWord);<br>    }<br>    return newLargeInteger;<br>}<br><br></div>THE CORRECTED GENERATED CODE:<br><br></div>Just change the ()?: assignment:<br>


<br>    largeClass = (isNegative<br>        ? /* begin 
fetchPointer:ofObject: */(oop = foo-&gt;specialObjectsOop),longAt((oop +
 (BASE_HEADER_SIZE)) + (ClassLargeNegativeInteger &lt;&lt; 
(SHIFT_FOR_WORD)))<br>        : /* begin fetchPointer:ofObject: */(oop1 =
 foo-&gt;specialObjectsOop),longAt((oop1 + (BASE_HEADER_SIZE)) + 
(ClassLargePositiveInteger &lt;&lt; (SHIFT_FOR_WORD))));<br><br>with an explicit if:<br><br>    if (isNegative) {<br>        /* begin fetchPointer:ofObject: */<br>        oop = foo-&gt;specialObjectsOop;<br>        largeClass = longAt((oop + (BASE_HEADER_SIZE)) + (ClassLargeNegativeInteger &lt;&lt; (SHIFT_FOR_WORD)));<br>


    } else {<br>        /* begin fetchPointer:ofObject: */<br>        oop1 = foo-&gt;specialObjectsOop;<br>        largeClass = longAt((oop1 + (BASE_HEADER_SIZE)) + (ClassLargePositiveInteger &lt;&lt; (SHIFT_FOR_WORD)));<br>


    }<br><br></div>THE OFFENDING METHOD JUST WORKS IN COG BUT GENERATED CODE IS DIFFERENT:<br><br>    largeClass = (isNegative<br>        ? longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (ClassLargeNegativeInteger &lt;&lt; ShiftForWord))<br>


        : longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (ClassLargePositiveInteger &lt;&lt; ShiftForWord)));<br><br></div>THE QUESTION:<br><br></div>I just don&#39;t understand what is incorrect in the (t)?a,b:c,d; construct...<br>


</div>Could it be that it is interpreted:<br><br>    ((t)?a,b:c),d;<br><br></div>Ah if so, maybe that would explain the warning about oop1 being potentially used before assigned! (a bulb just enlighten)<br><br></div>In this case we have a bug in the generator (probably a known one since we rearely ever use x := test ifTrue: [] ifFalse: [] in Slang)...<br>


<br></div>Nicolas<br><div><div><div><br><br><div><div><div><br><br></div></div></div></div></div></div></div>
<br></blockquote></div><br><br clear="all"><div><br></div>-- <br>best,<div>Eliot</div>
</div>
<br></blockquote></div><br></div>