Nicolas Cellier uploaded a new version of Compiler to project The Trunk:
http://source.squeak.org/trunk/Compiler-nice.164.mcz==================== Summary ====================
Name: Compiler-nice.164
Author: nice
Time: 17 August 2010, 10:45:20.737 pm
UUID: edf34da9-a326-490b-97f9-2768511b2768
Ancestors: Compiler-eem.163
Fix the case of special write binding.
Reminder: in case of special write binding, we must:
1) load the VariableBinding
2) push assigned value
3) send value:
(see AssignmentNode>>emitCodeForEffect:encoder: )
#sizeCodeForLoad: read inst var writeNode
#sizeCodeForStore: write inst var writeNode
#sizeCodeForLoad: is sent before #sizeCodeForStore:
Therefore writeNode is read before written and the door is open for bugs.
Fortunately, #sizeCodeForStore: redo the job of #sizeCodeForLoad: and reserve space for pushing the VariableBinding on stack.
Unfortunately, it sometimes happens that the sizeCodeFor... is requested twice, the writeNode is then initialized and sizeCodeForLoad: reserve space for pushing VariableBinding a second time leading to a code size discrepancy...
Present fix implement following solution:
1) let sizeCodeForLoad: reserve size for emitCodeForLoad:encoder: operations, but don't trust writeNode isNil for this job.
2) let sizeCodeForStore: reserve size for - and only for - emitCodeForStore:encoder: operations.
=============== Diff against Compiler-eem.163 ===============
Item was changed:
----- Method: LiteralVariableNode>>sizeCodeForLoad: (in category 'code generation (new scheme)') -----
sizeCodeForLoad: encoder
+ self reserve: encoder.
+ ^(key isVariableBinding and: [key isSpecialWriteBinding])
+ ifTrue: [encoder sizePushLiteral: index]
+ ifFalse: [0]!
- ^writeNode ifNil: [0] ifNotNil: [encoder sizePushLiteral: index]!
Item was changed:
----- Method: LiteralVariableNode>>sizeCodeForStore: (in category 'code generation (new scheme)') -----
sizeCodeForStore: encoder
self reserve: encoder.
(key isVariableBinding and: [key isSpecialWriteBinding]) ifFalse:
[^encoder sizeStoreLiteralVar: index].
code < 0 ifTrue:
[self flag: #dubious.
self code: (self code: self index type: LdLitType)].
"THIS IS WRONG!!!! THE VALUE IS LOST FROM THE STACK!!!!
The various value: methods on Association ReadOnlyVariableBinding
etc _do not_ return the value assigned; they return the receiver."
"Should generate something more like
push expr
push lit
push temp (index of expr)
send value:
pop"
self flag: #bogus.
writeNode := encoder encodeSelector: #value:.
+ ^writeNode sizeCode: encoder args: 1 super: false!
- ^(encoder sizePushLiteralVar: index)
- + (writeNode sizeCode: encoder args: 1 super: false)!