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

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Wed Feb 11 23:00:21 UTC 2015


2015-02-11 23:57 GMT+01:00 Nicolas Cellier <
nicolas.cellier.aka.nice at gmail.com>:

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

of course, it's the same for primitiveSmallFloatTimesTwoPower (where things
will really happen most of the time in Spur64)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20150212/f0f415b9/attachment.htm


More information about the Vm-dev mailing list