The Trunk: Kernel-nice.482.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

The Trunk: Kernel-nice.482.mcz

commits-2
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!