- live browsing of Self object memory -

lobby traitsint32or64

This code was originially written
by Ole Agesen, and follows a different model.
Rather than implement the standard protocol, but having
asInt32 (64) force into this representation,
it goes for speed by using smallInts whenever the value fits,
at the price of using a non-standard protocol such as add:And:
instead of +.
-- dmu 6/1

CopyDowns: vector

CreatorPath: traits int32or64

Module: int32and64

parent* = traits byteVector

arithmetic

+ = ( add: self With: x)
- = ( sub: self With: x)
complement = ( xor: self With: -1)bitwise complement
negate = ( sub: 0 With: self)
pred = ( sub: self With: 1)
succ = ( add: self With: 1)
addBigInteger: = ( i + asInteger)
addSmallInteger: = ( self add: self With: i)
subtractBigInteger: = ( i - asInteger)
subtractSmallInteger: = ( self add: negate With: i)

bit-wise operations

&& = ( and: self With: x)
+> = ( shr: self With: a)
<+ = ( << a)
<< = ( shl: self With: a)
>> = ( ushr: self With: x)
^^ = ( xor: self With: x)
rotate:LeftBy: =
( | leftBits. mask. n. rightBits |
    n: numberOfBits % bitSize.
    n < 0 ifTrue: [n: n + bitSize].
    mask: (1 << (bitSize - n)) pred.
    rightBits:  and: i With: mask.
     leftBits: ushr: i With: bitSize - n.
    or: leftBits With: shl: rightBits With: n)
rotate:RightBy: = ( rotate: i LeftBy: numberOfBits negate)
rotateLeftBy: = ( rotate: self LeftBy: numberOfBits)
rotateRightBy: = ( rotate: self RightBy: numberOfBits)
|| = ( or: self With: x)

bits

bitAt:In: = ( and: (maskForBitAt: n) With: x)
bitSize = ( size * 8)
booleanVectorFor: =
( 
    (vector copySize: bitSize) mapBy: [|:unused. :n|
      (bitAt: n In: x) != 0
    ])
maskForBitAt: = ( shl: 1 With: n)
numberOfOnesIn: =
( 
    x = 0 ifTrue: [^ 0].
    x < 0 ifTrue: [bitSize - (numberOfOnesIn: x complement)].
    (and: x With: 16rffff) numberOfOnes  + (numberOfOnesIn: ushr: x With: 16))

coercions

asInteger =
( 
    (ushr: self With: bitSize pred) asBoolean ifTrue: [
      ^ negate asUnsignedInteger negate
    ].
    asUnsignedInteger)
Convert to Self smallInt or bigInt. Respects sign.
asSmallInteger = ( asInteger asSmallInteger)
asSmallIntegerIfFail: = ( asInteger asSmallIntegerIfFail: fb)
asSmallIntegerIfPossible = ( add: 0 With: self)
asUnsignedInteger =
( | r <- 0 |
    size pred to: 0 By: -1 Do: [|:i|
      r: (256 * r) +  and: (ushr: self With: i * 8) With: 255.
    ].
    r)
high16Bits = ( (shr: self With: 16) low16Bits)
low16Bits = ( and: self With: 16rffff)

comparing

!= = ( ne: self With: x)
< = ( lt: self With: x)
<= = ( le: self With: x)
= = ( eq: self With: x)
> = ( gt: self With: x)
>= = ( ge: self With: x)
eq:With: = ( 0 = (cmp: a With: b))
ge:With: = ( -1 != (cmp: a With: b))
gt:With: = ( 1 = (cmp: a With: b))
le:With: = ( 1 != (cmp: a With: b))
lt:With: = ( -1 = (cmp: a With: b))
ne:With: = ( 0 != (cmp: a With: b))
compareBigInteger:IfLess:Equal:Greater: = ( asInteger compareBigInteger: x IfLess: lb Equal: eb Greater: gb)
equalsBigInteger: = ( asInteger = x)
equalsSmallInteger: = ( eq: i With: self)
reverseGreaterThanOrEqualSmallInteger: = ( ge: i With: self)
reverseGreaterThanSmallInteger: = ( gt: i With: self)
reverseLessThanOrEqualSmallInteger: = ( le: i With: self)
reverseLessThanSmallInteger: = ( lt: i With: self)

creating from bytes

in big-endian (MSB first) order

copyTakeBigEndianBytesFrom: =
( 
    [endianDependentServer].
    copyTakeBigEndianBytesFrom: bytes Index: 0)
