Eliot Miranda uploaded a new version of Compiler to project The Trunk:
http://source.squeak.org/trunk/Compiler-eem.384.mcz
==================== Summary ====================
Name: Compiler-eem.384
Author: eem
Time: 16 June 2018, 3:23:37.766854 pm
UUID: 79e07928-38ba-489e-a330-42bca61aac02
Ancestors: Compiler-eem.383
Oops! We need that support method.
=============== Diff against Compiler-eem.383 ===============
Item was added:
+ ----- Method: CompiledMethod>>newBlockStartMap (in category '*Compiler-private') -----
+ newBlockStartMap
+ "If blocks are embedded then keys in the map are simple integer pcs and a Dictionary can be used.
+ If blocks are full (separate method objects) then keys in the map are CompiledBlocks and
+ IdentityDictionary must be used to avoid confusing blocks with identical code."
+ ^(self encoderClass supportsFullBlocks
+ ifTrue: [IdentityDictionary]
+ ifFalse: [Dictionary]) new!
Eliot Miranda uploaded a new version of Compiler to project The Trunk:
http://source.squeak.org/trunk/Compiler-eem.383.mcz
==================== Summary ====================
Name: Compiler-eem.383
Author: eem
Time: 16 June 2018, 3:20:33.200059 pm
UUID: f72d6072-25d5-4064-8c6a-03cb9752c910
Ancestors: Compiler-eem.382
Fix decompilation in the full block regime. Whem mapping from block starts to ranges, temp names, etc, the keys are Compiledblock instance4s, not simple integer pcs, and so IdentityDictioanries must be used so as not to confuse two blocks that have the same literals and bytecodes.
=============== Diff against Compiler-eem.382 ===============
Item was changed:
----- Method: CompiledMethod>>mapFromBlockKeys:toSchematicTemps: (in category '*Compiler-support') -----
mapFromBlockKeys: keys toSchematicTemps: schematicTempNamesString
"Decode a schematicTempNamesString that encodes the layout of temp names
in a method and any closures/blocks within it, matching keys in keys to
vectors of temp names."
| map tempNames |
+ map := self newBlockStartMap.
- map := Dictionary new.
tempNames := schematicTempNamesString readStream.
keys do:
[:key| | tempSequence tempIndex |
tempSequence := OrderedCollection new.
tempIndex := 0.
[(tempNames skipSeparators; peek) ifNil: [true] ifNotNil: [:ch| '[]' includes: ch]] whileFalse:
[tempNames peek = $(
ifTrue: [tempSequence addAllLast: ((self tempsSubSequenceFrom: (tempNames next; yourself)) withIndexCollect:
[:temp :index|
{ temp. { tempIndex + 1. index } }]).
tempNames peek ~= $) ifTrue: [self error: 'parse error'].
tempIndex := tempIndex + 1.
tempNames next]
ifFalse: [tempSequence addAllLast: ((self tempsSubSequenceFrom: tempNames) withIndexCollect:
[:temp :index|
{ temp. tempIndex := tempIndex + 1 }])]].
map at: key put: tempSequence asArray.
[tempNames peek = $]] whileTrue: [tempNames next].
tempNames peek = $[ ifTrue:
[tempNames next]].
^map!
Item was changed:
----- Method: CompiledMethod>>startKeysToBlockExtents (in category '*Compiler-support') -----
startKeysToBlockExtents
"Answer a Dictionary of start key to Interval of blockExtent, using the
identical numbering scheme described in and orchestrated by
BlockNode>>analyseArguments:temporaries:rootNode:. A start key
identifies a block within a method and is either the startpc for an
embedded block or the block method itself for a full block. This is
used in part to find the temp names for any block in a method, as
needed by the debugger. The other half is to recompile the method,
obtaining the temp names for each block extent. By indirecting through
the blockExtent instead of using the startpc directly we decouple the
debugger's access to temp names from the exact bytecode; insulating
debugging from minor changes in the compiler (e.g. changes in literal
pooling, adding prefix bytecodes, adding inst vars to CompiledMethod
in literals towards the end of the literal frame, etc). If the recompilation
doesn't produce exactly the same bytecode at exactly the same offset
no matter; the blockExtents will be the same."
| index |
self flag: 'belongs in DebuggerMethodMap'.
index := 0.
^self
+ blockExtentsInto: self newBlockStartMap
- blockExtentsInto: Dictionary new
from: self initialPC
to: self endPC
method: self
numberer: [| value | value := index. index := index + 2. value]!
Item was changed:
----- Method: Decompiler>>statementsTo: (in category 'control') -----
statementsTo: end
"Decompile the method from pc up to end and return an array of
expressions. If at run time this block will leave a value on the stack,
set hasValue to true. If the block ends with a jump or return, set exit
to the destination of the jump, or the end of the method; otherwise, set
exit = end. Leave pc = end."
+ | encoderClass blockPos stackPos localLastPC |
- | encoderClass blockPos stackPos |
encoderClass := method encoderClass.
blockPos := statements size.
stackPos := stack size.
[pc < end]
whileTrue:
+ [lastPc := localLastPC := pc. limit := end. "for performs"
- [lastPc := pc. limit := end. "for performs"
"If you want instrumentation replace the following statement with this one,
and edit the implementation:
self interpretNextInstructionFor: self"
encoderClass interpretNextInstructionFor: self in: self].
"If there is an additional item on the stack, it will be the value
of this block."
(hasValue := stack size > stackPos)
ifTrue:
[statements addLast: stack removeLast].
lastJumpPc = lastPc ifFalse: [exit := pc].
^self popTo: blockPos!
Eliot Miranda uploaded a new version of Tools to project The Trunk:
http://source.squeak.org/trunk/Tools-eem.821.mcz
==================== Summary ====================
Name: Tools-eem.821
Author: eem
Time: 16 June 2018, 2:35:48.93167 pm
UUID: bfb6adeb-a9c8-44a3-bd7e-fe35f317872d
Ancestors: Tools-eem.820
Correct pc range computation for full blocks. "self method" answers the home metyhod, and hence confuses things horribly when using full blocks. This is a slip; I had added the method argument but not used it in all cases. Doh!
=============== Diff against Tools-eem.820 ===============
Item was removed:
- ----- Method: DebuggerMethodMap>>rangeForPC:contextIsActiveContext: (in category 'private but obsolete') -----
- rangeForPC: contextsConcretePC contextIsActiveContext: contextIsActiveContext
- "Answer the indices in the source code for the supplied pc.
- If the context is the actve context (is at the hot end of the stack)
- then its pc is the current pc. But if the context isn't, because it is
- suspended sending a message, then its current pc is the previous pc."
-
- | pc i end |
- pc := self method abstractPCForConcretePC: (contextIsActiveContext
- ifTrue: [contextsConcretePC]
- ifFalse: [(self method pcPreviousTo: contextsConcretePC)
- ifNotNil: [:prevpc| prevpc]
- ifNil: [contextsConcretePC]]).
- (self abstractSourceMap includesKey: pc) ifTrue:
- [^self abstractSourceMap at: pc].
- sortedSourceMap ifNil:
- [sortedSourceMap := self abstractSourceMap associations
- replace: [ :each | each copy ];
- sort].
- sortedSourceMap isEmpty ifTrue: [^1 to: 0].
- i := sortedSourceMap findNearbyBinaryIndex: [:assoc| pc - assoc key].
- i < 1 ifTrue: [^1 to: 0].
- i > sortedSourceMap size ifTrue:
- [end := sortedSourceMap inject: 0 into:
- [:prev :this | prev max: this value last].
- ^end+1 to: end].
- ^(sortedSourceMap at: i) value
-
- "| method source scanner map |
- method := DebuggerMethodMap compiledMethodAt: #rangeForPC:contextIsActiveContext:.
- source := method getSourceFromFile asString.
- scanner := InstructionStream on: method.
- map := method debuggerMap.
- Array streamContents:
- [:ranges|
- [scanner atEnd] whileFalse:
- [| range |
- range := map rangeForPC: scanner pc contextIsActiveContext: true.
- ((map abstractSourceMap includesKey: scanner abstractPC)
- and: [range first ~= 0]) ifTrue:
- [ranges nextPut: (source copyFrom: range first to: range last)].
- scanner interpretNextInstructionFor: InstructionClient new]]"!
Item was changed:
----- Method: DebuggerMethodMap>>rangeForPC:in:contextIsActiveContext: (in category 'source mapping') -----
rangeForPC: contextsConcretePC in: method contextIsActiveContext: contextIsActiveContext
"Answer the indices in the source code for the supplied pc.
If the context is the actve context (is at the hot end of the stack)
then its pc is the current pc. But if the context isn't, because it is
suspended sending a message, then its current pc is the previous pc."
| pc i end |
+ pc := method abstractPCForConcretePC: (contextIsActiveContext
- pc := self method abstractPCForConcretePC: (contextIsActiveContext
ifTrue: [contextsConcretePC]
+ ifFalse: [(method pcPreviousTo: contextsConcretePC)
- ifFalse: [(self method pcPreviousTo: contextsConcretePC)
ifNotNil: [:prevpc| prevpc]
ifNil: [contextsConcretePC]]).
(self abstractSourceMap includesKey: pc) ifTrue:
[^self abstractSourceMap at: pc].
sortedSourceMap ifNil:
[sortedSourceMap := self abstractSourceMap associations
replace: [ :each | each copy ];
sort].
sortedSourceMap isEmpty ifTrue: [^1 to: 0].
i := sortedSourceMap findNearbyBinaryIndex: [:assoc| pc - assoc key].
i < 1 ifTrue: [^1 to: 0].
i > sortedSourceMap size ifTrue:
[end := sortedSourceMap inject: 0 into:
[:prev :this | prev max: this value last].
^end+1 to: end].
^(sortedSourceMap at: i) value
"| method source scanner map |
method := DebuggerMethodMap compiledMethodAt: #rangeForPC:in:contextIsActiveContext:.
source := method getSourceFromFile asString.
scanner := InstructionStream on: method.
map := method debuggerMap.
Array streamContents:
[:ranges|
[scanner atEnd] whileFalse:
[| range |
range := map rangeForPC: scanner pc in: method contextIsActiveContext: true.
((map abstractSourceMap includesKey: scanner abstractPC)
and: [range first ~= 0]) ifTrue:
[ranges nextPut: (source copyFrom: range first to: range last)].
scanner interpretNextInstructionFor: InstructionClient new]]"!
Item was changed:
----- Method: DebuggerMethodMapForFullBlockCompiledMethods>>rangeForPC:in:contextIsActiveContext: (in category 'source mapping') -----
rangeForPC: contextsConcretePC in: method contextIsActiveContext: contextIsActiveContext
"Answer the indices in the source code for the supplied pc.
If the context is the actve context (is at the hot end of the stack)
then its pc is the current pc. But if the context isn't, because it is
suspended sending a message, then its current pc is the previous pc."
| pc i end mapForMethod sortedMap |
+ pc := method abstractPCForConcretePC: (contextIsActiveContext
- pc := self method abstractPCForConcretePC: (contextIsActiveContext
ifTrue: [contextsConcretePC]
+ ifFalse: [(method pcPreviousTo: contextsConcretePC)
- ifFalse: [(self method pcPreviousTo: contextsConcretePC)
ifNotNil: [:prevpc| prevpc]
ifNil: [contextsConcretePC]]).
((mapForMethod := self abstractSourceMapForMethod: method) includesKey: pc) ifTrue:
[^mapForMethod at: pc].
sortedSourceMap ifNil:
[sortedSourceMap := IdentityDictionary new].
sortedMap := sortedSourceMap
at: method
ifAbsentPut: [mapForMethod associations
replace: [ :each | each copy ];
sort].
sortedMap isEmpty ifTrue: [^1 to: 0].
i := sortedMap findNearbyBinaryIndex: [:assoc| pc - assoc key].
i < 1 ifTrue: [^1 to: 0].
i > sortedMap size ifTrue:
[end := sortedMap inject: 0 into:
[:prev :this | prev max: this value last].
^end+1 to: end].
^(sortedMap at: i) value
"| method source scanner map |
method := DebuggerMethodMapForFullBlockCompiledMethods compiledMethodAt: #rangeForPC:in:contextIsActiveContext:.
source := method getSourceFromFile asString.
scanner := InstructionStream on: method.
map := method debuggerMap.
Array streamContents:
[:ranges|
[scanner atEnd] whileFalse:
[| range |
range := map rangeForPC: scanner pc in: method contextIsActiveContext: true.
((map abstractSourceMap includesKey: scanner abstractPC)
and: [range first ~= 0]) ifTrue:
[ranges nextPut: (source copyFrom: range first to: range last)].
scanner interpretNextInstructionFor: InstructionClient new]]"!
Eliot Miranda uploaded a new version of Monticello to project The Trunk:
http://source.squeak.org/trunk/Monticello-eem.684.mcz
==================== Summary ====================
Name: Monticello-eem.684
Author: eem
Time: 15 June 2018, 1:08:30.353809 pm
UUID: edb03d67-d035-4a12-a5d8-8351848c9e0a
Ancestors: Monticello-dtl.683
Add MCMethodDefinition>>protocol, a much better message name than "category".
=============== Diff against Monticello-dtl.683 ===============
Item was added:
+ ----- Method: MCMethodDefinition>>protocol (in category 'accessing') -----
+ protocol
+ "Answer in which protocol (conceptual groups of methods) the receiver is grouped into."
+ ^category!
Eliot Miranda uploaded a new version of Monticello to project The Trunk:
http://source.squeak.org/trunk/Monticello-TonelReaderTest.684.mcz
==================== Summary ====================
Name: Monticello-TonelReaderTest.684
Author: TonelReaderTest
Time: 15 June 2018, 12:39:16.107577 pm
UUID: fafb033d-9440-4a4a-bdb6-a6d6f7eb4b6a
Ancestors: Monticello-dtl.683
Add MCMethodDefinition>>protocol, a much better selectror name than category.
=============== Diff against Monticello-dtl.683 ===============
Item was added:
+ ----- Method: MCMethodDefinition>>protocol (in category 'accessing') -----
+ protocol
+ "Answer in which protocol (conceptual groups of methods) the receiver is grouped into."
+ ^category!
Eliot Miranda uploaded a new version of Tools to project The Trunk:
http://source.squeak.org/trunk/Tools-eem.820.mcz
==================== Summary ====================
Name: Tools-eem.820
Author: eem
Time: 14 June 2018, 4:02:54.342614 pm
UUID: 7c6f4563-ffe9-4fa7-ac3c-eccfbd88b635
Ancestors: Tools-nice.819
Provide concretePCForAbstractPC:, the inverse of abstractPCForConcretePC:. Used by the TempScopeEditor
=============== Diff against Tools-nice.819 ===============
Item was added:
+ ----- Method: CompiledCode>>concretePCForAbstractPC: (in category '*Tools-Debugger-support') -----
+ concretePCForAbstractPC: abstractPCQuery
+ "Answer the concretePC matching abstractPC."
+
+ | abstractPC scanner client endPC |
+ self flag: 'belongs in DebuggerMethodMap?'.
+ abstractPC := 1.
+ scanner := InstructionStream on: self.
+ client := InstructionClient new.
+ "cache endPC for methods with embedded source; finding out the endPC is very slow in this case..."
+ endPC := self endPC.
+ [abstractPC >= abstractPCQuery ifTrue:
+ [^scanner pc].
+ abstractPC := abstractPC + 1.
+ scanner interpretNextInstructionFor: client.
+ scanner pc < endPC] whileTrue.
+ ^endPC!
Levente Uzonyi uploaded a new version of Tests to project The Trunk:
http://source.squeak.org/trunk/Tests-ul.400.mcz
==================== Summary ====================
Name: Tests-ul.400
Author: ul
Time: 14 June 2018, 11:55:26.048374 pm
UUID: 4c2d51f0-2dc3-4f2f-8ba9-87f1ee697845
Ancestors: Tests-ul.399
do not nag the user about setting the author initials #4
=============== Diff against Tests-ul.399 ===============
Item was changed:
----- Method: MethodReferenceTest>>setUp (in category 'running') -----
setUp
| g p |
env := Environment withName: 'test'.
g := self createClass: #Griffle.
p := self createClass: #Plonk.
+ g compileSilently: 'foo ^ 1'.
- g compile: 'foo ^ 1'.
g organization classify: #foo under: #accessing.
+ g class compileSilently: 'classFoo ^ 1'.
+ g compileSilently: 'bar ^ 1'.
+ p compileSilently: 'foo ^ 2'.
- g class compile: 'classFoo ^ 1'.
- g compile: 'bar ^ 1'.
- p compile: 'foo ^ 2'.
self createClass: #Unused.!