<div dir="ltr">Hi Chris, Hi All,<div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jul 2, 2015 at 12:26 PM, Chris Muller <span dir="ltr">&lt;<a href="mailto:ma.chris.m@gmail.com" target="_blank">ma.chris.m@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">We have a release candidate image.<br>
<br>
  <a href="http://ftp.squeak.org/4.6/" rel="noreferrer" target="_blank">http://ftp.squeak.org/4.6/</a><br>
<br>
The new sources file is required.<br>
<br>
Please test your apps.  This could be the final image unless major<br>
issues are uncovered.<br></blockquote><div><br></div><div>One issue that I&#39;m very tempted to address before the final release is the bug to do with inadvertent editing of a breakpointed method.</div><div><br></div><div>When a breakpointed method is installed, the original is kept in a class var of BreakpointManager, and the new method, while it has full source, has that source stored in the method&#39;s trailer, not on the changes file, and so there is no back pointer to the source.  If one doesn&#39;t realise the method contains a break and one redefines it, then the version history for the method will be broken.  The new version fo the method will appear to be the only version.</div><div><br></div><div>There are two things that IMO should be done:</div><div><br></div><div>1. a special warning should be raised when the compiler encounters a self break in method source.  The BreakpointManager can catch and squash this warning when it is raised, but the warning can alert the programmer and give them a chance to abort the compilation, revert the method, and resubmit.</div><div><br></div><div>2. when ClassDescription&gt;&gt;logMethodSource:forMethodWithNode:inCategory:withStamp:notifying: looks for the previous version of a method it can query the BreakpointManager to find out if the current version is a breakpointed method and get the real method from the BreakpointManager to preserve the history links.</div><div><br></div><div>#1 is nice to have, and likely reduces the need for #2, but #2 is a must-have because it prevents history links being broken.  My issue is how ClassDescription&gt;&gt;logMethodSource:forMethodWithNode:inCategory:withStamp:notifying: queries the BreakpointManager.  The issue is the dependency it introduces in a key Kernel method on the SYstem package.  Right now there are probably lots of such dependencies and unloading System is impossible anyway, but I don&#39;t want to introduce any more dependencies. I can see two approaches that avoid the dependency.</div><div><br></div><div>One is to use CompiledMethod&gt;&gt;#hasBreakpoint:</div><div><br></div><div><div>logMethodSource: aText forMethodWithNode: aCompiledMethodWithNode inCategory: category withStamp: changeStamp notifying: requestor</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>| priorMethodOrNil newText |</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>priorMethodOrNil := self compiledMethodAt: aCompiledMethodWithNode selector ifAbsent: [].</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>(priorMethodOrNil notNil and: [priorMethodOrNil hasBreakpoint]) ifTrue:</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>[priorMethodOrNil := priorMethodOrNil nonBreakpointedOriginal].</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>newText := (requestor notNil</div><div><span class="Apple-tab-span" style="white-space:pre">                                                </span>and: [Preferences confirmFirstUseOfStyle])</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>ifTrue: [aText askIfAddStyle: priorMethodOrNil req: requestor]</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>ifFalse: [aText].</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>aCompiledMethodWithNode method putSource: newText</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>fromParseNode: aCompiledMethodWithNode node</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>class: self category: category withStamp: changeStamp </div><div><span class="Apple-tab-span" style="white-space:pre">                </span>inFile: 2 priorMethod: priorMethodOrNil.</div></div><div><br></div><div>where CompiledMethod&gt;&gt; nonBreakpointedOriginal is a new method that gets the original from BreakpointManager.  But for this to be a good approach CompiledMethod&gt;&gt; hasBreakpoint needs to be an override.  Currently hasBreakpoint is a System method:</div><div><br></div><div><div>!CompiledMethod methodsFor: &#39;*System-Tools-debugger support&#39; stamp: &#39;emm 5/30/2002 09:22&#39;!</div><div>hasBreakpoint</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>^BreakpointManager methodHasBreakpoint: self! !</div></div><div><br></div><div>SO the question is how do I introduce an original that read</div><div><br></div><div><div>!CompiledMethod methodsFor: &#39;debugger support&#39; stamp: &#39;blah de blah&#39;!</div><div>hasBreakpoint</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>^false! !</div></div><div> </div><div>so that  System&#39;s version overrides it?  Also how do I write an update that accomplishes that?</div><div><br></div><div><br></div><div>The second approach is merely to use Smalltalk classNamed:, but that&#39;s ugly:</div><div><br></div><div><div>logMethodSource: aText forMethodWithNode: aCompiledMethodWithNode inCategory: category withStamp: changeStamp notifying: requestor</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>| priorMethodOrNil newText |</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>priorMethodOrNil := self compiledMethodAt: aCompiledMethodWithNode selector ifAbsent: [].</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>priorMethodOrNil ifNotNil:</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>[(Smalltalk classNamed: #BreakpointManager) ifNotNil:</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>[priorMethodOrNil := priorMethodOrNil nonBreakpointedOriginalFor: priorMethodOrNil]].</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>newText := (requestor notNil</div><div><span class="Apple-tab-span" style="white-space:pre">                                                </span>and: [Preferences confirmFirstUseOfStyle])</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>ifTrue: [aText askIfAddStyle: priorMethodOrNil req: requestor]</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>ifFalse: [aText].</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>aCompiledMethodWithNode method putSource: newText</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>fromParseNode: aCompiledMethodWithNode node</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>class: self category: category withStamp: changeStamp </div><div><span class="Apple-tab-span" style="white-space:pre">                </span>inFile: 2 priorMethod: priorMethodOrNil.</div></div><div><br></div><div>or something similar.</div><div><br></div><div><br></div><div>I wouldn&#39;t suggest this except that I&#39;ve made this error several times in the VMMaker package over the past few weeks.  it&#39;s very easy to do, and it screws up history horribly.  i really think we should fix this.  It makes breakpoints dangerous otherwise.</div><div><br></div><div>What d&#39;y&#39;all think?</div></div><div><br></div>-- <br><div class="gmail_signature">best,<div>Eliot</div></div>
</div></div>