<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Exchange Server">
<!-- converted from text --><style><!-- .EmailQuote { margin-left: 1pt; padding-left: 4pt; border-left: #800000 2px solid; } --></style>
</head>
<body>
<meta content="text/html; charset=UTF-8">
<style type="text/css" style="">
<!--
p
        {margin-top:0;
        margin-bottom:0}
-->
</style>
<div dir="ltr">
<div id="x_divtagdefaultwrapper" dir="ltr" style="font-size:12pt; color:#000000; font-family:Calibri,Helvetica,sans-serif">
<p>Hi Marcel, thanks for merging! :-)</p>
<p>(You did not mention the fix of #doesNotUnderstand: simulation, but it does not matter.)</p>
<p><br>
</p>
<p>Just two interested questions:</p>
<p><span style="font-size:12pt">1.</span><span style="font-size:12pt"> Does Monticello provide an option for me to watch the changes you adapted to my commits directly? "Changes" against my working copy show so much noise (a have many changes in my working
 copy) that I cannot see the interesting changes there.</span></p>
<p><span style="font-size:12pt">2. #<span>isSpecialCategoryName: - what was the reason not to use #includes: but #or: here? Performance? Just curious :-)</span></span></p>
<p><span style="font-size:12pt"><span><br>
</span></span></p>
<p><span style="font-size:12pt"><span>Best,</span></span></p>
<p><span style="font-size:12pt"><span>Christoph</span></span></p>
<div id="x_Signature">
<div id="x_divtagdefaultwrapper" dir="ltr" style="font-size:12pt; color:rgb(0,0,0); font-family:Calibri,Helvetica,sans-serif,EmojiFont,"Apple Color Emoji","Segoe UI Emoji",NotoColorEmoji,"Segoe UI Symbol","Android Emoji",EmojiSymbols">
<div name="x_divtagdefaultwrapper" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:; margin:0">
<div><font size="2" color="#808080"></font></div>
</div>
</div>
</div>
</div>
<hr tabindex="-1" style="display:inline-block; width:98%">
<div id="x_divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>Von:</b> Squeak-dev <squeak-dev-bounces@lists.squeakfoundation.org> im Auftrag von commits@source.squeak.org <commits@source.squeak.org><br>
<b>Gesendet:</b> Freitag, 21. Februar 2020 16:20:35<br>
<b>An:</b> squeak-dev@lists.squeakfoundation.org; packages@lists.squeakfoundation.org<br>
<b>Betreff:</b> [squeak-dev] The Trunk: Kernel-mt.1303.mcz</font>
<div> </div>
</div>
</div>
<font size="2"><span style="font-size:10pt;">
<div class="PlainText">Marcel Taeumel uploaded a new version of Kernel to project The Trunk:<br>
<a href="http://source.squeak.org/trunk/Kernel-mt.1303.mcz">http://source.squeak.org/trunk/Kernel-mt.1303.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: Kernel-mt.1303<br>
Author: mt<br>
Time: 21 February 2020, 4:20:32.494211 pm<br>
UUID: 0ef679e3-e47a-9945-b433-a81e5ecb8bf7<br>
Ancestors: Kernel-ct.1287, Kernel-ct.1296, Kernel-ct.1298, Kernel-ct.1302, Kernel-eem.1296<br>
<br>
Merges several smaller fixes from inbox. Thanks Christoph (ct)!<br>
<br>
- fixes drag-drop methods between classes on the "--all--" category <br>
- fixes two simulation bugs concerning #ensure: and #on:do:<br>
- fixes ObjectTracer DNU<br>
- fixes #readCarefullyFrom: in Object by correctly catching SyntaxErrorNotification<br>
<br>
=============== Diff against Kernel-eem.1296 ===============<br>
<br>
Item was changed:<br>
  ----- Method: Categorizer>>addCategory:before: (in category 'accessing') -----<br>
  addCategory: catString before: nextCategory<br>
         "Add a new category named heading.<br>
         If default category exists and is empty, remove it.<br>
         If nextCategory is nil, then add the new one at the end,<br>
         otherwise, insert it before nextCategory."<br>
         | index newCategory |<br>
         newCategory := catString asSymbol.<br>
         (categoryArray indexOf: newCategory) > 0<br>
                 ifTrue: [^self].        "heading already exists, so done"<br>
+        (self isSpecialCategoryName: newCategory)<br>
+                ifTrue: [^self inform: 'This category name is system reserved' translated].<br>
         index := categoryArray indexOf: nextCategory<br>
                 ifAbsent: [categoryArray size + 1].<br>
         categoryArray := categoryArray<br>
                 copyReplaceFrom: index<br>
                 to: index-1<br>
                 with: (Array with: newCategory).<br>
         categoryStops := categoryStops<br>
                 copyReplaceFrom: index<br>
                 to: index-1<br>
                 with: (Array with: (index = 1<br>
                                 ifTrue: [0]<br>
                                 ifFalse: [categoryStops at: index-1])).<br>
         "remove empty default category"<br>
         (newCategory ~= Default<br>
                         and: [(self listAtCategoryNamed: Default) isEmpty])<br>
                 ifTrue: [self removeCategory: Default]!<br>
<br>
Item was changed:<br>
  ----- Method: Categorizer>>classify:under:suppressIfDefault: (in category 'classifying') -----<br>
  classify: element under: heading suppressIfDefault: aBoolean<br>
         "Store the argument, element, in the category named heading.   If aBoolean is true, then invoke special logic such that the classification is NOT done if the new heading is the Default and the element already had a non-Default classification -- useful
 for filein"<br>
  <br>
         | catName catIndex elemIndex realHeading |<br>
+        realHeading := (heading isNil or: [self isSpecialCategoryName: heading])<br>
+                ifTrue: [Default]<br>
+                ifFalse: [heading asSymbol].<br>
-        ((heading = NullCategory) or: [heading == nil])<br>
-                ifTrue: [realHeading := Default]<br>
-                ifFalse: [realHeading := heading asSymbol].<br>
         (catName := self categoryOfElement: element) = realHeading<br>
                 ifTrue: [^ self].  "done if already under that category"<br>
  <br>
+        catName ifNotNil: [<br>
+                (aBoolean and: [realHeading = Default])<br>
-        catName ~~ nil ifTrue: <br>
-                [(aBoolean and: [realHeading = Default])<br>
                                 ifTrue: [^ self].         "return if non-Default category already assigned in memory"<br>
                 self basicRemoveElement: element].      "remove if in another category"<br>
  <br>
         (categoryArray indexOf: realHeading) = 0 ifTrue: [self addCategory: realHeading].<br>
  <br>
         catIndex := categoryArray indexOf: realHeading.<br>
         elemIndex := <br>
                 catIndex > 1<br>
                         ifTrue: [categoryStops at: catIndex - 1]<br>
                         ifFalse: [0].<br>
         [(elemIndex := elemIndex + 1) <= (categoryStops at: catIndex) <br>
                 and: [element >= (elementArray at: elemIndex)]] whileTrue.<br>
  <br>
         "elemIndex is now the index for inserting the element. Do the insertion before it."<br>
         elementArray := elementArray copyReplaceFrom: elemIndex to: elemIndex-1<br>
                                                 with: (Array with: element).<br>
  <br>
         "add one to stops for this and later categories"<br>
         catIndex to: categoryArray size do: <br>
                 [:i | categoryStops at: i put: (categoryStops at: i) + 1].<br>
  <br>
         ((categoryArray includes: Default)<br>
                 and: [(self listAtCategoryNamed: Default) size = 0]) ifTrue: [self removeCategory: Default].<br>
                 <br>
         self assertInvariant.!<br>
<br>
Item was added:<br>
+ ----- Method: Categorizer>>isSpecialCategoryName: (in category 'testing') -----<br>
+ isSpecialCategoryName: aName<br>
+ <br>
+        ^ aName = self class nullCategory<br>
+                or: [aName = self class allCategory]!<br>
<br>
Item was changed:<br>
  ----- Method: Context class>>contextEnsure: (in category 'special context creation') -----<br>
  contextEnsure: block<br>
+        "Create an #ensure: context that is ready to return from executing its receiver.<br>
+        <br>
+        As ctxt is *not* a top context as required by #jump, we need to put a (fake) return value (nil) on its stack. Otherwise, #jump will pop something different from the stack. Concretely, this caused the bug described in [1] (Scenario 1) because the latest
 stack top was the closure vector {chain}. This closure vector was accidently popped away so that in the final return statement, #pushRemoteTemp:inVectorAt: raised an error subscript bounds (because the next stack item was not variable). Read the linked bug
 report for more details.<br>
-        "Create an #ensure: context that is ready to return from executing its receiver"<br>
  <br>
+        [1] <a href="http://forum.world.st/BUG-s-in-Context-control-jump-runUntilErrorOrReturnFrom-td5107263.html">
http://forum.world.st/BUG-s-in-Context-control-jump-runUntilErrorOrReturnFrom-td5107263.html</a>"<br>
+ <br>
         | ctxt chain |<br>
         ctxt := thisContext.<br>
+        [chain := thisContext sender cut: ctxt.<br>
+        ctxt push: nil. "fake return value"<br>
+        ctxt jump] ensure: block.<br>
-        [chain := thisContext sender cut: ctxt. ctxt jump] ensure: block.<br>
         "jump above will resume here without unwinding chain"<br>
         ^ chain!<br>
<br>
Item was changed:<br>
  ----- Method: Context class>>contextOn:do: (in category 'special context creation') -----<br>
  contextOn: exceptionClass do: block<br>
+        "Create an #on:do: context that is ready to return from executing its receiver.<br>
+        <br>
+        As ctxt is *not* a top context as required by #jump, we need to put a (fake) return value (nil) on its stack. Otherwise, #jump will pop something different from the stack. Concretely, this caused the bug described in [1] (Scenario 1) because the latest
 stack top was the closure vector {chain}. This closure vector was accidently popped away so that in the final return statement, #pushRemoteTemp:inVectorAt: raised an error subscript bounds (because the next stack item was not variable). Read the linked bug
 report for more details.<br>
-        "Create an #on:do: context that is ready to return from executing its receiver"<br>
  <br>
+        [1] <a href="http://forum.world.st/BUG-s-in-Context-control-jump-runUntilErrorOrReturnFrom-td5107263.html">
http://forum.world.st/BUG-s-in-Context-control-jump-runUntilErrorOrReturnFrom-td5107263.html</a>"<br>
+ <br>
         | ctxt chain |<br>
         ctxt := thisContext.<br>
+        [chain := thisContext sender cut: ctxt.<br>
+        ctxt push: nil. "fake return value"<br>
+        ctxt jump] on: exceptionClass do: block.<br>
-        [chain := thisContext sender cut: ctxt. ctxt jump] on: exceptionClass do: block.<br>
         "jump above will resume here without unwinding chain"<br>
         ^ chain!<br>
<br>
Item was changed:<br>
  ----- Method: Context>>send:to:with:lookupIn: (in category 'controlling') -----<br>
  send: selector to: rcvr with: arguments lookupIn: lookupClass<br>
         "Simulate the action of sending a message with selector and arguments<br>
          to rcvr. The argument, lookupClass, is the class in which to lookup the<br>
          message.  This is the receiver's class for normal messages, but for super<br>
          messages it will be some specific class related to the source method."<br>
  <br>
         | meth primIndex val ctxt |<br>
         (meth := lookupClass lookupSelector: selector) ifNil:<br>
                 [^self send: #doesNotUnderstand:<br>
                                 to: rcvr<br>
+                                with: {(Message selector: selector arguments: arguments) lookupClass: lookupClass}<br>
-                                with: {Message selector: selector arguments: arguments}<br>
                                 lookupIn: lookupClass].<br>
         meth numArgs ~= arguments size ifTrue:<br>
                 [^self error: 'Wrong number of arguments in simulated message ', selector printString].<br>
         (primIndex := meth primitive) > 0 ifTrue:<br>
                 [val := self doPrimitive: primIndex method: meth receiver: rcvr args: arguments.<br>
                  (self isPrimFailToken: val) ifFalse:<br>
                         [^val]].<br>
         (selector == #doesNotUnderstand: and: [lookupClass == ProtoObject]) ifTrue:<br>
                 [^self error: 'Simulated message ', arguments first selector, ' not understood'].<br>
         ctxt := Context sender: self receiver: rcvr method: meth arguments: arguments.<br>
         primIndex > 0 ifTrue:<br>
                 [ctxt failPrimitiveWith: val].<br>
         ^ctxt!<br>
<br>
Item was added:<br>
+ ----- Method: Object class>>basicReadFrom: (in category 'instance creation') -----<br>
+ basicReadFrom: textStringOrStream<br>
+        "Create an object based on the contents of textStringOrStream."<br>
+ <br>
+        | object |<br>
+        (Compiler couldEvaluate: textStringOrStream)<br>
+                ifFalse: [^ self error: 'expected String, Stream, or Text' translated].<br>
+        object := self environment beCurrentDuring: [<br>
+                Compiler evaluate: textStringOrStream environment: self environment].<br>
+        (object isKindOf: self) ifFalse: [self error: ('{1} expected' translated format: {self name})].<br>
+        ^object!<br>
<br>
Item was changed:<br>
  ----- Method: Object class>>readCarefullyFrom: (in category 'instance creation') -----<br>
  readCarefullyFrom: textStringOrStream<br>
         "Create an object based on the contents of textStringOrStream.  Return an error instead of putting up a SyntaxError window."<br>
  <br>
+        ^ [self basicReadFrom: textStringOrStream]<br>
+                on: SyntaxErrorNotification<br>
+                do: [:ex | self error: ex messageText]!<br>
-        | object |<br>
-        (Compiler couldEvaluate: textStringOrStream)<br>
-                ifFalse: [^ self error: 'expected String, Stream, or Text'].<br>
-        object := Compiler evaluate: textStringOrStream for: nil <br>
-                                notifying: #error: "signal we want errors".<br>
-        (object isKindOf: self) ifFalse: [self error: self name, ' expected'].<br>
-        ^object!<br>
<br>
Item was changed:<br>
  ----- Method: Object class>>readFrom: (in category 'instance creation') -----<br>
  readFrom: textStringOrStream<br>
         "Create an object based on the contents of textStringOrStream."<br>
  <br>
+        ^ self basicReadFrom: textStringOrStream!<br>
-        | object |<br>
-        (Compiler couldEvaluate: textStringOrStream)<br>
-                ifFalse: [^ self error: 'expected String, Stream, or Text'].<br>
-        object := self environment beCurrentDuring: [Compiler evaluate: textStringOrStream environment: self environment].<br>
-        (object isKindOf: self) ifFalse: [self error: self name, ' expected'].<br>
-        ^object!<br>
<br>
Item was removed:<br>
- ----- Method: ObjectTracer class>>initialize (in category 'initialize-release') -----<br>
- initialize<br>
-        "Fix for inconsistent image state in which ObjectTracer improperly appears as a subclass<br>
-        of Class. This initialization should appear in the Squeak update stream in order to repair<br>
-        existing images, and may be removed in a future update."<br>
- <br>
-        Class removeSubclass: ObjectTracer class!<br>
<br>
Item was changed:<br>
  ----- Method: ObjectTracer>>doesNotUnderstand: (in category 'very few messages') -----<br>
  doesNotUnderstand: aMessage <br>
+        "Present a debugger before proceeding to re-send the message"<br>
-        "All external messages (those not caused by the re-send) get trapped here"<br>
-        "Present a dubugger before proceeding to re-send the message"<br>
  <br>
+        "All external messages (those not caused by the re-send) get trapped here"<br>
+        Warning signal: ('About to perform: {1}' translated format: {aMessage selector storeString}).<br>
+        ^ aMessage sendTo: tracedObject!<br>
-        self notify: 'About to perform: ', aMessage selector.<br>
-        ^ aMessage sentTo: tracedObject.<br>
- !<br>
<br>
<br>
</div>
</span></font>
</body>
</html>