<div dir="ltr"><div>John Brant discovered this bug recenlty:<br><br>(see bottom of his post)<br><a href="http://forum.world.st/collection-flatCollect-something-VS-collection-collect-something-flattened-tp4929422p4929479.html">http://forum.world.st/collection-flatCollect-something-VS-collection-collect-something-flattened-tp4929422p4929479.html</a><br><br></div><br><div><div><div><div class="gmail_extra"><br><div class="gmail_quote">2017-04-21 1:56 GMT+02:00 Eliot Miranda <span dir="ltr"><<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> <br><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Apr 20, 2017 at 4:41 PM, Eliot Miranda <span dir="ltr"><<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Hi All,<div><br></div><div>    just stumbled across a bytecode compiler bug that's in both the Squeak compiler and the Opal compiler.  I'm told by Clément that Opal mimics the bug to avoid crashing legacy code.  So there may be places that depend on this bug.  It would be good to eliminate the dependencies and the bug.</div><div><br></div><div>For illustration look at the to:do: loop in the ifNil: arm in Context>>privRefresh:</div><div><br></div><div>Context>>privRefresh<br></div><div><div><span class="gmail-m_-8577370749062638447m_-1413025380511457414gmail-Apple-tab-span" style="white-space:pre-wrap">  </span>"Reinitialize the receiver so that it is in the state it was at its creation."</div><div><span class="gmail-m_-8577370749062638447m_-1413025380511457414gmail-Apple-tab-span" style="white-space:pre-wrap">        </span>closureOrNil</div><div><span class="gmail-m_-8577370749062638447m_-1413025380511457414gmail-Apple-tab-span" style="white-space:pre-wrap">            </span>ifNotNil:</div><div><span class="gmail-m_-8577370749062638447m_-1413025380511457414gmail-Apple-tab-span" style="white-space:pre-wrap">                       </span>[pc := closureOrNil startpc.</div><div><span class="gmail-m_-8577370749062638447m_-1413025380511457414gmail-Apple-tab-span" style="white-space:pre-wrap">                    </span>self stackp: closureOrNil numArgs + closureOrNil numCopiedValues.</div><div><span class="gmail-m_-8577370749062638447m_-1413025380511457414gmail-Apple-tab-span" style="white-space:pre-wrap">                       </span>1 to: closureOrNil numCopiedValues do:</div><div><span class="gmail-m_-8577370749062638447m_-1413025380511457414gmail-Apple-tab-span" style="white-space:pre-wrap">                          </span>[:i | self tempAt: closureOrNil numArgs + i put: (closureOrNil at: i)]]</div><div><span class="gmail-m_-8577370749062638447m_-1413025380511457414gmail-Apple-tab-span" style="white-space:pre-wrap">         </span>ifNil:</div><div><span class="gmail-m_-8577370749062638447m_-1413025380511457414gmail-Apple-tab-span" style="white-space:pre-wrap">                  </span>[pc := method initialPC.</div><div><span class="gmail-m_-8577370749062638447m_-1413025380511457414gmail-Apple-tab-span" style="white-space:pre-wrap">                        </span>self stackp: method numTemps.</div><div><span class="gmail-m_-8577370749062638447m_-1413025380511457414gmail-Apple-tab-span" style="white-space:pre-wrap">                   </span>method numArgs+1 to: method numTemps do:</div><div><span class="gmail-m_-8577370749062638447m_-1413025380511457414gmail-Apple-tab-span" style="white-space:pre-wrap">                                </span>[:i | self tempAt: i put: nil]]</div><div><br></div><div><br></div><div>This should evaluate method numArgs + 1 then method numTemps.  If it were written as a non-in-lined (method numArgs+1 to: method numTemps) do: [:i| self tempAt: i put: nil] then the [self tempAt: i put: nil] block would be created next.  But the bytecode for the inlined version is</div><div><br></div><div>self stackp: method numTemps.<br></div><div><div>63 <70> self</div><div>64 <84 40 03> pushRcvr: 3</div><div>67 <D6> send: numTemps</div><div>68 <E1> send: stackp:</div><div>69 <87> pop</div><div><br></div><div>iLimit := method numTemps</div><div>70 <84 40 03> pushRcvr: 3</div><div>73 <D6> send: numTemps</div><div>74 <69> popIntoTemp: 1</div><div><br></div><div>i := method numArgs + 1</div><div>75 <84 40 03> pushRcvr: 3</div><div>78 <D2> send: numArgs</div><div>79 <76> pushConstant: 1</div><div>80 <B0> send: +</div><div>81 <81 40> storeIntoTemp: 0 (squeak) <69> popIntoTemp: 1 (pharo)</div><div>83 <10> pushTemp: 0</div><div>84 <11> pushTemp: 1</div><div>85 <B4> send: <=</div><div>86 <AC 0B> jumpFalse: 99</div></div><div><br></div><div>There is a second bug in the Squeak bytecode; storeIntoTemp: is used to load i whereas it should be popIntoTemp:.  It was this second bug that alerted me to the order-of-evaluation bug.</div></div></div></blockquote><div><br></div><div>The second bug (Squeak's use of storeIntoTemp:) is actually only a poor implementation of the value/effect distinction through the inlined ifNil:ifNotNil:.  Because ifNil:ifNotNil: has a value (albeit one that is discarded) the Squeak compiler generates a storeIntoTemp: to p[reserve the value of the to:do: lop, which is the initial index.  So the bug is not within the generation of the to:do: (the only bug there being the order-of-evaluation one).  The bug is actually outside; the loop should be being generated for effect but is being evaluated for value.</div><div><br></div><div>On the order of evaluation bug, does anyone have any memory of which methods depended on this bug?</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div>_,,,^..^,,,_<br></div><div class="gmail-m_-8577370749062638447m_-1413025380511457414gmail_signature"><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>best, Eliot</div></span></div></div></div>
</div></div>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail-m_-8577370749062638447gmail_signature"><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div>
</div></div>
<br></blockquote></div><br></div></div></div></div></div>