The Inbox: Kernel-jar.1410.mcz

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

The Inbox: Kernel-jar.1410.mcz

commits-2
A new version of Kernel was added to project The Inbox:
http://source.squeak.org/inbox/Kernel-jar.1410.mcz

==================== Summary ====================

Name: Kernel-jar.1410
Author: jar
Time: 21 May 2021, 3:55:35.689716 pm
UUID: 8f28f106-e393-2a4f-beb1-c6e955c155fe
Ancestors: Kernel-nice.1402

Prevent VM crashes due to returning from #cannotReturn. The fix introduces a isRecursive variable to BlockCannotReturn to recognize an infinite loop.
#cannotReturn: loops to itself and notifies the user an infinite loop is starting. Returning from #cannotReturn: is no longer possible so that the user cannot crash the VM by accidentally pressing Proceed, by stepping over etc. #terminate can take advantage of this improved behavior.

This is a more sophisticated alternative to Kernel-jar.1404 for a discussion.

Examples like:

[^2] fork

or

[[self error] ensure: [^2]] fork

or even

a := [true ifTrue: [^ 1] yourself]
"and then do-it separately (c) Christoph:"
[a value] on: BlockCannotReturn do: [:ex | ex resume]

can no longer crash the image :)

=============== Diff against Kernel-nice.1402 ===============

Item was changed:
  Error subclass: #BlockCannotReturn
+ instanceVariableNames: 'result deadHome isRecursive'
- instanceVariableNames: 'result deadHome'
  classVariableNames: ''
  poolDictionaries: ''
  category: 'Kernel-Exceptions'!
 
  !BlockCannotReturn commentStamp: '<historical>' prior: 0!
  This class is private to the EHS implementation.  Its use allows for ensured execution to survive code such as:
 
  [self doThis.
  ^nil]
  ensure: [self doThat]
 
  Signaling or handling this exception is not recommended.!

Item was added:
+ ----- Method: BlockCannotReturn>>isRecursive (in category 'accessing') -----
+ isRecursive
+
+ ^isRecursive ifNil: [false]!

Item was added:
+ ----- Method: BlockCannotReturn>>isRecursive: (in category 'accessing') -----
+ isRecursive: aBoolean
+
+ ^isRecursive := aBoolean!

Item was changed:
  ----- Method: Context>>cannotReturn: (in category 'private-exceptions') -----
  cannotReturn: result
 
+ closureOrNil ifNotNil: [self cannotReturn: result to: self home sender.
+ [self cannotReturnRecursive: result to: self home sender.
+ self notify: '#cannotReturn: Invoking an infinite loop'.
+ true] whileTrue].
- closureOrNil ifNotNil: [^ self cannotReturn: result to: self home sender].
  Processor debugWithTitle: 'Computation has been terminated!!' translated full: false.!

Item was added:
+ ----- Method: Context>>cannotReturnRecursive:to: (in category 'private-exceptions') -----
+ cannotReturnRecursive: result to: homeContext
+ "The receiver tried to return result to homeContext that no longer exists.
+ This is a repeated invocation of the BlockCannotReturn error."
+
+ ^BlockCannotReturn new
+ result: result;
+ deadHome: homeContext;
+ isRecursive: true;
+ signal!