David T. Lewis uploaded a new version of Chronology-Core to project The Trunk:
http://source.squeak.org/trunk/Chronology-Core-ul.21.mcz
==================== Summary ====================
Name: Chronology-Core-ul.21
Author: dtl
Time: 4 January 2019, 1:17:39.848442 pm
UUID: 5d9b02fa-8e37-4678-adda-f302163732a1
Ancestors: Chronology-Core-dtl.20
>From Chronology-Core-ul.21 from inbox, and resaved to ensure that version history exactly matches that of trunk. Updated by dtl and saved with original author initials.
Name: Chronology-Core-ul.21
Author: ul
Time: 26 December 2018, 1:48:40.220196 am
UUID: 2e6f6ce2-d0ec-41a0-b27c-88c642e5afc9
Ancestors: Chronology-Core-dtl.20
- fix: do not subtract the offset twice while evaluating DateAndTime >> #setJdn:seconds:nano:localOffsetSeconds:
- use 0 for seconds in DateAndTime >> #midnight, because the offset will not be subtracted from the passed value
=============== Diff against Chronology-Core-dtl.20 ===============
Item was changed:
----- Method: DateAndTime>>midnight (in category 'squeak protocol') -----
midnight
"Answer a DateAndTime starting at midnight of the same timezone offset as the receiver."
^ self class basicNew
setJdn: self julianDayNumber
+ seconds: 0
- seconds: localOffsetSeconds
nano: 0
localOffsetSeconds: localOffsetSeconds.!
Item was changed:
----- Method: DateAndTime>>setJdn:seconds:nano:localOffsetSeconds: (in category 'private') -----
setJdn: jdn seconds: s nano: n localOffsetSeconds: offset
localOffsetSeconds := offset.
utcMicroseconds := self
microsecondsFromDay: jdn
+ seconds: s
- seconds: s - offset
nanos: n
offset: offset!
Eliot Miranda uploaded a new version of Compiler to project The Trunk:
http://source.squeak.org/trunk/Compiler-eem.398.mcz
==================== Summary ====================
Name: Compiler-eem.398
Author: eem
Time: 3 January 2019, 3:47:34.750814 pm
UUID: 641c8172-6e85-49c8-aa42-0e2cd184e05a
Ancestors: Compiler-eem.397
Fix a spelling error
=============== Diff against Compiler-eem.397 ===============
Item was changed:
----- Method: MethodNode>>preenableNodes (in category 'converting-private') -----
preenableNodes
"Answer a Dictionary from node or sequence of nodes to preen method selector for nodes
in the tree that require post-processing after either a format or a decompile. Such issues
are the variable for an ifNotNil: which is local to the ifNotNil: block but, due to the inlining
of ifNotNil: appears to be declared at the outer level, and, similarly, a temporary variable
that conflicts with one of the same name in a block when, were the variable declared
local to some inlined block it would no longer conflict. The resulting dictionary is used to
perform the value with the key (node or array) as argument to preen the tree."
| preenableNodes priorBlocks priorVariables |
preenableNodes := Dictionary new.
priorBlocks := OrderedCollection new.
priorVariables := Set new.
+ self nodesWithPrecedingStatementsDo:
- self nodesWithPreceedingStatementsDo:
[:node :preceedingStatementOrNil| | variable temps |
(node isMessageNode
and: [node macroPrinter == #printIfNilNotNil:indent:
and: [node receiver isMessageNode
and: [node receiver selector key == #==
and: [node receiver receiver isAssignmentNode
and: [(variable := node receiver receiver variable) isTemp
and: [variable isRemote not
and: [variable isOnlySubnodeOf: node in: self]]]]]]]) ifTrue:
[preenableNodes at: node put: #preenIfNotNilNode:.
priorVariables add: variable].
node isBlockNode ifTrue:
[temps := OrderedCollection new.
node temporaries do:
[:temp|
priorBlocks do:
[:aBlock|
aBlock temporaries do:
[:priorTemp|
(priorVariables includes: priorTemp) ifFalse:
[priorTemp key = temp key ifTrue:
[temps addLast: priorTemp]]]]].
temps isEmpty ifFalse:
[preenableNodes at: temps put: #preenTempsConflictingWithBlockNode:].
priorBlocks addLast: node].
(node == NodeNil
and: [preceedingStatementOrNil notNil
and: [preceedingStatementOrNil isMessageNode
and: [preceedingStatementOrNil isNilIf]]]) ifTrue:
[preenableNodes at: preceedingStatementOrNil put: #preenNilNodeFollowingNilIfNode:]].
^preenableNodes!
Item was added:
+ ----- Method: ParseNode>>nodesWithPrecedingStatementsDo: (in category 'visiting') -----
+ nodesWithPrecedingStatementsDo: aBinaryBlock
+ self accept: (ParseNodeWithPrecedingStatementEnumerator ofBlock: aBinaryBlock)!
Item was removed:
- ----- Method: ParseNode>>nodesWithPreceedingStatementsDo: (in category 'visiting') -----
- nodesWithPreceedingStatementsDo: aBinaryBlock
- self accept: (ParseNodeWithPreceedingStatementEnumerator ofBlock: aBinaryBlock)!
Item was added:
+ ParseNodeEnumerator subclass: #ParseNodeWithPrecedingStatementEnumerator
+ instanceVariableNames: 'precedingStatement'
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'Compiler-Support'!
Item was added:
+ ----- Method: ParseNodeWithPrecedingStatementEnumerator>>ofBlock: (in category 'initialize-release') -----
+ ofBlock: aBlock
+ "N.B. This enumerator visits a node before any of the node's children.
+ Hence, when enumewrating statements in a block, we can ensure that
+ the second argument to the block, the preceeding statement, is non-nil
+ only for top-level statements in the block by nilling out preceedingStatement
+ once the block is evaluated. Perhaps stronger would be to capture its value
+ in a temporary and nil it before evaluating, but this is good enough."
+ theBlock := [:node|
+ aBlock value: node value: precedingStatement.
+ preceedingStatement := nil]!
Item was added:
+ ----- Method: ParseNodeWithPrecedingStatementEnumerator>>ofBlock:select: (in category 'initialize-release') -----
+ ofBlock: aBlock select: aSelectBlock
+ self ofBlock: aBlock.
+ theSelectBlock := aSelectBlock!
Item was added:
+ ----- Method: ParseNodeWithPrecedingStatementEnumerator>>visitBlockNode: (in category 'visiting') -----
+ visitBlockNode: aBlockNode
+ | savedPrecedingStatement |
+ (theSelectBlock isNil or: [theSelectBlock value: aBlockNode]) ifFalse:
+ [^nil].
+ theBlock value: aBlockNode.
+ savedPrecedingStatement := precedingStatement.
+ precedingStatement := nil.
+ [aBlockNode statements do:
+ [:statement|
+ statement accept: self.
+ precedingStatement := statement]] ensure:
+ [precedingStatement := savedPrecedingStatement]!
Item was removed:
- ParseNodeEnumerator subclass: #ParseNodeWithPreceedingStatementEnumerator
- instanceVariableNames: 'preceedingStatement'
- classVariableNames: ''
- poolDictionaries: ''
- category: 'Compiler-Support'!
Item was removed:
- ----- Method: ParseNodeWithPreceedingStatementEnumerator>>ofBlock: (in category 'initialize-release') -----
- ofBlock: aBlock
- "N.B. This enumerator visits a node before any of the node's children.
- Hence, when enumewrating statements in a block, we can ensure that
- the second argument to the block, the preceeding statement, is non-nil
- only for top-level statements in the block by nilling out preceedingStatement
- once the block is evaluated. Perhaps stronger would be to capture its value
- in a temporary and nil it before evaluating, but this is good enough."
- theBlock := [:node|
- aBlock value: node value: preceedingStatement.
- preceedingStatement := nil]!
Item was removed:
- ----- Method: ParseNodeWithPreceedingStatementEnumerator>>ofBlock:select: (in category 'initialize-release') -----
- ofBlock: aBlock select: aSelectBlock
- self ofBlock: aBlock.
- theSelectBlock := aSelectBlock!
Item was removed:
- ----- Method: ParseNodeWithPreceedingStatementEnumerator>>visitBlockNode: (in category 'visiting') -----
- visitBlockNode: aBlockNode
- | savedPreceedingStatement |
- (theSelectBlock isNil or: [theSelectBlock value: aBlockNode]) ifFalse:
- [^nil].
- theBlock value: aBlockNode.
- savedPreceedingStatement := preceedingStatement.
- preceedingStatement := nil.
- [aBlockNode statements do:
- [:statement|
- statement accept: self.
- preceedingStatement := statement]] ensure:
- [preceedingStatement := savedPreceedingStatement]!
Eliot Miranda uploaded a new version of Tests to project The Trunk:
http://source.squeak.org/trunk/Tests-eem.405.mcz
==================== Summary ====================
Name: Tests-eem.405
Author: eem
Time: 3 January 2019, 3:07:27.378757 pm
UUID: 17c87dc5-be34-42cc-b043-82315ab82527
Ancestors: Tests-pre.404
Add tests that check that for all methods in a package all pcs in nodes in that method map to valid pcs.
=============== Diff against Tests-pre.404 ===============
Item was added:
+ ----- Method: CompiledMethod class>>noCheckSetPreferredBytecodeSetTo:while: (in category '*Tests-Compiler-support') -----
+ noCheckSetPreferredBytecodeSetTo: encoderClass while: aBlock
+ | savedEncoderClass |
+ encoderClass == PreferredBytecodeSetEncoderClass ifTrue:
+ [^aBlock value].
+ savedEncoderClass := PreferredBytecodeSetEncoderClass.
+ PreferredBytecodeSetEncoderClass := encoderClass.
+ ^aBlock ensure: [PreferredBytecodeSetEncoderClass := savedEncoderClass]!
Item was added:
+ ----- Method: CompilerTest>>runTestAllNodePCsAreForBytecodesInMethod: (in category 'private') -----
+ runTestAllNodePCsAreForBytecodesInMethod: aMethod
+ "Before 1/3/2019 14:10 the bytecode compiler would ascribe the wrong pcs for long conditional branches
+ at the head of ifTrue:ifFalse: et al. This test checks that all nodes with a pc map to a real bytecode."
+ | class methodAndNode bytecodes |
+ class := aMethod methodClass.
+ methodAndNode := CompiledMethod
+ noCheckSetPreferredBytecodeSetTo: aMethod encoderClass
+ while:
+ [class
+ compile:(class sourceCodeAt: aMethod selector)
+ environment: class environment
+ notifying: nil
+ trailer: aMethod trailer
+ ifFail: [^nil]].
+ bytecodes := self validPCsForMethod: methodAndNode method.
+ bytecodes add: methodAndNode node pc.
+ methodAndNode node nodesDo:
+ [:node|
+ node pc ifNotNil:
+ [:pc|
+ self assert: (bytecodes includes: pc)]]!
Item was added:
+ ----- Method: CompilerTest>>runTestAllNodePCsAreForBytecodesInPackage: (in category 'private') -----
+ runTestAllNodePCsAreForBytecodesInPackage: packageName
+ "Before 1/3/2019 14:10 the bytecode compiler would ascribe the wrong pcs for long conditional branches
+ at the head of ifTrue:ifFalse: et al. This slow test checks that all nodes with a pc in any method map to a
+ real bytecode."
+ (PackageInfo named: packageName) actualMethodsDo:
+ [:method| self runTestAllNodePCsAreForBytecodesInMethod: method]!
Item was added:
+ ----- Method: CompilerTest>>testAllNodePCsAreForBytecodesInCollections (in category 'debugging') -----
+ testAllNodePCsAreForBytecodesInCollections
+ <timeout: 30> "Approximately 2 seconds on 2018 2.9GHz Core i9 MacBook Pro running 64-bit Squeak Cog VM"
+ self runTestAllNodePCsAreForBytecodesInPackage: #Collections!
Item was added:
+ ----- Method: CompilerTest>>testAllNodePCsAreForBytecodesInKernel (in category 'debugging') -----
+ testAllNodePCsAreForBytecodesInKernel
+ <timeout: 30> "Approximately 3 seconds on 2018 2.9GHz Core i9 MacBook Pro running 64-bit Squeak Cog VM"
+ self runTestAllNodePCsAreForBytecodesInPackage: #Kernel!
Item was added:
+ ----- Method: CompilerTest>>testAllNodePCsAreForBytecodesInMorphic (in category 'debugging') -----
+ testAllNodePCsAreForBytecodesInMorphic
+ <timeout: 30> "Approximately 6 seconds on 2018 2.9GHz Core i9 MacBook Pro running 64-bit Squeak Cog VM"
+ self runTestAllNodePCsAreForBytecodesInPackage: #Morphic!
Item was added:
+ ----- Method: CompilerTest>>validPCsForMethod: (in category 'private') -----
+ validPCsForMethod: aMethod
+ "Answer a set of pcs (either integer pc for the method and embedded blocks,
+ or CompiledBlock -> integer pc for nested full blocks."
+ | validPCs is |
+ validPCs := Set new: aMethod size - aMethod initialPC.
+ (is := InstructionStream on: aMethod) scanFor:
+ [:b| validPCs add: is pc. false].
+ aMethod nestedBlockMethods do:
+ [:bm|
+ (is := InstructionStream on: bm) scanFor:
+ [:b| validPCs add: bm -> is pc. false]].
+ ^validPCs!