Hi, I tried to generate a recent COG (VMMaker.oscog-eem.570), but it produces spurious negative ints when accessing WordArrays (Bitmap and the like).
It's not a pure COG, it's home brewed, but I don't think that I introduced the problem.
I caught it after protecting Object>at:put: with (self class isWords and: [value isInteger and: [value between: -16r80000000 and: -1]]) ifTrue: [^self at:index put: (value bitAnd: 16rFFFFFFFF)]. Otherwise, image is unusable.
Then I can reproduce it for example while rotating a window, see attachment.
fills is a a WordArray(4278190081 4278190081) in BalloonEngine>>drawGeneralBezierShape:fill:borderWidth:borderColor:transform:
But then primAddBezierShape:segments:fill:lineWidth:lineFill: receive -16777215 as lineFill -16777215 bitAnd: 16rFFFFFFFF -> 4278190081, so this is correctly (fills at: 2) but with wrong sign interpretation.
Curiously, fillStyle (fills at: 1) remained positive.
Eliot, any idea?
2013/12/27 Nicolas Cellier nicolas.cellier.aka.nice@gmail.com
Hi, I tried to generate a recent COG (VMMaker.oscog-eem.570), but it produces spurious negative ints when accessing WordArrays (Bitmap and the like).
It's not a pure COG, it's home brewed, but I don't think that I introduced the problem.
I caught it after protecting Object>at:put: with (self class isWords and: [value isInteger and: [value between: -16r80000000 and: -1]]) ifTrue: [^self at:index put: (value bitAnd: 16rFFFFFFFF)]. Otherwise, image is unusable.
Then I can reproduce it for example while rotating a window, see attachment.
fills is a a WordArray(4278190081 4278190081) in BalloonEngine>>drawGeneralBezierShape:fill:borderWidth:borderColor:transform:
But then primAddBezierShape:segments:fill:lineWidth:lineFill: receive -16777215 as lineFill -16777215 bitAnd: 16rFFFFFFFF -> 4278190081, so this is correctly (fills at: 2) but with wrong sign interpretation.
Curiously, fillStyle (fills at: 1) remained positive.
Eliot, any idea?
OK, it was partly my fault, partly incorrect type simplification in CCodeGenerator inlining. I redefined positive32BitInteger: to take an #usqInt argument. Thus I don't have to test >= 0, because the argument is always re-interpreted positive. For some reason, bytecodePrimAt is inlining like this: sqInt result1; ... /* Bitmap */ result1 = long32At((rcvr + BaseHeaderSize) + ((((index >> 1)) - 1) << 2)); /* begin positive32BitIntegerFor: */ if (result1 < 0x40000000) { result = ((result1 << 1) | 1); goto l123; }
long32At is signed (pouah!) Thus 16rFF000001, is interpreted < 0 Thus a (negative) SmallInteger is returned...
Why it sometimes work and sometimes fail may be related to the at cache, but I did not try to dig further...
vm-dev@lists.squeakfoundation.org