'From Squeak 1.18 of December 12, 1996 on 20 March 1997 at 9:36:38 pm'! Integer subclass: #SmallInteger instanceVariableNames: '' classVariableNames: 'MaxVal Digitbuffer MinVal ' poolDictionaries: '' category: 'Numeric-Numbers'! !Integer class methodsFor: 'instance creation'! byte1: byte1 byte2: byte2 byte3: byte3 byte4: byte4 "Depending on high-order byte copy directly into a LargeInteger, or build up a SmallInteger by shifting. Modified to be more robust in the presence of different SmallInteger range." | value | byte4 = 0 ifTrue: [^ (byte3 bitShift: 16) + (byte2 bitShift: 8) + byte1]. value _ LargePositiveInteger new: 4. value digitAt: 4 put: byte4. value digitAt: 3 put: byte3. value digitAt: 2 put: byte2. value digitAt: 1 put: byte1. ^ value normalize! ! !SmallInteger methodsFor: 'system primitives'! digitAt: n "Answer the value of an indexable field in the receiver. Fail if the argument (the index) is not an Integer or is out of bounds." n>4 ifTrue: [^ 0]. self < 0 ifTrue: [self = SmallInteger minVal ifTrue: ["Can't negate minVal -- treat specially" n < 4 ifTrue: [^0]. ^(self bitShift: -24) digitAt: 1]. ^ ((0-self) bitShift: (1-n)*8) bitAnd: 16rFF] ifFalse: [^ (self bitShift: (1-n)*8) bitAnd: 16rFF]! ! !SmallInteger methodsFor: 'private'! tryAdd: aNumber "Use the primitive to detect SmallInteger bounds." ^nil! ! !SmallInteger class methodsFor: 'class initialization'! initializeMinMaxVal "SmallInteger initializeMinMaxVal" | min next | min := -1. [next := min tryAdd: min. next == nil] whileFalse: [min := next]. MinVal := min. MaxVal := 0 - (min + 1)! largeIntFor: anObject "Return nil if anObject is not a SmallInteger or no conversion is required. Otherwise, return a corresponding LargeInteger." | largeInt positiveObject | anObject class == self ifFalse: [^nil]. (anObject >= -16r20000000 and: [anObject <= 16r1FFFFFFF]) ifTrue: [^nil]. largeInt := (anObject < 0 ifTrue: [LargeNegativeInteger] ifFalse: [LargePositiveInteger]) basicNew: 4. positiveObject := anObject < 0 ifTrue: [0 - anObject] ifFalse: [anObject]. 1 to: 4 do: [:i | largeInt digitAt: i put: ((positiveObject bitShift: 1-i*8) bitAnd: 255) ]. ^largeInt! prepareFor2BitTags "Enumerate all objects in the image, replacing all SmallIntegers that would not be representable with 2 tag bits by corresponding LargeIntegers. Returns how many SmallIntegers were affected" "SmallInteger prepareFor2BitTags" | class largeInt count | count := 0. Smalltalk allObjectsDo: [:object | class := object class. (class isPointers and: [class ~~ MethodContext]) ifTrue: [ 1 to: class instSize do: [:i | largeInt := self largeIntFor: (object instVarAt: i). largeInt == nil ifFalse: [ object instVarAt: i put: largeInt. count := count+1 ] ]. 1 to: object basicSize do: [:i | largeInt := self largeIntFor: (object basicAt: i). largeInt == nil ifFalse: [ object basicAt: i put: largeInt. count := count+1 ] ] ] ifFalse: [ class == CompiledMethod ifTrue: [ 1 to: object numLiterals+1 do: [:i | largeInt := self largeIntFor: (object objectAt: i). largeInt == nil ifFalse: [ i = 1 ifTrue: [self error: 'method header']. object objectAt: i put: largeInt. count := count+1 ] ] ] ] ]. ^count! ! !SmallInteger class methodsFor: 'constants'! maxVal "Answer the maximum value for a SmallInteger." ^MaxVal! minVal "Answer the minimum value for a SmallInteger." ^MinVal! ! !SystemDictionary methodsFor: 'snapshot and quit'! processStartUpList "Call the startUp method on each object that needs to gracefully restart itself after a snapshot." SmallInteger initializeMinMaxVal. DisplayScreen startUp. Cursor startUp. Smalltalk installLowSpaceWatcher. "OK to do again later" InputSensor startUp. ProcessorScheduler hiddenBackgroundProcess. Delay startUp. Smalltalk startUp. ControlManager startUp. "NOTE: The active process terminates here." ! ! SmallInteger initializeMinMaxVal. SmallInteger prepareFor2BitTags. PopUpMenu notify: 'You should save your image now, but make sure you have a backup...'!