[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