copyTakeBigEndianBytesFrom:Index: =
( 
    [endianDependentServer].
    copyTakeBigEndianBytesFrom: bytes Index: i IfFail: raiseError)
copyTakeBigEndianBytesFrom:Index:IfFail: =
( 
    [endianDependentServer].
    isThisPlatformBigEndian ifTrue: [
      copyTakeBytesFrom: bytes Index: i IfFail: errBlk
    ]
    False: [
      copyTakeReversedBytesFrom: bytes Index: i IfFail: errBlk
    ])

in littne-endian (LSB first) order

copyTakeLittleEndianBytesFrom: = ( copyTakeLittleEndianBytesFrom: bytes Index: 0)
copyTakeLittleEndianBytesFrom:Index: = ( copyTakeLittleEndianBytesFrom: bytes Index: i IfFail: raiseError)
copyTakeLittleEndianBytesFrom:Index:IfFail: =
( 
    isThisPlatformLittleEndian ifTrue: [
      copyTakeBytesFrom: bytes Index: i IfFail: errBlk
    ]
    False: [
      copyTakeReversedBytesFrom: bytes Index: i IfFail: errBlk
    ])

in native C order

copyTakeBytesFrom: = ( copyTakeBytesFrom: bytes Index: 0)
copyTakeBytesFrom:Index: = ( copyTakeBytesFrom: bv Index: idx IfFail: raiseError)
copyTakeBytesFrom:Index:IfFail: =
( 
    copy copyRangeDstPos: 0
                SrcArray: bv
                  SrcPos: idx
                     Len: size
                  IfFail: [|:e| ^ errBlk value: e printString, ' is absent'])
Copy and initialize the bytes from bv starting at index idx.

in reverse order

copyTakeReversedBytesFrom: = ( copyTakeReversedBytesFrom: bytes Index: 0)
copyTakeReversedBytesFrom:Index: = ( copyTakeReversedBytesFrom: bytes Index: i IfFail: raiseError)
copyTakeReversedBytesFrom:Index:IfFail: =
( | r |
    r: copy.
    size do: [|:i|  r at: i Put:
                       (bv at: idx + (size pred - i)) asByte
                       IfAbsent: [^ errBlk value: e printString, ' is absent']].
    r)
Copy and initialize the bytes from bv starting at index idx.

functions

max: = ( < n ifTrue: n False: self)
min: = ( > n ifTrue: n False: self)

primitives

floatFromInt32: = ( _FloatFromInt32: i)
floatFromInt64: = ( _FloatFromInt64: i)
int16FromInt32: = ( _Int16FromInt32: i)
int16FromInt64: = ( _Int16FromInt64: i)
int8FromInt32: = ( _Int8FromInt32: i)
int8FromInt64: = ( _Int8FromInt64: i)

printing

hexPrintString =
( | r <- ''. s |
    [aaa]. "Why is this method not just calling bytesDo:? -- Adam, Mar. 2009"
    size pred downTo: 0 Do: [|:i|
      s: (and: 255 With: (ushr: self With: i * typeSizes bitsPerByte)) hexPrintString.
      s: ('00' copySize: 2 - s size), s.
      r: r, s.
    ].
    r)
printString = ( printStringBase: 16)
printStringBase: =
( 
    b = 16 ifTrue: [^ hexPrintString]. "optimization"
    asInteger printStringBase: b)
shortIfPossibleHexPrintString =
( 
    "if short were possible, I would be a smallInt"
    shortIfPossibleHexPrintStringPrefix: '16r')
shortIfPossibleHexPrintStringPrefix: = ( pre, hexPrintString)
statePrintString = ( printStringBase: 16)
storeStringFor: = ( storeStringFor: a IfFail: [|:e| error: e])
storeStringFor:IfFail: =
( 
    "Leverage of the bigInt storeStrings."
    (a asInteger storeStringIfFail: [|:e| ^ fb value: e]), ' asInt', 
    (typeSizes bitsPerByte * size) printString)
storeStringIfFail: = ( storeStringFor: self IfFail: fb)

testing

isThisPlatformBigEndian =
( | bv |
    "Optimization: Used to say (0 & 0 & 0 & 1) asByteVector, but that
     was 4-5 times slower. -- Adam, 8/06"
    bv: byteVector copySize: 4 FillingWith: 0.
    bv at: 3 Put: 1.
    (bv cIntSize: 32 Signed: true At: 0) = 1)
isThisPlatformLittleEndian =
( 
    [endianDependentServer].
     isThisPlatformBigEndian not)