<div dir="ltr"><div>Arghh... I forgot this one which is preempting my asUnsignedInteger cast:<br><br><br>generateIntegerObjectOf: msgNode on: aStream indent: level<br> "Generate the C code for this message onto the given stream."<br> | expr castToSqint |<br> expr := msgNode args first.<br> aStream nextPutAll: '(('.<br> "Note that the default type of an integer constant in C is int. Hence we /must/<br> cast constants to long if in the 64-bit world, since e.g. in 64-bits<br> (int)(16r1FFFFF << 3) = (int)16rFFFFFFF8 = -8<br> whereas<br> (long)(16r1FFFFF << 3) = (long) 16rFFFFFFF8 = 4294967288."<br> castToSqint := expr isConstant and: [vmClass isNil or: [vmClass objectMemoryClass wordSize = 8]].<br> castToSqint ifTrue:<br> [aStream nextPutAll: '(sqInt)'].<br> self emitCExpression: expr on: aStream.<br> aStream<br> nextPutAll: ' << ';<br> print: vmClass objectMemoryClass numSmallIntegerTagBits;<br> nextPutAll: ') | 1)'<br><br></div>I think we should completely remove this from translationDictionary... It's not object oriented.<br><br><div><div><div class="gmail_extra"><div class="gmail_quote">2016-08-18 3:19 GMT+02:00 Nicolas Cellier <span dir="ltr"><<a href="mailto:nicolas.cellier.aka.nice@gmail.com" target="_blank">nicolas.cellier.aka.nice@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">The test fails with -2^31 and 2^31-1<br>It's not so amazing, because when I debug, I find this incorrect version:<br><div><br> 64769 sqInt<br> 64770 signed32BitIntegerFor(sqInt integerValue)<br> 64771 {<br>-> 64772 return (((((int) integerValue)) << 3) | 1);<br> 64773 <br> 64774 }<br> 64775<br><br></div><div>of course, the shift will overflow for large positive or large negative 32bits int.<br></div><div>But I don't understand how it's been generated...<br></div><div>I would expect<br> return ((((usqInt)((int) integerValue)) << 3) | 1);</div><div><br>Indeed:<br><br>signed32BitIntegerFor: integerValue<br> "Answer a full 32 bit integer object for the given integer value.<br> N.B. Returning in each arm separately enables Slang inlining.<br> /Don't/ return the ifTrue:ifFalse: unless Slang inlining of conditionals is fixed."<br> <inline: true><br> objectMemory hasSixtyFourBitImmediates<br> ifTrue:<br> [^objectMemory integerObjectOf: <br> (self cCode: [self cCoerceSimple: integerValue to: #int]<br> inSmalltalk: [(integerValue bitAnd: 16r7FFFFFFF)<br> - ((integerValue >> 31 anyMask: 1)<br> ifTrue: [-16r100000000]<br> ifFalse: [0])])]<br> ifFalse:<br> [^self noInlineSigned32BitIntegerFor: integerValue]<br><br></div><div>has the cast to int.<br></div><div>Then there is another cast here:<br><br>integerObjectOf: value<br> "Convert the integer value, assumed to be in SmallInteger range, into a tagged SmallInteger object.<br> In C, use a shift and an add to set the tag bit.<br> In Smalltalk we have to work harder because the simulator works with strictly positive bit patterns."<br> <returnTypeC: #sqInt><br> ^self<br> cCode: [value asUnsignedInteger << self numTagBits + 1]<br> inSmalltalk: [value << self numTagBits<br> + (value >= 0<br> ifTrue: [1]<br> ifFalse: [16r10000000000000001])]<br><br></div><div>and asUnsignedInteger is translated like this by CCodeGenerator:<br><br>generateAsUnsignedInteger: msgNode on: aStream indent: level<br> "Generate the C code for this message onto the given stream."<br><br> aStream nextPutAll:'((usqInt)'.<br> self emitCExpression: msgNode receiver on: aStream.<br> aStream nextPut: $)<br></div><div><br></div><div>How the hell could the hardcoded (usqInt) be not generated?<br></div></div>
</blockquote></div><br></div></div></div></div>