David T. Lewis uploaded a new version of 60Deprecated to project The Trunk:
http://source.squeak.org/trunk/60Deprecated-dtl.93.mcz
==================== Summary ====================
Name: 60Deprecated-dtl.93
Author: dtl
Time: 11 April 2021, 9:49:18.524698 pm
UUID: 332f4c4f-97b4-463d-b226-b3dcad07e8f8
Ancestors: 60Deprecated-mt.92
Symbol>>asMutator is used by Seaside, do not deprecate it. Instead let it be a synonym for the preferred Symbol>>asSimpleSetter.
=============== Diff against 60Deprecated-mt.92 ===============
Item was removed:
- ----- Method: Symbol>>asMutator (in category '*60Deprecated-converting') -----
- asMutator
- "Return a setter message from a getter message. For example, #name asMutator returns #name:"
- self deprecated: 'Use #asSimpleSetter instead'.
- ^ self last = $:
- ifTrue: [ self ]
- ifFalse: [ (self copyWith: $:) asSymbol ]!
Nicolas Cellier uploaded a new version of Tests to project The Trunk:
http://source.squeak.org/trunk/Tests-nice.446.mcz
==================== Summary ====================
Name: Tests-nice.446
Author: nice
Time: 11 April 2021, 10:10:51.107508 am
UUID: 4bf76380-a2ad-41d3-a16b-8684a2a9b938
Ancestors: Tests-tobe.445
The defaultAction of an Exception should be evaluated in the Context of the method that signalled the Exception.
Thus, an enclosing exception handler (on:do:) upper in the stack shall still be active whenever the defaultAction raise another exception.
This documents why simply deactivating the exception (see handlerActive, tempAt: 3, of #on:do:) is not the right way to fix handling of nested exception.
See #testHandlerFromAction, see also
https://source.squeak.org/treated/Kernel-ar.540.diff
=============== Diff against Tests-tobe.445 ===============
Item was added:
+ ----- Method: ExceptionTests>>testCatchingDefaultAction (in category 'tests - outer') -----
+ testCatchingDefaultAction
+ "The #defaultAction method is executed in the context of the signaling environment.
+ The defaultAction will raise an UnhandledWarning that should be caught by this handler."
+ | result |
+ result := [ Warning signal: 'Warning signalled' ] on: UnhandledWarning do: [ :ex | 'UnhandledWarning caught' ].
+ self assert: 'UnhandledWarning caught' equals: result!
A new version of Kernel was added to project The Inbox:
http://source.squeak.org/inbox/Kernel-jar.1385.mcz
==================== Summary ====================
Name: Kernel-jar.1385
Author: jar
Time: 11 April 2021, 9:19:58.900241 am
UUID: fc94f858-9307-e943-b23a-180be1ffad4a
Ancestors: Kernel-mt.1383
Fix a list of termination bugs described in http://forum.world.st/Solving-multiple-termination-bugs-summary-amp-proposa…
A set of tests will follow.
=============== Diff against Kernel-mt.1383 ===============
Item was changed:
----- Method: Process>>isSuspended (in category 'testing') -----
isSuspended
+ "A process is suspended if it is not active, not terminated and
+ not waiting in a scheduler or a semaphore queue."
+
+ self isActiveProcess ifTrue: [^ false].
+ ^myList isNil and: [self isTerminated not]!
- "A process is suspended if it has been suspended with the suspend primitive.
- It is distinguishable from the active process and a terminated process by
- having a non-nil suspendedContext that is either not the bottom context
- or has not reached its endPC."
- ^nil == myList
- and: [nil ~~ suspendedContext
- and: [suspendedContext isBottomContext
- ifTrue: [suspendedContext closure
- ifNil: [suspendedContext methodClass ~~ Process
- or: [suspendedContext selector ~~ #terminate]]
- ifNotNil: [suspendedContext pc < suspendedContext closure endPC]]
- ifFalse: [true]]]!
Item was changed:
----- Method: Process>>isTerminated (in category 'testing') -----
isTerminated
+ "Answer if the receiver is terminated. A process is considered terminated
+ if the suspendedContext is the bottomContext and the pc is at the endPC"
+
- "Answer if the receiver is terminated, or at least terminating."
self isActiveProcess ifTrue: [^ false].
+ ^suspendedContext isNil or: [
+ suspendedContext isBottomContext and: [
+ suspendedContext isDead or: [suspendedContext atEnd]]]!
- ^suspendedContext isNil
- or: ["If the suspendedContext is the bottomContext it is the block in Process>>newProcess.
- If so, and the pc is at the endPC, the block has already sent and returned
- from value and there is nothing more to do."
- suspendedContext isBottomContext
- and: [suspendedContext closure
- ifNil: [suspendedContext methodClass == Process
- and: [suspendedContext selector == #terminate]]
- ifNotNil: [suspendedContext pc >= suspendedContext closure endPC]]]!
Item was changed:
----- Method: Process>>terminate (in category 'changing process state') -----
terminate
"Stop the process that the receiver represents forever.
Unwind to execute pending ensure:/ifCurtailed: blocks before terminating.
If the process is in the middle of a critical: critical section, release it properly."
+ | ctxt unwindBlock oldList outerMost |
+ self isActiveProcess ifTrue: [
+ "If terminating the active process, suspend it first and terminate it as a suspended process."
+ [self terminate] fork.
+ ^self suspend].
- | ctxt unwindBlock oldList |
- self isActiveProcess ifTrue:
- [ctxt := thisContext.
- [ctxt := ctxt findNextUnwindContextUpTo: nil.
- ctxt ~~ nil] whileTrue:
- [(ctxt tempAt: 2) ifNil:
- ["N.B. Unlike Context>>unwindTo: we do not set complete (tempAt: 2) to true."
- unwindBlock := ctxt tempAt: 1.
- thisContext terminateTo: ctxt.
- unwindBlock value]].
- thisContext terminateTo: nil.
- self suspend.
- "If the process is resumed this will provoke a cannotReturn: error.
- Would self debug: thisContext title: 'Resuming a terminated process' be better?"
- ^self].
"Always suspend the process first so it doesn't accidentally get woken up.
N.B. If oldList is a LinkedList then the process is runnable. If it is a Semaphore/Mutex et al
then the process is blocked, and if it is nil then the process is already suspended."
oldList := self suspend.
suspendedContext ifNotNil:
["Release any method marked with the <criticalSection> pragma.
The argument is whether the process is runnable."
self releaseCriticalSection: (oldList isNil or: [oldList class == LinkedList]).
+ "If terminating a process halfways through an unwind, try to complete that unwind block first;
+ if there are multiple such nested unwind blocks, try to complete the outer-most one; the inner
+ blocks will be completed in the process."
+ ctxt := suspendedContext.
+ [(ctxt := ctxt findNextUnwindContextUpTo: nil) isNil] whileFalse:
+ "Contexts under evaluation have already set their complete (tempAt: 2) to true."
+ [(ctxt tempAt:2) ifNotNil: [outerMost := ctxt]].
+ outerMost ifNotNil: [
+ "This is the outer-most unwind context currently under evaluation;
+ let's find an inner context executing outerMost's argument block (tempAt: 1)"
+ (suspendedContext findContextSuchThat: [:ctx |
+ ctx closure == (outerMost tempAt: 1)]) ifNotNil: [:inner |
+ "Let's finish the unfinished unwind context only (i.e. up to inner) and return here"
+ suspendedContext runUntilErrorOrReturnFrom: inner.
+ "Update the receiver's suspendedContext (the previous step reset its sender to nil)"
+ suspendedContext := outerMost]].
- "If terminating a process halfways through an unwind, try to complete that unwind block first."
- (suspendedContext findNextUnwindContextUpTo: nil) ifNotNil:
- [:outer|
- (suspendedContext findContextSuchThat:[:c| c closure == (outer tempAt: 1)]) ifNotNil:
- [:inner| "This is an unwind block currently under evaluation"
- suspendedContext runUntilErrorOrReturnFrom: inner]].
+ "Now all unwind blocks caught halfway through have been completed;
+ let's execute the ones still pending. Note: #findNextUnwindContextUpTo: starts
+ searching from the receiver's sender but the receiver itself may be an unwind context."
+ ctxt := suspendedContext.
+ ctxt isUnwindContext ifFalse: [ctxt := ctxt findNextUnwindContextUpTo: nil].
+ [ctxt isNil] whileFalse: [
+ (ctxt tempAt: 2) ifNil: [
+ ctxt tempAt: 2 put: true.
+ unwindBlock := ctxt tempAt: 1.
+ "Create a context for the unwind block and execute it on the unwind block's stack.
+ Note: using #value instead of #runUntilErrorOrReturnFrom: would lead to executing
+ the unwind on the wrong stack preventing the correct execution of non-local returns."
+ suspendedContext := unwindBlock asContextWithSender: ctxt.
+ suspendedContext runUntilErrorOrReturnFrom: suspendedContext].
+ ctxt := ctxt findNextUnwindContextUpTo: nil].
+
+ "Reset the context's pc and sender to nil for the benefit of isTerminated."
+ suspendedContext terminate]!
- ctxt := self popTo: suspendedContext bottomContext.
- ctxt == suspendedContext bottomContext ifFalse:
- [self debugWithTitle: 'Unwind error during termination' translated full: false].
- "Set the context to its endPC for the benefit of isTerminated."
- ctxt pc: ctxt endPC]!
Nicolas Cellier uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-nice.933.mcz
==================== Summary ====================
Name: Collections-nice.933
Author: nice
Time: 10 April 2021, 9:16:54.312889 pm
UUID: c066bf52-b7a5-474a-9614-90bbc3212e07
Ancestors: Collections-ul.932
Quick fix for double utf8->squeak conversion via nextChunk.
(MultiByteFileStream newFileNamed: 'foo.utf8') nextPutAll: 'À'; close.
(MultiByteFileStream oldFileNamed: 'foo.utf8') nextChunk.
=============== Diff against Collections-ul.932 ===============
Item was changed:
----- Method: PositionableStream>>basicUpTo: (in category 'private basic') -----
basicUpTo: anObject
"Answer a subcollection from the current access position to the
occurrence (if any, but not inclusive) of anObject in the receiver. If
anObject is not in the collection, answer the entire rest of the receiver."
| newStream element |
newStream := WriteStream on: (self collectionSpecies new: 100).
+ [self atEnd or: [(element := self basicNext) = anObject]]
- [self atEnd or: [(element := self next) = anObject]]
whileFalse: [newStream nextPut: element].
^newStream contents!
Nicolas Cellier uploaded a new version of Regex-Tests-Core to project The Trunk:
http://source.squeak.org/trunk/Regex-Tests-Core-ct.11.mcz
==================== Summary ====================
Name: Regex-Tests-Core-ct.11
Author: ct
Time: 8 September 2020, 5:06:20.887336 pm
UUID: 6d0bb586-18f2-1045-ba9c-6b288515c123
Ancestors: Regex-Tests-Core-nice.10
Adds regression test for capturing-like behavior of lookaround expressions
See also: http://forum.world.st/The-Inbox-Regex-Core-ct-56-mcz-tp5113011p5114971.html
=============== Diff against Regex-Tests-Core-nice.10 ===============
Item was added:
+ ----- Method: RxParserTest>>testLookaroundNullable (in category 'tests') -----
+ testLookaroundNullable
+
+ self should: ['(?<=a)?b' asRegex] raise: RegexSyntaxError.!
Nicolas Cellier uploaded a new version of Regex-Core to project The Trunk:
http://source.squeak.org/trunk/Regex-Core-ct.58.mcz
==================== Summary ====================
Name: Regex-Core-ct.58
Author: ct
Time: 8 September 2020, 5:07:32.229336 pm
UUID: 66a3d373-fd7a-fc41-ba4f-7233d60a5ec4
Ancestors: Regex-Core-ul.57
Fixes capturing-like behavior of lookaround expressions. Complements Regex-Tests-Core-ct.11.
Thanks to Levente (ul) for the bug report! [1]
[1] http://forum.world.st/The-Inbox-Regex-Core-ct-56-mcz-tp5113011p5114971.html
=============== Diff against Regex-Core-ul.57 ===============
Item was added:
+ ----- Method: RxsLookaround>>isNullable (in category 'testing') -----
+ isNullable
+
+ ^ true!