Christoph Thiede uploaded a new version of Compiler to project The Trunk:
http://source.squeak.org/trunk/Compiler-ct.497.mcz
==================== Summary ====================
Name: Compiler-ct.497
Author: ct
Time: 3 March 2024, 7:35:18.153958 pm
UUID: 7ee52c4b-be72-c64f-bcb5-0607b502b9b5
Ancestors: Compiler-ct.496
Merges SimulationSideEffectWarning.5.cs (step 1/2):
In Context>>doPrimitive:method:receiver:args:, replaces generic "simulation guard" warnings for undebuggable methods by new specific, suppressable SimulationSideEffectWarnings. Also warns when primitive 87 (primitiveResume) is hit. Refactors <primitive: 19> simulation guards into a named alias pragma <simulationGuard>.
Revision: Revise documentation and document emergence and usage of SimulationSideEffectWarning in Context>>runSimulated:.... Fix resumption value of SimulationSideEffectWarning when proceeding from a debugger. Avoid infinite recursion due to process-faithful debugging when debugging a SimulationSideEffectWarning from a debugger. Improves tests.
Step 1/2: Prepare the parser to handle the new <simulationGuard> pragma (as well as unary pragma parsers in general).
Thanks to Marcel (mt) for the advice! See: https://lists.squeakfoundation.org/archives/list/squeak-dev%40lists.squeakf…
=============== Diff against Compiler-ct.496 ===============
Item was changed:
----- Method: Parser>>pragmaStatement (in category 'pragmas') -----
pragmaStatement
"Parse a pragma statement. The leading '<' has already been consumed. The 'here' token is the first one in the pragma. Use that token to dispatch to a custom pragma-parsing method if one can be found with a selector that matches it.
Note that custom pragma parsers need to fulfill two requirements:
- method selector must match the current token as simple getter,
e.g., <apicall: ...> matches #apicall or <primitive: ...> matches #primitive
- method must have pragma <pragmaParser> to be called."
"0) Early exit"
(hereType = #keyword or: [ hereType = #word or: [ hereType = #binary ] ])
ifFalse: [ ^ self expected: 'pragma declaration' ].
+
-
"1) Do not consider one-word pragmas such as <primitive> and <foobar>. Only keyword pragmas."
+ "2) Avoid interning new symbols for made-up pragmas such as #my for <my: 1 pragma: 2>."
+ (Symbol lookup: (here last == $: ifTrue: [here allButLast] ifFalse: [here]))
+ ifNotNil: [:parserSelector |
- here last == $: ifTrue: [
- "2) Avoid interning new symbols for made-up pragmas such as #my for <my: 1 pragma: 2>."
- (Symbol lookup: here allButLast) ifNotNil: [:parserSelector |
Parser methodDict at: parserSelector ifPresent: [:parserMethod |
"3) Only call methods that claim to be a custom pragma parser via <pragmaParser>."
(parserMethod hasPragma: #pragmaParser)
+ ifTrue: [^ self executeMethod: parserMethod]]].
+
- ifTrue: [^ self executeMethod: parserMethod]]]].
-
"X) No custom pragma parser found. Use the default one."
^ self pragmaStatementKeywords!
Item was added:
+ ----- Method: Parser>>simulationGuard (in category 'primitives') -----
+ simulationGuard
+ "primitive 19 is a null primitive that always fails. Just a marker for the simulator for methods that are typically undebuggable and could lock your image when simulated."
+ <pragmaParser>
+
+ self addPragma: (Pragma keyword: #primitive: arguments: #(19)).
+
+ self advance.
+ ^ true!
Christoph Thiede uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-ct.1301.mcz
==================== Summary ====================
Name: Kernel-ct.1301
Author: ct
Time: 16 February 2020, 11:36:54.104878 pm
UUID: e766ce27-fd99-2c4b-ac94-408d4bde8d4f
Ancestors: Kernel-tonyg.1293
Documents the small but essential difference between #sendTo: and #sentTo:
Refactored against Kent's Type Suggesting Parameter Name idiom. Thanks to Chris for the reminder!
Committed again due to broken ancestry.
=============== Diff against Kernel-tonyg.1293 ===============
Item was changed:
----- Method: Message>>sendTo: (in category 'sending') -----
+ sendTo: receiverObject
+ "Answer the result of sending this message to receiverObject"
- sendTo: receiver
- "answer the result of sending this message to receiver"
+ ^ receiverObject perform: selector withArguments: args!
- ^ receiver perform: selector withArguments: args!
Item was changed:
----- Method: Message>>sentTo: (in category 'sending') -----
+ sentTo: receiverObject
+ "Answer the result of sending this message to receiver. Kind of private!! To send the message to a different receiver (for example, via #doesNotUnderstand:), use #sendTo: instead."
- sentTo: receiver
- "answer the result of sending this message to receiver"
+ ^ lookupClass == nil
+ ifTrue: [receiverObject perform: selector withArguments: args]
+ ifFalse: [receiverObject perform: selector withArguments: args inSuperclass: lookupClass]!
- lookupClass == nil
- ifTrue: [^ receiver perform: selector withArguments: args]
- ifFalse: [^ receiver perform: selector withArguments: args inSuperclass: lookupClass]!
Christoph Thiede uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-ct.1385.mcz
==================== Summary ====================
Name: Kernel-ct.1385
Author: ct
Time: 12 April 2021, 10:15:07.18369 pm
UUID: e2817a6e-1a1f-e246-aa66-2fa9289a7703
Ancestors: Kernel-nice.1384
Improves multilingual support for basic errors on Object.
=============== Diff against Kernel-nice.1384 ===============
Item was changed:
----- Method: Object>>error (in category 'error handling') -----
error
"Throw a generic Error exception."
+ ^ self error: 'Error!!' translated!
- ^self error: 'Error!!'.!
Item was changed:
----- Method: Object>>errorImproperStore (in category 'private') -----
errorImproperStore
"Create an error notification that an improper store was attempted."
+ ^ self error: 'Improper store into indexable object' translated!
- self error: 'Improper store into indexable object'!
Item was changed:
----- Method: Object>>errorNonIntegerIndex (in category 'private') -----
errorNonIntegerIndex
"Create an error notification that an improper object was used as an index."
+ ^ self error: 'Only integers should be used as indices' translated!
- self error: 'only integers should be used as indices'!
Item was changed:
----- Method: Object>>errorSubscriptBounds: (in category 'private') -----
errorSubscriptBounds: index
"Create an error notification that an improper integer was used as an index."
+ ^ self error: ('Subscript is out of bounds: {1}' translated format: {index})!
- self error: 'subscript is out of bounds: ' , index printString!
**Steps to reproduce**
Do it/print it:
```smalltalk
[self error] ensure: [self halt]
```
In the debugger, yellow-click `UndefinedObject>>DoIt` (home), choose "return entered value", and enter any value.
**Expected:** Should land in `UndefinedObject(Object)>>halt`.
**Actual:** Land in `Compiler>>evaluateCue:ifFail:logged:` (but the process suspendedContext is not actually yet there).
**Patch:**
```diff
Debugger>>returnValue
"Force a return of a given value to the previous context!"
- | previous selectedContext expression value |
+ | previous selectedContext expression value newContext |
contextStackIndex = 0 ifTrue: [^Beeper beep].
selectedContext := self selectedContext.
expression := UIManager default request: 'Enter expression for return value:'.
value := Compiler new
evaluate: expression
in: selectedContext
to: selectedContext receiver.
previous := selectedContext sender.
- self resetContext: previous.
- interruptedProcess popTo: previous value: value
+ newContext := self
+ handleLabelUpdatesIn: [interruptedProcess popTo: previous value: value]
+ whenExecuting: previous.
+ self resetContext: newContext. "might differ from previous in case of error during unwinding"
```
With that change, let's continue and step out of `[] in UndefinedObject>>DoIt`. Whether you use step over or step through from `UndefinedObject>>DoIt` or step into all the details of the unwind stack, in any case the process ends up completely terminated before the debugger halts in `Compiler>>evaluateCue:ifFail:logged:` as expected, and you get anything like disabled stepping buttons in the debugger, a cannotReturn: error, or a nil DNU from the debugger.
Something seems to be wrong with the unwinding logic here. I checked: This is **not** a regression and already failed in 6.0 and 5.3.
@isCzech FYIO, just in case you're up for another round of unwinding fun. Otherwise, I might myself address this one day. :-)
--
Reply to this email directly or view it on GitHub:
https://github.com/squeak-smalltalk/squeak-object-memory/issues/119
You are receiving this because you are subscribed to this thread.
Message ID: <squeak-smalltalk/squeak-object-memory/issues/119(a)github.com>
Christoph Thiede uploaded a new version of Tools to project The Trunk:
http://source.squeak.org/trunk/Tools-ct.1249.mcz
==================== Summary ====================
Name: Tools-ct.1249
Author: ct
Time: 3 March 2024, 8:10:31.669958 pm
UUID: d9867cc9-cad5-0a41-8b64-86f1fbb54fe3
Ancestors: Tools-ct.1248
Complements Kernel-ct.1559 (merges SimulationSideEffectWarning.5.cs, step 2/2).
Revision: Also handle label updates in debugger when resuming from a method with a possible primitive.
=============== Diff against Tools-ct.1248 ===============
Item was changed:
----- Method: Debugger>>handleLabelUpdatesIn:whenExecuting: (in category 'context stack menu') -----
handleLabelUpdatesIn: aBlock whenExecuting: aContext
"Send the selected message in the accessed method, and regain control
after the invoked method returns."
+
+ | originalProcess |
+ originalProcess := Processor activeProcess.
^aBlock
on: Notification
do: [:ex|
(ex tag isArray
and: [ex tag size = 2
and: [(ex tag first == aContext or: [ex tag first hasSender: aContext])]])
ifTrue:
[self labelString: ex tag second description.
ex resume]
ifFalse:
+ [ex pass]]
+
+ on: SimulationSideEffectWarning
+ do: [:ex |
+ ex isControlPrimitive ifTrue: [ex unsuppress].
+ ex resume:
+ "Avoid infinite recursion in Process>>effectiveProcess when debugging this warning, because the warning while the simulator was evaluating on behalf of the interrupted process."
+ (originalProcess
+ evaluate: [ex defaultAction]
+ onBehalfOf: nil)]!
- [ex pass]]!
Item was changed:
----- Method: Debugger>>tryRestartFrom: (in category 'context stack menu') -----
tryRestartFrom: context
"Try to restart from the initial state of the context.
Return whether an unwind error occurred."
+ | currentContext unwindError |
+ currentContext := self selectedContext.
+ currentContext := self
+ handleLabelUpdatesIn: [interruptedProcess popTo: context]
+ whenExecuting: currentContext.
+ unwindError := currentContext ~= context.
- | actualContext unwindError |
- actualContext := interruptedProcess popTo: context.
- unwindError := actualContext ~= context.
unwindError ifFalse: [
+ currentContext := self
+ handleLabelUpdatesIn: [interruptedProcess restartTop; stepToSendOrReturn]
+ whenExecuting: currentContext].
+ self resetContext: currentContext.
- actualContext := interruptedProcess restartTop; stepToSendOrReturn].
- self resetContext: actualContext.
^ unwindError!
Christoph Thiede uploaded a new version of ST80 to project The Trunk:
http://source.squeak.org/trunk/ST80-ct.298.mcz
==================== Summary ====================
Name: ST80-ct.298
Author: ct
Time: 3 March 2024, 7:56:11.711958 pm
UUID: fcb9f599-f766-3143-98b0-634c455acf9c
Ancestors: ST80-dtl.297
Complements Kernel-ct.1559 (merges SimulationSideEffectWarning.5.cs, step 2/2).
=============== Diff against ST80-dtl.297 ===============
Item was changed:
----- Method: ControlManager>>activeController: (in category 'accessing') -----
activeController: aController
+ "Set aController to be the currently active controller. Give the user control in it."
+ <simulationGuard>
+
- "Set aController to be the currently active controller. Give the user
- control in it."
- <primitive: 19> "Simulation guard"
activeController := aController.
(activeController == screenController)
ifFalse: [self promote: activeController].
activeControllerProcess :=
[activeController startUp.
self searchForActiveController] newProcess.
activeControllerProcess priority: Processor userSchedulingPriority.
activeControllerProcess resume!
Item was changed:
----- Method: ControlManager>>scheduleActive: (in category 'scheduling') -----
scheduleActive: aController
+ "Make aController be scheduled as the active controller. Presumably the active scheduling process asked to schedule this controller and that a new process associated this controller takes control. So this is the last act of the active scheduling process."
+ <simulationGuard>
+
- "Make aController be scheduled as the active controller. Presumably the
- active scheduling process asked to schedule this controller and that a
- new process associated this controller takes control. So this is the last act
- of the active scheduling process."
- <primitive: 19> "Simulation guard"
self scheduleActiveNoTerminate: aController.
Processor terminateActive!