<div dir="ltr"><div>Bah, being nominated for the Charles Steinmetz <span>Chalk</span> <span>Mark</span> Medal was a great honor.</div><div>But I never saw the $9,999, what the hell Henry Ford is doing with the money?</div><div>I have to retry with an easier chalk mark, we've fortunately got complex enough machinery ;)<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Le mer. 30 oct. 2019 à 23:10, <<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>> a écrit :<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> <br>
Nicolas Cellier uploaded a new version of VMMaker to project VM Maker:<br>
<a href="http://source.squeak.org/VMMaker/VMMaker.oscog-nice.2575.mcz" rel="noreferrer" target="_blank">http://source.squeak.org/VMMaker/VMMaker.oscog-nice.2575.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: VMMaker.oscog-nice.2575<br>
Author: nice<br>
Time: 30 October 2019, 11:09:02.913836 pm<br>
UUID: 7833e19b-d77a-4ead-af27-7744aa426280<br>
Ancestors: VMMaker.oscog-nice.2574<br>
<br>
Fix yet another BitBlt source access past end<br>
<br>
<a href="https://github.com/OpenSmalltalk/opensmalltalk-vm/issues/441" rel="noreferrer" target="_blank">https://github.com/OpenSmalltalk/opensmalltalk-vm/issues/441</a><br>
<br>
=============== Diff against VMMaker.oscog-nice.2574 ===============<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation>>copyLoop (in category 'inner loop') -----<br>
  copyLoop<br>
        | prevWord thisWord skewWord halftoneWord mergeWord hInc y unskew skewMask notSkewMask mergeFnwith destWord |<br>
        "This version of the inner loop assumes noSource = false."<br>
        <inline: false><br>
        <var: #prevWord type: #'unsigned int'><br>
        <var: #thisWord type: #'unsigned int'><br>
        <var: #skewWord type: #'unsigned int'><br>
        <var: #halftoneWord type: #'unsigned int'><br>
        <var: #mergeWord type: #'unsigned int'><br>
        <var: #destWord type: #'unsigned int'><br>
        <var: #skewMask type: #'unsigned int'><br>
        <var: #notSkewMask type: #'unsigned int'><br>
        <var: #unskew type: #int> "unskew is a bitShift and MUST remain signed, while skewMask is unsigned."<br>
        <var: #mergeFnwith declareC: 'unsigned int (*mergeFnwith)(unsigned int, unsigned int)'><br>
        mergeFnwith := self cCoerce: (opTable at: combinationRule+1) to: 'unsigned int (*)(unsigned int, unsigned int)'.<br>
        mergeFnwith.  "null ref for compiler"<br>
<br>
        self deny: (preload and: [skew = 0]).<br>
        self assert: (skew between: -31 and: 31).<br>
<br>
        hInc := hDir * 4.  "Byte delta"<br>
        skew < 0<br>
                ifTrue: [unskew := skew + 32. skewMask := AllOnes << (0 - skew).<br>
                                self cCode: [] inSmalltalk: [skewMask := skewMask bitAnd: 16rFFFFFFFF]]<br>
                ifFalse:<br>
                        [skew = 0<br>
                                ifTrue: [unskew := 0. skewMask := AllOnes]<br>
                                ifFalse: [unskew := skew - 32. skewMask := AllOnes >> skew]].<br>
<br>
        notSkewMask := skewMask bitInvert32.<br>
        noHalftone<br>
                ifTrue: [halftoneWord := AllOnes.  halftoneHeight := 0]<br>
                ifFalse: [halftoneWord := self halftoneAt: 0].<br>
