Eliot Miranda uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-eem.1155.mcz
==================== Summary ====================
Name: Kernel-eem.1155
Author: eem
Time: 27 February 2018, 12:52:46.556955 pm
UUID: 0041924e-8077-4c30-8456-45ce511eb376
Ancestors: Kernel-eem.1154
Improve class comments for CompiledCode, CompiledMethod, and CompiledBlock.
=============== Diff against Kernel-eem.1154 ===============
Item was changed:
CompiledCode variableByteSubclass: #CompiledBlock
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'Kernel-Methods'!
+ !CompiledBlock commentStamp: 'eem 2/27/2018 12:27' prior: 0!
+ CompiledBlock instances are blocks suitable for interpretation by the virtual machine. They are a specialization of CompiledCode. This requires both bytecode set and compiler support. The V3 bytecode (EncoderForV3PlusClosures) does not provide support for CompiledBlock. The SistaV1 set does (EncoderForSistaV1).
- !CompiledBlock commentStamp: 'eem 3/22/2017 12:10' prior: 0!
- CompiledBlock instances are blocks suitable for interpretation by the virtual machine. They are a specialization oif CompiledCode. This requires both bytecode set and compiler support. The V3 bytecode (EncoderForV3PlusClosures) does not provide support for CompiledBlock. The SistaV1 set does (EncoderForSistaV1).
The last literal in a CompiledBlock is reserved for a reference to its enclosing CompiledBlock or CompiledMethod. Super sends in CompiledBlocks must use the directed super send bytecode.
By convention the penultimate literal of a method is either its selector or an instance of AdditionalMethodState. AdditionalMethodState may be used to add instance variables to a method, albeit ones held in the method's AdditionalMethodState. Subclasses of CompiledBlock that want to add state should subclass AdditionalMethodState to add the state they want, and implement methodPropertiesClass on the class side of the CompiledBlock subclass to answer the specialized subclass of AdditionalMethodState. Enterprising programmers are encouraged to try and implement this support automatically through suitable modifications to the compiler and class builder.!
Item was changed:
ByteArray variableByteSubclass: #CompiledCode
instanceVariableNames: ''
classVariableNames: 'LargeFrame PreferredBytecodeSetEncoderClass PrimaryBytecodeSetEncoderClass SecondaryBytecodeSetEncoderClass SmallFrame'
poolDictionaries: ''
category: 'Kernel-Methods'!
+ !CompiledCode commentStamp: 'eem 2/27/2018 12:23' prior: 0!
+ CompiledCode instances are methods suitable for execution by the virtual machine. Instances of CompiledCode and its subclasses are the only objects in the system that have both indexable pointer fields and indexable 8-bit integer fields. The pointer fields are used for literals and metadata, and the bytes are used for bytecodes and a variety of encoded informaton such as source code, source code position, etc. The first part of a CompiledCode object is pointers, the second part is bytes. CompiledCode inherits from ByteArray to avoid duplicating some of ByteArray's methods, not because a CompiledCode is-a ByteArray.
- !CompiledCode commentStamp: 'eem 3/23/2017 14:33' prior: 0!
- CompiledCode instances are methods suitable for execution by the virtual machine. Instances of CompiledCode and its subclasses are the only objects in the system that have both indexable pointer fields and indexable 8-bit integer fields. The first part of a CompiledCode object is pointers, the second part is bytes. CompiledCode inherits from ByteArray to avoid duplicating some of ByteArray's methods, not because a CompiledCode is-a ByteArray.
Instance variables: *indexed* (no named inst vars)
Class variables:
SmallFrame - the number of stack slots in a small frame Context
LargeFrame - the number of stack slots in a large frame Context
PrimaryBytecodeSetEncoderClass - the encoder class that defines the primary instruction set
SecondaryBytecodeSetEncoderClass - the encoder class that defines the secondary instruction set
The current format of a CompiledCode object is as follows:
header (4 or 8 bytes, SmallInteger)
literals (4 or 8 bytes each, Object, see "The last literal..." below)
bytecodes (variable, bytes)
trailer (variable, bytes)
The header is a SmallInteger (which in the 32-bit system has 31 bits, and in the 64-bit system, 61 bits) in the following format:
(index 0) 15 bits: number of literals (#numLiterals)
(index 15) 1 bit: jit without counters - reserved for methods that have been optimized by Sista
(index 16) 1 bit: has primitive
(index 17) 1 bit: whether a large frame size is needed (#frameSize => either SmallFrame or LargeFrame)
(index 18) 6 bits: number of temporary variables (#numTemps)
(index 24) 4 bits: number of arguments to the method (#numArgs)
(index 28) 2 bits: reserved for an access modifier (00-unused, 01-private, 10-protected, 11-public), although accessors for bit 29 exist (see #flag).
sign bit: 1 bit: selects the instruction set, >= 0 Primary, < 0 Secondary (#signFlag)
If the method has a primitive then the first bytecode of the method must be a callPrimitive: bytecode that encodes the primitive index. This bytecode can encode a primitive index from 0 to 65535.
The trailer is an encoding of an instance of CompiledMethodTrailer. It is typically used to encode the index into the source files array of the method's source, but may be used to encode other values, e.g. tempNames, source as a string, etc. See the class CompiledMethodTrailer.
While there are disadvantages to this "flat" representation (it is impossible to add named instance variables to CompiledCode or its subclasses, but it is possible indirectly; see AdditionalMethodState) it is effective for interpreters. It means that both bytecodes and literals can be fetched directly from a single method object, and that only one object, the method, must be saved and restored on activation and return. A more natural representation, in which there are searate instance variables for the bytecode, and (conveniently) the literals, requires either much more work on activation and return setting up references to the literals and bytecodes, or slower access to bytecodes and literals, indirecting on each access.
The last literal of a CompiledCode object is reserved for special use by the kernel and/or the virtual machine. In CompiledMethod instances it must either be the methodClassAssociation, used to implement super sends, or nil, if the method is anonymous. In CompiledBlock it is to be used for a reference to the enclosing method or block object.
+ By convention, the penultimate literal is reserved for special use by the kernel. In CompiledMethod instances it must either be the method selector, or an instance of AdditionalMethodState which holds the selector and any pragmas or properties in the method. In CompiledBlock it is reserved for use for an AdditionalMethodState.
- By convention, the penultimate literal is reserved for special use by the kernel. CompiledMethod instances it must either be the method selector, or an instance of AdditionalMethodState which holds the selector and any pragmas or properties in the method. In CompiledBlock it is reserved for use for an AdditionalMethodState.
Note that super sends in CompiledBlock instances do not use a methodClass association, but expect a directed supersend bytecode, in which the method class (the subclass of the class in which to start the lookup) is a literal. Logically when we switch to a bytecode set that supports the directed super send bytecode, and discard the old super send bytecodes, we can use the last literal to store the selector or the enclosing method/block or an AdditionalMethodState, and the AdditionalMethodState can hold the selector and/or the enclosing method/block.!
Item was changed:
CompiledCode variableByteSubclass: #CompiledMethod
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'Kernel-Methods'!
+ !CompiledMethod commentStamp: 'eem 2/27/2018 12:48' prior: 0!
+ CompiledMethod instances are methods suitable for interpretation by the virtual machine. They are a specialization of CompiledCode. They represent methods, and may also, depending on the bytecode set, include nested blocks. Bytecode sets that support non-nested blocks use CompiledBlock instances to implement nested block methods, that are separate from their enclosing method. Bytecode sets that do not support non-nested blocks require the literals and bytecodes for a block to occur within the literals and bytecodes of a single CompiledMethod. For example, the inject:into: method in the EncoderForV3PlusClosures bytecode set is as follows
- !CompiledMethod commentStamp: 'eem 3/22/2017 13:17' prior: 0!
- CompiledMethod instances are methods suitable for interpretation by the virtual machine. They are a specialization of CompiledCode. They represent methods, and may also, depending on the bytecode set, include nested blocks. Bytecode sets that support non-nested blocks with use CompiledBlock instances to implement nested block methods, that are separate from their enclosing method. This requires compiler support.
+ Collection>>#inject:into:
+ header ((primitive: 0) (numArgs: 2) (numTemps: 3) (numLiterals: 3) (frameSize: 16) (bytecodeSet: V3PlusClosures))
+ literal1 #value:value:
+ literal2 #inject:into:
+ literal3 #Collection=>Collection
+ 33 <8A 01> push: (Array new: 1)
+ 35 <6A> popIntoTemp: 2
+ 36 <10> pushTemp: 0
+ 37 <8E 00 02> popIntoTemp: 0 inVectorAt: 2
+ 40 <70> self
+ 41 <11> pushTemp: 1
+ 42 <12> pushTemp: 2
+ 43 <8F 21 00 0A> closureNumCopied: 2 numArgs: 1 bytes 47 to 56
+ 47 <11> pushTemp: 1
+ 48 <8C 00 02> pushTemp: 0 inVectorAt: 2
+ 51 <10> pushTemp: 0
+ 52 <F0> send: value:value:
+ 53 <8D 00 02> storeIntoTemp: 0 inVectorAt: 2
+ 56 <7D> blockReturn
+ 57 <CB> send: do:
+ 58 <87> pop
+ 59 <8C 00 02> pushTemp: 0 inVectorAt: 2
+ 62 <7C> returnTop
+
+ whereas using the encoderForSistaV1 bytecode set it is
+
+ Collection>>#inject:into:
+ header ((primitive: 0) (numArgs: 2) (numTemps: 3) (numLiterals: 3) (frameSize: 16) (bytecodeSet: #SistaV1))
+ literal1 ([] in Collection>>#inject:into: "a CompiledBlock(3755867)")
+ literal2 #inject:into:
+ literal3 #Collection=>Collection
+ 33 <E7 01> push: (Array new: 1)
+ 35 <D2> popIntoTemp: 2
+ 36 <40> pushTemp: 0
+ 37 <FD 00 02> popIntoTemp: 0 inVectorAt: 2
+ 40 <4C> self
+ 41 <41> pushTemp: 1
+ 42 <42> pushTemp: 2
+ 43 <F9 00 02> closureNumCopied: 2 numArgs: 1
+ 46 <7B> send: do:
+ 47 <D8> pop
+ 48 <FB 00 02> pushTemp: 0 inVectorAt: 2
+ 51 <5C> returnTop
+
+ [] in Collection>>#inject:into: "a CompiledBlock(3755867)"
+ header ((block #full) (numArgs: 1) (numTemps: 3) (numLiterals: 3) (frameSize: 16) (bytecodeSet: #SistaV1))
+ literal1 #value:value:
+ literal2 nil
+ literal3 (Collection>>#inject:into: "a CompiledMethod(736427)")
+ 33 <41> pushTemp: 1
+ 34 <FB 00 02> pushTemp: 0 inVectorAt: 2
+ 37 <40> pushTemp: 0
+ 38 <A0> send: value:value:
+ 39 <FC 00 02> storeIntoTemp: 0 inVectorAt: 2
+ 42 <5E> blockReturn
+
The last literal in a CompiledMethod must be its methodClassAssociation, a binding whose value is the class the method is installed in. The methodClassAssociation is used to implement super sends. If a method contains no super send then its methodClassAssociation may be nil (as would be the case for example of methods providing a pool of inst var accessors).
By convention the penultimate literal of a method is either its selector or an instance of AdditionalMethodState. AdditionalMethodState holds the method's selector and any pragmas and properties of the method. AdditionalMethodState may also be used to add instance variables to a method, albeit ones held in the method's AdditionalMethodState. Subclasses of CompiledMethod that want to add state should subclass AdditionalMethodState to add the state they want, and implement methodPropertiesClass on the class side of the CompiledMethod subclass to answer the specialized subclass of AdditionalMethodState. Enterprising programmers are encouraged to try and implement this support automatically through suitable modifications to the compiler and class builder.!
Patrick Rein uploaded a new version of Network to project The Trunk:
http://source.squeak.org/trunk/Network-pre.219.mcz
==================== Summary ====================
Name: Network-pre.219
Author: pre
Time: 23 February 2018, 8:01:29.067294 pm
UUID: 730b43c6-9824-ce4e-ba60-0c5639be4f65
Ancestors: Network-ul.218
Fixes a regression causing long lines in mail bodys to be broken into shorter lines. This should only have been done for header values and even for them it only is a recommendation not a requirement. Further, the current implementation was not used in the mail sending process before the restructuring of the mail message model.
=============== Diff against Network-ul.218 ===============
Item was changed:
----- Method: MailMessage>>asSendableText (in category 'printing/formatting') -----
asSendableText
+ ^ self text!
- | serializedMail |
- serializedMail := self text.
- ^ self wrapLinesOf: serializedMail!
Item was removed:
- ----- Method: MailMessage>>wrapLinesOf: (in category 'printing/formatting') -----
- wrapLinesOf: aString
-
- "break lines in the given string into shorter lines"
- | result atAttachment width pastHeader |
- width := 72.
- result := WriteStream on: (String new: aString size * 50 // 49).
- pastHeader := false.
- atAttachment := false.
- aString asString
- linesDo:
- [:line | | end start |
- line isEmpty ifTrue: [pastHeader := true].
- pastHeader
- ifTrue:
- ["(line beginsWith: '--==')
- ifTrue: [atAttachment := true]."
- atAttachment
- ifTrue:
- ["at or after an attachment line; no more
- wrapping for the rest of the message"
- result nextPutAll: line.
- result cr]
- ifFalse: [(line beginsWith: '>')
- ifTrue:
- ["it's quoted text; don't wrap it"
- result nextPutAll: line.
- result cr]
- ifFalse:
- ["regular old line. Wrap it to multiple
- lines "
- start := 1.
- "output one shorter line each time
- through this loop"
- [start + width <= line size]
- whileTrue:
- ["find the end of the line"
- end := start + width - 1.
- [end >= start and: [(line at: end + 1) isSeparator not]]
- whileTrue: [end := end - 1].
- end < start ifTrue: ["a word spans the entire
- width!! "
- end := start + width - 1].
- "copy the line to the output"
- result nextPutAll: (line copyFrom: start to: end).
- result cr.
- "get ready for next iteration"
- start := end + 1.
- (line at: start) isSeparator ifTrue: [start := start + 1]].
- "write out the final part of the line"
- result nextPutAll: (line copyFrom: start to: line size).
- result cr]]]
- ifFalse:
- [result nextPutAll: line.
- result cr]].
-
- ^ result contents!
Patrick Rein uploaded a new version of NetworkTests to project The Trunk:
http://source.squeak.org/trunk/NetworkTests-pre.55.mcz
==================== Summary ====================
Name: NetworkTests-pre.55
Author: pre
Time: 23 February 2018, 7:58:19.082294 pm
UUID: 550f8ecc-049d-fc46-afce-219720fbe0d0
Ancestors: NetworkTests-pre.54
Adds a test which checks whether a long line in the body is correctly transmitted.
=============== Diff against NetworkTests-pre.54 ===============
Item was added:
+ ----- Method: MailMessageTest>>testSendableVersionHasCorrectLineBreaks (in category 'testing') -----
+ testSendableVersionHasCorrectLineBreaks
+
+ | newMail longContent |
+ "To create a string which is too long to very old recommendations
+ of the mail message format, which is about 70 characters."
+ longContent := ((1 to: 80) do: [:i | i asString]) joinSeparatedBy: ''.
+ newMail := self fixtureMail.
+ newMail body: ((MIMEDocument
+ contentType: MIMEDocument contentTypePlainText
+ content: longContent)
+ charset: 'UTF-8';
+ yourself).
+ newMail := MailMessage from: newMail asSendableText.
+ self assert: (newMail bodyTextFormatted asString includesSubstring: longContent)!
Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1399.mcz
==================== Summary ====================
Name: Morphic-mt.1399
Author: mt
Time: 21 February 2018, 8:30:20.139447 am
UUID: 255b694a-28f2-4d77-94e0-6eccbc80f8d3
Ancestors: Morphic-mt.1398
Fixes the use of #shadowPoint: such as via the halo control menu to configure drop shadows of morphs.
=============== Diff against Morphic-mt.1398 ===============
Item was changed:
----- Method: Morph>>shadowPoint: (in category 'drop shadows') -----
shadowPoint: newPoint
+ "Can be reset in #addDropShadow."
+
+ | delta |
+ delta := newPoint - self center.
+ self shadowOffset: (self useSoftDropShadow
+ ifTrue: [(10@8 corner: 10@12) outsetBy: delta]
+ ifFalse: [delta]).
+
+ !
- self changed.
- self shadowOffset: newPoint - self center // 5.
- fullBounds ifNotNil:[fullBounds := self privateFullBounds].
- self changed.!
Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1398.mcz
==================== Summary ====================
Name: Morphic-mt.1398
Author: mt
Time: 21 February 2018, 8:16:34.893099 am
UUID: be36db5d-0096-234f-ac7c-7ae5ad6644fa
Ancestors: Morphic-mt.1397
Adds more documentation about system-window concepts: activate/passivate, look focused/unfocused, and being the "key" window on screen.
=============== Diff against Morphic-mt.1397 ===============
Item was changed:
----- Method: SystemWindow>>activate (in category 'focus') -----
activate
+ "An active window delegate user input events as usual to its contents such as buttons or lists. There is a preference to ensure that all windows stay active regardless of being focused or not. Also take a look at #passivate, #lookFocused, and #beKeyWindow."
+
- "Bring the receiver to the top. If I am modal, bring along my modal owning window and my model child as well."
-
self isActive ifTrue: [self lookFocused. ^ self].
self topRendererOrSelf owner ifNil: [^ self "avoid spurious activate when drop in trash"].
self isActive: true.
"Special handling for expanded windows."
self isCollapsed ifFalse: [
model modelWakeUpIn: self.
self positionSubmorphs].
self submorphsDo: [:each | each unlock].
self lookFocused.!
Item was changed:
----- Method: SystemWindow>>beKeyWindow (in category 'top window') -----
beKeyWindow
+ "Let me be the most important window on the screen. I am at the top and I can have a shadow to get more attention by the user. I am the window that is responsible for window keyboard shortcuts. Also see #isKeyWindow, #activate, and #lookFocused."
- "Let me be the most important window on the screen. I am at the top and I can have a shadow to get more attention by the user. I am the window that is responsible for window keyboard shortcuts."
| oldKeyWindow |
self isKeyWindow ifTrue: [^ self].
oldKeyWindow := TopWindow.
TopWindow := self.
self
unlockWindowDecorations; "here, because all windows might be active anyway"
activate; "if not already active, activate now"
comeToFront. "key windows are on top"
"Change appearance to get noticed."
self hasDropShadow: Preferences menuAppearance3d.
(self valueOfProperty: #borderWidthWhenActive)
ifNotNil: [:bw | self acquireBorderWidth: bw].
oldKeyWindow ifNotNil: [:wnd |
wnd passivateIfNeeded.
"Change appearance to not look prettier than the new key window."
wnd hasDropShadow: false.
(wnd valueOfProperty: #borderWidthWhenInactive)
ifNotNil: [:bw | wnd acquireBorderWidth: bw]].
"Synchronize focus look with position of current hand because any call could have made this window the new key window."
self updateFocusLookAtHand.!
Item was changed:
----- Method: SystemWindow>>isKeyWindow (in category 'top window') -----
isKeyWindow
+ "The key window is the window with the user's main attention. It usually has a shadow or other visual hints to separate it from other windows. Usually, the key window is at the top of the screen. On large screens, however, many windows may appear at the top. Also see #beKeyWindow, #activate, and #lookFocused."
- "The key window is the window with the user's main attention. It usually has a shadow or other visual hints to separate it from other windows. Usually, the key window is at the top of the screen. On large screens, however, many windows may appear at the top."
^ self == self class keyWindow!
Item was changed:
----- Method: SystemWindow>>lookFocused (in category 'focus') -----
lookFocused
+ "Some elements of windows change visually depending on the user input focus. This is property is orthogonal to being active or passive. Active windows can either look focused or unfocused. Passive windows will always look unfocused. Also see #lookUnfocused, #activate, #passivate, and #beKeyWindow."
- "Optimize performance."
self isLookingFocused ifTrue: [^ self].
self isLookingFocused: true.
label ifNotNil: [ label color: (self userInterfaceTheme focusedLabelColor ifNil: [Color black]) ].
(self isKeyWindow or: [self class windowTitleActiveOnFirstClick])
ifTrue: [self undimWindowButtons].
self paneColorToUse in: [ : col |
self
setStripeColorsFrom: col ;
adoptPaneColor: col].!
Item was changed:
----- Method: SystemWindow>>lookUnfocused (in category 'focus') -----
lookUnfocused
+ "See #lookFocused, #activate, and #passivate."
- "Optimize performance."
self isLookingFocused ifFalse: [^ self].
self isLookingFocused: false.
label ifNotNil: [ label color: (self userInterfaceTheme unfocusedLabelColor ifNil: [Color darkGray]) ].
self dimWindowButtons.
self paneColorToUseWhenNotActive in: [ : col |
self
setStripeColorsFrom: col ;
adoptPaneColor: col ]!
Item was changed:
----- Method: SystemWindow>>passivate (in category 'focus') -----
passivate
+ "A passive window's contents do not handle user input events until being activated, for example, by a single extra mouse click. There is a preference to configure whether windows can be passive at all. Also see #activate and #lookUnfocused."
- "Reconfigure my focus according to preferences."
self isActive ifFalse: [^ self].
self isActive: false.
self isCollapsed ifFalse: [model modelSleep].
self submorphsDo: [:each | each lock].
self activeHand keyboardFocus ifNotNil: [:morph |
morph containingWindow == self
ifTrue: [self activeHand releaseKeyboardFocus]].
self lookUnfocused.!
David T. Lewis uploaded a new version of MorphicExtras to project The Trunk:
http://source.squeak.org/trunk/MorphicExtras-dtl.222.mcz
==================== Summary ====================
Name: MorphicExtras-dtl.222
Author: dtl
Time: 19 February 2018, 9:58:54.987645 pm
UUID: 7d4e14dd-aad7-4cf8-8f68-41e1381c4727
Ancestors: MorphicExtras-tpr.221
FlapTab>>positionObject: anObject atEdgeOf: container expects container to be a Morph, not a Rectangle. Make it so when sending from FlapTab>>positionObject.
Fixes flap opening in a Worldlet, such as the flap tabs in "EventRecordingSpace open".
=============== Diff against MorphicExtras-tpr.221 ===============
Item was changed:
----- Method: FlapTab>>positionObject: (in category 'positioning') -----
positionObject: anObject
"anObject could be myself or my referent"
+ | pum clearArea |
- "Could consider container := referent pasteUpMorph, to allow flaps on things other than the world, but for the moment, let's skip it!!"
-
- "19 sept 2000 - going for all paste ups"
-
- | pum |
pum := self pasteUpMorph ifNil: [^ self].
+ clearArea := Morph newBounds: pum clearArea.
^self
positionObject: anObject
+ atEdgeOf: clearArea!
- atEdgeOf: pum clearArea!