Nicolas Cellier uploaded a new version of KernelTests to project The Trunk:
http://source.squeak.org/trunk/KernelTests-nice.368.mcz
==================== Summary ====================
Name: KernelTests-nice.368
Author: nice
Time: 21 August 2019, 2:46:11.211524 am
UUID: ecd4016f-706e-46c8-bf63-eef66063726d
Ancestors: KernelTests-mt.367
Illustrate issue with inexact mixed SmallInteger/Float comparison in Spur64
See https://github.com/OpenSmalltalk/opensmalltalk-vm/issues/417
The issue only happen when code is jitted, so it might be necessary to tun the tests several times before seeing the failure.
=============== Diff against KernelTests-mt.367 ===============
Item was added:
+ ----- Method: SmallIntegerTest>>testCompareWithBoxedFloat (in category 'testing - Class Methods') -----
+ testCompareWithBoxedFloat
+ "In 64 bits, naive asFloat conversion should not be used"
+
+ | bf sf si |
+ Smalltalk wordSize = 8 ifFalse: [^self].
+ si := 1<<(Float precision + 2)+1.
+ sf := si asFloat.
+ (bf := BoxedFloat64 new: 2) basicAt: 1 put: (sf basicAt: 1);basicAt: 2 put: (sf basicAt: 2).
+
+ self deny: si = bf.
+ self deny: bf = si.!
Item was added:
+ ----- Method: SmallIntegerTest>>testCompareWithSmallFloat (in category 'testing - Class Methods') -----
+ testCompareWithSmallFloat
+ "In 64 bits, naive asFloat conversion should not be used"
+
+ | sf si |
+ Smalltalk wordSize = 8 ifFalse: [^self].
+ si := 1<<(Float precision + 2)+1.
+ sf := si asFloat.
+ self deny: sf = si.
+ self deny: si = sf.!
Marcel Taeumel uploaded a new version of TrueType to project The Trunk:
http://source.squeak.org/trunk/TrueType-mt.52.mcz
==================== Summary ====================
Name: TrueType-mt.52
Author: mt
Time: 20 August 2019, 3:35:06.793246 pm
UUID: 6fb23ce7-780d-784a-96ab-4b108da4c7da
Ancestors: TrueType-pre.51
Fixes TTCFont-to-TextStyle detection, which makes EtoysTheme look better.
Note that Squeak's management of fonts and text styles and text-font changes and text-font references is kind of ugly. :-)
=============== Diff against TrueType-pre.51 ===============
Item was changed:
----- Method: TTCFont>>textStyle (in category 'accessing') -----
textStyle
+ | styles |
+ styles := TextStyle actualTextStyles.
+
+ ^ (styles includesKey: self name)
+ ifTrue: [styles at: self name]
+ ifFalse: [
+ "Fallback: Maybe this font is in a text style with another name?"
+ styles
+ detect: [:aStyle | aStyle fontArray anySatisfy: [:font | font name = self name]]
+ ifNone: [nil]]!
- ^ TextStyle actualTextStyles
- detect: [:aStyle | (aStyle fontArray collect: [:s | s name]) includes: self name]
- ifNone: [nil]!
Nicolas Cellier uploaded a new version of Kernel to project The Inbox:
http://source.squeak.org/inbox/Kernel-nice.1260.mcz
==================== Summary ====================
Name: Kernel-nice.1260
Author: nice
Time: 20 August 2019, 12:47:47.233148 pm
UUID: 71e9900d-adf5-194d-be4b-28fbe395a937
Ancestors: Kernel-nice.1259
Fast-up the SmallInteger/Float comparisons
This is not necessary in 32 bits images, because SmallInteger asFloat is exact, so comparison can be performed exactly by the primitive and is already very fast.
But in 64bits images, SmallInteger asFloat may be inexact. Thus the primitive may fail, reverting to slower adaptToFloat:andCompare:
Though, we can perform the comparison very simply for SmallInteger:
if anInteger asFloat == aFloat
then we are not sure that anInteger asFloat did not introduce a rounding error.
However, in this case, we know that aFloat has no fraction part, and that it can be converted back to Integer exactly (without fear of overflow).
So we just have to perform the comparison the other way around,
anInteger op: aFloat truncated
if anInteger asFloat != aFloat, then we are safe, the rounding error cannot modify the result of operation, so we simply return the result of
anInteger asFloat op: aFloat
I put this in the inbox so as to show and demonstrate the hack, but IMO the right place would be in the primitive (and JIT) because the scheme is simple enough.
=============== Diff against Kernel-nice.1259 ===============
Item was changed:
----- Method: SmallInteger>>< (in category 'comparing') -----
< aNumber
"Primitive. Compare the receiver with the argument and answer with
true if the receiver is less than the argument. Otherwise answer false.
Fail if the argument is not a SmallInteger. Essential. No Lookup. See
Object documentation whatIsAPrimitive."
<primitive: 3>
+ aNumber isFloat ifTrue: [| asFloat |
+ ^(asFloat := self asFloat) = aNumber
+ ifTrue: [self < aNumber truncated]
+ ifFalse: [asFloat < aNumber] ].
^super < aNumber!
Item was changed:
----- Method: SmallInteger>><= (in category 'comparing') -----
<= aNumber
"Primitive. Compare the receiver with the argument and answer true if
the receiver is less than or equal to the argument. Otherwise answer
false. Fail if the argument is not a SmallInteger. Optional. No Lookup.
See Object documentation whatIsAPrimitive. "
<primitive: 5>
+ aNumber isFloat ifTrue: [| asFloat |
+ ^(asFloat := self asFloat) = aNumber
+ ifTrue: [self <= aNumber truncated]
+ ifFalse: [asFloat <= aNumber] ].
^super <= aNumber!
Item was changed:
----- Method: SmallInteger>>= (in category 'comparing') -----
= aNumber
"Primitive. Compare the receiver with the argument and answer true if
the receiver is equal to the argument. Otherwise answer false. Fail if the
argument is not a SmallInteger. Essential. No Lookup. See Object
documentation whatIsAPrimitive. "
<primitive: 7>
+ aNumber isFloat ifTrue: [ ^self asFloat = aNumber and: [self = aNumber truncated] ].
^super = aNumber!
Item was changed:
----- Method: SmallInteger>>> (in category 'comparing') -----
> aNumber
"Primitive. Compare the receiver with the argument and answer true if
the receiver is greater than the argument. Otherwise answer false. Fail if
the argument is not a SmallInteger. Essential. No Lookup. See Object
documentation whatIsAPrimitive."
<primitive: 4>
+ aNumber isFloat ifTrue: [| asFloat |
+ ^(asFloat := self asFloat) = aNumber
+ ifTrue: [self > aNumber truncated]
+ ifFalse: [asFloat > aNumber] ].
^super > aNumber!
Item was changed:
----- Method: SmallInteger>>>= (in category 'comparing') -----
>= aNumber
"Primitive. Compare the receiver with the argument and answer true if
the receiver is greater than or equal to the argument. Otherwise answer
false. Fail if the argument is not a SmallInteger. Optional. No Lookup.
See Object documentation whatIsAPrimitive."
<primitive: 6>
+ aNumber isFloat ifTrue: [| asFloat |
+ ^(asFloat := self asFloat) = aNumber
+ ifTrue: [self >= aNumber truncated]
+ ifFalse: [asFloat >= aNumber] ].
^super >= aNumber!
Item was added:
+ ----- Method: SmallInteger>>adaptToFloat:andCompare: (in category 'converting') -----
+ adaptToFloat: rcvr andCompare: selector
+ "If I am involved in comparison with a Float, care to perform an exact comparison of values."
+
+ | asFloat |
+ "First try cheap asFloat conversion.
+ There is no comparison ambiguity when self does not round to same Float value"
+ asFloat := self asFloat.
+ (rcvr ~= asFloat or: [self isAnExactFloat]) ifTrue: [^rcvr perform: selector with: asFloat].
+ "rcvr and self are not equal because self is not an exact Float, but self round to same Float value.
+ It is necessary to convert the Float to an exact representation so as to perform the compariosn without rounding error.
+ We know that the Float has no fractionPart because it is equal to self asFloat, and self asFloat has no fractionPart.
+ Thus we can use truncated which is faster than asTrueFraction."
+ selector == #= ifTrue: [^false].
+ selector == #~= ifTrue: [^true].
+ ^ rcvr truncated perform: selector with: self!
Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-nice.1259.mcz
==================== Summary ====================
Name: Kernel-nice.1259
Author: nice
Time: 20 August 2019, 10:58:50.044539 am
UUID: fcd050cd-0337-8f4c-a1c3-b04d0eef3b0a
Ancestors: Kernel-nice.1258
Accelerate mixed Integer/Fraction comparison.
Implementation note: we can assume that Fraction are properly reduced, failing to do so is programmer responsibility.
If someone cheat by using numerator:denominator: instead of / to avoid a costly gcd:, then someone will care to not get caught.
=============== Diff against Kernel-nice.1258 ===============
Item was changed:
----- Method: Fraction>>= (in category 'comparing') -----
= aNumber
aNumber isNumber ifFalse: [^ false].
+ aNumber isInteger ifTrue: ["If properly reduced, self cannot be an Integer" ^ false].
aNumber isFraction
+ ifTrue: ["Assume that both Fraction are reduced"
+ ^ numerator = aNumber numerator and:
+ [denominator = aNumber denominator]].
- ifTrue: [numerator = 0 ifTrue: [^ aNumber numerator = 0].
- ^ (numerator * aNumber denominator) =
- (aNumber numerator * denominator)
- "Note: used to just compare num and denom,
- but this fails for improper fractions"].
^ aNumber adaptToFraction: self andCompare: #=!
Item was added:
+ ----- Method: Fraction>>adaptToInteger:andCompare: (in category 'converting') -----
+ adaptToInteger: rcvr andCompare: selector
+ "Assuming that self is properly reduced, it cannot be an Integer"
+ selector == #= ifTrue: [^false].
+ selector == #~= ifTrue: [^true].
+ "Inequality: avoid division with this transformation:
+ rcvr op: (num/den)
+ rcvr - (num/den) op: 0
+ rcvr*den op: num"
+ ^rcvr * denominator perform: selector with: numerator!
Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-nice.1258.mcz
==================== Summary ====================
Name: Kernel-nice.1258
Author: nice
Time: 20 August 2019, 10:02:55.377539 am
UUID: a05ee2dc-141d-f54b-8c76-9d4dc6b3c7ee
Ancestors: Kernel-mt.1257
Minor tweak: if log2 is exact, then can log: 4, 8, 16, 32 too
=============== Diff against Kernel-mt.1257 ===============
Item was changed:
----- Method: Fraction>>log2 (in category 'mathematical functions') -----
log2
+ "This function is defined because super log2 might overflow."
- "This function is defined because super log might overflow."
| res |
self <= 0 ifTrue: [DomainError signal: 'log2 is only defined for x > 0'].
"Test self < 1 before converting to float in order to avoid precision loss due to gradual underflow."
numerator < denominator ifTrue: [^self reciprocal log2 negated].
res := super log2.
res isFinite ifTrue: [^res].
^numerator log2 - denominator log2!
Item was changed:
----- Method: Number>>log: (in category 'mathematical functions') -----
log: aNumber
"Answer the log base aNumber of the receiver."
aNumber = 2 ifTrue: [^self log2].
+ aNumber isPowerOfTwo ifTrue: [^self log2 / aNumber log2].
^self ln / aNumber ln!
Marcel Taeumel uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-ct.1086.mcz
==================== Summary ====================
Name: System-ct.1086
Author: ct
Time: 15 August 2019, 5:44:16.577735 pm
UUID: f5823ddc-52ec-1646-9c42-c7976406b360
Ancestors: System-mt.1085
Fix a typo
=============== Diff against System-mt.1085 ===============
Item was changed:
----- Method: Project>>tellAFriend: (in category 'SuperSwiki') -----
tellAFriend: emailAddressOrNil
"
+ Project current tellAFriend
- Project current tellAFrien
"
| urlForLoading |
(urlForLoading := self urlForLoading)
ifNil: [urlForLoading := self url
"fallback for dtp servers"].
urlForLoading isEmptyOrNil
ifTrue: [^ self inform: 'Since this project has not been saved yet,
I cannot tell someone where it is.' translated].
FancyMailComposition new
celeste: nil
to: (emailAddressOrNil
ifNil: ['RECIPIENT.GOESHERE'])
subject: 'New/Updated Squeak project'
initialText: 'This is a link to the Squeak project ' , self name , ': ' , String crlf
theLinkToInclude: urlForLoading;
open!
Marcel Taeumel uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-mt.1087.mcz
==================== Summary ====================
Name: System-mt.1087
Author: mt
Time: 19 August 2019, 6:10:49.749665 pm
UUID: 634a8b56-cd36-874e-9b69-a839b0e30bf0
Ancestors: System-mt.1086, System-ct.1086
Merge.
=============== Diff against System-mt.1086 ===============
Item was changed:
----- Method: Project>>tellAFriend: (in category 'SuperSwiki') -----
tellAFriend: emailAddressOrNil
"
+ Project current tellAFriend
- Project current tellAFrien
"
| urlForLoading |
(urlForLoading := self urlForLoading)
ifNil: [urlForLoading := self url
"fallback for dtp servers"].
urlForLoading isEmptyOrNil
ifTrue: [^ self inform: 'Since this project has not been saved yet,
I cannot tell someone where it is.' translated].
FancyMailComposition new
celeste: nil
to: (emailAddressOrNil
ifNil: ['RECIPIENT.GOESHERE'])
subject: 'New/Updated Squeak project'
initialText: 'This is a link to the Squeak project ' , self name , ': ' , String crlf
theLinkToInclude: urlForLoading;
open!
Marcel Taeumel uploaded a new version of 46Deprecated to project The Trunk:
http://source.squeak.org/trunk/46Deprecated-ct.9.mcz
==================== Summary ====================
Name: 46Deprecated-ct.9
Author: ct
Time: 15 August 2019, 5:17:14.602735 pm
UUID: 54830347-b1b2-fd45-9e7a-3ac3e26db472
Ancestors: 46Deprecated-ct.8
Mark further methods as deprecated
=============== Diff against 46Deprecated-ct.8 ===============
Item was changed:
----- Method: CodeHolder>>abbreviatedWordingFor: (in category '*46Deprecated') -----
abbreviatedWordingFor: aButtonSelector
"Answer the abbreviated form of wording, from a static table. Answer nil if there is no entry -- in which case the long form will be used on the corresponding browser button."
+ self deprecated.
#(
(browseMethodFull 'browse')
(browseSendersOfMessages 'senders')
(browseMessages 'impl')
(browseVersions 'vers')
(methodHierarchy 'inher')
(classHierarchy 'hier')
(browseVariableReferences 'refs')
(offerMenu 'menu')) do:
[:pair | pair first == aButtonSelector ifTrue: [^ pair second]].
^ nil!
Item was changed:
----- Method: CodeHolder>>showingDiffsString (in category '*46Deprecated') -----
showingDiffsString
"Answer a string representing whether I'm showing diffs. Not sent any more but retained so that prexisting buttons that sent this will not raise errors."
+ self deprecated.
^ (self showingRegularDiffs
ifTrue:
['<yes>']
ifFalse:
['<no>']), 'showDiffs'!
Item was changed:
----- Method: CodeHolder>>toggleDiff (in category '*46Deprecated') -----
toggleDiff
"Retained for backward compatibility with existing buttons in existing images"
+ self deprecated: 'Use ', #toggleDiffing.
self toggleDiffing!
Item was changed:
----- Method: MCMcmUpdater class>>useLatestPackagesFrom: (in category '*46Deprecated') -----
useLatestPackagesFrom: repo
"For overriding on a per repository basis.
Implementation is now on the instance side, but is also maintained here because
an older image may be trying to update to current and may still be evaluating a block
in its class:>>updateFromRepositoriesMCMcmUpdater that expects thiis method to
be present. Delegate to the current default instance."
+ self deprecated: 'Call this message on self default'.
^ self default useLatestPackagesFrom: repo
!
Item was changed:
----- Method: MorphicProject>>exportSegmentWithCatagories:classes:fileName:directory: (in category '*46Deprecated') -----
exportSegmentWithCatagories: catList classes: classList fileName: aFileName directory: aDirectory
"Store my project out on the disk as an *exported* ImageSegment. All outPointers will be in a form that can be resolved in the target image. Name it <project name>.extSeg. What do we do about subProjects, especially if they are out as local image segments? Force them to come in?
Player classes are included automatically."
| is str ans revertSeg roots holder |
+ self deprecated: 'Use ', #exportSegmentWithChangeSet:fileName:directory:, ' instead'.
- self flag: #toRemove.
- self halt. "unused"
"world == World ifTrue: [^ false]."
"self inform: 'Can''t send the current world out'."
world ifNil: [^ false]. world presenter ifNil: [^ false].
ScrapBook default emptyScrapBook.
world currentHand pasteBuffer: nil. "don't write the paste buffer."
world currentHand mouseOverHandler initialize. "forget about any references here"
"Display checkCurrentHandForObjectToPaste."
Command initialize.
world clearCommandHistory.
world fullReleaseCachedState; releaseViewers.
world cleanseStepList.
world localFlapTabs size = world flapTabs size ifFalse: [
self error: 'Still holding onto Global flaps'].
world releaseSqueakPages.
holder := Project allProjects. "force them in to outPointers, where DiskProxys are made"
"Just export me, not my previous version"
revertSeg := self parameterAt: #revertToMe.
self projectParameters removeKey: #revertToMe ifAbsent: [].
roots := OrderedCollection new.
roots add: self; add: world; add: transcript; add: changeSet; add: thumbnail.
roots add: world activeHand; addAll: classList; addAll: (classList collect: [:cls | cls class]).
roots := roots reject: [ :x | x isNil]. "early saves may not have active hand or thumbnail"
catList do: [:sysCat |
(SystemOrganization listAtCategoryNamed: sysCat asSymbol) do: [:symb |
roots add: (Smalltalk at: symb); add: (Smalltalk at: symb) class]].
is := ImageSegment copySmartRootsExport: roots asArray.
"old way was (is := ImageSegment new copyFromRootsForExport: roots asArray)"
is state = #tooBig ifTrue: [^ false].
str := ''.
"considered legal to save a project that has never been entered"
(is outPointers includes: world) ifTrue: [
str := str, '\Project''s own world is not in the segment.' withCRs].
str isEmpty ifFalse: [
ans := (UIManager default
chooseFrom: #('Do not write file' 'Write file anyway' 'Debug')
title: str).
ans = 1 ifTrue: [
revertSeg ifNotNil: [self projectParameterAt: #revertToMe put: revertSeg].
^ false].
ans = 3 ifTrue: [self halt: 'Segment not written']].
is writeForExportWithSources: aFileName inDirectory: aDirectory.
revertSeg ifNotNil: [self projectParameterAt: #revertToMe put: revertSeg].
holder.
world flapTabs do: [:ft |
(ft respondsTo: #unhibernate) ifTrue: [ft unhibernate]].
is arrayOfRoots do: [:obj |
obj isScriptEditorMorph ifTrue: [obj unhibernate]].
^ true
!
Item was removed:
- ----- Method: ScrollPane>>hInitScrollBarTEMPORARY (in category '*46Deprecated') -----
- hInitScrollBarTEMPORARY
- "This is called lazily before the hScrollBar is accessed in a couple of places. It is provided to transition old ScrollPanes lying around that do not have an hScrollBar. Once it has been in the image for awhile, and all ScrollPanes have an hScrollBar, this method and it's references can be removed. "
-
- "Temporary method for filein of changeset"
- hScrollBar ifNil:
- [hScrollBar := ScrollBar new model: self slotName: 'hScrollBar'.
- hScrollBar borderWidth: 1; borderColor: Color black.
- self
- resizeScrollBars;
- setScrollDeltas;
- hideOrShowScrollBars].
- !
Item was changed:
----- Method: ScrollPane>>isAScrollbarShowing (in category '*46Deprecated') -----
isAScrollbarShowing
"Return true if a either retractable scroll bar is currently showing"
+ self deprecated: 'mt: Use #isAnyScrollbarShowing'.
- self flag: #deprectaed. "mt: Use #isAnyScrollbarShowing"
retractableScrollBar ifFalse:[^true].
^self hIsScrollbarShowing or: [self vIsScrollbarShowing]
!