<br>
        y := dy.<br>
        "Here is the vertical loop, in two versions, one for the combinationRule = 3 copy mode, one for the general case."<br>
        combinationRule = 3<br>
                ifTrue:<br>
                        [1 to: bbH do: "here is the vertical loop for combinationRule = 3 copy mode; no need to call merge"<br>
                                [ :i |<br>
                                halftoneHeight > 1 ifTrue:  "Otherwise, its always the same"<br>
                                        [halftoneWord := self halftoneAt: y.<br>
                                        y := y + vDir].<br>
                                preload<br>
                                        ifTrue: "load the 64-bit shifter"<br>
                                                [prevWord := self srcLongAt: sourceIndex.<br>
                                                self incSrcIndex: hInc]<br>
                                        ifFalse:<br>
                                                [prevWord := 0].<br>
<br>
                                "Note: the horizontal loop has been expanded into three parts for speed:"<br>
<br>
                                "This first section requires masking of the destination store..."<br>
                                destMask := mask1.<br>
                                thisWord := self srcLongAt: sourceIndex.  "pick up next word"<br>
                                self incSrcIndex: hInc.<br>
                                skewWord := ((prevWord bitAnd: notSkewMask) bitShift: unskew)<br>
                                                                bitOr:  "32-bit rotate"<br>
                                                                        ((thisWord bitAnd: skewMask) bitShift: skew).<br>
                                prevWord := thisWord.<br>
                                destWord := self dstLongAt: destIndex.<br>
                                destWord := (destMask bitAnd: (skewWord bitAnd: halftoneWord))<br>
                                                                bitOr: (destWord bitAnd: destMask bitInvert32).<br>
                                self dstLongAt: destIndex put: destWord.<br>
                                self incDestIndex: hInc.<br>
<br>
                                "This central horizontal loop requires no store masking"<br>
                                destMask := AllOnes.<br>
                                (skew = 0 and: [halftoneWord = AllOnes])<br>
                                        ifTrue: "Very special inner loop for STORE mode with no skew -- just move words"<br>
                                                [(preload and: [hDir = 1])<br>
                                                        ifTrue:<br>
                                                                [2 to: nWords-1 do: <br>
                                                                        [ :word |  "Note loop starts with prevWord loaded (due to preload)"<br>
                                                                        self dstLongAt: destIndex put: prevWord.<br>
                                                                        self incDestIndex: hInc.<br>
                                                                        prevWord := self srcLongAt: sourceIndex.<br>
                                                                        self incSrcIndex: hInc]]<br>
                                                        ifFalse:<br>
                                                                [2 to: nWords-1 do: <br>
                                                                        [ :word |<br>
                                                                        thisWord := self srcLongAt: sourceIndex.<br>
                                                                        self incSrcIndex: hInc.<br>
                                                                        self dstLongAt: destIndex put: thisWord.<br>
                                                                        self incDestIndex: hInc].<br>
                                                                 prevWord := thisWord]]<br>
                                                ifFalse:<br>
                                                        [2 to: nWords-1 do: <br>
                                                                [ :word |<br>
                                                                thisWord := self srcLongAt: sourceIndex.<br>
                                                                self incSrcIndex: hInc.<br>
                                                                skewWord := ((prevWord bitAnd: notSkewMask) bitShift: unskew)<br>
                                                                                                bitOr:  "32-bit rotate"<br>
                                                                                        ((thisWord bitAnd: skewMask) bitShift: skew).<br>
                                                                prevWord := thisWord.<br>
                                                                self dstLongAt: destIndex put: (skewWord bitAnd: halftoneWord).<br>
                                                                self incDestIndex: hInc]].<br>
<br>
                                "This last section, if used, requires masking of the destination store..."<br>
                                nWords > 1 ifTrue:<br>
                                        [destMask := mask2.<br>
+                                       thisWord :=((skewMask bitShift: skew) bitAnd: mask2) = 0<br>
+                                               ifTrue: [0 "we don't need more bits, they will all come from prevWord"]<br>
+                                               ifFalse: [self srcLongAt: sourceIndex.  "pick up last bits from next word".].<br>
+                                       self incSrcIndex: hInc. "Note: this will be undone by inncSrcIndex: sourceDelta below if undue"<br>
-                                       thisWord := self srcLongAt: sourceIndex.  "pick up next word"<br>
-                                       self incSrcIndex: hInc.<br>
                                        skewWord := ((prevWord bitAnd: notSkewMask) bitShift: unskew)<br>
                                                                        bitOr:  "32-bit rotate"<br>
                                                                                ((thisWord bitAnd: skewMask) bitShift: skew).<br>
                                        destWord := self dstLongAt: destIndex.<br>
                                        destWord := (destMask bitAnd: (skewWord bitAnd: halftoneWord))<br>
                                                                        bitOr: (destWord bitAnd: destMask bitInvert32).<br>
                                        self dstLongAt: destIndex put: destWord.<br>
                                        self incDestIndex: hInc].<br>
<br>
                                self incSrcIndex: sourceDelta.<br>
                                self incDestIndex: destDelta]]<br>
                ifFalse:<br>
                        [1 to: bbH do: "here is the vertical loop for the general case (combinationRule ~= 3)"<br>
                                [ :i |<br>
                                halftoneHeight > 1 ifTrue:  "Otherwise, its always the same"<br>
                                        [halftoneWord := self halftoneAt: y.<br>
                                        y := y + vDir].<br>
                                preload<br>
                                        ifTrue: "load the 64-bit shifter"<br>
                                                [prevWord := self srcLongAt: sourceIndex.<br>
                                                self incSrcIndex: hInc]<br>
                                        ifFalse:<br>
                                                [prevWord := 0].<br>
<br>
                                "Note: the horizontal loop has been expanded into three parts for speed:"<br>
<br>
                                "This first section requires masking of the destination store..."<br>
                                destMask := mask1.<br>
                                thisWord := self srcLongAt: sourceIndex.  "pick up next word"<br>
                                self incSrcIndex: hInc.<br>
                                skewWord := ((prevWord bitAnd: notSkewMask) bitShift: unskew)<br>
                                                                bitOr:  "32-bit rotate"<br>
                                                        ((thisWord bitAnd: skewMask) bitShift: skew).<br>
                                prevWord := thisWord.<br>
                                destWord := self dstLongAt: destIndex.<br>
                                mergeWord := self mergeFn: (skewWord bitAnd: halftoneWord) with: destWord.<br>
                                destWord := (destMask bitAnd: mergeWord)<br>
                                                                bitOr: (destWord bitAnd: destMask bitInvert32).<br>
                                self dstLongAt: destIndex put: destWord.<br>
                                self incDestIndex: hInc.<br>
<br>
                                "This central horizontal loop requires no store masking"<br>
                                destMask := AllOnes.<br>
                                2 to: nWords-1 do: "Normal inner loop does merge:"<br>
                                        [ :word |<br>
                                        thisWord := self srcLongAt: sourceIndex.  "pick up next word"<br>
                                        self incSrcIndex: hInc.<br>
                                        skewWord := ((prevWord bitAnd: notSkewMask) bitShift: unskew)<br>
                                                                        bitOr:  "32-bit rotate"<br>
                                                                ((thisWord bitAnd: skewMask) bitShift: skew).<br>
                                        prevWord := thisWord.<br>
                                        mergeWord := self mergeFn: (skewWord bitAnd: halftoneWord)<br>
                                                                        with: (self dstLongAt: destIndex).<br>
                                        self dstLongAt: destIndex put: mergeWord.<br>
                                        self incDestIndex: hInc].<br>
<br>
                                "This last section, if used, requires masking of the destination store..."<br>
                                nWords > 1 ifTrue:<br>
                                        [destMask := mask2.<br>
+                                       thisWord :=((skewMask bitShift: skew) bitAnd: mask2) = 0<br>
+                                               ifTrue: [0 "we don't need more bits, they will all come from prevWord"]<br>
+                                               ifFalse: [self srcLongAt: sourceIndex.  "pick up last bits from next word".].<br>
+                                       self incSrcIndex: hInc. "Note: this will be undone by incSrcIndex: sourceDelta below if undue"<br>
-                                       thisWord := self srcLongAt: sourceIndex.  "pick up next word"<br>
-                                       self incSrcIndex: hInc.<br>
                                        skewWord := ((prevWord bitAnd: notSkewMask) bitShift: unskew)<br>
                                                                        bitOr:  "32-bit rotate"<br>
                                                                ((thisWord bitAnd: skewMask) bitShift: skew).<br>
                                        destWord := self dstLongAt: destIndex.<br>
                                        mergeWord := self mergeFn: (skewWord bitAnd: halftoneWord) with: destWord.<br>
                                        destWord := (destMask bitAnd: mergeWord)<br>
                                                                        bitOr: (destWord bitAnd: destMask bitInvert32).<br>
                                        self dstLongAt: destIndex put: destWord.<br>
                                        self incDestIndex: hInc].<br>
<br>
                                self incSrcIndex: sourceDelta.<br>
                                self incDestIndex: destDelta]]!<br>
<br>
</blockquote></div>