Eliot Miranda uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-eem.808.mcz
==================== Summary ====================
Name: Collections-eem.808
Author: eem
Time: 22 October 2018, 4:54:43.989805 pm
UUID: c6b15e95-b365-4ea0-8211-71ec7f55084b
Ancestors: Collections-ul.807
Faster ByteString/ByteArray hashing. The VM will accept either 1 or 2 args for the primitiveStringHash primitive so it can be used on the instance size, avoiding a little overhead.
=============== Diff against Collections-ul.807 ===============
Item was added:
+ ----- Method: ByteArray>>bytesHashWithInitialHash: (in category 'private') -----
+ bytesHashWithInitialHash: speciesHash
+ "Answer the hash of a byte-indexed array, using speciesHash as the initial value.
+ See SmallInteger>>hashMultiply."
+ <primitive: 'primitiveStringHash' module: 'MiscPrimitivePlugin'>
+
+ ^String stringHash: self initialHash: speciesHash!
Item was changed:
----- Method: ByteArray>>hash (in category 'comparing') -----
hash
"#hash is implemented, because #= is implemented"
+ ^self bytesHashWithInitialHash: self species hash!
- ^self class
- hashBytes: self
- startingWith: self species hash!
Item was added:
+ ----- Method: ByteString>>stringHashWithInitialHash: (in category 'private') -----
+ stringHashWithInitialHash: speciesHash
+ "Answer the hash of a byte-indexed string, using speciesHash as the initial value.
+ See SmallInteger>>hashMultiply."
+ <primitive: 'primitiveStringHash' module: 'MiscPrimitivePlugin'>
+
+ ^super stringHashWithInitialHash: speciesHash!
Item was added:
+ ----- Method: ByteSymbol>>stringHashWithInitialHash: (in category 'private') -----
+ stringHashWithInitialHash: speciesHash
+ "Answer the hash of a byte-indexed string, using speciesHash as the initial value.
+ See SmallInteger>>hashMultiply."
+ <primitive: 'primitiveStringHash' module: 'MiscPrimitivePlugin'>
+
+ ^super stringHashWithInitialHash: speciesHash!
Item was changed:
----- Method: String>>hash (in category 'comparing') -----
hash
"#hash is implemented, because #= is implemented"
"ar 4/10/2005: I had to change this to use ByteString hash as initial
hash in order to avoid having to rehash everything and yet compute
the same hash for ByteString and WideString.
md 16/10/2006: use identityHash as initialHash, as behavior hash will
use String hash (name) to have a better hash soon.
eem 4/17/2017 it's not possible to use String hash (name) for the
initial hash because that would be recursive."
+ ^self stringHashWithInitialHash: ByteString identityHash!
- ^self class stringHash: self initialHash: ByteString identityHash!
Item was added:
+ ----- Method: String>>stringHashWithInitialHash: (in category 'private') -----
+ stringHashWithInitialHash: speciesHash
+ "Answer the hash of a byte-indexed string, using speciesHash as the initial value.
+ See SmallInteger>>hashMultiply."
+ | hash |
+ hash := speciesHash bitAnd: 16r0FFFFFFF.
+ 1 to: self size do:
+ [:pos |
+ hash := (hash + (self basicAt: pos)) hashMultiply].
+ ^hash!
Levente Uzonyi uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-ul.807.mcz
==================== Summary ====================
Name: Collections-ul.807
Author: ul
Time: 22 October 2018, 9:27:33.883624 pm
UUID: c2efe147-56f8-43ff-a08b-f42390390418
Ancestors: Collections-eem.806
- introduced KeyedSet >> #put: which works like #add:, but replaces existing objects with the argument as Dictionary's #at:put: does
- unified the usage of primitiveStringHash by adding it to ByteSymbol and by using String's implementation as fallback, which works for ByteArrays too
=============== Diff against Collections-eem.806 ===============
Item was changed:
----- Method: ByteArray class>>hashBytes:startingWith: (in category 'byte based hash') -----
hashBytes: aByteArray startingWith: speciesHash
"Answer the hash of a byte-indexed collection, using speciesHash as the initial value.
See SmallInteger>>hashMultiply.
The primitive should be renamed at a suitable point in the future"
<primitive: 'primitiveStringHash' module: 'MiscPrimitivePlugin'>
+
+ ^String stringHash: aByteArray initialHash: speciesHash!
- | byteArraySize hash |
- <var: 'aByteArray' type: #'unsigned char *'>
- <var: 'speciesHash' type: #int>
-
- byteArraySize := aByteArray size.
- hash := speciesHash bitAnd: 16rFFFFFFF.
- 1 to: byteArraySize do:
- [:pos |
- hash := hash + (aByteArray basicAt: pos).
- "Inlined hashMultiply, written this way for translation to C."
- hash := hash * 1664525 bitAnd: 16r0FFFFFFF].
- ^hash!
Item was changed:
----- Method: ByteString class>>stringHash:initialHash: (in category 'primitives') -----
stringHash: aString initialHash: speciesHash
"Answer the hash of a byte-indexed string, using speciesHash as the initial value.
See SmallInteger>>hashMultiply."
<primitive: 'primitiveStringHash' module: 'MiscPrimitivePlugin'>
+
+ ^super stringHash: aString initialHash: speciesHash!
- | hash |
- hash := speciesHash bitAnd: 16rFFFFFFF.
- 1 to: aString size do:
- [:pos |
- hash := (hash + (aString basicAt: pos)) hashMultiply].
- ^hash!
Item was added:
+ ----- Method: ByteSymbol class>>stringHash:initialHash: (in category 'primitives') -----
+ stringHash: aString initialHash: speciesHash
+ "Answer the hash of a byte-indexed string, using speciesHash as the initial value.
+ See SmallInteger>>hashMultiply."
+ <primitive: 'primitiveStringHash' module: 'MiscPrimitivePlugin'>
+
+ ^super stringHash: aString initialHash: speciesHash!
Item was added:
+ ----- Method: KeyedSet>>put: (in category 'accessing') -----
+ put: newObject
+ "Include newObject as one of the receiver's elements even if there is already an element with the same key. Answer the replaced SetElement object or nil if no element existed with newObject's key. This method's behavior is similar to Dictionary >> #at:put:'s, hence the name."
+
+ | index |
+ index := self scanFor: (keyBlock value: newObject).
+ (array at: index)
+ ifNil: [
+ self atNewIndex: index put: newObject asSetElement.
+ ^nil ]
+ ifNotNil: [ :oldObject |
+ array at: index put: newObject asSetElement.
+ ^oldObject ]!
Chris Muller uploaded a new version of Chronology-Core to project The Trunk:
http://source.squeak.org/trunk/Chronology-Core-cmm.15.mcz
==================== Summary ====================
Name: Chronology-Core-cmm.15
Author: cmm
Time: 18 October 2018, 3:06:21.843002 pm
UUID: 388f1031-54aa-49b4-a070-726ae1d5f489
Ancestors: Chronology-Core-tcj.12
- Add Timespan>>#beCanonical so that dates created via "myDateAndTime asDate" can be made canonical.
- A fix and optimization of Timespan>>#=. Both elements being compared must have the same timezone (or same state of #noTimezone) in order to take advantage of the optimized #hasEqualTicks: comparison. Otherwise (if different timezones), a full comparison of their starts (via #=) is needed.
- There was a mention of this optimization put into the class comment. This level of detail may be a bit tedious for users to read at that level, so Brents original comment was restored.
=============== Diff against Chronology-Core-tcj.12 ===============
Item was changed:
Magnitude subclass: #Timespan
instanceVariableNames: 'start duration'
classVariableNames: ''
poolDictionaries: ''
category: 'Chronology-Core'!
+ !Timespan commentStamp: 'cmm 10/17/2018 22:00' prior: 0!
+ I represent a duration starting on a specific DateAndTime.!
- !Timespan commentStamp: 'bf 2/18/2016 14:43' prior: 0!
- I represent a duration starting on a specific DateAndTime.
-
- If my start has an offset identical to my #defaultOffset then comparisons ignore timezone offset.!
Item was changed:
----- Method: Timespan>>= (in category 'ansi protocol') -----
= comparand
+ ^ self class = comparand class
+ and: [(((self noTimezone and: [comparand noTimezone]) or: [self start offset = comparand start offset])
+ ifTrue: [ self start hasEqualTicks: comparand start ]
+ ifFalse: [ self start = comparand start ])
+ and: [ self duration = comparand duration ] ]
- ^ self class = comparand class
- and: [((self noTimezone or: [ comparand noTimezone ])
- ifTrue: [ self start hasEqualTicks: comparand start ]
- ifFalse: [ self start = comparand start ])
- and: [ self duration = comparand duration ] ]
.!
Item was added:
+ ----- Method: Timespan>>beCanonical (in category 'squeak protocol') -----
+ beCanonical
+ "Make the receiver a canonical Date (or Month or Year) instead of a timespan of my duration starting at a specific local time. Canonical are the most common use of Dates in applications."
+ self stripTimezone!
Item was added:
+ ----- Method: Timespan>>stripTimezone (in category 'squeak protocol') -----
+ stripTimezone
+ "Chronology preserves Timespans that are extracted from DateAndTime's, making Dates, Months and Years in Squeak able to represent a true Timespan of those durations starting at a specific local DateAndTime. In case a canonical version is needed, make the receiver independent of any Timezone by removing it."
+ start primOffset: self class defaultOffset!
Eliot Miranda uploaded a new version of Tools to project The Trunk:
http://source.squeak.org/trunk/Tools-eem.833.mcz
==================== Summary ====================
Name: Tools-eem.833
Author: eem
Time: 17 October 2018, 9:19:18.006868 am
UUID: df9e1979-bd01-4f51-9e12-40fd3b872978
Ancestors: Tools-cmm.831
Fix a bug with DebuggerMethodMap and full blocks (Sista V1 bytecode set). DebuggerMethodMap must be careful to use the right kind iof dictionry (Dictionary vs IdentityDictionary) for mapping startKeys to block starts and block starts to temps. startKeys may be values (startpc with embedded blocks) or objects (initialPC and block itself for full blocks). And blockExtentsToTempRefs must always be a Dictionary ince block extents are ranges.
[N.B. Tools-eem.832 contained a broken fix for this bug, sending the message homeMethod to aContext, instead of aContext home method]
=============== Diff against Tools-cmm.831 ===============
Item was changed:
----- Method: DebuggerMethodMapForClosureCompiledMethods>>privateTempRefsForContext:startKeysToBlockExtents: (in category 'private') -----
privateTempRefsForContext: aContext startKeysToBlockExtents: theContextsStartKeysToBlockExtents
"Answer the sequence of temps in scope in aContext in the natural order,
outermost arguments and temporaries first, innermost last. Each temp is
a pair of the temp's name followed by a reference. The reference can be
integer - index of temp in aContext
#( indirectionVectorIndex tempIndex ) - remote temp in indirectionVector at index in aContext
#( outer. temp reference ) - a temp reference in an outer context."
blockExtentsToTempRefs ifNil:
[blockExtentsToTempRefs := (aContext method holdsTempNames
ifTrue: [aContext method]
ifFalse: [methodNode]) blockExtentsToTempsMap.
+ blockExtentsToTempRefs
+ ifNil: ["an empty method. shouldn't be able to step into here but it
+ can happen in weird circumstances (i.e. with MethodWrapper)."
+ blockExtentsToTempRefs := Dictionary new.
+ blockExtentsToTempRefs
+ at: (theContextsStartKeysToBlockExtents at: aContext startKey)
+ put: {}]
+ ifNotNil:
+ [(blockExtentsToTempRefs isKindOf: IdentityDictionary) ifTrue:
+ [blockExtentsToTempRefs := Dictionary withAll: blockExtentsToTempRefs associations]].
+ startKeysToTempRefs := aContext home method newBlockStartMap].
- blockExtentsToTempRefs ifNil:
- ["an empty method. shouldn't be able to step into here but it
- can happen in weird circumstances (i.e. with MethodWrapper)."
- blockExtentsToTempRefs := Dictionary new.
- blockExtentsToTempRefs
- at: (theContextsStartKeysToBlockExtents at: aContext startKey)
- put: {}].
- startKeysToTempRefs := Dictionary new].
^startKeysToTempRefs
at: aContext startKey
ifAbsentPut:
[| localRefs |
localRefs := blockExtentsToTempRefs at: (theContextsStartKeysToBlockExtents at: aContext startKey) ifAbsent: [#()].
aContext outerContext
ifNil: [localRefs]
ifNotNil:
[:outer| | outerTemps |
"Present temps in the order outermost to innermost left-to-right, but replace
copied outermost temps with their innermost copies"
outerTemps := (self
privateTempRefsForContext: outer
startKeysToBlockExtents: theContextsStartKeysToBlockExtents) collect:
[:outerPair|
localRefs
detect: [:localPair| outerPair first = localPair first]
ifNone: [{ outerPair first. { #outer. outerPair last } }]].
outerTemps,
(localRefs reject: [:localPair| outerTemps anySatisfy: [:outerPair| localPair first = outerPair first]])]]!
Patrick Rein uploaded a new version of KernelTests to project The Trunk:
http://source.squeak.org/trunk/KernelTests-pre.350.mcz
==================== Summary ====================
Name: KernelTests-pre.350
Author: pre
Time: 17 October 2018, 4:51:14.818895 pm
UUID: ca4e331b-75b7-da42-bbc4-cc15a7476fc0
Ancestors: KernelTests-pre.349
Restores the float gradual undeflow test disabled for the 5.2 release
=============== Diff against KernelTests-pre.349 ===============
Item was removed:
- ----- Method: FloatTest>>expectedFailures (in category 'failures') -----
- expectedFailures
-
- ^#(testTimesTwoPowerGradualUnderflow)!
Item was changed:
----- Method: FloatTest>>testTimesTwoPowerGradualUnderflow (in category 'testing - arithmetic') -----
testTimesTwoPowerGradualUnderflow
"Here is a vicious case where timesTwoPower is inexact because it underflows.
And two consecutive inexact operations lead to a different result than a single one.
Typically expressed as multiple of Float fmin in base 2,
2r1011*Float fmin shifted by -3 with round to nearest, tie to even mode:
-> round(1.011) -> 1.0 = fmin
But if first shifted by -2 then by -1:
-> round(10.11) -> 11.0 = 3*fmin
-> round(1.1) -> 10.0 = 2*fmin
Or first shifted by -1 then by -2:
-> round(101.1) -> 110.0 = 6*fmin
-> round(1.1) -> 10.0 = 2*fmin
A naive implementation that split the shift uncarefully might fail to handle such case correctly."
| f |
f := 2r1011 asFloat.
"scan the whole range of possible exponents for this significand"
Float fmin exponent + f exponent to: Float fmax exponent - f exponent
do:
[:exp |
| g |
g := f timesTwoPower: exp.
+ self assert: (g timesTwoPower: Float fmin exponent - g exponent) = Float fmin].!
- self assert: (g timesTwoPower: Float fmin exponent - g exponent) = Float fmin].
-
- "Forces a failure for 5.2 release. The test result seems to depend on the word size of the VM --pre"
- self assert: false. !
Eliot Miranda uploaded a new version of Tools to project The Trunk:
http://source.squeak.org/trunk/Tools-eem.832.mcz
==================== Summary ====================
Name: Tools-eem.832
Author: eem
Time: 16 October 2018, 4:20:50.731928 pm
UUID: 9aa4b922-fe6a-41cb-8cba-974b14632177
Ancestors: Tools-cmm.831
Fix a bug with DebuggerMethodMap and full blocks (Sista V1 bytecode set). DebuggerMethodMap must be careful to use the right kind iof dictionry (Dictionary vs IdentityDictionary) for mapping startKeys to block starts and block starts to temps. startKeys may be values (startpc with embedded blocks) or objects (initialPC and block itself for full blocks). And blockExtentsToTempRefs must always be a Dictionary ince block extents are ranges.
=============== Diff against Tools-cmm.831 ===============
Item was changed:
----- Method: DebuggerMethodMapForClosureCompiledMethods>>privateTempRefsForContext:startKeysToBlockExtents: (in category 'private') -----
privateTempRefsForContext: aContext startKeysToBlockExtents: theContextsStartKeysToBlockExtents
"Answer the sequence of temps in scope in aContext in the natural order,
outermost arguments and temporaries first, innermost last. Each temp is
a pair of the temp's name followed by a reference. The reference can be
integer - index of temp in aContext
#( indirectionVectorIndex tempIndex ) - remote temp in indirectionVector at index in aContext
#( outer. temp reference ) - a temp reference in an outer context."
blockExtentsToTempRefs ifNil:
[blockExtentsToTempRefs := (aContext method holdsTempNames
ifTrue: [aContext method]
ifFalse: [methodNode]) blockExtentsToTempsMap.
+ blockExtentsToTempRefs
+ ifNil: ["an empty method. shouldn't be able to step into here but it
+ can happen in weird circumstances (i.e. with MethodWrapper)."
+ blockExtentsToTempRefs := Dictionary new.
+ blockExtentsToTempRefs
+ at: (theContextsStartKeysToBlockExtents at: aContext startKey)
+ put: {}]
+ ifNotNil:
+ [(blockExtentsToTempRefs isKindOf: IdentityDictionary) ifTrue:
+ [blockExtentsToTempRefs := Dictionary withAll: blockExtentsToTempRefs associations]].
+ startKeysToTempRefs := aContext homeMethod newBlockStartMap].
- blockExtentsToTempRefs ifNil:
- ["an empty method. shouldn't be able to step into here but it
- can happen in weird circumstances (i.e. with MethodWrapper)."
- blockExtentsToTempRefs := Dictionary new.
- blockExtentsToTempRefs
- at: (theContextsStartKeysToBlockExtents at: aContext startKey)
- put: {}].
- startKeysToTempRefs := Dictionary new].
^startKeysToTempRefs
at: aContext startKey
ifAbsentPut:
[| localRefs |
localRefs := blockExtentsToTempRefs at: (theContextsStartKeysToBlockExtents at: aContext startKey) ifAbsent: [#()].
aContext outerContext
ifNil: [localRefs]
ifNotNil:
[:outer| | outerTemps |
"Present temps in the order outermost to innermost left-to-right, but replace
copied outermost temps with their innermost copies"
outerTemps := (self
privateTempRefsForContext: outer
startKeysToBlockExtents: theContextsStartKeysToBlockExtents) collect:
[:outerPair|
localRefs
detect: [:localPair| outerPair first = localPair first]
ifNone: [{ outerPair first. { #outer. outerPair last } }]].
outerTemps,
(localRefs reject: [:localPair| outerTemps anySatisfy: [:outerPair| localPair first = outerPair first]])]]!
Eliot Miranda uploaded a new version of PreferenceBrowser to project The Trunk:
http://source.squeak.org/trunk/PreferenceBrowser-eem.84.mcz
==================== Summary ====================
Name: PreferenceBrowser-eem.84
Author: eem
Time: 16 October 2018, 9:25:54.339914 am
UUID: c3268d47-e23a-47a5-acb1-1c0b26ae3340
Ancestors: PreferenceBrowser-mt.83
Add acceptOnCR: to text preference fields. The Update URL cannot be set without this change (sort of a catch 22, this being a fix in trunk that sould be applied to the 5.2 release :-/).
=============== Diff against PreferenceBrowser-mt.83 ===============
Item was changed:
----- Method: PBTextPreferenceView>>textField (in category 'user interface') -----
textField
^(PluggableTextMorph
on: self
text: #preferenceValue
accept: #preferenceValue:)
+ acceptOnCR: true;
hideScrollBarsIndefinitely;
borderStyle: BorderStyle inset;
borderWidth: 1;
vResizing: #rigid;
hResizing: #spaceFill;
height: TextStyle defaultFont height + 6;
yourself.!
Patrick Rein uploaded a new version of Graphics to project The Trunk:
http://source.squeak.org/trunk/Graphics-pre.405.mcz
==================== Summary ====================
Name: Graphics-pre.405
Author: pre
Time: 16 October 2018, 5:07:10.382369 pm
UUID: 75b41799-4dd2-7a44-b98f-89612c4d7af9
Ancestors: Graphics-pre.404
Restores the 32bit black-transparent conversion. The corresponding test has been adapted and set to be an expected failure as the behavior should be tackled for 32bit at one point. The inconsistency results in major issues when working with forms resulting from loading pictures from external resources. An alternative approach would require changing all methods creating forms from external sources, although that would destroy color information.
=============== Diff against Graphics-pre.404 ===============
Item was changed:
----- Method: Color class>>colorFromPixelValue:depth: (in category 'instance creation') -----
colorFromPixelValue: p depth: d
"Convert a pixel value for the given display depth into a color."
"Details: For depths of 8 or less, the pixel value is simply looked up in a table. For greater depths, the color components are extracted and converted into a color."
| r g b alpha |
d = 8 ifTrue: [^ IndexedColors at: (p bitAnd: 16rFF) + 1].
d = 4 ifTrue: [^ IndexedColors at: (p bitAnd: 16r0F) + 1].
d = 2 ifTrue: [^ IndexedColors at: (p bitAnd: 16r03) + 1].
d = 1 ifTrue: [^ IndexedColors at: (p bitAnd: 16r01) + 1].
(d = 16) | (d = 15) ifTrue: [
"five bits per component"
r := (p bitShift: -10) bitAnd: 16r1F.
g := (p bitShift: -5) bitAnd: 16r1F.
b := p bitAnd: 16r1F.
(r = 0 and: [g = 0]) ifTrue: [
b = 0 ifTrue: [^Color transparent].
b = 1 ifTrue: [^Color black]].
^ Color r: r g: g b: b range: 31].
d = 32 ifTrue: [
"eight bits per component; 8 bits of alpha"
r := (p bitShift: -16) bitAnd: 16rFF.
g := (p bitShift: -8) bitAnd: 16rFF.
b := p bitAnd: 16rFF.
alpha := p bitShift: -24.
alpha = 0 ifTrue: [^Color transparent].
+ (r = 0 and: [g = 0 and: [b = 0]]) ifTrue: [^Color transparent].
alpha < 255
ifTrue: [^ (Color r: r g: g b: b range: 255) alpha: (alpha asFloat / 255.0)]
ifFalse: [^ (Color r: r g: g b: b range: 255)]].
d = 12 ifTrue: [
"four bits per component"
r := (p bitShift: -8) bitAnd: 16rF.
g := (p bitShift: -4) bitAnd: 16rF.
b := p bitAnd: 16rF.
^ Color r: r g: g b: b range: 15].
d = 9 ifTrue: [
"three bits per component"
r := (p bitShift: -6) bitAnd: 16r7.
g := (p bitShift: -3) bitAnd: 16r7.
b := p bitAnd: 16r7.
^ Color r: r g: g b: b range: 7].
self error: 'unknown pixel depth: ', d printString
!
Patrick Rein uploaded a new version of GraphicsTests to project The Trunk:
http://source.squeak.org/trunk/GraphicsTests-pre.49.mcz
==================== Summary ====================
Name: GraphicsTests-pre.49
Author: pre
Time: 16 October 2018, 5:03:04.269369 pm
UUID: 50c6b4da-e66d-714b-8611-cd2c9c4d59ed
Ancestors: GraphicsTests-pre.48
This partially reverts the previous commit as the current 32 bit pixel value behavior is integral to the graphics package. However, as the behavior is inconsistent with the general color model I would like to keep the test around as an expected failure and a reminder to tackle this consistently for 32 bit at one point.
=============== Diff against GraphicsTests-pre.48 ===============
Item was added:
+ ----- Method: ColorTest>>expectedFailures (in category 'failures') -----
+ expectedFailures
+
+ ^ #(testColorsFromPixelValue32BitBlack)!
Item was changed:
----- Method: ColorTest>>testColorsFromPixelValue32BitBlack (in category 'tests') -----
testColorsFromPixelValue32BitBlack
+ "This is a test which tests for the particular behavior of
- "This is a regression test which tests for deprecated behavior of
colorFromPixelValue:depth: which set 32bit rgb black to transparent."
self assert: Color black equals: (Color colorFromPixelValue: 16rFF000000 depth: 32)!