<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Sep 22, 2014 at 2:16 PM, Bert Freudenberg <span dir="ltr">&lt;<a href="mailto:bert@freudenbergs.de" target="_blank">bert@freudenbergs.de</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div><span class=""><div>On 22.09.2014, at 22:47, Nicolas Cellier &lt;<a href="mailto:nicolas.cellier.aka.nice@gmail.com" target="_blank">nicolas.cellier.aka.nice@gmail.com</a>&gt; wrote:</div><br><blockquote type="cite"><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">2014-09-22 22:34 GMT+02:00 Bert Freudenberg <span dir="ltr">&lt;<a href="mailto:bert@freudenbergs.de" target="_blank">bert@freudenbergs.de</a>&gt;</span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span><br>
On 22.09.2014, at 22:21, Ron Teitelbaum &lt;<a href="mailto:ron@usmedrec.com" target="_blank">ron@usmedrec.com</a>&gt; wrote:<br>
<br>
&gt;<br>
&gt;&gt; From: Bert Freudenberg<br>
&gt;&gt; Sent: Monday, September 22, 2014 4:00 PM<br>
&gt;&gt;<br>
&gt;&gt; I just found out why PNG decoding was broken in SqueakJS [*]. Wouldn&#39;t<br>
&gt;&gt; have believed that any code actually relied on the following behavior:<br>
&gt;&gt;<br>
&gt;&gt;      | a |<br>
&gt;&gt;      a := (1 to: 20) asArray.<br>
&gt;&gt;      a replaceFrom: 11 to: 20 with: a startingAt: 8.<br>
&gt;&gt;<br>
&gt;&gt;      ==&gt; #(1 2 3 4 5 6 7 8 9 10 8 9 10 8 9 10 8 9 10 8)<br>
&gt;&gt;<br>
&gt; That&#39;s funky!  Hope it wasn&#39;t my code!  Seems wrong to not copy the array<br>
&gt; before modifying it  (Like your buggy VM did).<br>
<br>
</span>It&#39;s not a copy. It moved the numbers 8-17 to index 11. Which is what I erroneously had assumed to be the desired behavior.<br>
<span><font color="#888888"><br>
- Bert -<br>
</font></span><div><div><br></div></div></blockquote><div><br></div><div>It&#39;s a known problem.<br></div><div>The primitive should use memmove rather than memcpy.<br></div><div>So the solution is quite simple, it&#39;s just that it&#39;s waiting for a good soul to integrate it.<br></div></div></div></div></blockquote><div><br></div></span><div>What I&#39;m saying is that there is code which will actually fail in subtle ways if we change that behavior. The LZW decode *relies* on this. If we change the primitive it would fail.</div><div><br></div><div>So rather than changing what the &quot;stringReplace&quot; primitive does we might rather want to add a &quot;stringMove&quot; primitive.</div></div></div></blockquote><div><br></div><div>+1.  An implement a move family, e.g.</div><div><br></div><div><br></div><div>SequenceableCollection&gt;&gt;moveFrom: start to: stop with: replacement startingAt: repStart</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>| index repOff |</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>repOff := repStart - start.</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>start &gt; repStart</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>ifTrue:</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>[index := stop + 1.</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span> [(index := index - 1) &gt;= start] whileTrue:</div><div><span class="Apple-tab-span" style="white-space:pre">                                </span>[self at: index put: (replacement at: repOff + index)]]</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>ifFalse:</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>[index := start - 1.</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span> [(index := index + 1) &lt;= stop] whileTrue:</div><div><span class="Apple-tab-span" style="white-space:pre">                                </span>[self at: index put: (replacement at: repOff + index)]] </div><div><br></div><div>But more reasonably</div><div><br></div><div><div>SequenceableCollection&gt;&gt;moveFrom: start to: stop to: repStart</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>| index repOff |</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>repOff := repStart - start.</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>start &gt; repStart</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>ifTrue:</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>[index := stop + 1.</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span> [(index := index - 1) &gt;= start] whileTrue:</div><div><span class="Apple-tab-span" style="white-space:pre">                                </span>[self at: index put: (self at: repOff + index)]]</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>ifFalse:</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>[index := start - 1.</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span> [(index := index + 1) &lt;= stop] whileTrue:</div><div><span class="Apple-tab-span" style="white-space:pre">                                </span>[self at: index put: (self at: repOff + index)]]</div></div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><div>Btw, BitBlt has &quot;move&quot; semantics and I believe this is even used in some places (via #hackBits:).<br></div></div></div></blockquote><div><br></div><div>Yes, you&#39;re right.  But I think there was a time when you could turn that off and get interesting effects :-).</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><div></div><span class="HOEnZb"><font color="#888888"><div><span class="Apple-style-span" style="font-size:14px">- Bert -</span><br></div></font></span><span class=""><div><span style="font-size:12px"><br></span></div><br><blockquote type="cite"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><br> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div>
&gt; Ron<br>
&gt;<br>
&gt;&gt; In my (buggy) VM it answered<br>
&gt;&gt;<br>
&gt;&gt;      ==&gt; #(1 2 3 4 5 6 7 8 9 10 8 9 10 11 12 13 14 15 16 17)<br>
&gt;&gt;<br>
&gt;&gt; which apparently did not at all match what The Creators intended ;)<br>
&gt;&gt;<br>
&gt;&gt; - Bert -<br>
&gt;&gt;<br>
&gt;&gt; [*] specifically, #decompressBlock:with:<br>
&gt;<br>
&gt;<br>
<br>
<br>
</div></div><br><br>
<br></blockquote></div><br></div></div>
<br></blockquote></span></div><div><span style="border-collapse:separate;border-spacing:0px;font-family:&#39;Lucida Grande&#39;;font-size:12px"><div style="word-wrap:break-word"><br></div></span><br>

</div>
<br></div><br><br>
<br></blockquote></div><br><br clear="all"><div><br></div>-- <br>best,<div>Eliot</div>
</div></div>