<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">&lt;<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>&gt;</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&#39;s stack index)<br>
        send value:<br>
        pop<br>
<br>
=============== Diff against Compiler-eem.257 ===============<br>
<br>
Item was changed:<br>
  ----- Method: AssignmentNode&gt;&gt;emitCodeForEffect:encoder: (in category &#39;code generation&#39;) -----<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. &quot;debug pc is first byte of the store, i.e. the next byte&quot;.<br>
        variable emitCodeForStorePop: stack encoder: encoder!<br>
<br>
Item was changed:<br>
  ----- Method: AssignmentNode&gt;&gt;emitCodeForValue:encoder: (in category &#39;code generation&#39;) -----<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. &quot;debug pc is first byte of the store, i.e. the next byte&quot;.<br>
        variable emitCodeForStore: stack encoder: encoder!<br>
<br>
Item was changed:<br>
  ----- Method: AssignmentNode&gt;&gt;sizeCodeForEffect: (in category &#39;code generation&#39;) -----<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&gt;&gt;sizeCodeForValue: (in category &#39;code generation&#39;) -----<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&gt;&gt;sizePushTempLong: (in category &#39;opcode sizing&#39;) -----<br>
+ sizePushTempLong: tempIndex<br>
+       ^self sizeOpcodeSelector: #genPushTempLong: withArguments: {tempIndex}!<br>
<br>
Item was added:<br>
+ ----- Method: EncoderForV3&gt;&gt;genPushTempLong: (in category &#39;bytecode generation&#39;) -----<br>
+ genPushTempLong: tempIndex<br>
+       &quot;See BlueBook page 596&quot;<br>
+       (tempIndex &gt;= 0 and: [tempIndex &lt; 64]) ifTrue:<br>
+               [&quot;128   10000000 jjkkkkkk       Push (Receiver Variable, Temporary Location, Literal Constant, Literal Variable) [jj] #kkkkkk&quot;<br>
+                stream<br>
+                       nextPut: 128;<br>
+                       nextPut: 64 + tempIndex.<br>
+                ^self].<br>
+       ^self outOfRangeError: &#39;index&#39; index: tempIndex range: 0 to: 63!<br>
<br>
Item was removed:<br>
- ----- Method: FieldNode&gt;&gt;emitCodeForLoad:encoder: (in category &#39;code generation&#39;) -----<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&gt;&gt;emitCodeForLoad:forValue:encoder: (in category &#39;code generation&#39;) -----<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&gt;&gt;emitCodeForLoad:encoder: (in category &#39;code generation&#39;) -----<br>
- emitCodeForLoad: stack encoder: encoder<br>
-       &quot;Default is to do nothing.<br>
-        Subclasses may need to override.&quot;!<br>
<br>
Item was added:<br>
+ ----- Method: LeafNode&gt;&gt;emitCodeForLoad:forValue:encoder: (in category &#39;code generation&#39;) -----<br>
+ emitCodeForLoad: stack forValue: forValue encoder: encoder<br>
+       &quot;Default is to do nothing.<br>
+        Subclasses may need to override.&quot;!<br>
<br>
Item was removed:<br>
- ----- Method: LeafNode&gt;&gt;sizeCodeForLoad: (in category &#39;code generation&#39;) -----<br>
- sizeCodeForLoad: encoder<br>
-       &quot;Default is to do nothing.<br>
-        Subclasses may need to override.&quot;<br>
-       ^0!<br>
<br>
Item was added:<br>
+ ----- Method: LeafNode&gt;&gt;sizeCodeForLoad:forValue: (in category &#39;code generation&#39;) -----<br>
+ sizeCodeForLoad: encoder forValue: forValue<br>
+       &quot;Default is to do nothing.<br>
+        Subclasses may need to override.&quot;<br>
+       ^0!<br>
<br>
Item was removed:<br>
- ----- Method: LiteralVariableNode&gt;&gt;emitCodeForLoad:encoder: (in category &#39;code generation&#39;) -----<br>
- emitCodeForLoad: stack encoder: encoder<br>
-       writeNode ifNotNil:<br>
-               [encoder genPushLiteral: index.<br>
-                stack push: 1]!<br>
<br>
Item was added:<br>
+ ----- Method: LiteralVariableNode&gt;&gt;emitCodeForLoad:forValue:encoder: (in category &#39;code generation&#39;) -----<br>
+ emitCodeForLoad: stack forValue: forValue encoder: encoder<br>
+       &quot;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:.&quot;<br>
+       (writeNode isNil or: [forValue]) ifTrue: [^self].<br>
+       encoder genPushLiteral: index.<br>
+       stack push: 1!<br>
<br>
Item was changed:<br>
  ----- Method: LiteralVariableNode&gt;&gt;emitCodeForStore:encoder: (in category &#39;code generation&#39;) -----<br>
  emitCodeForStore: stack encoder: encoder<br>
+       | exprOffset |<br>
        writeNode ifNil: [^encoder genStoreLiteralVar: index].<br>
+       &quot;On entry the stack has only the expression.  Push the binding,<br>
+        duplicate the expression, send #value: and pop.&quot;<br>
+       exprOffset := stack position - 1.<br>
+       encoder genPushLiteral: index.<br>
+       stack push: 1.<br>
+       encoder genPushTempLong: exprOffset.<br>
+       stack push: 1.<br>
-       &quot;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.&quot;<br>
-       &quot;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:&quot;<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&gt;&gt;sizeCodeForLoad: (in category &#39;code generation&#39;) -----<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&gt;&gt;sizeCodeForLoad:forValue: (in category &#39;code generation&#39;) -----<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&gt;&gt;sizeCodeForStore: (in category &#39;code generation&#39;) -----<br>
  sizeCodeForStore: encoder<br>
        self reserve: encoder.<br>
        (key isVariableBinding and: [key isSpecialWriteBinding]) ifFalse:<br>
                [^encoder sizeStoreLiteralVar: index].<br>
        code &lt; 0 ifTrue:<br>
                [self flag: #dubious.<br>
                 self code: (self code: self index type: LdLitType)].<br>
-       &quot;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.&quot;<br>
-       &quot;Should generate something more like<br>
-               push expr<br>
-               push lit<br>
-               push temp (index of expr)<br>
-               send value:<br>
-               pop&quot;<br>
-       self flag: #bogus.<br>
        writeNode := encoder encodeSelector: #value:.<br>
+       &quot;On entry the stack has only the expression.  Push the binding,<br>
+        duplicate the expression, send #value: and pop.&quot;<br>
+       ^(encoder sizePushLiteral: index)<br>
+         + (encoder sizePushTempLong: 0) &quot;we don&#39;t know yet, hence long, sigh...&quot;<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&gt;&gt;emitCodeForLoad:encoder: (in category &#39;code generation&#39;) -----<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&gt;&gt;emitCodeForLoad:forValue:encoder: (in category &#39;code generation&#39;) -----<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&gt;&gt;sizeCodeForLoad: (in category &#39;code generation&#39;) -----<br>
- sizeCodeForLoad: encoder<br>
-       ^remoteNode<br>
-               ifNil: [0]<br>
-               ifNotNil: [remoteNode sizeCodeForLoadFor: self encoder: encoder]!<br>
<br>
Item was added:<br>
+ ----- Method: TempVariableNode&gt;&gt;sizeCodeForLoad:forValue: (in category &#39;code generation&#39;) -----<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&gt;&gt;emitCodeForLoad:encoder: (in category &#39;code generation&#39;) -----<br>
- emitCodeForLoad: stack encoder: encoder<br>
-       &quot;Do nothing&quot;!<br>
<br>
Item was added:<br>
+ ----- Method: VariableNode&gt;&gt;emitCodeForLoad:forValue:encoder: (in category &#39;code generation&#39;) -----<br>
+ emitCodeForLoad: stack forValue: forValue encoder: encoder<br>
+       &quot;Do nothing&quot;!<br>
<br>
<br>
</blockquote></div><br></div>