Skip to content

Commit

Permalink
Exception retry.
Browse files Browse the repository at this point in the history
  • Loading branch information
rmacnak committed May 4, 2024
1 parent b6f7884 commit 181f577
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 4 deletions.
3 changes: 3 additions & 0 deletions newspeak/Kernel.ns
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ private internalKernel = k.
public ArgumentError = (
^internalKernel ArgumentError
)
public CannotReturn = (
^internalKernel CannotReturn
)
public Ephemeron = (
^internalKernel Ephemeron
)
Expand Down
24 changes: 21 additions & 3 deletions newspeak/KernelForPrimordialSoup.ns
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,28 @@ public receiver: value = (
(* :pragma: primitive: 175 *)
panic.
)
public restart = (
| unwindActivation unwindBlock |
self method primitive = 161 ifFalse: [panic].
self isDead ifTrue: [^self cannotReturn: nil].
self bci: 1.
self size: 3.
self tempAt: 3 put: false.
unwindActivation:: currentActivation.
[unwindActivation:: unwindActivation findNextUnwindContextUpTo: self.
nil = unwindActivation]
whileFalse:
[nil = (unwindActivation tempAt: 2) ifTrue: [
unwindActivation tempAt: 2 put: true.
unwindBlock:: unwindActivation tempAt: 1.
currentActivation terminateTo: unwindActivation.
unwindBlock value]].
currentActivation terminateTo: self.
^self pop
)
public resume: value = (
| unwindActivation unwindBlock |
self isDead ifTrue: [self cannotReturn: value to: self].
self isDead ifTrue: [^self cannotReturn: value].
unwindActivation:: currentActivation.
[unwindActivation:: unwindActivation findNextUnwindContextUpTo: self.
nil = unwindActivation]
Expand Down Expand Up @@ -560,7 +579,7 @@ public withAll: bytes <Collection[Integer] | ByteArray | String> ^<ByteArray> =
)
)
(* Signalled when attempting to return to (or through) a nil sender or a sender that has already returned. *)
class CannotReturn result: r = Exception (
public class CannotReturn result: r = Exception (
|
public result = r.
|) (
Expand Down Expand Up @@ -900,7 +919,6 @@ public resume: resumptionValue = (
^savedSignalActivation return: resumptionValue
)
public retry = (
panic. (* Needs test *)
handlerActivation restart.
panic.
)
Expand Down
57 changes: 56 additions & 1 deletion newspeak/KernelTests.ns
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
class KernelTests usingPlatform: p minitest: m = (|
private TestContext = m TestContext.
private Message = p kernel Message.
private CannotReturn = p kernel CannotReturn.
private MessageNotUnderstood = p kernel MessageNotUnderstood.
private Exception = p kernel Exception.
private Proxy = p kernel Proxy.
Expand Down Expand Up @@ -1146,7 +1147,7 @@ nonInlineRepeat = (
]) repeat.
)
public testCannotReturn = (
should: [cannotReturn value] signal: Exception.
should: [cannotReturn value] signal: CannotReturn.
)
public testCull = (
assert: ([42] cull: 7) equals: 42.
Expand Down Expand Up @@ -1266,6 +1267,9 @@ protected doesNotUnderstand: message = (
) : (
)
public class ExceptionTests = TestContext () (
cannotReturn = (
[Exception new signal] on: Exception do: [:ex | ^ex].
)
nonLocalReturnCrossingExceptionHandler = (
[^'correct']
on: Exception
Expand Down Expand Up @@ -1429,6 +1433,52 @@ public testExceptionResume = (
assert: signalResult equals: 63.
assert: result equals: 42.
)
public testExceptionResumeCannotReturn = (
| exception |
exception:: cannotReturn.
should: [exception resume: 42] signal: CannotReturn.
)
public testExceptionRetry = (
|
beforeSignal ::= 0.
afterSignal ::= 0.
handler ::= 0.
afterRetry ::= 0.
exceptionSignaled
exceptionHandled
signalResult
result
|

result::
[beforeSignal:: beforeSignal + 1.
handler = 0 ifTrue:
[exceptionSignaled:: Exception new.
signalResult:: exceptionSignaled signal.
afterSignal:: afterSignal + 1].
42]
on: Exception
do:
[:ex |
handler:: handler + 1.
exceptionHandled:: ex.
ex retry.
afterRetry:: afterReturn + 1.
84].

assert: beforeSignal equals: 2.
assert: afterSignal equals: 0.
assert: handler equals: 1.
assert: afterRetry equals: 0.
assert: exceptionSignaled equals: exceptionHandled.
assert: signalResult equals: nil.
assert: result equals: 42.
)
public testExceptionRetryCannotReturn = (
| exception |
exception:: cannotReturn.
should: [exception retry] signal: CannotReturn.
)
public testExceptionReturn = (
|
beforeSignal ::= false.
Expand Down Expand Up @@ -1464,6 +1514,11 @@ public testExceptionReturn = (
assert: signalResult equals: nil.
assert: result equals: 63.
)
public testExceptionReturnCannotReturn = (
| exception |
exception:: cannotReturn.
should: [exception return: 42] signal: CannotReturn.
)
public testExceptionSignalInHandler = (
|
outerBefore ::= false.
Expand Down

0 comments on commit 181f577

Please sign in to comment.