[squeak-dev] The Trunk: Kernel-nice.482.mcz
commits at source.squeak.org
commits at source.squeak.org
Sun Aug 22 19:13:01 UTC 2010
Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-nice.482.mcz
==================== Summary ====================
Name: Kernel-nice.482
Author: nice
Time: 22 August 2010, 9:12:15.834 pm
UUID: 0cda1747-d4ad-4e81-b7f9-a085602e5344
Ancestors: Kernel-nice.481
Fix WeakMessageSends Part 1.
Thanks to Juan, see http://bugs.squeak.org/view.php?id=7352
I could nor resist and added my own simplifications
There will be a second part for this fix.
=============== Diff against Kernel-nice.481 ===============
Item was added:
+ ----- Method: WeakMessageSend>>withEnsuredReceiverAndArgumentsDo:otherwise: (in category 'private') -----
+ withEnsuredReceiverAndArgumentsDo: aBlock otherwise: altBlock
+ "Grab real references to receiver and arguments. If they still exist, evaluate aBlock."
+
+ "Return if my receiver has gone away"
+ | r a |
+ r := self receiver.
+ r ifNil: [ ^altBlock value ].
+
+
+ "Make sure that my arguments haven't gone away"
+ a := Array withAll: arguments.
+ a with: shouldBeNil do: [ :arg :flag |
+ arg ifNil: [ flag ifFalse: [ ^altBlock value ]]
+ ].
+
+ ^aBlock value: r value: a!
Item was changed:
----- Method: WeakMessageSend>>valueWithArguments: (in category 'evaluating') -----
valueWithArguments: anArray
+ ^ self valueWithArguments: anArray otherwise: []!
- self ensureReceiverAndArguments ifFalse: [ ^nil ].
- ^ self receiver
- perform: selector
- withArguments: (self collectArguments: anArray)!
Item was added:
+ ----- Method: MessageSend>>valueOtherwise: (in category 'evaluating') -----
+ valueOtherwise: aBlock
+ "Send the message and answer the return value"
+
+ ^self value!
Item was added:
+ ----- Method: WeakMessageSend>>withEnsuredReceiverDo:otherwise: (in category 'private') -----
+ withEnsuredReceiverDo: aBlock otherwise: altBlock
+ "Grab a real reference to receive. If still there, evaluate aBlock.
+ Use altBlock if my receiver has gone away."
+ ^self receiver
+ ifNil: [ altBlock value ]
+ ifNotNil: [:r | aBlock value: r ]!
Item was changed:
----- Method: WeakActionSequence>>valueWithArguments: (in category 'evaluating') -----
valueWithArguments: anArray
-
"Return the last result"
+ ^self inject: nil into: [ :previousAnswer :each |
+ each valueWithArguments: anArray otherwise: [ previousAnswer ]]!
- | answer |
- self do:
- [:each |
- each isValid ifTrue: [answer := each valueWithArguments: anArray]].
- ^answer!
Item was added:
+ ----- Method: WeakMessageSend>>valueOtherwise: (in category 'evaluating') -----
+ valueOtherwise: aBlock
+ ^ arguments
+ ifNil: [
+ self withEnsuredReceiverDo: [ :r | r perform: selector ] otherwise: [ aBlock value ]]
+ ifNotNil: [
+ self
+ withEnsuredReceiverAndArgumentsDo: [ :r :a |
+ r
+ perform: selector
+ withArguments: a ]
+ otherwise: [ aBlock value ]]!
Item was added:
+ ----- Method: MessageSend>>isReceiverOrAnyArgumentGarbage (in category 'private') -----
+ isReceiverOrAnyArgumentGarbage
+ ^false!
Item was changed:
----- Method: WeakMessageSend>>asMinimalRepresentation (in category 'converting') -----
asMinimalRepresentation
+ ^self isReceiverOrAnyArgumentGarbage
+ ifTrue: [ nil ]
+ ifFalse: [ self ]!
- self isReceiverOrAnyArgumentGarbage
- ifTrue: [^nil]
- ifFalse:[^self].!
Item was added:
+ ----- Method: MessageSend>>valueWithArguments:otherwise: (in category 'evaluating') -----
+ valueWithArguments: anArray otherwise: aBlock
+
+ ^ self valueWithArguments: anArray!
Item was changed:
----- Method: Object>>actionForEvent:ifAbsent: (in category 'events-accessing') -----
actionForEvent: anEventSelector
ifAbsent: anExceptionBlock
"Answer the action to be evaluated when <anEventSelector> has been triggered."
| actions |
actions := self actionMap
at: anEventSelector asSymbol
ifAbsent: [nil].
+ ^actions ifNil: [anExceptionBlock value]!
- actions ifNil: [^anExceptionBlock value].
- ^ actions asMinimalRepresentation!
Item was changed:
----- Method: Object>>actionForEvent: (in category 'events-accessing') -----
actionForEvent: anEventSelector
"Answer the action to be evaluated when <anEventSelector> has been triggered."
+ ^self actionMap
- | actions |
- actions := self actionMap
at: anEventSelector asSymbol
+ ifAbsent: [nil]!
- ifAbsent: [nil].
- actions ifNil: [^nil].
- ^ actions asMinimalRepresentation!
Item was changed:
----- Method: WeakActionSequence>>asMinimalRepresentation (in category 'converting') -----
asMinimalRepresentation
| valid |
+ valid := self reject: [:e | e isReceiverOrAnyArgumentGarbage ].
- valid := self select: [:e | e isValid ].
valid size = 0
+ ifTrue: [ ^nil ].
- ifTrue: [^nil].
valid size = 1
+ ifTrue: [ ^valid first ].
- ifTrue: [^valid first].
^valid!
Item was changed:
----- Method: Object>>setActionSequence:forEvent: (in category 'events-accessing') -----
setActionSequence: actionSequence
forEvent: anEventSelector
+ | action |
+ "This is a good time to compact the action sequence of old, garbage collected stuff."
+ action := actionSequence asMinimalRepresentation.
+ action
+ ifNil: [ self removeActionsForEvent: anEventSelector]
+ ifNotNil: [
+ self updateableActionMap
+ at: anEventSelector asSymbol
+ put: action]!
- | action |
- action := actionSequence asMinimalRepresentation.
- action == nil
- ifTrue:
- [self removeActionsForEvent: anEventSelector]
- ifFalse:
- [self updateableActionMap
- at: anEventSelector asSymbol
- put: action]!
Item was changed:
----- Method: WeakMessageSend>>value (in category 'evaluating') -----
value
+ ^self valueOtherwise: []!
- ^ arguments isNil
- ifTrue: [self ensureReceiver
- ifTrue: [self receiver perform: selector] ifFalse: []]
- ifFalse: [self ensureReceiverAndArguments
- ifTrue: [self receiver
- perform: selector
- withArguments: (Array withAll: arguments)] ifFalse: []]!
Item was added:
+ ----- Method: WeakMessageSend>>valueWithArguments:otherwise: (in category 'evaluating') -----
+ valueWithArguments: anArray otherwise: aBlock
+ | argsToUse |
+
+ "Safe to use, because they are built before ensureing receiver and args..."
+ argsToUse := self collectArguments: anArray.
+ ^ self
+ withEnsuredReceiverAndArgumentsDo: [ :r :a |
+ r
+ perform: selector
+ withArguments: argsToUse ]
+ otherwise: [ aBlock value ]!
Item was changed:
----- Method: WeakActionSequence>>value (in category 'evaluating') -----
value
+ "Answer the result of evaluating the elements of the receiver.
- "Answer the result of evaluating the elements of the receiver.
Actually, return just the last result."
+ ^self inject: nil into: [ :previousAnswer :each |
+ each valueOtherwise: [ previousAnswer ]].!
- | answer |
- self do:
- [:each | each isValid ifTrue: [answer := each value]].
- ^answer!
More information about the Squeak-dev
mailing list
|