Marcel Taeumel uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-ct.1357.mcz
==================== Summary ====================
Name: Kernel-ct.1357
Author: ct
Time: 28 October 2020, 9:30:35.577652 pm
UUID: efd94ae0-26ab-0c4f-b854-52f414ff2d3e
Ancestors: Kernel-eem.1354
Implement missing simulation of objects as methods.
In the past, it was not possible to debug/simulate code that used objects as methods properly. (Thanks to Marcel for the hint!) This very simple commit adds support of the OaM protocol [1] to the simulation machinery. Now you can debug all tests in TestObjectsAsMethods as you would expect, instead of crashing your image!
Update: Uploaded a third time, this time with Kent Beck block formatting preserved.
[1] "The [Objects as Methods] contract is that, when the VM encounters an ordinary object (rather than a compiled method) in the method dictionary during lookup, it sends it the special selector #run:with:in: providing the original selector, arguments, and receiver.". DOI: 10.1145/2991041.2991062.
=============== Diff against Kernel-eem.1354 ===============
Item was changed:
----- Method: Context>>send:to:with:lookupIn: (in category 'controlling') -----
send: selector to: rcvr with: arguments lookupIn: lookupClass
+ "Simulate the action of sending a message with selector and arguments to rcvr. The argument, lookupClass, is the class in which to lookup the message. This is the receiver's class for normal messages, but for super messages it will be some specific class related to the source method."
- "Simulate the action of sending a message with selector and arguments
- to rcvr. The argument, lookupClass, is the class in which to lookup the
- message. This is the receiver's class for normal messages, but for super
- messages it will be some specific class related to the source method."
| meth primIndex val ctxt |
(meth := lookupClass lookupSelector: selector) ifNil:
[^self send: #doesNotUnderstand:
to: rcvr
with: {(Message selector: selector arguments: arguments) lookupClass: lookupClass}
lookupIn: lookupClass].
+
+ meth isCompiledMethod ifFalse:
+ ["Object as Methods (OaM) protocol: 'The contract is that, when the VM encounters an ordinary object (rather than a compiled method) in the method dictionary during lookup, it sends it the special selector #run:with:in: providing the original selector, arguments, and receiver.'. DOI: 10.1145/2991041.2991062."
+ ^ self send: #run:with:in:
+ to: meth
+ with: {selector. arguments. rcvr}].
+
+ meth numArgs = arguments size ifFalse:
+ [^ self error: ('Wrong number of arguments in simulated message {1}' translated format: {selector})].
- meth numArgs ~= arguments size ifTrue:
- [^self error: 'Wrong number of arguments in simulated message ', selector printString].
(primIndex := meth primitive) > 0 ifTrue:
[val := self doPrimitive: primIndex method: meth receiver: rcvr args: arguments.
+ (self isPrimFailToken: val) ifFalse:
- (self isPrimFailToken: val) ifFalse:
[^val]].
+
(selector == #doesNotUnderstand: and: [lookupClass == ProtoObject]) ifTrue:
+ [^ self error: ('Simulated message {1} not understood' translated format: {arguments first selector})].
+
- [^self error: 'Simulated message ', arguments first selector, ' not understood'].
ctxt := Context sender: self receiver: rcvr method: meth arguments: arguments.
+ (primIndex notNil and: [primIndex > 0]) ifTrue:
- primIndex > 0 ifTrue:
[ctxt failPrimitiveWith: val].
+
^ctxt!
Marcel Taeumel uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-ct.1359.mcz
==================== Summary ====================
Name: Kernel-ct.1359
Author: ct
Time: 1 November 2020, 7:50:24.183428 pm
UUID: 3b12b316-79f3-de41-8765-8296d964b821
Ancestors: Kernel-mt.1353
Revise and extend Context #runSimulated: implementation. Remove restriction to blocks that do not have a method return. Add support for exception signaling during the execution, which caused unterminated simulation of the calling process in the past. Support argless contextAtEachStep blocks.
Benchmarks:
code:
[Context runSimulated: [100@100 corner: 200@200]] bench
before:
16.7 ms/run
after:
19.8 ms/run
I think this should be okay, given the fact that the primary purpose of simulation is providing explorability but not efficiency ...
=============== Diff against Kernel-mt.1353 ===============
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."
- "Simulate the execution of the argument, current. Answer the result it
- returns."
^ thisContext sender
runSimulated: aBlock
+ contextAtEachStep: []
- contextAtEachStep: [:ignored]
"Context runSimulated: [Pen new defaultNib: 5; go: 100]"!
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."
+
+ | current resume ensure |
+ resume := false.
- runSimulated: aBlock contextAtEachStep: block2
- "Simulate the execution of the argument, aBlock, until it ends. aBlock
- MUST NOT contain an '^'. Evaluate block2 with the current context
- prior to each instruction executed. Answer the simulated value of aBlock."
- | current |
- aBlock hasMethodReturn
- ifTrue: [self error: 'simulation of blocks with ^ can run loose'].
current := aBlock asContext.
+ ensure := current insertSender: (Context contextEnsure: [resume := true]).
+ ensure sender ifNil: [ensure privSender: self]. "For backward compatibility, do not fail if aBlock is dead."
+
+ (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]]] ])
- current pushArgs: Array new from: self.
- [current == self]
whileFalse:
+ [anotherBlock cull: current.
- [block2 value: current.
current := current step].
+
+ ^ current jump!
- ^self pop!
Marcel Taeumel uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-nice.1128.mcz
==================== Summary ====================
Name: System-nice.1128
Author: nice
Time: 9 December 2019, 6:25:31.07858 pm
UUID: 8b2bd676-0898-c843-914e-039dde2db037
Ancestors: System-mt.1127
Nuke windows CE OS support.
Let Win32 VM default to UTF32InputInterpreter rather than MacRomanInputInterpreter.
Note: I think that this method is unused and is just adding confusion to already convoluted code... But it is difficult to analyze the source, so it's better to differ this after 5.3 release if unsure. Unless we have a good set of tests?
=============== Diff against System-mt.1127 ===============
Item was changed:
----- Method: Locale class>>defaultInputInterpreter (in category 'platform specific') -----
defaultInputInterpreter
+ | platformName |
- | platformName osVersion |
platformName := Smalltalk platformName.
+ platformName = 'Win32' ifTrue: [^UTF32InputInterpreter new].
- osVersion := Smalltalk getSystemAttribute: 1002.
- (platformName = 'Win32' and: [osVersion = 'CE'])
- ifTrue: [^NoInputInterpreter new].
- platformName = 'Win32' ifTrue: [^MacRomanInputInterpreter new].
^NoInputInterpreter new!
Marcel Taeumel uploaded a new version of Monticello to project The Trunk:
http://source.squeak.org/trunk/Monticello-mt.731.mcz
==================== Summary ====================
Name: Monticello-mt.731
Author: mt
Time: 4 November 2020, 10:45:45.08162 am
UUID: cc112dfa-3c81-8844-b323-1e07d2f73e32
Ancestors: Monticello-mt.730
Show a warning when trying to copy an inbox version to trunk or treated as a compromise until a proper move operation can be implemented in the image.
=============== Diff against Monticello-mt.730 ===============
Item was changed:
----- Method: MCVersionInspector>>save (in category 'accessing') -----
save
self pickRepository ifNotNil:
+ [:repository |
+ (self repository = MCRepository inbox and:
+ [repository = MCRepository trunk or: [repository = MCRepository treated]]) ifTrue:
+ [self notify: 'Versions from the inbox should only be moved, not copied. Instead, use the web interface via source.squeak.org to manage inbox constributions.\\Do you want to proceed anyway?' translated withCRs].
+ repository storeVersion: self version]!
- [:ea |
- ea storeVersion: self version]!
Marcel Taeumel uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-ct.876.mcz
==================== Summary ====================
Name: Collections-ct.876
Author: ct
Time: 16 February 2020, 3:38:21.566 pm
UUID: 83e0e8f6-a3b2-f540-a88e-6d833e2146fd
Ancestors: Collections-topa.873
Fixes a typo in #withFirstCharacterDownshifted
=============== Diff against Collections-topa.873 ===============
Item was changed:
----- Method: Symbol>>withFirstCharacterDownshifted (in category 'converting') -----
withFirstCharacterDownshifted
+ "Answer an object like the receiver but with first character downshifted if necessary"
- "Answer an object like the receiver but with first character downshifted if necesary"
+ ^self asString withFirstCharacterDownshifted asSymbol!
- ^self asString withFirstCharacterDownshifted asSymbol.!
Marcel Taeumel uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-ct.855.mcz
==================== Summary ====================
Name: Collections-ct.855
Author: ct
Time: 20 September 2019, 6:56:22.518437 pm
UUID: 079663b5-47e2-bd47-bfa4-86db03bd98d8
Ancestors: Collections-mt.854
Add convenience method for adding many attributes to a Text.
=============== Diff against Collections-mt.854 ===============
Item was added:
+ ----- Method: Text>>addAllAttributes: (in category 'emphasis') -----
+ addAllAttributes: attributes
+
+ attributes do: [:attribute |
+ self addAttribute: attribute].!
Eliot Miranda uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-eem.1361.mcz
==================== Summary ====================
Name: Kernel-eem.1361
Author: eem
Time: 2 November 2020, 10:40:38.260046 am
UUID: 7c6efb93-d626-4a62-86f4-c258f8cf199d
Ancestors: Kernel-eem.1360
I couldn't resist...
=============== Diff against Kernel-eem.1360 ===============
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."
^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]]]"!
- "Context runSimulated: [Pen new defaultNib: 5; go: 100]"!
Eliot Miranda uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-eem.1360.mcz
==================== Summary ====================
Name: Kernel-eem.1360
Author: eem
Time: 2 November 2020, 10:10:50.874417 am
UUID: 2041d4e1-746a-49f9-9098-8fbd6ba2f787
Ancestors: Kernel-eem.1359, Kernel-ct.1359
Merge Kernel-ct.1359 from inbox
Author: ct
Time: 1 November 2020, 7:50:24.183428 pm
UUID: 3b12b316-79f3-de41-8765-8296d964b821
Ancestors: Kernel-mt.1353
Revise and extend Context #runSimulated: implementation. Remove restriction to blocks that do not have a method return. Add support for exception signaling during the execution, which caused unterminated simulation of the calling process in the past. Support argless contextAtEachStep blocks.
Benchmarks:
code:
[Context runSimulated: [100@100 corner: 200@200]] bench
before:
16.7 ms/run
after:
19.8 ms/run
I think this should be okay, given the fact that the primary purpose of simulation is providing explorability but not efficiency ...
eem: Fix a bug in the use of runSimulated:contextAtEachStep:. Presumably because of the pre-closure block model existing senders were of the form
thisContext sender
runSimulated: aBlock
contextAtEachStep: [....]
but this caused the jump at the end of runSimulated:contextAtEachStep: to short-cut any processing done after runSimulated:contextAtEachStep:. So rewrite all users of runSimulated:contextAtEachStep: in this form:
thisContext
runSimulated: aBlock
contextAtEachStep: [....]
and consequently have tallyInstruction: rallyMethods: et al answer their intended results.
=============== Diff against Kernel-eem.1359 ===============
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."
- "Simulate the execution of the argument, current. Answer the result it
- returns."
+ ^thisContext
- ^ thisContext sender
runSimulated: aBlock
+ contextAtEachStep: []
- contextAtEachStep: [:ignored]
"Context runSimulated: [Pen new defaultNib: 5; go: 100]"!
Item was changed:
----- Method: Context class>>tallyInstructions: (in category 'examples') -----
tallyInstructions: aBlock
"This method uses the simulator to count the number of occurrences of
each of the Smalltalk instructions executed during evaluation of aBlock.
Results appear in order of the byteCode set."
| tallies |
tallies := Bag new.
+ thisContext
- thisContext sender
runSimulated: aBlock
contextAtEachStep:
[:current | tallies add: current nextByte].
^tallies sortedElements
"Context tallyInstructions: [3.14159 printString]"!
Item was changed:
----- Method: Context class>>tallyMethods: (in category 'examples') -----
tallyMethods: aBlock
"This method uses the simulator to count the number of calls on each method
invoked in evaluating aBlock. Results are given in order of decreasing counts."
| prev tallies |
tallies := Bag new.
prev := aBlock.
+ thisContext
- thisContext sender
runSimulated: aBlock
contextAtEachStep:
[:current |
current == prev ifFalse: "call or return"
[prev sender == nil ifFalse: "call only"
[tallies add: current printString].
prev := current]].
^tallies sortedCounts
"Context tallyMethods: [3.14159 printString]"!
Item was changed:
----- Method: Context class>>trace:on: (in category 'examples') -----
trace: aBlock on: aStream "Context trace: [3 factorial]"
"This method uses the simulator to print calls to a file."
| prev |
prev := aBlock.
+ ^thisContext
- ^ thisContext sender
runSimulated: aBlock
contextAtEachStep:
[:current |
+ Sensor anyButtonPressed ifTrue: [^nil].
+ current == prev ifFalse:
+ [prev sender ifNil:
+ [aStream space; nextPut: $^.
+ self carefullyPrint: current top on: aStream].
+ aStream cr.
+ (current depthBelow: aBlock) timesRepeat: [aStream space].
+ self carefullyPrint: current receiver on: aStream.
+ aStream space; nextPutAll: current selector; flush.
+ prev := current]]!
- Sensor anyButtonPressed ifTrue: [^ nil].
- current == prev
- ifFalse:
- [prev sender ifNil:
- [aStream space; nextPut: $^.
- self carefullyPrint: current top on: aStream].
- aStream cr.
- (current depthBelow: aBlock) timesRepeat: [aStream space].
- self carefullyPrint: current receiver on: aStream.
- aStream space; nextPutAll: current selector; flush.
- prev := current]]!
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."
+
+ | current resume ensure |
+ resume := false.
- runSimulated: aBlock contextAtEachStep: block2
- "Simulate the execution of the argument, aBlock, until it ends. aBlock
- MUST NOT contain an '^'. Evaluate block2 with the current context
- prior to each instruction executed. Answer the simulated value of aBlock."
- | current |
- aBlock hasMethodReturn
- ifTrue: [self error: 'simulation of blocks with ^ can run loose'].
current := aBlock asContext.
+ ensure := current insertSender: (Context contextEnsure: [resume := true]).
+ ensure sender ifNil: [ensure privSender: self]. "For backward compatibility, do not fail if aBlock is dead."
+
+ (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]]] ])
- current pushArgs: Array new from: self.
- [current == self]
whileFalse:
+ [anotherBlock cull: current.
- [block2 value: current.
current := current step].
+
+ ^ current jump!
- ^self pop!