<div dir="ltr">Please review Compiler-nice.260 in the inbox because emitying code of a special assigment for effect seems to push twice the binding and pop only once. (If you run Decompiler tests you can see it)<br></div><div class="gmail_extra">
<br><br><div class="gmail_quote">2013/4/3 <span dir="ltr"><<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>></span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Eliot Miranda uploaded a new version of Compiler to project The Trunk:<br>
<a href="http://source.squeak.org/trunk/Compiler-eem.258.mcz" target="_blank">http://source.squeak.org/trunk/Compiler-eem.258.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: Compiler-eem.258<br>
Author: eem<br>
Time: 3 April 2013, 12:59:36.409 pm<br>
UUID: 7721a43f-63e6-4524-bb6d-48eddc955654<br>
Ancestors: Compiler-eem.257<br>
<br>
Fix store of special bindings. Exsting code dropped the<br>
value assigned from the stack, so v := binding := expr would<br>
leave v holding binding, not expr. New code generates<br>
push expr<br>
push binding<br>
duplicate expr (by pushTemp: of expr's stack index)<br>
send value:<br>
pop<br>
<br>
=============== Diff against Compiler-eem.257 ===============<br>
<br>
Item was changed:<br>
----- Method: AssignmentNode>>emitCodeForEffect:encoder: (in category 'code generation') -----<br>
emitCodeForEffect: stack encoder: encoder<br>
<br>
+ variable emitCodeForLoad: stack forValue: false encoder: encoder.<br>
- variable emitCodeForLoad: stack encoder: encoder.<br>
value emitCodeForValue: stack encoder: encoder.<br>
pc := encoder methodStreamPosition + 1. "debug pc is first byte of the store, i.e. the next byte".<br>
variable emitCodeForStorePop: stack encoder: encoder!<br>
<br>
Item was changed:<br>
----- Method: AssignmentNode>>emitCodeForValue:encoder: (in category 'code generation') -----<br>
emitCodeForValue: stack encoder: encoder<br>
<br>
+ variable emitCodeForLoad: stack forValue: true encoder: encoder.<br>
- variable emitCodeForLoad: stack encoder: encoder.<br>
value emitCodeForValue: stack encoder: encoder.<br>
pc := encoder methodStreamPosition + 1. "debug pc is first byte of the store, i.e. the next byte".<br>
variable emitCodeForStore: stack encoder: encoder!<br>
<br>
Item was changed:<br>
----- Method: AssignmentNode>>sizeCodeForEffect: (in category 'code generation') -----<br>
sizeCodeForEffect: encoder<br>
<br>
+ ^(variable sizeCodeForLoad: encoder forValue: false)<br>
- ^(variable sizeCodeForLoad: encoder)<br>
+ (value sizeCodeForValue: encoder)<br>
+ (variable sizeCodeForStorePop: encoder)!<br>
<br>
Item was changed:<br>
----- Method: AssignmentNode>>sizeCodeForValue: (in category 'code generation') -----<br>
sizeCodeForValue: encoder<br>
<br>
+ ^(variable sizeCodeForLoad: encoder forValue: true)<br>
- ^(variable sizeCodeForLoad: encoder)<br>
+ (value sizeCodeForValue: encoder)<br>
+ (variable sizeCodeForStore: encoder)!<br>
<br>
Item was added:<br>
+ ----- Method: BytecodeEncoder>>sizePushTempLong: (in category 'opcode sizing') -----<br>
+ sizePushTempLong: tempIndex<br>
+ ^self sizeOpcodeSelector: #genPushTempLong: withArguments: {tempIndex}!<br>
<br>
Item was added:<br>
+ ----- Method: EncoderForV3>>genPushTempLong: (in category 'bytecode generation') -----<br>
+ genPushTempLong: tempIndex<br>
+ "See BlueBook page 596"<br>
+ (tempIndex >= 0 and: [tempIndex < 64]) ifTrue:<br>
+ ["128 10000000 jjkkkkkk Push (Receiver Variable, Temporary Location, Literal Constant, Literal Variable) [jj] #kkkkkk"<br>
+ stream<br>
+ nextPut: 128;<br>
+ nextPut: 64 + tempIndex.<br>
+ ^self].<br>
+ ^self outOfRangeError: 'index' index: tempIndex range: 0 to: 63!<br>
<br>
Item was removed:<br>
- ----- Method: FieldNode>>emitCodeForLoad:encoder: (in category 'code generation') -----<br>
- emitCodeForLoad: stack encoder: encoder<br>
- rcvrNode emitCodeForValue: stack encoder: encoder.<br>
- fieldDef accessKey ifNotNil:[<br>
- super emitCodeForValue: stack encoder: encoder.<br>
- ].!<br>
<br>
Item was added:<br>
+ ----- Method: FieldNode>>emitCodeForLoad:forValue:encoder: (in category 'code generation') -----<br>
+ emitCodeForLoad: stack forValue: forValue encoder: encoder<br>
+ rcvrNode emitCodeForValue: stack encoder: encoder.<br>
+ fieldDef accessKey ifNotNil:<br>
+ [super emitCodeForValue: stack encoder: encoder]!<br>
<br>
Item was removed:<br>
- ----- Method: LeafNode>>emitCodeForLoad:encoder: (in category 'code generation') -----<br>
- emitCodeForLoad: stack encoder: encoder<br>
- "Default is to do nothing.<br>
- Subclasses may need to override."!<br>
<br>
Item was added:<br>
+ ----- Method: LeafNode>>emitCodeForLoad:forValue:encoder: (in category 'code generation') -----<br>
+ emitCodeForLoad: stack forValue: forValue encoder: encoder<br>
+ "Default is to do nothing.<br>
+ Subclasses may need to override."!<br>
<br>
Item was removed:<br>
- ----- Method: LeafNode>>sizeCodeForLoad: (in category 'code generation') -----<br>
- sizeCodeForLoad: encoder<br>
- "Default is to do nothing.<br>
- Subclasses may need to override."<br>
- ^0!<br>
<br>
Item was added:<br>
+ ----- Method: LeafNode>>sizeCodeForLoad:forValue: (in category 'code generation') -----<br>
+ sizeCodeForLoad: encoder forValue: forValue<br>
+ "Default is to do nothing.<br>
+ Subclasses may need to override."<br>
+ ^0!<br>
<br>
Item was removed:<br>
- ----- Method: LiteralVariableNode>>emitCodeForLoad:encoder: (in category 'code generation') -----<br>
- emitCodeForLoad: stack encoder: encoder<br>
- writeNode ifNotNil:<br>
- [encoder genPushLiteral: index.<br>
- stack push: 1]!<br>
<br>
Item was added:<br>
+ ----- Method: LiteralVariableNode>>emitCodeForLoad:forValue:encoder: (in category 'code generation') -----<br>
+ emitCodeForLoad: stack forValue: forValue encoder: encoder<br>
+ "If a normal literal variable (not sending value:), do nothing.<br>
+ If for value (e.g. v := Binding := expr) do nothing; the work will be done in emitCodeForStore:encoder:.<br>
+ If not for value then indeed load. The rest of the work will be done in emitCodeForStorePop:encoder:."<br>
+ (writeNode isNil or: [forValue]) ifTrue: [^self].<br>
+ encoder genPushLiteral: index.<br>
+ stack push: 1!<br>
<br>
Item was changed:<br>
----- Method: LiteralVariableNode>>emitCodeForStore:encoder: (in category 'code generation') -----<br>
emitCodeForStore: stack encoder: encoder<br>
+ | exprOffset |<br>
writeNode ifNil: [^encoder genStoreLiteralVar: index].<br>
+ "On entry the stack has only the expression. Push the binding,<br>
+ duplicate the expression, send #value: and pop."<br>
+ exprOffset := stack position - 1.<br>
+ encoder genPushLiteral: index.<br>
+ stack push: 1.<br>
+ encoder genPushTempLong: exprOffset.<br>
+ stack push: 1.<br>
- "THIS IS WRONG!!!! THE VALUE IS LOST FROM THE STACK!!!!<br>
- The various value: methods on Association ReadOnlyVariableBinding<br>
- etc _do not_ return the value assigned; they return the receiver."<br>
- "Should generate something more like<br>
- push expr<br>
- push lit<br>
- push temp (index of expr)<br>
- send value:<br>
- pop<br>
- or use e.g. valueForStore:"<br>
- self flag: #bogus.<br>
writeNode<br>
emitCode: stack<br>
args: 1<br>
encoder: encoder<br>
+ super: false.<br>
+ stack pop: 1.<br>
+ encoder genPop!<br>
- super: false!<br>
<br>
Item was removed:<br>
- ----- Method: LiteralVariableNode>>sizeCodeForLoad: (in category 'code generation') -----<br>
- sizeCodeForLoad: encoder<br>
- self reserve: encoder.<br>
- ^(key isVariableBinding and: [key isSpecialWriteBinding])<br>
- ifTrue: [encoder sizePushLiteral: index]<br>
- ifFalse: [0]!<br>
<br>
Item was added:<br>
+ ----- Method: LiteralVariableNode>>sizeCodeForLoad:forValue: (in category 'code generation') -----<br>
+ sizeCodeForLoad: encoder forValue: forValue<br>
+ self reserve: encoder.<br>
+ ^(key isVariableBinding and: [key isSpecialWriteBinding and: [forValue not]])<br>
+ ifTrue: [encoder sizePushLiteral: index]<br>
+ ifFalse: [0]!<br>
<br>
Item was changed:<br>
----- Method: LiteralVariableNode>>sizeCodeForStore: (in category 'code generation') -----<br>
sizeCodeForStore: encoder<br>
self reserve: encoder.<br>
(key isVariableBinding and: [key isSpecialWriteBinding]) ifFalse:<br>
[^encoder sizeStoreLiteralVar: index].<br>
code < 0 ifTrue:<br>
[self flag: #dubious.<br>
self code: (self code: self index type: LdLitType)].<br>
- "THIS IS WRONG!!!! THE VALUE IS LOST FROM THE STACK!!!!<br>
- The various value: methods on Association ReadOnlyVariableBinding<br>
- etc _do not_ return the value assigned; they return the receiver."<br>
- "Should generate something more like<br>
- push expr<br>
- push lit<br>
- push temp (index of expr)<br>
- send value:<br>
- pop"<br>
- self flag: #bogus.<br>
writeNode := encoder encodeSelector: #value:.<br>
+ "On entry the stack has only the expression. Push the binding,<br>
+ duplicate the expression, send #value: and pop."<br>
+ ^(encoder sizePushLiteral: index)<br>
+ + (encoder sizePushTempLong: 0) "we don't know yet, hence long, sigh..."<br>
+ + (writeNode sizeCode: encoder args: 1 super: false)<br>
+ + encoder sizePop!<br>
- ^writeNode sizeCode: encoder args: 1 super: false!<br>
<br>
Item was removed:<br>
- ----- Method: TempVariableNode>>emitCodeForLoad:encoder: (in category 'code generation') -----<br>
- emitCodeForLoad: stack encoder: encoder<br>
- remoteNode ~~ nil ifTrue:<br>
- [remoteNode emitCodeForLoadFor: self stack: stack encoder: encoder]!<br>
<br>
Item was added:<br>
+ ----- Method: TempVariableNode>>emitCodeForLoad:forValue:encoder: (in category 'code generation') -----<br>
+ emitCodeForLoad: stack forValue: forValue encoder: encoder<br>
+ remoteNode ~~ nil ifTrue:<br>
+ [remoteNode emitCodeForLoadFor: self stack: stack encoder: encoder]!<br>
<br>
Item was removed:<br>
- ----- Method: TempVariableNode>>sizeCodeForLoad: (in category 'code generation') -----<br>
- sizeCodeForLoad: encoder<br>
- ^remoteNode<br>
- ifNil: [0]<br>
- ifNotNil: [remoteNode sizeCodeForLoadFor: self encoder: encoder]!<br>
<br>
Item was added:<br>
+ ----- Method: TempVariableNode>>sizeCodeForLoad:forValue: (in category 'code generation') -----<br>
+ sizeCodeForLoad: encoder forValue: forValue<br>
+ ^remoteNode<br>
+ ifNil: [0]<br>
+ ifNotNil: [remoteNode sizeCodeForLoadFor: self encoder: encoder]!<br>
<br>
Item was removed:<br>
- ----- Method: VariableNode>>emitCodeForLoad:encoder: (in category 'code generation') -----<br>
- emitCodeForLoad: stack encoder: encoder<br>
- "Do nothing"!<br>
<br>
Item was added:<br>
+ ----- Method: VariableNode>>emitCodeForLoad:forValue:encoder: (in category 'code generation') -----<br>
+ emitCodeForLoad: stack forValue: forValue encoder: encoder<br>
+ "Do nothing"!<br>
<br>
<br>
</blockquote></div><br></div>