Christoph Thiede uploaded a new version of KernelTests to project The Trunk:
http://source.squeak.org/trunk/KernelTests-jar.448.mcz
==================== Summary ====================
Name: KernelTests-jar.448
Author: jar
Time: 30 December 2023, 6:28:02.589852 pm
UUID: 058e235e-90d4-d648-9442-b468fee2bb2e
Ancestors: KernelTests-jar.447
Test if #return:from: correctly handles returns to dead or nil contexts.
=============== Diff against KernelTests-jar.447 ===============
Item was added:
+ ----- Method: ContextTest>>testBlockCannotReturn (in category 'tests') -----
+ testBlockCannotReturn
+ "Test if #return:from: correctly handles returns to dead or nil contexts."
+
+ | p |
+ p := [ thisContext pc: nil ] newProcess.
+ p runUntil: [:ctx | ctx method selector = #pc: and: [ctx sender isDead]].
+
+ "assert p stoped at the last instruction, i.e. a return, of #pc:
+ and is about to return to a dead context"
+ self assert: p suspendedContext method selector equals: #pc:.
+ self assert: p suspendedContext sender isDead.
+ self assert: p suspendedContext willReturn.
+ self assert: p suspendedContext atEnd.
+
+ p step. "step into a return to a dead sender"
+
+ self assert: p suspendedContext method selector = #cannotReturn:!
Christoph Thiede uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-jar.1539.mcz
==================== Summary ====================
Name: Kernel-jar.1539
Author: jar
Time: 28 November 2023, 1:07:51.739521 am
UUID: 7dfe0ed8-86ec-f54a-9b12-11c337e0e8e5
Ancestors: Kernel-jar.1538
fix a bug in runUntilErrorOrReturnFrom: that prevents removing the guard contexts if they are placed below the bottom context (or above a dead context). The bug is a part of a series of bugs described in detail in the post from 27 Nov 2023 at:
https://lists.squeakfoundation.org/archives/list/squeak-dev@lists.squeakfou…
This changeset requires and complements its ancestor Kernel-jar.1538
=============== Diff against Kernel-jar.1538 ===============
Item was changed:
----- Method: Context>>runUntilErrorOrReturnFrom: (in category 'controlling') -----
runUntilErrorOrReturnFrom: aSender
"ASSUMES aSender is a sender of self. Execute self's stack until aSender returns or an unhandled exception is raised. Return a pair containing the new top context and a possibly nil exception. The exception is not nil if it was raised before aSender returned and it was not handled. The exception is returned rather than openning the debugger, giving the caller the choice of how to handle it."
"Self is run by jumping directly to it (the active process abandons thisContext and executes self). However, before jumping to self we insert an ensure block under aSender that jumps back to thisContext when evaluated. We also insert an exception handler under aSender that jumps back to thisContext when an unhandled exception is raised. In either case, the inserted ensure and exception handler are removed once control jumps back to thisContext."
| error ctxt here topContext |
here := thisContext.
"Insert ensure and exception handler contexts under aSender"
error := nil.
ctxt := aSender insertSender: (Context
contextOn: UnhandledError do: [:ex |
error ifNil: [
error := ex exception.
topContext := thisContext.
ex resumeUnchecked: here jump]
ifNotNil: [ex pass]
]).
ctxt := ctxt insertSender: (Context
contextEnsure: [error ifNil: [
topContext := thisContext.
here jump]
]).
self jump. "Control jumps to self"
"Control resumes here once above ensure block or exception handler is executed"
^ error ifNil: [
"No error was raised, remove ensure context by stepping until popped"
+ [ctxt isDead or: [topContext isNil]] whileFalse: [topContext := topContext stepToCalleeOrNil].
- [ctxt isDead or: [topContext isNil]] whileFalse: [topContext := topContext stepToCallee].
{topContext. nil}
] ifNotNil: [
"Error was raised, remove inserted above contexts then return signaler context"
aSender terminateTo: ctxt sender. "remove above ensure and handler contexts"
{topContext. error}
]!
Item was added:
+ ----- Method: Context>>stepToCalleeOrNil (in category 'private') -----
+ stepToCalleeOrNil
+ "Step to callee or sender; step to return and answer nil in case sender cannot be returned to."
+
+ | ctxt |
+ ctxt := self.
+ [(ctxt willReturn and: [ctxt sender isNil or: [ctxt sender isDead]]) not and: [(ctxt := ctxt step) == self]] whileTrue.
+ ctxt == self ifTrue: [^nil].
+ ^ctxt!
Christoph Thiede uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-jar.1538.mcz
==================== Summary ====================
Name: Kernel-jar.1538
Author: jar
Time: 27 November 2023, 12:00:15.196233 am
UUID: d37b82ee-c73e-ed4b-be1c-478b708c5d9c
Ancestors: Kernel-jar.1537
fix stepOver bug when debugging e.g.
[[self halt. ^ 1] on: BlockCannotReturn do: [:ex | ex resume] ] fork
(step over halt and then stepover ^1 you get a nonsensical error as a result of decoding nil as an instruction)
the root cause is in the #return:from: method: it only checks whether aSender is dead but ignores the possibility that aSender sender may be nil or dead
This changeset requires its ancestor Kernel-jar.1537
(Please remove Kernel-jar.1535 from the Inbox)
=============== Diff against Kernel-jar.1537 ===============
Item was changed:
Error subclass: #BlockCannotReturn
+ instanceVariableNames: 'pc result deadHome finalContext'
- instanceVariableNames: 'pc 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>>finalContext (in category 'accessing') -----
+ finalContext
+
+ ^ finalContext!
Item was added:
+ ----- Method: BlockCannotReturn>>finalContext: (in category 'accessing') -----
+ finalContext: context
+
+ finalContext := context!
Item was changed:
----- Method: Context>>cannotReturn:to: (in category 'private') -----
cannotReturn: result to: homeContext
"The receiver tried to return result to homeContext that cannot be returned from.
+ Capture the return context/pc in a BlockCannotReturn. Nil the pc to prevent repeat
- Capture the return pc in a BlockCannotReturn. Nil the pc to prevent repeat
attempts and/or invalid continuation. Answer the result of raising the exception."
+ | exception previousPc |
- | exception |
exception := BlockCannotReturn new.
+ previousPc := pc ifNotNil: [self previousPc].
exception
result: result;
deadHome: homeContext;
+ finalContext: self;
+ pc: previousPc.
- pc: self previousPc.
pc := nil.
^exception signal!
Item was changed:
----- Method: Context>>return:from: (in category 'instruction decoding') -----
return: value from: aSender
"For simulation. Roll back self to aSender and return value from it. Execute any unwind blocks on the way. ASSUMES aSender is a sender of self"
| newTop |
- aSender isDead ifTrue:
- [^self send: #cannotReturn: to: self with: {value}].
newTop := aSender sender.
+ (aSender isDead or: [newTop isNil or: [newTop isDead]]) ifTrue:
+ [^self pc: nil; send: #cannotReturn: to: self with: {value}].
(self findNextUnwindContextUpTo: newTop) ifNotNil:
"Send #aboutToReturn:through: with nil as the second argument to avoid this bug:
Cannot #stepOver '^2' in example '[^2] ensure: []'.
See http://lists.squeakfoundation.org/pipermail/squeak-dev/2022-June/220975.html"
[^self send: #aboutToReturn:through: to: self with: {value. nil}].
self releaseTo: newTop.
newTop ifNotNil: [newTop push: value].
^newTop!
Christoph Thiede uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-jar.1537.mcz
==================== Summary ====================
Name: Kernel-jar.1537
Author: jar
Time: 25 November 2023, 12:03:48.496163 am
UUID: 94c7c0ef-7a40-3149-b9df-0751d16ead54
Ancestors: Kernel-eem.1536
replace debugger invocation with an error; complements Kernel-eem.1535, Kernel-eem.1536 and KernelTests-jar.447.
=============== Diff against Kernel-eem.1536 ===============
Item was changed:
----- Method: Context>>cannotReturn: (in category 'private-exceptions') -----
cannotReturn: result
closureOrNil ifNotNil: [^ self cannotReturn: result to: self home sender].
+ self error: 'Computation has been terminated!!'!
- Processor debugWithTitle: 'Computation has been terminated!!' translated full: false.!
Christoph Thiede uploaded a new version of ToolsTests to project The Trunk:
http://source.squeak.org/trunk/ToolsTests-ct.125.mcz
==================== Summary ====================
Name: ToolsTests-ct.125
Author: ct
Time: 30 December 2023, 6:08:05.812543 pm
UUID: 4fea1ba5-b1d9-3947-8e2f-2f2ae82374bd
Ancestors: ToolsTests-mt.124
Complements Kernel-jar.1537.
=============== Diff against ToolsTests-mt.124 ===============
Item was changed:
----- Method: DebuggerTests>>test16HandleSimulationError (in category 'tests') -----
test16HandleSimulationError
"Regression test. In the past, the scenario below led to an infinite debugger chain freezing your image. Be careful when running this test in an unpatched image!! For more information, see http://forum.world.st/I-broke-the-debugger-td5110752.html."
| userProcess |
process := Process forBlock: [
+ "the faulty user code - representative for any kind of (yet) unhandled bug in the simulator "
+ thisContext pc: false].
- "the faulty user code"
- thisContext pc: nil].
debugger := process debug.
[userProcess := [debugger stepThrough] fork.
Processor yield.
self deny: [process isTerminated].
self assert: [userProcess isSuspended]]
ensure: [
process destroy.
debugger close.
process := userProcess.
self findDebugger "for correct tearDown"].!
Christoph Thiede uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-ct.1545.mcz
==================== Summary ====================
Name: Kernel-ct.1545
Author: ct
Time: 30 December 2023, 6:07:29.181543 pm
UUID: 4089c9dd-3a41-1240-8e53-b7a8a6fe1cae
Ancestors: Kernel-mt.1544, Kernel-jar.1539
Merges Kernel-jar.1537, Kernel-jar.1538, and Kernel-jar.1539, which make 'Computation has been terminated' a regular error, fix the simulation of non-local returns for dead senders, and store the final context in BlockCannotReturn exceptions.
=============== Diff against Kernel-mt.1544 ===============
Item was changed:
Error subclass: #BlockCannotReturn
+ instanceVariableNames: 'pc result deadHome finalContext'
- instanceVariableNames: 'pc 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>>finalContext (in category 'accessing') -----
+ finalContext
+
+ ^ finalContext!
Item was added:
+ ----- Method: BlockCannotReturn>>finalContext: (in category 'accessing') -----
+ finalContext: context
+
+ finalContext := context!
Item was changed:
----- Method: Context>>cannotReturn: (in category 'private-exceptions') -----
cannotReturn: result
closureOrNil ifNotNil: [^ self cannotReturn: result to: self home sender].
+ self error: 'Computation has been terminated!!'!
- Processor debugWithTitle: 'Computation has been terminated!!' translated full: false.!
Item was changed:
----- Method: Context>>cannotReturn:to: (in category 'private') -----
cannotReturn: result to: homeContext
"The receiver tried to return result to homeContext that cannot be returned from.
+ Capture the return context/pc in a BlockCannotReturn. Nil the pc to prevent repeat
- Capture the return pc in a BlockCannotReturn. Nil the pc to prevent repeat
attempts and/or invalid continuation. Answer the result of raising the exception."
+ | exception previousPc |
- | exception |
exception := BlockCannotReturn new.
+ previousPc := pc ifNotNil: [self previousPc].
exception
result: result;
deadHome: homeContext;
+ finalContext: self;
+ pc: previousPc.
- pc: self previousPc.
pc := nil.
^exception signal!
Item was changed:
----- Method: Context>>return:from: (in category 'instruction decoding') -----
return: value from: aSender
"For simulation. Roll back self to aSender and return value from it. Execute any unwind blocks on the way. ASSUMES aSender is a sender of self"
| newTop |
- aSender isDead ifTrue:
- [^self send: #cannotReturn: to: self with: {value}].
newTop := aSender sender.
+ (aSender isDead or: [newTop isNil or: [newTop isDead]]) ifTrue:
+ [^self pc: nil; send: #cannotReturn: to: self with: {value}].
(self findNextUnwindContextUpTo: newTop) ifNotNil:
"Send #aboutToReturn:through: with nil as the second argument to avoid this bug:
Cannot #stepOver '^2' in example '[^2] ensure: []'.
See http://lists.squeakfoundation.org/pipermail/squeak-dev/2022-June/220975.html"
[^self send: #aboutToReturn:through: to: self with: {value. nil}].
self releaseTo: newTop.
newTop ifNotNil: [newTop push: value].
^newTop!
Item was changed:
----- Method: Context>>runUntilErrorOrReturnFrom: (in category 'controlling') -----
runUntilErrorOrReturnFrom: aSender
"ASSUMES aSender is a sender of self. Execute self's stack until aSender returns or an unhandled exception is raised. Return a pair containing the new top context and a possibly nil exception. The exception is not nil if it was raised before aSender returned and it was not handled. The exception is returned rather than openning the debugger, giving the caller the choice of how to handle it."
"Self is run by jumping directly to it (the active process abandons thisContext and executes self). However, before jumping to self we insert an ensure block under aSender that jumps back to thisContext when evaluated. We also insert an exception handler under aSender that jumps back to thisContext when an unhandled exception is raised. In either case, the inserted ensure and exception handler are removed once control jumps back to thisContext."
| error ctxt here topContext |
here := thisContext.
"Insert ensure and exception handler contexts under aSender"
error := nil.
ctxt := aSender insertSender: (Context
contextOn: UnhandledError do: [:ex |
error ifNil: [
error := ex exception.
topContext := thisContext.
ex resumeUnchecked: here jump]
ifNotNil: [ex pass]
]).
ctxt := ctxt insertSender: (Context
contextEnsure: [error ifNil: [
topContext := thisContext.
here jump]
]).
self jump. "Control jumps to self"
"Control resumes here once above ensure block or exception handler is executed"
^ error ifNil: [
"No error was raised, remove ensure context by stepping until popped"
+ [ctxt isDead or: [topContext isNil]] whileFalse: [topContext := topContext stepToCalleeOrNil].
- [ctxt isDead or: [topContext isNil]] whileFalse: [topContext := topContext stepToCallee].
{topContext. nil}
] ifNotNil: [
"Error was raised, remove inserted above contexts then return signaler context"
aSender terminateTo: ctxt sender. "remove above ensure and handler contexts"
{topContext. error}
]!
Item was added:
+ ----- Method: Context>>stepToCalleeOrNil (in category 'private') -----
+ stepToCalleeOrNil
+ "Step to callee or sender; step to return and answer nil in case sender cannot be returned to."
+
+ | ctxt |
+ ctxt := self.
+ [(ctxt willReturn and: [ctxt sender isNil or: [ctxt sender isDead]]) not and: [(ctxt := ctxt step) == self]] whileTrue.
+ ctxt == self ifTrue: [^nil].
+ ^ctxt!
Christoph Thiede uploaded a new version of Kernel to project The Treated Inbox:
http://source.squeak.org/treated/Kernel-jar.1535.mcz
==================== Summary ====================
Name: Kernel-jar.1535
Author: jar
Time: 19 November 2023, 6:34:30.215053 pm
UUID: d384c660-ec50-3e49-aa7e-1dba3227105b
Ancestors: Kernel-mt.1534
Fix incorrect / inconsistent behavior after resuming from BCR exception.
Consider the following examples:
[[^ 1] on: BlockCannotReturn do: #resume ] fork. "VM crash"
[[true ifTrue: [^ 1]] on: BlockCannotReturn do: #resume ] fork. "Illegal return from ^1"
Explanation: In the first example the VM places a #cannotReturn context on top of the [^1] context which at this time has pc past the last bytecode instruction and thus the VM crashes when attempting to return here.
In the second example the pc is past the return, but more bytecodes follow so the return from #cannotReturn context can happily continue, however, this continuing is "illegal" in the sense it should not have happened.
The two examples should consistently cause a walk-back indicating an illegal return attempt.
Complemented by a change in the Debugger to correctly debug this situation: Tools-jar.1240
=============== Diff against Kernel-mt.1534 ===============
Item was changed:
----- Method: Context>>cannotReturn: (in category 'private-exceptions') -----
cannotReturn: result
+ "NB: Nil the receiver's pc to make sure it can't resume; backup the pc before nilling for the sake of debugging.
+ Check Debugger >> #checkContextSelection for a debuuger support when resuming from the BCR exception.
+ Example:
+ Without nilling the pc the following example would crash the VM after resumption:
+ [[^ 1] on: BlockCannotReturn do: #resume ] fork
+ and the following example would run and happily execute an illegal return after resumption:
+ [[true ifTrue: [^ 1]] on: BlockCannotReturn do: #resume ] fork
+ "
+ closureOrNil ifNotNil: [^self cannotReturn: result to: self home sender; push: pc; pc: nil].
+ Processor debugWithTitle: 'Computation has been terminated!!' translated full: false!
- closureOrNil ifNotNil: [^ self cannotReturn: result to: self home sender].
- Processor debugWithTitle: 'Computation has been terminated!!' translated full: false.!
Christoph Thiede uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-ct.1441.mcz
==================== Summary ====================
Name: System-ct.1441
Author: ct
Time: 28 December 2023, 6:14:35.822302 pm
UUID: 6815f755-34db-064a-a120-bf0266234c98
Ancestors: System-ct.1440
Adds Leon Matthes (LM) to the authors table.
=============== Diff against System-ct.1440 ===============
Item was changed:
----- Method: SystemNavigation class>>privateAuthorsRaw (in category 'class initialization') -----
(excessive size, no diff calculated)
Item was changed:
(PackageInfo named: 'System') postscript: '"In Process, threadId/threadAffinity have been around for a long time."
Smalltalk processHasThreadAffinityInstVar: true.
"Squeak 6.0 and above have #scaleFactor support in image."
+ Smalltalk upscaleDisplayOnHighDPI: false.
+
+ SystemNavigation initializeAuthors. "Adds Leon Matthes (LM)"'!
- Smalltalk upscaleDisplayOnHighDPI: false.'!
Marcel Taeumel uploaded a new version of Regex-Tests-Core to project The Trunk:
http://source.squeak.org/trunk/Regex-Tests-Core-mt.35.mcz
==================== Summary ====================
Name: Regex-Tests-Core-mt.35
Author: mt
Time: 21 December 2023, 5:11:41.06102 pm
UUID: 26ba76e8-4b6e-6149-91f7-112ce481f547
Ancestors: Regex-Tests-Core-mt.34
Now that we had an extra checkpoint in the update map, this clean-up of Regex tests should actually work.
Revive #testBackQuotesEscape as expected failure. Is this okay?
=============== Diff against Regex-Tests-Core-mt.34 ===============
Item was removed:
- ----- Method: RxParserTest>>DoesNotWorktestBackQuotesEscape (in category 'tests') -----
- DoesNotWorktestBackQuotesEscape
- "self debug: #testBackQuotesEscape"
-
- "Regular expressions can also include the following backquote escapes
- to refer to popular classes of characters:
- \w any word constituent character (same as [a-zA-Z0-9:=])
- \W any character but a word constituent
- \d a digit (same as [0-9])
- \D anything but a digit
- \s a whitespace character
- \S anything but a whitespace character
- These escapes are also allowed in character classes: '[\w+-]' means
- 'any character that is either a word constituent, or a plus, or a
- minus'."
-
- self assert: ('one word' matchesRegex: '\w').
-
- self assert: ('one' matchesRegex: '\w').
- !
Item was changed:
----- Method: RxParserTest>>expectedFailures (in category 'failures') -----
expectedFailures
+ ^ #(testBackQuotesEscape)!
- ^ #(testOptionalLookbehind2)!
Item was added:
+ ----- Method: RxParserTest>>testBackQuotesEscape (in category 'tests') -----
+ testBackQuotesEscape
+ "self debug: #testBackQuotesEscape"
+
+ "Regular expressions can also include the following backquote escapes
+ to refer to popular classes of characters:
+ \w any word constituent character (same as [a-zA-Z0-9:=])
+ \W any character but a word constituent
+ \d a digit (same as [0-9])
+ \D anything but a digit
+ \s a whitespace character
+ \S anything but a whitespace character
+ These escapes are also allowed in character classes: '[\w+-]' means
+ 'any character that is either a word constituent, or a plus, or a
+ minus'."
+
+ self assert: ('one word' matchesRegex: '\w').
+
+ self assert: ('one' matchesRegex: '\w').
+ !
Item was removed:
- ----- Method: RxParserTest>>testOptionalLookbehind2 (in category 'tests') -----
- testOptionalLookbehind2
-
- self assert: [('AB' allRegexMatches: '((?<=a)b)?') asArray = #('A')].!
Item was removed:
- ----- Method: RxParserTest>>toDotestSpecialCharacterInSetRange (in category 'tests') -----
- toDotestSpecialCharacterInSetRange
- "self debug: #testSpecialCharacterInSetRange"
-
- "Special characters within a set are `^', `-', and `]' that closes the
- set. Below are the examples of how to literally use them in a set:
- [01^] -- put the caret anywhere except the beginning
- [01-] -- put the dash as the last character
- []01] -- put the closing bracket as the first character
- [^]01] (thus, empty and universal sets cannot be specified)"
-
- self assert: ('0' matchesRegex: '[01^]').
-
- self assert: ('0' matchesRegex: '[0-9]').
- !