[Vm-dev] Potential issue of primitiveTimesTwoPower in Spur 64

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Wed Feb 11 22:57:19 UTC 2015

Some C functions in libm only take an int, not a long.
In 32 bits int=long, so no problem.
In 64 bits generally int=32 bits, long=64 bits, so casting a long to int
might lead to catastrophic loss and unexpected behavior.

This is the case for example in primitiveTimesTwoPower
    | rcvr arg |
    <var: #rcvr type: #double>
    arg := self popInteger.
    rcvr := self popFloat.
    self successful
        ifTrue: [ self pushFloat: (self cCode: 'ldexp(rcvr, arg)'
inSmalltalk: [rcvr timesTwoPower: arg]) ]
        ifFalse: [ self unPop: 2 ]

arg will be a long in Spur64, won't it?
but ldexp only takes an int
    double ldexp(double x, int exp);.

So guess what if we call (1.0 timesTwoPower: 16r10000000001)...
Normally there should be a C compiler warning, and we should care of it.

To solve this, maybe we need a

    <var: #arg type: #int>
    arg := self signed32BitValueOf: stackTop.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20150211/1788ffba/attachment.htm

More information about the Vm-dev mailing list