[Vm-dev] VM Maker: VMMaker.oscog-nice.1732.mcz
Nicolas Cellier
nicolas.cellier.aka.nice at gmail.com
Fri Mar 18 22:28:31 UTC 2016
2016-03-18 21:40 GMT+01:00 Eliot Miranda <eliot.miranda at gmail.com>:
>
> Hi Nicolas,
>
> On Thu, Mar 17, 2016 at 3:24 PM, <commits at source.squeak.org> wrote:
>
>>
>> Nicolas Cellier uploaded a new version of VMMaker to project VM Maker:
>> http://source.squeak.org/VMMaker/VMMaker.oscog-nice.1732.mcz
>>
>> ==================== Summary ====================
>>
>> Name: VMMaker.oscog-nice.1732
>> Author: nice
>> Time: 17 March 2016, 11:22:07.715 pm
>> UUID: ea9dd158-4847-464e-9642-9786252797dc
>> Ancestors: VMMaker.oscog-nice.1731
>>
>> Use little endian accelerators too for fetching 32 & 64 bits large
>> integers value (like the ones used for storing value).
>>
>> Dramatically simplify fetching of signedInteger values by using an
>> intermediate unsigned magnitude.
>>
>> Declare the positive32/64BitIntegerFor: and
>> maybeInlinePositive32BitIntegerFor: parameter as unsigned since it is
>> interpreted as positive.
>>
>> Use asUnsignedInteger in isIntegerValue: tests, integerObjectOf: and
>> rotatedFloatBitsOf: in order to ban potential UB.
>>
>> Simplify bit operations using
>> positiveMachineIntegerValueOf:/positiveMachineIntegerFor: rather than doing
>> 32/64 bits dissertation.
>>
>> Fetch magnitude of positive large ints into an unsigned for large int bit
>> ops.
>>
>
>
> In the following
>
> ----- Method: StackInterpreter>>maybeInlinePositive32BitIntegerFor: (in
> category 'primitive support') -----
> maybeInlinePositive32BitIntegerFor: integerValue
> "N.B. will *not* cause a GC.
> integerValue is interpreted as POSITIVE, e.g. as the result of
> Bitmap>at:."
> <notOption: #Spur64BitMemoryManager>
> + <var: 'integerValue' type: #'unsigned int'>
> | newLargeInteger |
> self deny: objectMemory hasSixtyFourBitImmediates.
> + integerValue <= objectMemory maxSmallInteger
> + ifTrue: [^ objectMemory integerObjectOf: integerValue].
> - (integerValue asInteger >= 0
> - and: [objectMemory isIntegerValue: integerValue]) ifTrue:
> - [^objectMemory integerObjectOf: integerValue].
>
> shouldn't we compare against minSmallInteger as well, because e.g.
> -16r80000000 could overflow SmallInteger and answer 0?
>
>
>
> P.S. Lovely seeing this code getting some good loving.
>
>
Hi Eliot,
the idea is that every sender of positive32BitIntegerFor: will pass an
unsigned int.
At least that's the intention of every sender.
Unfortunately, slang inlining does not force a parameter variable copy in
case of sign mismatch
That's the case of primitiveBitShift in which a variable is declare signed
sqInt shifted;
Then the send:
shifted := self positiveMachineIntegerFor: shifted.
is translated into:
if (shifted <= (MaxSmallInteger)) {
shifted = ((shifted << 1) | 1);
instead of:
unsigned int integerValue = shifted;
if (integerValue <= (MaxSmallInteger)) {
shifted = ((integerValue << 1) | 1);
...
Here we have 3 options:
1) fix slang inlining
2) patch every sender of positiveMachineIntegerFor: to make sure that
effective parameter is unsigned
3) revert this change
In my branch I have opted for 2), but completely failed to backport the
patch in trunk (this change is 2 years old...).
Right now I'm testing that the patch work and I will commit ASAP.
Sorry for breaking, I've not tested enough because I'm too much focused on
64bits brand.
But testing all the flavours is not a task for a human anyway, more for a
bot like a Jenkins server.
>
>
>>
>> =============== Diff against VMMaker.oscog-nice.1731 ===============
>>
>> Item was changed:
>> ----- Method: InterpreterPrimitives>>magnitude64BitIntegerFor:neg: (in
>> category 'primitive support') -----
>> magnitude64BitIntegerFor: magnitude neg: isNegative
>> "Return a Large Integer object for the given integer magnitude
>> and sign"
>> | newLargeInteger largeClass highWord sz isSmall smallVal |
>> <var: 'magnitude' type: #usqLong>
>> <var: 'highWord' type: #usqInt>
>>
>> isSmall := isNegative
>> ifTrue: [magnitude <= (objectMemory
>> maxSmallInteger + 1)]
>> ifFalse: [magnitude <= objectMemory
>> maxSmallInteger].
>> isSmall ifTrue:
>> [smallVal := self cCoerceSimple: magnitude to: #sqInt.
>> isNegative ifTrue: [smallVal := 0 - smallVal].
>> ^objectMemory integerObjectOf: smallVal].
>>
>> largeClass := isNegative
>> ifTrue: [objectMemory
>> classLargeNegativeInteger]
>> ifFalse: [objectMemory
>> classLargePositiveInteger].
>> objectMemory wordSize = 8
>> ifTrue: [sz := 8]
>> ifFalse:
>> [(highWord := magnitude >> 32) = 0
>> ifTrue: [sz := 4]
>> ifFalse:
>> [sz := 5.
>> (highWord := highWord >> 8) = 0
>> ifFalse:
>> [sz := sz + 1.
>> (highWord := highWord >>
>> 8) = 0 ifFalse:
>> [sz := sz + 1.
>> (highWord :=
>> highWord >> 8) = 0 ifFalse: [sz := sz + 1]]]]].
>> newLargeInteger := objectMemory instantiateClass: largeClass
>> indexableSize: sz.
>> self cppIf: VMBIGENDIAN
>> ifTrue:
>> [sz > 4 ifTrue:
>> [objectMemory
>> storeByte: 7 ofObject:
>> newLargeInteger withValue: (magnitude >> 56 bitAnd: 16rFF);
>> storeByte: 6 ofObject:
>> newLargeInteger withValue: (magnitude >> 48 bitAnd: 16rFF);
>> storeByte: 5 ofObject:
>> newLargeInteger withValue: (magnitude >> 40 bitAnd: 16rFF);
>> storeByte: 4 ofObject:
>> newLargeInteger withValue: (magnitude >> 32 bitAnd: 16rFF)].
>> objectMemory
>> storeByte: 3 ofObject: newLargeInteger
>> withValue: (magnitude >> 24 bitAnd: 16rFF);
>> storeByte: 2 ofObject: newLargeInteger
>> withValue: (magnitude >> 16 bitAnd: 16rFF);
>> storeByte: 1 ofObject: newLargeInteger
>> withValue: (magnitude >> 8 bitAnd: 16rFF);
>> storeByte: 0 ofObject: newLargeInteger
>> withValue: (magnitude ">> 0" bitAnd: 16rFF)]
>> ifFalse:
>> + [sz > 4
>> + ifTrue: [objectMemory storeLong64: 0
>> ofObject: newLargeInteger withValue: magnitude]
>> + ifFalse: [objectMemory storeLong32: 0
>> ofObject: newLargeInteger withValue: (self cCode: [magnitude] inSmalltalk:
>> [magnitude bitAnd: 16rFFFFFFFF])]].
>> - [sz > 4 ifTrue:
>> - [objectMemory storeLong32: 1 ofObject:
>> newLargeInteger withValue: magnitude >> 32].
>> - objectMemory
>> - storeLong32: 0
>> - ofObject: newLargeInteger
>> - withValue: (self cCode: [magnitude]
>> inSmalltalk: [magnitude bitAnd: 16rFFFFFFFF])].
>>
>> ^newLargeInteger!
>>
>> Item was changed:
>> ----- Method: InterpreterPrimitives>>magnitude64BitValueOf: (in
>> category 'primitive support') -----
>> magnitude64BitValueOf: oop
>> "Convert the given object into an integer value.
>> The object may be either a positive SmallInteger or an eight-byte
>> LargeInteger."
>> | sz value ok smallIntValue |
>> <returnTypeC: #usqLong>
>> <var: #value type: #usqLong>
>>
>> (objectMemory isIntegerObject: oop) ifTrue:
>> [smallIntValue := (objectMemory integerValueOf: oop).
>> smallIntValue < 0 ifTrue: [smallIntValue := 0 -
>> smallIntValue].
>> ^self cCoerce: smallIntValue to: #usqLong].
>>
>> (objectMemory isNonIntegerImmediate: oop) ifTrue:
>> [self primitiveFail.
>> ^0].
>>
>> ok := objectMemory isClassOfNonImm: oop
>> equalTo: (objectMemory splObj:
>> ClassLargePositiveInteger)
>> compactClassIndex:
>> ClassLargePositiveIntegerCompactIndex.
>> ok
>> ifFalse:
>> [ok := objectMemory isClassOfNonImm: oop
>> equalTo:
>> (objectMemory splObj: ClassLargeNegativeInteger)
>>
>> compactClassIndex: ClassLargeNegativeIntegerCompactIndex.
>> ok ifFalse:
>> [self primitiveFail.
>> ^0]].
>> sz := objectMemory numBytesOfBytes: oop.
>> sz > (self sizeof: #sqLong) ifTrue:
>> [self primitiveFail.
>> ^0].
>>
>> + self cppIf: VMBIGENDIAN
>> + ifTrue:
>> + [value := objectMemory fetchByte: sz - 1
>> ofObject: oop.
>> + sz - 2 to: 0 by: -1 do:
>> + [:i | value := value << 8 + (objectMemory
>> fetchByte: i ofObject: oop)]]
>> + ifFalse:
>> + [sz > 4
>> + ifTrue: [value := self cCoerceSimple:
>> (objectMemory fetchLong64: 0 ofObject: oop) to: #usqLong]
>> + ifFalse: [value := self cCoerceSimple:
>> (objectMemory fetchLong32: 0 ofObject: oop) to: #'unsigned int'].].
>> - value := objectMemory fetchByte: sz - 1 ofObject: oop.
>> - sz - 2 to: 0 by: -1 do:
>> - [:i | value := value << 8 + (objectMemory fetchByte: i
>> ofObject: oop)].
>> ^value!
>>
>> Item was changed:
>> ----- Method: InterpreterPrimitives>>positive64BitValueOf: (in category
>> 'primitive support') -----
>> positive64BitValueOf: oop
>> "Convert the given object into an integer value.
>> The object may be either a positive SmallInteger or an eight-byte
>> LargePositiveInteger."
>>
>> <returnTypeC: #usqLong>
>> | sz value ok |
>> <var: #value type: #usqLong>
>> (objectMemory isIntegerObject: oop) ifTrue:
>> [(objectMemory integerValueOf: oop) < 0 ifTrue:
>> [^self primitiveFail].
>> ^objectMemory integerValueOf: oop].
>>
>> (objectMemory isNonIntegerImmediate: oop) ifTrue:
>> [self primitiveFail.
>> ^0].
>>
>> ok := objectMemory
>> isClassOfNonImm: oop
>> equalTo: (objectMemory splObj:
>> ClassLargePositiveInteger)
>> compactClassIndex:
>> ClassLargePositiveIntegerCompactIndex.
>> ok ifFalse:
>> [self primitiveFail.
>> ^0].
>> sz := objectMemory numBytesOfBytes: oop.
>> sz > (self sizeof: #sqLong) ifTrue:
>> [self primitiveFail.
>> ^0].
>>
>> + self cppIf: VMBIGENDIAN
>> + ifTrue:
>> + [value := 0.
>> + 0 to: sz - 1 do: [:i |
>> + value := value + ((self cCoerce:
>> (objectMemory fetchByte: i ofObject: oop) to: #usqLong) << (i*8))]]
>> + ifFalse:
>> + [sz > 4
>> + ifTrue: [value := self cCoerceSimple:
>> (objectMemory fetchLong64: 0 ofObject: oop) to: #usqLong]
>> + ifFalse: [value := self cCoerceSimple:
>> (objectMemory fetchLong32: 0 ofObject: oop) to: #'unsigned int'].].
>> - value := 0.
>> - 0 to: sz - 1 do: [:i |
>> - value := value + ((self cCoerce: (objectMemory fetchByte:
>> i ofObject: oop) to: #usqLong) << (i*8))].
>> ^value!
>>
>> Item was changed:
>> ----- Method: InterpreterPrimitives>>primitiveBitAnd (in category
>> 'arithmetic integer primitives') -----
>> primitiveBitAnd
>> <inline: false>
>> + <var: 'integerArgument' type: #usqInt>
>> + <var: 'intergerReceiver' type: #usqInt>
>> | integerReceiver integerArgument |
>> integerArgument := self stackTop.
>> integerReceiver := self stackValue: 1.
>> "Comment out the short-cut. Either the inline interpreter
>> bytecode or the JIT primitive will handle this case.
>> ((objectMemory isIntegerObject: integerArgument)
>> and: [objectMemory isIntegerObject: integerReceiver])
>> ifTrue: [self pop: 2 thenPush: (integerArgument bitAnd:
>> integerReceiver)]
>> ifFalse:
>> + ["
>> + integerArgument := self
>> positiveMachineIntegerValueOf: integerArgument.
>> + integerReceiver := self
>> positiveMachineIntegerValueOf: integerReceiver.
>> + self successful ifTrue:
>> + [self pop: 2 thenPush: (self
>> positiveMachineIntegerFor: (integerArgument bitAnd: integerReceiver))]
>> - ["objectMemory wordSize = 8
>> - ifTrue:
>> - [integerArgument := self
>> positive64BitValueOf: integerArgument.
>> - integerReceiver := self
>> positive64BitValueOf: integerReceiver.
>> - self successful ifTrue:
>> - [self pop: 2 thenPush:
>> (self positive64BitIntegerFor: (integerArgument bitAnd: integerReceiver))]]
>> ifFalse:
>> + []"]"!
>> - [integerArgument := self
>> positive32BitValueOf: integerArgument.
>> - integerReceiver := self
>> positive32BitValueOf: integerReceiver.
>> - self successful ifTrue:
>> - [self pop: 2 thenPush:
>> (self positive32BitIntegerFor: (integerArgument bitAnd:
>> integerReceiver))]]"]"!
>>
>> Item was changed:
>> ----- Method: InterpreterPrimitives>>primitiveBitAndLargeIntegers (in
>> category 'arithmetic largeint primitives') -----
>> primitiveBitAndLargeIntegers
>> "Primitive logical operations for large integers in 64 bit range"
>> | integerRcvr integerArg oopResult |
>> <export: true>
>> + <var: 'integerRcvr' type: 'usqLong'>
>> + <var: 'integerArg' type: 'usqLong'>
>> - <var: 'integerRcvr' type: 'sqLong'>
>> - <var: 'integerArg' type: 'sqLong'>
>>
>> integerArg := self positive64BitValueOf: (self stackValue: 0).
>> integerRcvr := self positive64BitValueOf: (self stackValue: 1).
>> self successful ifFalse:[^nil].
>>
>> oopResult := self positive64BitIntegerFor: (integerRcvr bitAnd:
>> integerArg).
>> self successful ifTrue:[self pop: 2 thenPush: oopResult]!
>>
>> Item was changed:
>> ----- Method: InterpreterPrimitives>>primitiveBitOr (in category
>> 'arithmetic integer primitives') -----
>> primitiveBitOr
>> <inline: false>
>> + <var: 'integerArgument' type: #usqInt>
>> + <var: 'intergerReceiver' type: #usqInt>
>> | integerReceiver integerArgument |
>> integerArgument := self stackTop.
>> integerReceiver := self stackValue: 1.
>> "Comment out the short-cut. Either the inline interpreter
>> bytecode or the JIT primitive will handle this case.
>> ((objectMemory isIntegerObject: integerArgument)
>> and: [objectMemory isIntegerObject: integerReceiver])
>> ifTrue: [self pop: 2 thenPush: (integerArgument bitOr:
>> integerReceiver)]
>> ifFalse:
>> + ["
>> + integerArgument := self
>> positiveMachineIntegerValueOf: integerArgument.
>> + integerReceiver := self
>> positiveMachineIntegerValueOf: integerReceiver.
>> + self successful ifTrue:
>> + [self pop: 2 thenPush: (self
>> positiveMachineIntegerFor: (integerArgument bitOr: integerReceiver))]
>> - ["objectMemory wordSize = 8
>> - ifTrue:
>> - [integerArgument := self
>> positive64BitValueOf: integerArgument.
>> - integerReceiver := self
>> positive64BitValueOf: integerReceiver.
>> - self successful ifTrue:
>> - [self pop: 2 thenPush:
>> (self positive64BitIntegerFor: (integerArgument bitOr: integerReceiver))]]
>> ifFalse:
>> + []"]"!
>> - [integerArgument := self
>> positive32BitValueOf: integerArgument.
>> - integerReceiver := self
>> positive32BitValueOf: integerReceiver.
>> - self successful ifTrue:
>> - [self pop: 2 thenPush:
>> (self positive32BitIntegerFor: (integerArgument bitOr:
>> integerReceiver))]]"]"!
>>
>> Item was changed:
>> ----- Method: InterpreterPrimitives>>primitiveBitOrLargeIntegers (in
>> category 'arithmetic largeint primitives') -----
>> primitiveBitOrLargeIntegers
>> "Primitive logical operations for large integers in 64 bit range"
>> | integerRcvr integerArg oopResult |
>> <export: true>
>> + <var: 'integerRcvr' type: 'usqLong'>
>> + <var: 'integerArg' type: 'usqLong'>
>> - <var: 'integerRcvr' type: 'sqLong'>
>> - <var: 'integerArg' type: 'sqLong'>
>>
>> integerArg := self positive64BitValueOf: (self stackValue: 0).
>> integerRcvr := self positive64BitValueOf: (self stackValue: 1).
>> self successful ifFalse:[^nil].
>>
>> oopResult := self positive64BitIntegerFor: (integerRcvr bitOr:
>> integerArg).
>> self successful ifTrue:[self pop: 2 thenPush: oopResult]!
>>
>> Item was changed:
>> ----- Method: InterpreterPrimitives>>primitiveBitXor (in category
>> 'arithmetic integer primitives') -----
>> primitiveBitXor
>> <inline: false>
>> | integerReceiver integerArgument |
>> integerArgument := self stackTop.
>> integerReceiver := self stackValue: 1.
>> ((objectMemory isIntegerObject: integerArgument)
>> and: [objectMemory isIntegerObject: integerReceiver])
>> ifTrue: "xoring will leave the tag bits zero, whether the
>> tag is 1 or zero, so add it back in."
>> [self pop: 2 thenPush: (integerArgument bitXor:
>> integerReceiver) + objectMemory smallIntegerTag]
>> ifFalse:
>> + [integerArgument := self
>> positiveMachineIntegerValueOf: integerArgument.
>> + integerReceiver := self
>> positiveMachineIntegerValueOf: integerReceiver.
>> + self successful ifTrue:
>> + [self pop: 2 thenPush: (self
>> positiveMachineIntegerFor: (integerArgument bitXor: integerReceiver))]]!
>> - [objectMemory wordSize = 8
>> - ifTrue:
>> - [integerArgument := self
>> positive64BitValueOf: integerArgument.
>> - integerReceiver := self
>> positive64BitValueOf: integerReceiver.
>> - self successful ifTrue:
>> - [self pop: 2 thenPush:
>> (self positive64BitIntegerFor: (integerArgument bitXor: integerReceiver))]]
>> - ifFalse:
>> - [integerArgument := self
>> positive32BitValueOf: integerArgument.
>> - integerReceiver := self
>> positive32BitValueOf: integerReceiver.
>> - self successful ifTrue:
>> - [self pop: 2 thenPush:
>> (self positive32BitIntegerFor: (integerArgument bitXor:
>> integerReceiver))]]]!
>>
>> Item was changed:
>> ----- Method: InterpreterPrimitives>>primitiveBitXorLargeIntegers (in
>> category 'arithmetic largeint primitives') -----
>> primitiveBitXorLargeIntegers
>> "Primitive logical operations for large integers in 64 bit range"
>> | integerRcvr integerArg oopResult |
>> <export: true>
>> + <var: 'integerRcvr' type: 'usqLong'>
>> + <var: 'integerArg' type: 'usqLong'>
>> - <var: 'integerRcvr' type: 'sqLong'>
>> - <var: 'integerArg' type: 'sqLong'>
>>
>> integerArg := self positive64BitValueOf: (self stackValue: 0).
>> integerRcvr := self positive64BitValueOf: (self stackValue: 1).
>> self successful ifFalse:[^nil].
>>
>> oopResult := self positive64BitIntegerFor: (integerRcvr bitXor:
>> integerArg).
>> self successful ifTrue:[self pop: 2 thenPush: oopResult]!
>>
>> Item was changed:
>> ----- Method: InterpreterPrimitives>>signed32BitValueOf: (in category
>> 'primitive support') -----
>> signed32BitValueOf: oop
>> "Convert the given object into an integer value.
>> The object may be either a positive SmallInteger or a four-byte
>> LargeInteger."
>> + | value negative ok magnitude |
>> - | value negative ok |
>> <inline: false>
>> <returnTypeC: #int>
>> <var: #value type: #int>
>> + <var: #magnitude type: #'unsigned int'>
>> <var: #value64 type: #long>
>> (objectMemory isIntegerObject: oop) ifTrue:
>> [objectMemory wordSize = 4
>> ifTrue:
>> [^objectMemory integerValueOf: oop]
>> ifFalse: "Must fail for SmallIntegers with
>> digitLength > 4"
>> [| value64 |
>> value64 := objectMemory integerValueOf:
>> oop.
>> (self cCode: [(self cCoerceSimple:
>> value64 to: #int) ~= value64]
>> inSmalltalk: [value64 >>
>> 31 ~= 0 and: [value64 >> 31 ~= -1]]) ifTrue:
>> [self primitiveFail. value64 :=
>> 0].
>> ^value64]].
>>
>> (objectMemory isNonIntegerImmediate: oop) ifTrue:
>> [self primitiveFail.
>> ^0].
>>
>> ok := objectMemory
>> isClassOfNonImm: oop
>> equalTo: (objectMemory splObj:
>> ClassLargePositiveInteger)
>> compactClassIndex:
>> ClassLargePositiveIntegerCompactIndex.
>> ok
>> ifTrue: [negative := false]
>> ifFalse:
>> [negative := true.
>> ok := objectMemory isClassOfNonImm: oop
>> equalTo:
>> (objectMemory splObj: ClassLargeNegativeInteger)
>>
>> compactClassIndex: ClassLargeNegativeIntegerCompactIndex.
>> ok ifFalse:
>> [self primitiveFail.
>> ^0]].
>> (objectMemory numBytesOfBytes: oop) > 4 ifTrue:
>> [^self primitiveFail].
>>
>> + magnitude := self cppIf: VMBIGENDIAN
>> - value := self cppIf: VMBIGENDIAN
>> ifTrue:
>> [ (objectMemory fetchByte: 0
>> ofObject: oop) +
>> ((objectMemory fetchByte: 1
>> ofObject: oop) << 8) +
>> ((objectMemory fetchByte: 2
>> ofObject: oop) << 16) +
>> ((objectMemory fetchByte: 3
>> ofObject: oop) << 24)]
>> ifFalse:
>> + [(objectMemory fetchLong32: 0
>> ofObject: oop) asUnsignedInteger].
>> +
>> + (negative
>> + ifTrue: [magnitude > 16r80000000]
>> + ifFalse: [magnitude >= 16r80000000])
>> + ifTrue:
>> + [self primitiveFail.
>> + ^0].
>> + negative
>> + ifTrue: [value := 0 - magnitude]
>> + ifFalse: [value := magnitude].
>> + ^value!
>> - [objectMemory fetchLong32: 0
>> ofObject: oop].
>> - self cCode: []
>> - inSmalltalk:
>> - [(value anyMask: 16r80000000) ifTrue:
>> - [value := value - 16r100000000]].
>> - "Filter out values out of range for the signed interpretation
>> such as
>> - 16rFFFFFFFF (positive w/ bit 32 set) and -16rFFFFFFFF (negative
>> w/ bit
>> - 32 set). Since the sign is implicit in the class we require that
>> the high
>> - bit of the magnitude is not set which is a simple test here.
>> Note that
>> - we have to handle the most negative 32-bit value -2147483648
>> specially."
>> - value < 0 ifTrue:
>> - [self assert: (self sizeof: value) == 4.
>> - "Don't fail for -16r80000000/-2147483648
>> - Alas the simple (negative and: [value - 1 > 0]) isn't
>> adequate since in C the result of signed integer
>> - overflow is undefined and hence under optimization this
>> may fail. The shift, however, is well-defined."
>> - (negative and: [0 = (self cCode: [value << 1]
>> -
>> inSmalltalk: [value << 1 bitAnd: (1 << 32) - 1])]) ifTrue:
>> - [^value].
>> - self primitiveFail.
>> - ^0].
>> - ^negative
>> - ifTrue: [0 - value]
>> - ifFalse: [value]!
>>
>> Item was changed:
>> ----- Method: InterpreterPrimitives>>signed64BitValueOf: (in category
>> 'primitive support') -----
>> signed64BitValueOf: oop
>> "Convert the given object into an integer value.
>> The object may be either a positive SmallInteger or a eight-byte
>> LargeInteger."
>> + | sz value negative ok magnitude |
>> - | sz value negative ok |
>> <inline: false>
>> <returnTypeC: #sqLong>
>> <var: #value type: #sqLong>
>> + <var: #magnitude type: #usqLong>
>> (objectMemory isIntegerObject: oop) ifTrue:
>> [^self cCoerce: (objectMemory integerValueOf: oop) to:
>> #sqLong].
>>
>> (objectMemory isNonIntegerImmediate: oop) ifTrue:
>> [self primitiveFail.
>> ^0].
>>
>> ok := objectMemory isClassOfNonImm: oop
>> equalTo: (objectMemory splObj:
>> ClassLargePositiveInteger)
>> compactClassIndex:
>> ClassLargePositiveIntegerCompactIndex.
>> ok
>> ifTrue: [negative := false]
>> ifFalse:
>> [negative := true.
>> ok := objectMemory isClassOfNonImm: oop
>> equalTo:
>> (objectMemory splObj: ClassLargeNegativeInteger)
>>
>> compactClassIndex: ClassLargeNegativeIntegerCompactIndex.
>> ok ifFalse:
>> [self primitiveFail.
>> ^0]].
>> sz := objectMemory numBytesOfBytes: oop.
>> sz > (self sizeof: #sqLong) ifTrue:
>> [self primitiveFail.
>> ^0].
>>
>> self cppIf: VMBIGENDIAN
>> ifTrue:
>> + [magnitude := objectMemory fetchByte: sz - 1
>> ofObject: oop.
>> - [value := objectMemory fetchByte: sz - 1
>> ofObject: oop.
>> sz - 2 to: 0 by: -1 do: [:i |
>> + magnitude := magnitude << 8 +
>> (objectMemory fetchByte: i ofObject: oop)]]
>> - value := value << 8 + (objectMemory
>> fetchByte: i ofObject: oop)]]
>> ifFalse:
>> + [magnitude := sz > 4
>> - [value := sz > 4
>> ifTrue: [objectMemory
>> fetchLong64: 0 ofObject: oop]
>> ifFalse: [(objectMemory
>> fetchLong32: 0 ofObject: oop) asUnsignedInteger]].
>> +
>> + (negative
>> + ifTrue: [magnitude > 16r8000000000000000]
>> + ifFalse: [magnitude >= 16r8000000000000000])
>> + ifTrue: [self primitiveFail.
>> + ^0].
>> + negative
>> + ifTrue: [value := 0 - magnitude]
>> + ifFalse: [value := magnitude].
>> + ^value!
>> - "Filter out values out of range for the signed interpretation
>> such as
>> - 16rFFFFFFFF... (positive w/ bit 64 set) and -16rFFFFFFFF...
>> (negative w/ bit
>> - 64 set). Since the sign is implicit in the class we require that
>> the high bit of
>> - the magnitude is not set which is a simple test here. Note that
>> we have to
>> - handle the most negative 64-bit value -9223372036854775808
>> specially."
>> - self cCode: []
>> - inSmalltalk:
>> - [(value anyMask: 16r8000000000000000) ifTrue:
>> - [value := value - 16r10000000000000000]].
>> - value < 0 ifTrue:
>> - [self cCode:
>> - [self assert: (self sizeof: value) == 8.
>> - self assert: (self sizeof: value << 1) == 8].
>> - "Don't fail for -9223372036854775808/-16r8000000000000000.
>> - Alas the simple (negative and: [value - 1 > 0]) isn't
>> adequate since in C the result of signed integer
>> - overflow is undefined and hence under optimization this
>> may fail. The shift, however, is well-defined."
>> - (negative and: [0 = (self cCode: [value << 1]
>> -
>> inSmalltalk: [value << 1 bitAnd: (1 << 64) - 1])]) ifTrue:
>> - [^value].
>> - self primitiveFail.
>> - ^0].
>> - ^negative
>> - ifTrue:[0 - value]
>> - ifFalse:[value]!
>>
>> Item was changed:
>> ----- Method: InterpreterPrimitives>>signedMachineIntegerValueOf: (in
>> category 'primitive support') -----
>> signedMachineIntegerValueOf: oop
>> "Answer a signed value of an integer up to the size of a machine
>> word.
>> The object may be either a positive SmallInteger or a
>> LargeInteger of size <= word size."
>> <returnTypeC: #'long'>
>> + | negative ok bs value limit magnitude |
>> - | negative ok bs value bits |
>> <var: #value type: #long>
>> + <var: #magnitude type: #usqInt>
>> + <var: #limit type: #usqInt>
>> (objectMemory isIntegerObject: oop) ifTrue:
>> [^objectMemory integerValueOf: oop].
>>
>> (objectMemory isNonIntegerImmediate: oop) ifTrue:
>> [^self primitiveFail].
>>
>> ok := objectMemory isClassOfNonImm: oop
>> equalTo: (objectMemory splObj:
>> ClassLargePositiveInteger)
>> compactClassIndex:
>> ClassLargePositiveIntegerCompactIndex.
>> ok
>> ifTrue: [negative := false]
>> ifFalse:
>> [negative := true.
>> ok := objectMemory isClassOfNonImm: oop
>> equalTo:
>> (objectMemory splObj: ClassLargeNegativeInteger)
>>
>> compactClassIndex: ClassLargeNegativeIntegerCompactIndex.
>> ok ifFalse: [^self primitiveFail]].
>> bs := objectMemory numBytesOf: oop.
>> bs > (self sizeof: #'unsigned long') ifTrue:
>> [^self primitiveFail].
>>
>> ((self sizeof: #'unsigned long') = 8
>> and: [bs > 4]) ifTrue:
>> + [magnitude := self cppIf: VMBIGENDIAN
>> - [value := self cppIf: VMBIGENDIAN
>> ifTrue:
>> [ (objectMemory
>> fetchByte: 0 ofObject: oop)
>> + ((objectMemory
>> fetchByte: 1 ofObject: oop) << 8)
>> + ((objectMemory
>> fetchByte: 2 ofObject: oop) << 16)
>> + ((objectMemory
>> fetchByte: 3 ofObject: oop) << 24)
>> + ((objectMemory
>> fetchByte: 4 ofObject: oop) << 32)
>> + ((objectMemory
>> fetchByte: 5 ofObject: oop) << 40)
>> + ((objectMemory
>> fetchByte: 6 ofObject: oop) << 48)
>> + ((objectMemory
>> fetchByte: 7 ofObject: oop) << 56)]
>> ifFalse:
>> [objectMemory
>> fetchLong64: 0 ofObject: oop]]
>> ifFalse:
>> + [magnitude := self cppIf: VMBIGENDIAN
>> - [value := self cppIf: VMBIGENDIAN
>> ifTrue:
>> [
>> (objectMemory fetchByte: 0 ofObject: oop)
>> + ((objectMemory
>> fetchByte: 1 ofObject: oop) << 8)
>> + ((objectMemory
>> fetchByte: 2 ofObject: oop) << 16)
>> + ((objectMemory
>> fetchByte: 3 ofObject: oop) << 24)]
>> ifFalse:
>> [(objectMemory
>> fetchLong32: 0 ofObject: oop) asUnsignedInteger]].
>> +
>> + limit := 1 asUnsignedInteger << ((self sizeof: #usqInt) * 8 - 1).
>> + (negative
>> + ifTrue: [magnitude > limit]
>> + ifFalse: [magnitude >= limit])
>> + ifTrue: [self primitiveFail.
>> + ^0].
>> + negative
>> + ifTrue: [value := 0 - magnitude]
>> + ifFalse: [value := magnitude].
>> + ^value!
>> -
>> - self cCode: []
>> - inSmalltalk:
>> - [bits := (self sizeof: #long) * 8.
>> - (value bitShift: 1 - bits) > 0 ifTrue:
>> - [value := value - (1 bitShift: bits)]].
>> - value < 0 ifTrue:
>> - ["Don't fail for -16r80000000[00000000].
>> - Alas the simple (negative and: [value - 1 > 0]) isn't
>> adequate since in C the result of signed integer
>> - overflow is undefined and hence under optimization this
>> may fail. The shift, however, is well-defined."
>> - (negative and: [0 = (self cCode: [value << 1]
>> -
>> inSmalltalk: [value << 1 bitAnd: (1 << bits) - 1])]) ifTrue:
>> - [^value].
>> - ^self primitiveFail].
>> - ^negative
>> - ifTrue: [0 - value]
>> - ifFalse: [value]!
>>
>> Item was changed:
>> ----- Method: InterpreterProxy>>positive32BitIntegerFor: (in category
>> 'converting') -----
>> positive32BitIntegerFor: integerValue
>> + <var: 'integerValue' type: #'unsigned int'>
>> integerValue isInteger ifFalse:[self error:'Not an Integer
>> object'].
>> ^integerValue > 0
>> ifTrue:[integerValue]
>> ifFalse:[ (1 bitShift: 32) + integerValue]!
>>
>> Item was changed:
>> ----- Method: InterpreterProxy>>positive64BitIntegerFor: (in category
>> 'converting') -----
>> positive64BitIntegerFor: integerValue
>> <api>
>> <returnTypeC: #sqInt> "...because answering the 64-bit argument
>> causes the type inferencer to say this answers 64-bits."
>> + <var: 'integerValue' type: #usqLong>
>> - <var: 'integerValue' type: #sqLong>
>> integerValue isInteger ifFalse:[self error:'Not an Integer
>> object'].
>> ^integerValue > 0
>> ifTrue:[integerValue]
>> ifFalse:[ (1 bitShift: 64) + integerValue]!
>>
>> Item was changed:
>> ----- Method: ObjectMemory>>isIntegerValue: (in category 'interpreter
>> access') -----
>> isIntegerValue: intValue
>> "Answer if the given value can be represented as a Smalltalk
>> integer value.
>> In C, use a shift and XOR to set the sign bit if and only if the
>> top two bits of the given
>> value are the same, then test the sign bit. Note that the top
>> two bits are equal for
>> exactly those integers in the range that can be represented in
>> 31-bits or 63-bits."
>> <api>
>> ^self
>> + cCode: [(intValue asUnsignedInteger bitXor: (intValue
>> asUnsignedInteger << 1)) asInteger >= 0]
>> + inSmalltalk: [intValue >= self minSmallInteger and:
>> [intValue <= self maxSmallInteger]]!
>> - cCode: [(intValue bitXor: (intValue << 1)) asInteger >= 0]
>> - inSmalltalk: [intValue >= 16r-40000000 and: [intValue <=
>> 16r3FFFFFFF]]!
>>
>> Item was changed:
>> ----- Method: Spur32BitMemoryManager>>isIntegerValue: (in category
>> 'interpreter access') -----
>> isIntegerValue: intValue
>> "Answer if the given value can be represented as a Smalltalk
>> integer value.
>> In C, use a shift and XOR to set the sign bit if and only if the
>> top two bits of the given
>> value are the same, then test the sign bit. Note that the top
>> two bits are equal for
>> exactly those integers in the range that can be represented in
>> 31-bits or 63-bits."
>> <api>
>> ^self
>> + cCode: [(intValue asUnsignedInteger bitXor: (intValue
>> asUnsignedInteger << 1)) asInteger >= 0]
>> + inSmalltalk: [intValue >= self minSmallInteger and:
>> [intValue <= self maxSmallInteger]]!
>> - cCode: [(intValue bitXor: (intValue << 1)) asInteger >= 0]
>> - inSmalltalk: [intValue >= 16r-40000000 and: [intValue <=
>> 16r3FFFFFFF]]!
>>
>> Item was changed:
>> ----- Method: Spur64BitMemoryManager>>integerObjectOf: (in category
>> 'immediates') -----
>> 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]
>> - cCode: [value << self numTagBits + 1]
>> inSmalltalk: [value << self numTagBits
>> + (value >= 0
>> ifTrue: [1]
>> ifFalse:
>> [16r10000000000000001])]!
>>
>> Item was changed:
>> ----- Method: Spur64BitMemoryManager>>isIntegerValue: (in category
>> 'interpreter access') -----
>> isIntegerValue: intValue
>> "Answer if the given value can be represented as a Smalltalk
>> integer value.
>> In 64-bits we use a 3 bit tag which leaves 61 bits for 2's
>> complement signed
>> integers. In C, use a shift add and mask to test if the top 4
>> bits are all the same.
>> Since 16rFFFFFFFFFFFFFFFF >> 60 = 16rF the computation intValue
>> >> 60 + 1 bitAnd: 16rF
>> maps in-range -ve values to 0 and in-range +ve values to 1."
>> <api>
>> ^self
>> cCode: [(intValue >> 60 + 1 bitAnd: 16rF) <= 1] "N.B.
>> (16rFFFFFFFFFFFFFFFF >> 60) + 1 = 16"
>> + inSmalltalk: [intValue >= self minSmallInteger and:
>> [intValue <= self maxSmallInteger]]!
>> - inSmalltalk: [intValue >= -16r1000000000000000 and:
>> [intValue <= 16rFFFFFFFFFFFFFFF]]!
>>
>> Item was changed:
>> ----- Method: Spur64BitMemoryManager>>rotatedFloatBitsOf: (in category
>> 'interpreter access') -----
>> rotatedFloatBitsOf: oop
>> "Answer the signed, but unadjusted value of a SmallFloat64,
>> suitable for use as a hash.
>> Keeping the exponent unadjusted keeps the value in the
>> SmallInteger range.
>> See section 61-bit Immediate Floats in the SpurMemoryManager
>> class comment.
>> msb
>> lsb
>> Decode:
>> [8expsubset][52mantissa][1s][3tags]
>> shift away tags & sign: [ 0000
>> ][8expsubset][52mantissa]
>> add sign: [ ssss
>> ][8expsubset][52mantissa]"
>> self assert: (self isImmediateFloat: oop).
>> ^oop asUnsignedInteger >> (self numTagBits + 1)
>> + ((oop anyMask: self smallFloatSignBit)
>> + ifTrue: [-1 asUnsignedInteger << (64 - self numTagBits -
>> 1)]
>> - ifTrue: [-1 << (64 - self numTagBits - 1)]
>> ifFalse: [0])!
>>
>> Item was changed:
>> ----- Method: StackInterpreter>>maybeInlinePositive32BitIntegerFor: (in
>> category 'primitive support') -----
>> maybeInlinePositive32BitIntegerFor: integerValue
>> "N.B. will *not* cause a GC.
>> integerValue is interpreted as POSITIVE, e.g. as the result of
>> Bitmap>at:."
>> <notOption: #Spur64BitMemoryManager>
>> + <var: 'integerValue' type: #'unsigned int'>
>> | newLargeInteger |
>> self deny: objectMemory hasSixtyFourBitImmediates.
>> + integerValue <= objectMemory maxSmallInteger
>> + ifTrue: [^ objectMemory integerObjectOf: integerValue].
>> - (integerValue asInteger >= 0
>> - and: [objectMemory isIntegerValue: integerValue]) ifTrue:
>> - [^objectMemory integerObjectOf: integerValue].
>> newLargeInteger := objectMemory
>>
>> eeInstantiateSmallClassIndex: ClassLargePositiveIntegerCompactIndex
>> format:
>> (objectMemory byteFormatForNumBytes: 4)
>> numSlots: 1.
>> self cppIf: VMBIGENDIAN
>> ifTrue:
>> [objectMemory
>> storeByte: 3 ofObject: newLargeInteger
>> withValue: (integerValue >> 24 bitAnd: 16rFF);
>> storeByte: 2 ofObject: newLargeInteger
>> withValue: (integerValue >> 16 bitAnd: 16rFF);
>> storeByte: 1 ofObject: newLargeInteger
>> withValue: (integerValue >> 8 bitAnd: 16rFF);
>> storeByte: 0 ofObject: newLargeInteger
>> withValue: (integerValue ">> 0" bitAnd: 16rFF)]
>> ifFalse:
>> [objectMemory storeLong32: 0 ofObject:
>> newLargeInteger withValue: integerValue].
>> ^newLargeInteger!
>>
>> Item was changed:
>> ----- Method: StackInterpreter>>positive32BitIntegerFor: (in category
>> 'primitive support') -----
>> positive32BitIntegerFor: integerValue
>> "integerValue is interpreted as POSITIVE, e.g. as the result of
>> Bitmap>at:.
>> 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>
>> + <var: 'integerValue' type: #'unsigned int'>
>> objectMemory hasSixtyFourBitImmediates
>> ifTrue:
>> [^objectMemory integerObjectOf: (integerValue
>> bitAnd: 16rFFFFFFFF)]
>> ifFalse:
>> [^self maybeInlinePositive32BitIntegerFor:
>> integerValue]!
>>
>> Item was changed:
>> ----- Method: StackInterpreter>>positive64BitIntegerFor: (in category
>> 'primitive support') -----
>> positive64BitIntegerFor: integerValue
>> <api>
>> + <var: 'integerValue' type: #usqLong>
>> + <var: 'highWord' type: #'unsigned int'>
>> - <var: 'integerValue' type: #sqLong>
>> "Answer a Large Positive Integer object for the given integer
>> value. N.B. will *not* cause a GC."
>> | newLargeInteger highWord sz |
>> objectMemory hasSixtyFourBitImmediates
>> ifTrue:
>> + [integerValue <= objectMemory maxSmallInteger
>> ifTrue:
>> - [(integerValue >= 0 and: [objectMemory
>> isIntegerValue: integerValue]) ifTrue:
>> [^objectMemory integerObjectOf:
>> integerValue].
>> sz := 8]
>> ifFalse:
>> + [(highWord := integerValue >> 32) = 0 ifTrue:
>> - [(highWord := integerValue >>> 32) = 0 ifTrue:
>> [^self positive32BitIntegerFor:
>> integerValue].
>> sz := 5.
>> (highWord := highWord >> 8) = 0 ifFalse:
>> [sz := sz + 1.
>> (highWord := highWord >> 8) = 0 ifFalse:
>> [sz := sz + 1.
>> (highWord := highWord >> 8) = 0
>> ifFalse:[sz := sz + 1]]]].
>> newLargeInteger := objectMemory
>>
>> eeInstantiateSmallClassIndex: ClassLargePositiveIntegerCompactIndex
>> format:
>> (objectMemory byteFormatForNumBytes: sz)
>> numSlots: 8 /
>> objectMemory bytesPerOop.
>> self cppIf: VMBIGENDIAN
>> ifTrue:
>> [objectMemory
>> storeByte: 7 ofObject: newLargeInteger
>> withValue: (integerValue >> 56 bitAnd: 16rFF);
>> storeByte: 6 ofObject: newLargeInteger
>> withValue: (integerValue >> 48 bitAnd: 16rFF);
>> storeByte: 5 ofObject: newLargeInteger
>> withValue: (integerValue >> 40 bitAnd: 16rFF);
>> storeByte: 4 ofObject: newLargeInteger
>> withValue: (integerValue >> 32 bitAnd: 16rFF);
>> storeByte: 3 ofObject: newLargeInteger
>> withValue: (integerValue >> 24 bitAnd: 16rFF);
>> storeByte: 2 ofObject: newLargeInteger
>> withValue: (integerValue >> 16 bitAnd: 16rFF);
>> storeByte: 1 ofObject: newLargeInteger
>> withValue: (integerValue >> 8 bitAnd: 16rFF);
>> storeByte: 0 ofObject: newLargeInteger
>> withValue: (integerValue ">> 0" bitAnd: 16rFF)]
>> ifFalse:
>> [objectMemory storeLong64: 0 ofObject:
>> newLargeInteger withValue: integerValue].
>> ^newLargeInteger
>> !
>>
>> Item was changed:
>> ----- Method: StackInterpreter>>signed64BitIntegerFor: (in category
>> 'primitive support') -----
>> signed64BitIntegerFor: integerValue
>> <var: 'integerValue' type: #sqLong>
>> "Answer a Large Integer object for the given integer value. N.B.
>> will *not* cause a GC."
>> | newLargeInteger magnitude largeClass highWord sz |
>> <inline: false>
>> + <var: 'magnitude' type: #usqLong>
>> - <var: 'magnitude' type: #sqLong>
>> <var: 'highWord' type: #usqInt>
>>
>> - objectMemory wordSize = 8 ifTrue:
>> - [(objectMemory isIntegerValue: integerValue) ifTrue:
>> - [^objectMemory integerObjectOf: integerValue].
>> - sz := 8].
>> -
>> integerValue < 0
>> + ifTrue:[ integerValue >= objectMemory
>> minSmallInteger ifTrue: [^objectMemory integerObjectOf: integerValue
>> asInteger].
>> + largeClass :=
>> ClassLargeNegativeIntegerCompactIndex.
>> + magnitude := 0 - (self cCoerceSimple:
>> integerValue to: #usqLong)]
>> + ifFalse:[ integerValue <= objectMemory
>> maxSmallInteger ifTrue: [^objectMemory integerObjectOf: integerValue
>> asInteger].
>> + largeClass :=
>> ClassLargePositiveIntegerCompactIndex.
>> - ifTrue:[ largeClass :=
>> ClassLargeNegativeIntegerCompactIndex.
>> - magnitude := 0 - integerValue]
>> - ifFalse:[ largeClass :=
>> ClassLargePositiveIntegerCompactIndex.
>> magnitude := integerValue].
>>
>> + objectMemory wordSize = 8
>> + ifTrue: [sz := 8]
>> + ifFalse: [
>> - "Make sure to handle the most -ve value correctly. 0 - most -ve =
>> most -ve and most -ve - 1
>> - is +ve. Alas the simple (negative or: [integerValue - 1 < 0])
>> fails with contemporary gcc and icc
>> - versions with optimization and sometimes without. The shift
>> works on all, touch wood."
>> -
>> - objectMemory wordSize = 4 ifTrue:
>> - [(magnitude <= 16r7FFFFFFF
>> - and: [integerValue >= 0
>> - or: [0 ~= (self cCode: [integerValue << 1]
>> - inSmalltalk:
>> [integerValue << 1 bitAnd: (1 << 64) - 1])]]) ifTrue:
>> - [^self signed32BitIntegerFor:
>> integerValue].
>> -
>> (highWord := magnitude >> 32) = 0
>> ifTrue: [sz := 4]
>> ifFalse:
>> [sz := 5.
>> (highWord := highWord >> 8) = 0 ifFalse:
>> [sz := sz + 1.
>> (highWord := highWord >> 8) = 0
>> ifFalse:
>> [sz := sz + 1.
>> (highWord := highWord >>
>> 8) = 0 ifFalse:
>> [sz := sz +
>> 1]]]]].
>>
>> newLargeInteger := objectMemory
>>
>> eeInstantiateSmallClassIndex: largeClass
>> format:
>> (objectMemory byteFormatForNumBytes: sz)
>> numSlots: sz + 3
>> // objectMemory bytesPerOop.
>> self cppIf: VMBIGENDIAN
>> ifTrue:
>> [sz > 4 ifTrue:
>> [objectMemory
>> storeByte: 7 ofObject:
>> newLargeInteger withValue: (magnitude >> 56 bitAnd: 16rFF);
>> storeByte: 6 ofObject:
>> newLargeInteger withValue: (magnitude >> 48 bitAnd: 16rFF);
>> storeByte: 5 ofObject:
>> newLargeInteger withValue: (magnitude >> 40 bitAnd: 16rFF);
>> storeByte: 4 ofObject:
>> newLargeInteger withValue: (magnitude >> 32 bitAnd: 16rFF)].
>> objectMemory
>> storeByte: 3 ofObject: newLargeInteger
>> withValue: (magnitude >> 24 bitAnd: 16rFF);
>> storeByte: 2 ofObject: newLargeInteger
>> withValue: (magnitude >> 16 bitAnd: 16rFF);
>> storeByte: 1 ofObject: newLargeInteger
>> withValue: (magnitude >> 8 bitAnd: 16rFF);
>> storeByte: 0 ofObject: newLargeInteger
>> withValue: (magnitude ">> 0" bitAnd: 16rFF)]
>> ifFalse:
>> + [sz > 4
>> + ifTrue: [objectMemory storeLong64: 0
>> ofObject: newLargeInteger withValue: magnitude]
>> + ifFalse: [objectMemory storeLong32: 0
>> ofObject: newLargeInteger withValue: (self cCode: [magnitude] inSmalltalk:
>> [magnitude bitAnd: 16rFFFFFFFF])]].
>> - [sz > 4 ifTrue:
>> - [objectMemory storeLong32: 1 ofObject:
>> newLargeInteger withValue: magnitude >> 32.
>> - magnitude := magnitude bitAnd:
>> 16rFFFFFFFF].
>> - objectMemory storeLong32: 0 ofObject:
>> newLargeInteger withValue: magnitude].
>> ^newLargeInteger!
>>
>>
>
>
> --
> _,,,^..^,,,_
> best, Eliot
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20160318/9fdfb5f6/attachment-0001.htm
More information about the Vm-dev
mailing list