<div dir="ltr"><div><div><div>Yes, bad parenthesis...<br><br>#include <stdio.h><br>int main()<br>{<br> int a=0,b=11,c=22,d=33;<br> int e;<br> e=(a+b<c+d)?(a=4),++b:(c=6),d++;<br> printf("a=%d b=%d c=%d d=%d e=%d\n",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<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"><<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a>></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's fixed in the Cog branch (at least I remember fixing it). Try it in Cog. Its late but I'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"><<a href="mailto:nicolas.cellier.aka.nice@gmail.com" target="_blank">nicolas.cellier.aka.nice@gmail.com</a>></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>>magnitude64BitIntegerFor: magnitude neg: isNegative<br> "Return a Large Integer object for the given integer magnitude and sign"<br> | newLargeInteger largeClass lowWord highWord sz isSmall smallVal highWord2 |<br>
<var: 'magnitude' type: #usqLong><br> <var: 'lowWord' type: #usqInt><br> <var: 'highWord' type: #usqInt><br> <var: 'highWord2' type: #usqInt><br><br> isSmall := isNegative<br>
ifTrue: [magnitude <= 16r40000000]<br> ifFalse: [magnitude < 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 >> 32.<br> highWord = 0 <br> ifTrue: [sz := 4] <br> ifFalse:<br> [sz := 5.<br> (highWord2 := highWord >> 8) = 0 ifFalse: [sz := sz + 1].<br> (highWord2 := highWord2 >> 8) = 0 ifFalse: [sz := sz + 1].<br>
(highWord2 := highWord2 >> 8) = 0 ifFalse: [sz := sz + 1].].<br> newLargeInteger := objectMemory instantiateClass: largeClass indexableSize: sz.<br> objectMemory storeLong32: 0 ofObject: newLargeInteger withValue: lowWord.<br>
sz > 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 = &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 <= 1073741824<br> : magnitude < 1073741824);<br>
if (isSmall) {<br> smallVal = ((sqInt) magnitude);<br> if (isNegative) {<br> smallVal = 0 - smallVal;<br> }<br> return ((smallVal << 1) | 1);<br> }<br> largeClass = (isNegative<br>
? /* begin fetchPointer:ofObject: */(oop = foo->specialObjectsOop),longAt((oop + (BASE_HEADER_SIZE)) + (ClassLargeNegativeInteger << (SHIFT_FOR_WORD)))<br> : /* begin fetchPointer:ofObject: */(oop1 = foo->specialObjectsOop),longAt((oop1 + (BASE_HEADER_SIZE)) + (ClassLargePositiveInteger << (SHIFT_FOR_WORD))));<br>
lowWord = magnitude & 4294967295U;<br> highWord = magnitude >> 32;<br> if (highWord == 0) {<br> sz = 4;<br> } else {<br> sz = 5;<br> if (!(((highWord2 = ((usqInt) highWord) >> 8)) == 0)) {<br>
sz += 1;<br> }<br> if (!(((highWord2 = ((usqInt) highWord2) >> 8)) == 0)) {<br> sz += 1;<br> }<br> if (!(((highWord2 = ((usqInt) highWord2) >> 8)) == 0)) {<br>
sz += 1;<br> }<br> }<br> newLargeInteger = instantiateClassindexableSize(largeClass, sz);<br> long32Atput((newLargeInteger + (BASE_HEADER_SIZE)) + (0 << 2), lowWord);<br> if (sz > 4) {<br>
long32Atput((newLargeInteger + (BASE_HEADER_SIZE)) + (1 << 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->specialObjectsOop),longAt((oop +
(BASE_HEADER_SIZE)) + (ClassLargeNegativeInteger <<
(SHIFT_FOR_WORD)))<br> : /* begin fetchPointer:ofObject: */(oop1 =
foo->specialObjectsOop),longAt((oop1 + (BASE_HEADER_SIZE)) +
(ClassLargePositiveInteger << (SHIFT_FOR_WORD))));<br><br>with an explicit if:<br><br> if (isNegative) {<br> /* begin fetchPointer:ofObject: */<br> oop = foo->specialObjectsOop;<br> largeClass = longAt((oop + (BASE_HEADER_SIZE)) + (ClassLargeNegativeInteger << (SHIFT_FOR_WORD)));<br>
} else {<br> /* begin fetchPointer:ofObject: */<br> oop1 = foo->specialObjectsOop;<br> largeClass = longAt((oop1 + (BASE_HEADER_SIZE)) + (ClassLargePositiveInteger << (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 << ShiftForWord))<br>
: longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (ClassLargePositiveInteger << ShiftForWord)));<br><br></div>THE QUESTION:<br><br></div>I just don'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>