[Vm-dev] 64bits Alien testSignedLong failing

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Thu Aug 18 01:19:23 UTC 2016


The test fails with -2^31 and 2^31-1
It's not so amazing, because when I debug, I find this incorrect version:

   64769    sqInt
   64770    signed32BitIntegerFor(sqInt integerValue)
   64771    {
-> 64772        return (((((int) integerValue)) << 3) | 1);
   64773
   64774    }
   64775

of course, the shift will overflow for large positive or large negative
32bits int.
But I don't understand how it's been generated...
I would expect
    return ((((usqInt)((int) integerValue)) << 3) | 1);

Indeed:

signed32BitIntegerFor: integerValue
    "Answer a full 32 bit integer object for the given integer value.
     N.B.  Returning in each arm separately enables Slang inlining.
     /Don't/ return the ifTrue:ifFalse: unless Slang inlining of
conditionals is fixed."
    <inline: true>
    objectMemory hasSixtyFourBitImmediates
        ifTrue:
            [^objectMemory integerObjectOf:
                (self cCode: [self cCoerceSimple: integerValue to: #int]
                    inSmalltalk: [(integerValue bitAnd: 16r7FFFFFFF)
                                - ((integerValue >> 31 anyMask: 1)
                                    ifTrue: [-16r100000000]
                                    ifFalse: [0])])]
        ifFalse:
            [^self noInlineSigned32BitIntegerFor: integerValue]

has the cast to int.
Then there is another cast here:

integerObjectOf: value
    "Convert the integer value, assumed to be in SmallInteger range, into a
tagged SmallInteger object.
     In C, use a shift and an add to set the tag bit.
     In Smalltalk we have to work harder because the simulator works with
strictly positive bit patterns."
    <returnTypeC: #sqInt>
    ^self
        cCode: [value asUnsignedInteger << self numTagBits + 1]
        inSmalltalk: [value << self numTagBits
                    + (value >= 0
                        ifTrue: [1]
                        ifFalse: [16r10000000000000001])]

and asUnsignedInteger is translated like this by CCodeGenerator:

generateAsUnsignedInteger: msgNode on: aStream indent: level
    "Generate the C code for this message onto the given stream."

    aStream nextPutAll:'((usqInt)'.
    self emitCExpression: msgNode receiver on: aStream.
    aStream nextPut: $)

How the hell could the hardcoded (usqInt) be not generated?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20160818/cd28d62a/attachment.htm


More information about the Vm-dev mailing list