[squeak-dev] The Inbox: Compiler-nice.427.mcz

commits at source.squeak.org commits at source.squeak.org
Fri Apr 17 10:52:18 UTC 2020


Nicolas Cellier uploaded a new version of Compiler to project The Inbox:
http://source.squeak.org/inbox/Compiler-nice.427.mcz

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

Name: Compiler-nice.427
Author: nice
Time: 17 April 2020, 12:52:15.465993 pm
UUID: 1ea19d4a-47f4-4c94-8fef-2b43c99f2b04
Ancestors: Compiler-ct.426

Fixup: caseError must be sent to the receiver of the caseOf: message, not to the receiver of the home method.

For this, we must also dup/pop in the last case whenever there is no otherwise argument.

TODO: also fix the Decompiler...

=============== Diff against Compiler-ct.426 ===============

Item was changed:
  ----- Method: MessageNode>>emitCodeForCase:encoder:value: (in category 'code generation') -----
  emitCodeForCase: stack encoder: encoder value: forValue
  
  	| braceNode sizeStream allReturn |
  	forValue ifFalse:
  		[^super emitCodeForEffect: stack encoder: encoder].
  	braceNode := arguments first.
  	sizeStream := ReadStream on: sizes.
  	receiver emitCodeForValue: stack encoder: encoder.
  	"There must be at least one branch around the otherwise/caseError
  	  so the decompiler can identify the end of the otherwise/caseError."
  	allReturn := true. "assume every case ends with a return"
  	braceNode casesForwardDo:
  		[:keyNode :valueNode :last | | thenSize elseSize |
  		thenSize := sizeStream next.
  		elseSize := sizeStream next.
+ 		(last and: [arguments size = 2]) ifFalse: [encoder genDup. stack push: 1].
- 		last ifFalse: [encoder genDup. stack push: 1].
  		keyNode emitCodeForEvaluatedValue: stack encoder: encoder.
  		keyNode pc: encoder nextPC.
  		equalNode emitCode: stack args: 1 encoder: encoder.
  		self emitCodeForBranchOn: false dist: thenSize pop: stack encoder: encoder.
+ 		(last and: [arguments size = 2]) ifFalse: [encoder genPop. stack pop: 1].
- 		last ifFalse: [encoder genPop. stack pop: 1].
  		valueNode emitCodeForEvaluatedValue: stack encoder: encoder.
+ 		(last and: [arguments size = 2]) ifTrue: [stack pop: 1].
- 		last ifTrue: [stack pop: 1].
  		valueNode returns ifFalse:
  			[self emitCodeForJump: elseSize encoder: encoder.
  			 allReturn := false].
  		(last and: [allReturn]) ifTrue:
  			[self emitCodeForJump: elseSize encoder: encoder]].
  	arguments size = 2
  		ifTrue:
  			[arguments last emitCodeForEvaluatedValue: stack encoder: encoder] "otherwise: [...]"
  		ifFalse:
+ 			["the receiver of caseOf: has been previously dup, just send"
- 			[NodeSelf emitCodeForValue: stack encoder: encoder.
  			caseErrorNode emitCode: stack args: 0 encoder: encoder]!

Item was changed:
  ----- Method: MessageNode>>sizeCodeForCase:value: (in category 'code generation') -----
  sizeCodeForCase: encoder value: forValue
  
  	| braceNode sizeIndex elseSize allReturn |
  	forValue not ifTrue:
  		[^super sizeCodeForEffect: encoder].
  	equalNode := encoder encodeSelector: #=.
  	braceNode := arguments first.
  	sizes := Array new: 2 * braceNode numElements.
  	sizeIndex := sizes size.
  	elseSize := arguments size = 2
  		ifTrue:
  			[arguments last sizeCodeForEvaluatedValue: encoder] "otherwise: [...]"
  		ifFalse:
  			[caseErrorNode := encoder encodeSelector: #caseError.
+ 			 "Assume that the receiver of caseOf: has been dup"
+ 			(caseErrorNode sizeCode: encoder args: 0 super: false)]. "self caseError"
- 			 (NodeSelf sizeCodeForValue: encoder)
- 			 + (caseErrorNode sizeCode: encoder args: 0 super: false)]. "self caseError"
  	"There must be at least one branch around the otherwise/caseError
  	  so the decompiler can identify the end of the otherwise/caseError."
  	allReturn := true. "assume every case ends with a return"
  	braceNode casesForwardDo:
  		[:keyNode :valueNode :last |
  		valueNode returns ifFalse: [allReturn := false]].
  	braceNode casesReverseDo:
  		[:keyNode :valueNode :last | | thenSize |
  		sizes at: sizeIndex put: elseSize.
  		thenSize := valueNode sizeCodeForEvaluatedValue: encoder.
+ 		(last and: [arguments size = 2]) ifFalse: [thenSize := thenSize + encoder sizePop].
- 		last ifFalse: [thenSize := thenSize + encoder sizePop].
  		valueNode returns ifFalse: [thenSize := thenSize + (self sizeCode: encoder forJump: elseSize)].
  		(last and: [allReturn]) ifTrue: [thenSize := thenSize + (self sizeCode: encoder forJump: elseSize)].
  		sizes at: sizeIndex-1 put: thenSize.
+ 		(last and: [arguments size = 2]) ifFalse: [elseSize := elseSize + encoder sizeDup].
- 		last ifFalse: [elseSize := elseSize + encoder sizeDup].
  		elseSize := elseSize
  					+ (keyNode sizeCodeForEvaluatedValue: encoder)
  					+ (equalNode sizeCode: encoder args: 1 super: false)
  					+ (self sizeCode: encoder forBranchOn: false dist: thenSize)
  					+ thenSize.
  		sizeIndex := sizeIndex - 2].
  	^(receiver sizeCodeForValue: encoder) + elseSize!



More information about the Squeak-dev mailing list