Nicolas Cellier uploaded a new version of Compiler to project The Trunk:
http://source.squeak.org/trunk/Compiler-nice.430.mcz ==================== Summary ==================== Name: Compiler-nice.430 Author: nice Time: 10 May 2020, 9:27:14.242821 am UUID: 7ba9b09a-1ebd-4181-bf85-2dc912f42c9d Ancestors: Compiler-nice.429 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. See http://forum.world.st/Problems-with-caseError-tp5111930p5112255.html TODO: also fix the Decompiler... =============== Diff against Compiler-nice.429 =============== 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 dropReceiver | + dropReceiver := last and: [arguments size >= 2]. - [:keyNode :valueNode :last | | thenSize elseSize | thenSize := sizeStream next. elseSize := sizeStream next. + dropReceiver 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. + dropReceiver ifFalse: [encoder genPop. stack pop: 1]. - last ifFalse: [encoder genPop. stack pop: 1]. valueNode emitCodeForEvaluatedValue: stack encoder: encoder. + dropReceiver 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 dropReceiver | + dropReceiver := last and: [arguments size >= 2]. - [:keyNode :valueNode :last | | thenSize | sizes at: sizeIndex put: elseSize. thenSize := valueNode sizeCodeForEvaluatedValue: encoder. + dropReceiver 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. + dropReceiver 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! |
Free forum by Nabble | Edit this page |