<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">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>