[squeak-dev] The Inbox: Kernel-jar.1399.mcz

Jaromir Matas m at jaromir.net
Tue May 4 18:06:07 UTC 2021


Hi Jakob,


Jakob Reschke wrote
> Oh well, I am not even sure whether sending both resume and then
> return to the Exception is even well-defined behavior according to the
> standard.

I'd say yes - e.g. in case of #outer.


Jakob Reschke wrote
> Since return is specified referring to the "active exception handler",
> it should return from the on: do: handler 1 in your example. So I
> would in fact expect to get '12' in both cases. Handler 2 is no longer
> active after the resume.

Great point! So now we have another question: what does it mean to re-signal
an exception that has already been signaled? (This is NOT the same as
#resignalAs)

ANSI doesn't seem to be against this kind of re-signaling an existing
exception. Here's what it says about #resume:

"
Message: resume 

If the current exception action was activated as the result of sending the
message #outer to the 
receiver, return a resumption value as the value of the #outer message. 
If the receiver is a resumable exception a resumption value is returned as
the value of the message 
that signaled the receiver.
"

So you're right we should expect '12' as a result rather than just '2'. Your
interpretation seems to be consistent with the specification of #outer. I
checked other implementations but each of them provides different answers :D
(except Pharo). I used this modified test example:

| x |
x:=''.
[
	[1/0. x:=x,'B'] on: ZeroDivide do: [:ex | ex signal. x:=x,'A'. ex return].
"handler 1"
	x:=x,'1'
] on: ZeroDivide do: [:ex | ex resume]. "handler 2"
x:=x,'2'.
x  

Squeak/Pharo: answer inconsistently 'A2' or 'A12' depending on whether the
return is explicit or implicit.
VW: answers 'A12' - as a proper #outer (funny - their #outer answers 'A2'
which is wrong)
VA: answers 'A2' - totally flawed
Cuis raises an exception; re-signaling is simply prohibited :)

One more argument and then I'll leave it :) If you try the following example
where #return is replaced by #resume, Squeak (and Pharo and VA) will fail
completely raising a cannot return error:

| x |
x:=''.
[
	[1/0. x:=x,'B'] on: ZeroDivide do: [:ex | ex signal. x:=x,'A'. ex resume].
"handler 1"
	x:=x,'1'
] on: ZeroDivide do: [:ex | ex resume]. "handler 2"
x:=x,'2'.
x

VW however answers  'AB12' which is also consistent with the #outer
specification. I'd say it should be safe to implement this semantics, i.e.
#outer semantics for re-signaling, even if it's not explicitly mentioned in
ANSI.

I've even found a real use of re-signaling an exception in the trunk - see
DiskProxy>>comeFullyUpOnReload:

So my final suggestion is to define the behavior for re-signaling as
equivalent to #outer, to become consistent and avoid apparently incorrect
answers in above mentioned examples (I'm aware this is 99.9% academic
indeed):

Exception>>signal
	"Ask ContextHandlers in the sender chain to handle this signal.  The
default is to execute and return my defaultAction."

----->	signalContext ifNotNil: [^self outer]. "re-signalling an already
signalled exception is equivalent to sending #outer"
	signalContext := thisContext contextTag.
	^(thisContext nextHandlerContextForSignal: self) handleSignal: self


best,





-----
^[^ Jaromir
--
Sent from: http://forum.world.st/Squeak-Dev-f45488.html


More information about the Squeak-dev mailing list