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!
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!
Christoph Thiede uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-ct.1559.mcz
==================== Summary ====================
Name: Kernel-ct.1559
Author: ct
Time: 3 March 2024, 7:49:53.952958 pm
UUID: 12cceefa-01f6-fa46-917b-cc2ec6f91312
Ancestors: Kernel-ct.1558
Merges SimulationSideEffectWarning.5.cs (step 2/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 2/2: After the new <simulationGuard> pragma has been added to the compiler (Compiler-ct.497), we can use it in the tests and the ST80 package.
Thanks to Marcel (mt) for the advice! See: https://lists.squeakfoundation.org/archives/list/squeak-dev%40lists.squeakf…
=============== Diff against Kernel-ct.1558 ===============
Item was changed:
----- Method: Context class>>runSimulated: (in category 'simulation') -----
runSimulated: aBlock
+ "Simulate the execution of aBlock, until it ends or is curtailed. Answer the result it returns.
+
+ If aBlock attempts any action that escapes the control of the simulator (e.g., resuming another process), signal a SimulationSideEffectWarning. The client of the simulator (i.e., the sender of this method) may handle those warnings to remain control, or otherwise, these actions are allowed. Examples:
+ Context runSimulated: [[] fork]. --> fork is executed
+ [Context runSimulated: [[] fork]]
+ on: SimulationSideEffectWarning
+ do: [:ex |
+ ex isControlPrimitive ifTrue: [ex return: #forbidden].
+ ex pass]. --> fork is prevented"
- "Simulate the execution of aBlock, until it ends or is curtailed. Answer the result it returns."
^thisContext
runSimulated: aBlock
contextAtEachStep: []
"Context runSimulated: [Pen new ifNotNil: [:pen| pen defaultNib: 5. 4 timesRepeat: [pen go: 100; turn: 90]]]"
"Here's a fun example, reaching into the computation to squash the Display>>fillWhite that mandala: begins with..."
"thisContext
runSimulated: [Pen new mandala: 45]
contextAtEachStep: [:ctxt| ctxt selector == #fillWhite ifTrue: [ctxt scanFor: [:ign| ctxt willReturn]]]"!
Item was changed:
----- Method: Context>>doPrimitive:method:receiver:args: (in category 'private') -----
doPrimitive: primitiveIndex method: meth receiver: receiver args: arguments
"Simulate a primitive method whose index is primitiveIndex. The simulated receiver and
arguments are given as arguments to this message. If successful, push result and return
resuming context, else ^ {errCode, PrimitiveFailToken}. Any primitive which provokes
execution needs to be intercepted and simulated to avoid execution running away."
| value |
+ "Test for unsimulatable side effects (that is, code that will be triggered in the image outside of the simulator range). This includes simulation guards, which are traditionally flagged using primitive 19 (a null primitive that doesn't do anything), as well as certain control primitives that might trigger code on other processes. If a side effect is detected, raise a warning to give the user/client a chance to cancel or virtualize the operation."
+ "#(19 87) do: [:primitive | self systemNavigation browseAllSelect: [:m | m primitive = primitive]]"
+ (primitiveIndex = 19 "simulationGuard" or: [primitiveIndex = 87 "primitiveResume"]) ifTrue:
+ [[(SimulationSideEffectWarning forPrimitive: primitiveIndex)
+ context: self method: meth receiver: receiver arguments: arguments;
+ signalIfSkipped: [^ self]]
+ ifCurtailed:
+ [self push: receiver "Cheap fix of the context's internal state. Note that unwinding the receiver -- so that the next step would invoke the primitive again -- would be challenging due to to the variety of senders to this method."]].
- "Judicious use of primitive 19 (a null primitive that doesn't do anything) prevents
- the debugger from entering various run-away activities such as spawning a new
- process, etc. Injudicious use results in the debugger not being able to debug
- interesting code, such as the debugger itself. Hence use primitive 19 with care :-)"
- "SystemNavigation new browseAllSelect: [:m| m primitive = 19]"
- primitiveIndex = 19 ifTrue: [
- [self notify: ('The code being simulated is trying to control a process ({1}). Process controlling cannot be simulated. If you proceed, things may happen outside the observable area of the simulator.' translated format: {meth reference})]
- ifCurtailed: [self push: nil "Cheap fix of the context's internal state"]].
((primitiveIndex between: 201 and: 222)
and: [(self objectClass: receiver) includesBehavior: BlockClosure]) ifTrue:
[(primitiveIndex = 206
or: [primitiveIndex = 208]) ifTrue: "[Full]BlockClosure>>valueWithArguments:"
[^receiver simulateValueWithArguments: arguments first caller: self].
((primitiveIndex between: 201 and: 209) "[Full]BlockClosure>>value[:value:...]"
or: [primitiveIndex between: 221 and: 222]) ifTrue: "[Full]BlockClosure>>valueNoContextSwitch[:]"
[^receiver simulateValueWithArguments: arguments caller: self]].
primitiveIndex = 83 ifTrue: "afr 9/11/1998 19:50" "Object>>perform:[with:...]"
[| selector |
selector := arguments at: 1 ifAbsent:
[^ self class primitiveFailTokenFor: #'bad argument'].
^self send: selector to: receiver with: arguments allButFirst].
primitiveIndex = 84 ifTrue: "afr 9/11/1998 19:50 & eem 8/18/2009 17:04" "Object>>perform:withArguments:"
[| selector args |
arguments size = 2 ifFalse:
[^ self class primitiveFailTokenFor: #'bad argument'].
selector := arguments first.
args := arguments second.
args isArray ifFalse:
[^ self class primitiveFailTokenFor: #'bad argument'].
^self send: selector to: receiver with: args].
primitiveIndex = 100 ifTrue: "eem 8/18/2009 16:57" "Object>>perform:withArguments:inSuperclass:"
[| rcvr selector args superclass |
arguments size
caseOf: {
[3] -> [
rcvr := receiver.
selector := arguments first.
args := arguments second.
superclass := arguments third].
[4] -> ["mirror primitive"
rcvr := arguments first.
selector := arguments second.
args := arguments third.
superclass := arguments fourth] }
otherwise: [^ self class primitiveFailTokenFor: #'bad number of arguments'].
args isArray ifFalse:
[^ self class primitiveFailTokenFor: #'bad argument'].
((self objectClass: rcvr) includesBehavior: superclass) ifFalse:
[^ self class primitiveFailTokenFor: #'bad argument'].
^self send: selector to: rcvr with: args lookupIn: superclass].
"Mutex>>primitiveEnterCriticalSection
Mutex>>primitiveTestAndSetOwnershipOfCriticalSection"
(primitiveIndex = 186 or: [primitiveIndex = 187]) ifTrue:
[| effective |
effective := Processor activeProcess effectiveProcess.
"active == effective"
value := primitiveIndex = 186
ifTrue: [receiver primitiveEnterCriticalSectionOnBehalfOf: effective]
ifFalse: [receiver primitiveTestAndSetOwnershipOfCriticalSectionOnBehalfOf: effective].
^(self isPrimFailToken: value)
ifTrue: [value]
ifFalse: [self push: value]].
(primitiveIndex = 188 or: [primitiveIndex = 189]) ifTrue:
[| n args methodArg thisReceiver |
primitiveIndex caseOf:
{[188 "primitiveExecuteMethodArgsArray"] ->
["Object>>withArgs:executeMethod:
CompiledMethod class>>receiver:withArguments:executeMethod:
VMMirror>>ifFail:object:with:executeMethod: et al"
((n := arguments size) between: 2 and: 4) ifFalse:
[^self class primitiveFailTokenFor: #'unsupported operation'].
((self objectClass: (args := arguments at: n - 1)) == Array
and: [(self objectClass: (methodArg := arguments at: n)) includesBehavior: CompiledMethod]) ifFalse:
[^self class primitiveFailTokenFor: #'bad argument'].
thisReceiver := arguments at: n - 2 ifAbsent: [receiver]].
[189 "primitiveExecuteMethod"] ->
["Object>>executeMethod:
Object>>with:...executeMethod:"
(arguments size > 0) ifFalse:
[^self class primitiveFailTokenFor: #'bad argument'].
((self objectClass: (methodArg := arguments atLast: 1)) includesBehavior: CompiledMethod) ifFalse:
[^self class primitiveFailTokenFor: #'bad argument'].
args := arguments allButLast.
thisReceiver := receiver]}.
methodArg numArgs = args size ifFalse:
[^self class primitiveFailTokenFor: #'bad number of arguments'].
methodArg primitive > 0 ifTrue:
[methodArg isQuick ifTrue:
[^self push: (methodArg valueWithReceiver: thisReceiver arguments: args)].
^self doPrimitive: methodArg primitive method: methodArg receiver: thisReceiver args: args].
^self
activateMethod: methodArg
withArgs: args
receiver: thisReceiver].
primitiveIndex = 118 ifTrue: "[receiver:]tryPrimitive:withArgs:; avoid recursing in the VM"
[(arguments size = 3
and: [(self objectClass: arguments second) == SmallInteger
and: [(self objectClass: arguments last) == Array]]) ifTrue:
[^self doPrimitive: arguments second method: meth receiver: arguments first args: arguments last].
(arguments size = 2
and: [(self objectClass: arguments first) == SmallInteger
and: [(self objectClass: arguments last) == Array]]) ifFalse:
[^self class primitiveFailTokenFor: -3].
^self doPrimitive: arguments first method: meth receiver: receiver args: arguments last].
value := primitiveIndex = 120 "FFI method"
ifTrue: [(meth literalAt: 1) tryInvokeWithArguments: arguments]
ifFalse:
[primitiveIndex = 117 "named primitives"
ifTrue: [self tryNamedPrimitiveIn: meth for: receiver withArgs: arguments]
ifFalse: "should use self receiver: receiver tryPrimitive: primitiveIndex withArgs: arguments but this is only in later VMs (and appears to be broken)"
[receiver tryPrimitive: primitiveIndex withArgs: arguments]].
^(self isPrimFailToken: value)
ifTrue: [value]
ifFalse: [self push: value]!
Item was changed:
----- Method: Context>>runSimulated:contextAtEachStep: (in category 'system simulation') -----
runSimulated: aBlock contextAtEachStep: anotherBlock
+ "Simulate the execution of the argument, aBlock, until it ends or is curtailed. If any exception is signaled during the execution, simulate it being handled on the present caller stack. Evaluate anotherBlock with the current context prior to each instruction executed. Answer the simulated value of aBlock.
+
+ If aBlock attempts any action that escapes the control of the simulator (e.g., resuming another process), signal a SimulationSideEffectWarning. The client of the simulator (i.e., the sender of this method) may handle those warnings to remain control, or otherwise, these actions are allowed. Examples:
+ Context runSimulated: [[] fork]. --> fork is executed
+ [Context runSimulated: [[] fork]]
+ on: SimulationSideEffectWarning
+ do: [:ex |
+ ex isControlPrimitive ifTrue: [ex return: #forbidden].
+ ex pass]. --> fork is prevented"
- "Simulate the execution of the argument, aBlock, until it ends or is curtailed. If any exception is signaled during the execution, simulate it being handled on the present caller stack. Evaluate anotherBlock with the current context prior to each instruction executed. Answer the simulated value of aBlock."
| current resume ensure |
resume := false.
"Affect the context stack of the receiver during the simulation of aBlock."
current := aBlock asContextWithSender: self.
"Insert outer context denoting the end of the simulation."
ensure := (ensure := current) insertSender: (Context contextEnsure:
[resume := true.
ensure privSender: thisContext home sender]).
(anotherBlock numArgs = 0
ifTrue: ["optimized" [resume]]
ifFalse: ["stop execution on time, don't expose simulation details to caller"
[current == ensure or:
["Context >> #resume:"
current size >= 2 and:
[(current at: 2) == ensure]]] ])
whileFalse:
[anotherBlock cull: current.
current := current step].
"Continue with the execution in the previous context."
^ current jump!
Item was added:
+ Warning subclass: #SimulationSideEffectWarning
+ instanceVariableNames: 'primitiveIndex context method receiver arguments suppressed'
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'Kernel-Exceptions'!
+
+ !SimulationSideEffectWarning commentStamp: 'ct 3/3/2024 19:17' prior: 0!
+ I am signaled to notify the client of the simulator (i.e., a sender of Context>>step) about potential side effects of the next instruction to be executed that would escape the control of the simulator. For example, I am signaled before the simulated code starts another process. See Context>>doPrimitive:method:receiver:args:, my messageText, and Parser>>simulationGuard for more information.!
Item was added:
+ ----- Method: SimulationSideEffectWarning class>>forPrimitive: (in category 'instance creation') -----
+ forPrimitive: primitiveIndex
+
+ ^ self new primitive: primitiveIndex!
Item was added:
+ ----- Method: SimulationSideEffectWarning>>arguments (in category 'accessing') -----
+ arguments
+
+ ^ arguments!
Item was added:
+ ----- Method: SimulationSideEffectWarning>>context (in category 'accessing') -----
+ context
+
+ ^ context!
Item was added:
+ ----- Method: SimulationSideEffectWarning>>context:method:receiver:arguments: (in category 'initialize-release') -----
+ context: aContext method: aCompiledMethod receiver: rcvr arguments: args
+
+ context := aContext.
+ method := aCompiledMethod.
+ receiver := rcvr.
+ arguments := args.!
Item was added:
+ ----- Method: SimulationSideEffectWarning>>defaultAction (in category 'priv handling') -----
+ defaultAction
+
+ self suppressed ifFalse: [super defaultAction].
+ self flag: #forLater. "When we support explicit exception handler invocation (e.g., #resume, #retry) from the debugger, this exception should publish a #resume handler rather than relying on the weakly defined proceed semantics of the debugger."
+ ^ self defaultResumeValue!
Item was added:
+ ----- Method: SimulationSideEffectWarning>>defaultResumeValue (in category 'defaults') -----
+ defaultResumeValue
+
+ ^ true!
Item was added:
+ ----- Method: SimulationSideEffectWarning>>isControlPrimitive (in category 'testing') -----
+ isControlPrimitive
+ "See StackInterpreter class>>#initializePrimitiveTable."
+
+ ^ self primitive between: 80 and: 89!
Item was added:
+ ----- Method: SimulationSideEffectWarning>>isSimulationGuard (in category 'testing') -----
+ isSimulationGuard
+ "See Parser >> #simulationGuard."
+
+ ^ self primitive = 19!
Item was added:
+ ----- Method: SimulationSideEffectWarning>>messageText (in category 'printing') -----
+ messageText
+
+ ^ messageText ifNil: [
+ 'The code being simulated is trying to control a process ({1}). {2}' translated format: {
+ self context method reference.
+ self isSimulationGuard
+ ifTrue: ['If you proceed, your image may be locked. Continue at own risk, and better save your image before.' translated]
+ ifFalse: ['Process controlling cannot be simulated. If you proceed, side effects may occur outside the observable area of the simulator.' translated]}]!
Item was added:
+ ----- Method: SimulationSideEffectWarning>>method (in category 'accessing') -----
+ method
+
+ ^ method!
Item was added:
+ ----- Method: SimulationSideEffectWarning>>primitive (in category 'accessing') -----
+ primitive
+
+ ^ primitiveIndex!
Item was added:
+ ----- Method: SimulationSideEffectWarning>>primitive: (in category 'initialize-release') -----
+ primitive: anInteger
+
+ primitiveIndex := anInteger.!
Item was added:
+ ----- Method: SimulationSideEffectWarning>>signalIfSkipped: (in category 'signaling') -----
+ signalIfSkipped: skipBlock
+
+ ^ self signal ifFalse: skipBlock!
Item was added:
+ ----- Method: SimulationSideEffectWarning>>skipPrimitive (in category 'handling') -----
+ skipPrimitive
+
+ ^ self resume: false!
Item was added:
+ ----- Method: SimulationSideEffectWarning>>suppress (in category 'accessing') -----
+ suppress
+
+ suppressed := true.!
Item was added:
+ ----- Method: SimulationSideEffectWarning>>suppressed (in category 'accessing') -----
+ suppressed
+
+ ^ suppressed ifNil: [self isSimulationGuard not]!
Item was added:
+ ----- Method: SimulationSideEffectWarning>>theReceiver (in category 'accessing') -----
+ theReceiver
+
+ ^ receiver!
Item was added:
+ ----- Method: SimulationSideEffectWarning>>unsuppress (in category 'accessing') -----
+ unsuppress
+
+ suppressed := false.!
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.1558.mcz
==================== Summary ====================
Name: Kernel-ct.1558
Author: ct
Time: 2 March 2024, 8:30:30.372052 pm
UUID: b8e15dd5-2d06-b148-b83b-083c3e6aaaa9
Ancestors: Kernel-ct.1557
Repairs the comment in Object>>instVarNamed:put:.
=============== Diff against Kernel-ct.1557 ===============
Item was changed:
----- Method: Object>>instVarNamed:put: (in category 'system primitives') -----
instVarNamed: aString put: aValue
+ "Store the value into the instance variable in me with that name. Slow and unclean, but very useful. "
- "Store into the value of the instance variable in me of that name. Slow and unclean, but very useful. "
^self
instVarAt: (self class
instVarIndexFor: aString asString
ifAbsent: [self error: 'no such inst var' translated])
put: aValue
!
Christoph Thiede uploaded a new version of Tools to project The Trunk:
http://source.squeak.org/trunk/Tools-ct.1247.mcz
==================== Summary ====================
Name: Tools-ct.1247
Author: ct
Time: 2 March 2024, 8:28:46.009052 pm
UUID: 7ce4a4da-cc0f-1646-8421-a10fe85212de
Ancestors: Tools-ct.1246
Merges temputils.1.cs: Adds Context>>tempNamed: and Context>>tempNamed:put:.
Thanks to Eliot (emm) for the review!
=============== Diff against Tools-ct.1246 ===============
Item was added:
+ ----- Method: Context>>tempNamed: (in category '*Tools-debugger access') -----
+ tempNamed: aString
+ "Answer the value of the temporary variable in me with that name. Slower than #tempAt:, but very useful."
+
+ ^ self debuggerMap tempNamed: aString in: self!
Item was added:
+ ----- Method: Context>>tempNamed:put: (in category '*Tools-debugger access') -----
+ tempNamed: aString put: aValue
+ "Store the value into the temporary variable in me of that name. Slower than #tempAt:put:, but very useful."
+
+ ^ self debuggerMap
+ tempNamed: aString
+ put: aValue
+ in: self!
Item was added:
+ ----- Method: DebuggerMethodMap>>tempIndexFor:in:ifAbsent: (in category 'accessing') -----
+ tempIndexFor: tempName in: aContext ifAbsent: aBlock
+
+ ^ (self tempNamesForContext: aContext)
+ indexOf: tempName
+ ifAbsent: aBlock!
Item was added:
+ ----- Method: DebuggerMethodMap>>tempNamed:in: (in category 'accessing') -----
+ tempNamed: aString in: aContext
+ "Answer the value of the temporary variable in aContext with that name. Slower than Context>>tempAt:, but very useful."
+
+ ^ self
+ namedTempAt: (self
+ tempIndexFor: aString asString
+ in: aContext
+ ifAbsent: [self error: 'no such temp'])
+ in: aContext!
Item was added:
+ ----- Method: DebuggerMethodMap>>tempNamed:put:in: (in category 'accessing') -----
+ tempNamed: aString put: aValue in: aContext
+ "Store into the value of the temporary variable in aContext of that name. Slower than Context>>tempAt:put:, but very useful."
+
+ ^ self
+ namedTempAt: (self
+ tempIndexFor: aString asString
+ in: aContext
+ ifAbsent: [self error: 'no such temp'])
+ put: aValue
+ in: aContext!
Christoph Thiede uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-ct.1410.mcz
==================== Summary ====================
Name: Kernel-ct.1410
Author: ct
Time: 30 August 2021, 8:43:40.47076 pm
UUID: 46b520fa-b225-e349-8f11-a423359f0466
Ancestors: Kernel-eem.1408
Proposal: Makes IllegalResumeAttempt an error. Please find my argument in [1].
[1] http://lists.squeakfoundation.org/pipermail/squeak-dev/2021-May/215520.html
=============== Diff against Kernel-eem.1408 ===============
Item was changed:
+ Error subclass: #IllegalResumeAttempt
- Exception subclass: #IllegalResumeAttempt
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'Kernel-Exceptions'!
!IllegalResumeAttempt commentStamp: '<historical>' prior: 0!
This class is private to the EHS implementation. An instance of it is signaled whenever an attempt is made to resume from an exception which answers false to #isResumable.!
Item was removed:
- ----- Method: IllegalResumeAttempt>>defaultAction (in category 'handling') -----
- defaultAction
- "No one has handled this error, but now give them a chance to decide how to debug it. If none handle this either then open debugger (see UnhandedError-defaultAction)"
-
- UnhandledError signalForException: self!
Item was removed:
- ----- Method: IllegalResumeAttempt>>isResumable (in category 'handling') -----
- isResumable
-
- ^ false!
Item was removed:
- ----- Method: IllegalResumeAttempt>>readMe (in category 'comment') -----
- readMe
-
- "Never handle this exception!!"!