[squeak-dev] The Inbox: Compiler-ct.464.mcz

commits at source.squeak.org commits at source.squeak.org
Mon Nov 22 17:14:20 UTC 2021


A new version of Compiler was added to project The Inbox:
http://source.squeak.org/inbox/Compiler-ct.464.mcz

==================== Summary ====================

Name: Compiler-ct.464
Author: ct
Time: 22 November 2021, 6:14:18.611261 pm
UUID: b062f356-9bfa-d142-9175-1334362731ec
Ancestors: Compiler-mt.462

Honors otherwise block argument for #caseOf:otherwise: expressions in the decompiler. This fixes the DecompilerTests again. See Kernel-mt.1422.

(The part with the tempReadCounts checking is adopted from DecompilerConstructor >> #decodeIfNilWithReceiver:selector:arguments:tempReadCounts:.)

=============== Diff against Compiler-mt.462 ===============

Item was changed:
  ----- Method: Decompiler>>case: (in category 'instruction decoding') -----
  case: dist
  	"statements = keyStmts CascadeFlag keyValueBlock ... keyStmts"
  
+ 	| nextCase thenJump stmtStream elements b node cases otherBlock myExits receiver |
- 	| nextCase thenJump stmtStream elements b node cases otherBlock myExits |
  	nextCase := pc + dist.
  
  	"Now add CaseFlag & keyValueBlock to statements"
  	statements addLast: stack removeLast.
  	"Trick: put a flag on the stack.
  	If it is the last case before otherwise: block, then
  	- there won't be a dup of caseOf: receiver before sending =
  	- there won't be a pop in the case handling block"
  	stack addLast: OtherwiseFlag. "set for next pop"
  	statements addLast: (self blockForCaseTo: nextCase).
  		
  	stack last == OtherwiseFlag
  		ifTrue: "Last case"
  			["ensure jump is within block (in case thenExpr returns wierdly I guess)"
  			stack removeLast. "get rid of CaseFlag"
  			stmtStream := ReadStream on: (self popTo: stack removeLast).
  			
  			elements := OrderedCollection new.
  			b := OrderedCollection new.
  			[stmtStream atEnd] whileFalse:
  				[(node := stmtStream next) == CaseFlag
  					ifTrue:
  						[elements addLast: (constructor
  							codeMessage: (constructor codeBlock: b returns: false)
  							selector: (constructor codeSelector: #-> code: #macro)
  							arguments: (Array with: stmtStream next)).
  						 b := OrderedCollection new]
  					ifFalse: [b addLast: node]].
  			b size > 0 ifTrue: [self error: 'Bad cases'].
  			cases := constructor codeBrace: elements.
  			
  			"try find the end of the case"
  			myExits := caseExits removeLast: elements size.
  			myExits := myExits reject: [ :e | e isNil or: [ e < 0 or: [ e > method endPC ] ] ].
  			thenJump := myExits isEmpty
  							ifTrue: [ nextCase ]
  							ifFalse: [ myExits max ].
  			
  			otherBlock := self blockTo: thenJump.
+ 			receiver := stack removeLast.
+ 			"Like #to:(by:)do:, support only local temps."
+ 			receiver ifNilTemporary ifNotNil: [:temp |
+ 				((tempReadCounts includesKey: temp) or: [
+ 					"What about 'object caseOf: {...} otherwise: [:o | ]', which as not read the blockArg? Just check that there is no remote vector pointing to it."
+ 					tempReadCounts keys noneSatisfy:
+ 						[:otherTemp |
+ 							otherTemp isIndirectTempVector
+ 								ifTrue: [otherTemp remoteTemps anySatisfy:
+ 									[:remoteTemp |
+ 									remoteTemp name = temp name]]
+ 								ifFalse: [otherTemp name = temp name]]
+ 						])
+ 					ifTrue: [
+ 						temp beBlockArg.
+ 						otherBlock arguments: {temp}]].
  			stack addLast:
  				(constructor
+ 					codeMessage: receiver
- 					codeMessage: stack removeLast
  					selector: (constructor codeSelector: #caseOf:otherwise: code: #macro)
  					arguments: (Array with: cases with: otherBlock))].!

Item was changed:
  ----- Method: MessageNode>>printCaseOn:indent: (in category 'printing') -----
  printCaseOn: aStream indent: level 
  	"receiver caseOf: {[key]->[value]. ...} otherwise: [otherwise]"
  	| braceNode otherwise extra |
  	braceNode := arguments first.
  	otherwise := arguments last.
  	(arguments size = 1 or: [otherwise isJustCaseError]) ifTrue:
  		[otherwise := nil].
+ 	receiver ifNilValue
- 	receiver
  		printOn: aStream
  		indent: level
  		precedence: 3.
  	aStream nextPutAll: ' caseOf: '.
  	braceNode isVariableReference
  		ifTrue: [braceNode printOn: aStream indent: level]
  		ifFalse: 
  			[aStream nextPutAll: '{'; crtab: level + 1.
  			 braceNode casesForwardDo:
  				[:keyNode :valueNode :last | 
  				keyNode printOn: aStream indent: level + 1.
  				aStream nextPutAll: ' -> '.
  				valueNode isComplex
  					ifTrue: 
  						[aStream crtab: level + 2.
  						extra := 1]
  					ifFalse: [extra := 0].
  				valueNode printOn: aStream indent: level + 1 + extra.
  				last ifTrue: [aStream nextPut: $}]
  					ifFalse: [aStream nextPut: $.;
  							 crtab: level + 1]]].
  	otherwise notNil ifTrue:
  		[aStream crtab: level + 1; nextPutAll: ' otherwise: '.
  		 extra := otherwise isComplex
  					ifTrue: 
  						[aStream crtab: level + 2.
  						 1]
  					ifFalse: [0].
  		 otherwise printOn: aStream indent: level + 1 + extra]!



More information about the Squeak-dev mailing list