[squeak-dev] The Trunk: Kernel-eem.1426.mcz

mail at jaromir.net mail at jaromir.net
Sun Nov 28 09:14:58 UTC 2021


Thank you very much.

Now the #terminate in Kernel-jar.1426 can correctly process examples like this:

x1 := x2 := x3 := nil.
p:=[
		[
			[ ] ensure: [ "halfway through completion when suspended"
				[ ] ensure: [ "halfway through completion when suspended"
					Processor activeProcess suspend. 
					x1 := (2 / 0  "error!") > 0]. 
				x2 := true]
		] ensure: [ "not started yet when suspended"
			x3 := true]
] newProcess resume.
Processor yield.
p terminate

"This example should show both ZeroDivide and MessageNotUnderstood errors and still get out of the potential infinite loop. Process p gets suspended inside the inner ensure block and then it gets terminated. The unwind encounters the ZeroDivide and MNU errors and thanks to the protection against an infinite loop the unwind can continue.
Expected result:
{x1 . x2 . x3} = {Error: infinite recursion in doesNotUnderstand: . true . true}"

^[^ Jaromir
  --

Sent from Squeak Inbox Talk

On 2021-11-27T21:02:18+00:00, commits at source.squeak.org wrote:

> Eliot Miranda uploaded a new version of Kernel to project The Trunk:
> http://source.squeak.org/trunk/Kernel-eem.1426.mcz
> 
> ==================== Summary ====================
> 
> Name: Kernel-eem.1426
> Author: eem
> Time: 27 November 2021, 1:02:15.155642 pm
> UUID: 9ca49d5c-f988-4848-a26b-53b1f79d64a2
> Ancestors: Kernel-ct.1425
> 
> Implement protection against infinite recursion of doesNotUnderstand: within Object>>doesNotUnderstand:.
> 
> Note: this implementation puts the additional error handler within Object>>doesNotUnderstand: and sends error: to the receiver on detecting recursion.  An alternative might be to introduce a protected form of sentTo:, which would more naturally send error to the message.  e.g. either of
> 
> Message methods for sending
> sentWithProtectionAgainstRecursiveDoesNotUnderstandTo: receiver
> 	"Answer the result of sending this message to receiver, within a guard to
> 	 protect against infinite recursion."
> 
> 	^[self sentTo: receiver]
> 		on: MessageNotUnderstood
> 		do: [:ex|
> 			(receiver == ex receiver
> 			and: [self hasIdenticalContentsAs: ex message]) ifTrue:
> 				[receiver error: 'infinite recursion in doesNotUnderstand:'].
> 			ex pass]
> 
> or
> 
> sentWithProtectionAgainstRecursiveDoesNotUnderstandTo: receiver
> 	"Answer the result of sending this message to receiver, within a guard to
> 	 protect against infinite recursion."
> 
> 	^[self sentTo: receiver]
> 		on: MessageNotUnderstood
> 		do: [:ex|
> 			(receiver == ex receiver
> 			and: [self hasIdenticalContentsAs: ex message]) ifTrue:
> 				[self error: 'infinite recursion in doesNotUnderstand:'].
> 			ex pass]
> 
> I think this is too elaborate. Adding Message>>hasIdenticalContentsAs: is the key to making all variants concise enough.
> 
> =============== Diff against Kernel-ct.1425 ===============
> 
> Item was added:
> + ----- Method: Message>>hasIdenticalContentsAs: (in category 'comparing') -----
> + hasIdenticalContentsAs: aMessage
> + 	"Answer if the argument's selector and arguments are identically equal to those of the receiver.
> + 	 It is assumed that the argument aMessage is, in fact, a message."
> +        selector ~~ aMessage selector ifTrue:
> + 		[^false].
> + 	1 to: args size do:
> + 		[:i| (args at: i) ~~ (aMessage arguments at: i) ifTrue: [^false]].
> + 	^true!
> 
> Item was changed:
>   ----- Method: Object>>doesNotUnderstand: (in category 'error handling') -----
>   doesNotUnderstand: aMessage 
>   	 "Handle the fact that there was an attempt to send the given
>   	  message to the receiver but the receiver does not understand
>   	  this message (typically sent from the machine when a message
> + 	  is sent to the receiver and no method is defined for that selector).
> - 	 is sent to the receiver and no method is defined for that selector)."
>   
> + 	 Raise the MessageNotUnderstood signal.  If it is caught, answer
> + 	 the result supplied by the exception handler.  If it is not caught,
> + 	 answer the result of resending the message within a guard for
> + 	 infinite recursion. This allows, for example, the programmer to
> + 	 implement the method and continue."
> + 
>   	"Testing: (3 activeProcess)"
>   
>   	| exception resumeValue |
>   	(exception := MessageNotUnderstood new)
>   		message: aMessage;
>   		receiver: self.
>   	resumeValue := exception signal.
> + 	^exception reachedDefaultHandler "i.e. exception was not caught..."
> + 		ifTrue:
> + 			[[aMessage sentTo: self]
> + 				on: MessageNotUnderstood
> + 				do: [:ex|
> + 					(self == ex receiver
> + 					and: [aMessage hasIdenticalContentsAs: ex message]) ifFalse:
> + 						[ex pass].
> + 					self error: 'infinite recursion in doesNotUnderstand:']]
> - 	^exception reachedDefaultHandler
> - 		ifTrue: [aMessage sentTo: self]
>   		ifFalse: [resumeValue]!
> 
> 


More information about the Squeak-dev mailing list