[Vm-dev] VM Maker: VMMaker.oscog-eem.2338.mcz

Eliot Miranda eliot.miranda at gmail.com
Fri Feb 23 03:37:32 UTC 2018


Hi Levente,

    I really appreciate you taking a look.  I will say that the rewrite tried the stay as close to the originals while changing 1-relative indexing to 0-relative.  But I think we can also improve on the originals.  Indeed I spotted and fixed a potential bounds violation in primitiveConvert8Bit that only checked the size of one of the two array arguments.

So can I ask you to read the primitives in the previous commit too?  Let's polish these a little :-)

_,,,^..^,,,_ (phone)

> On Feb 22, 2018, at 3:14 PM, Levente Uzonyi <leves at caesar.elte.hu> wrote:
> 
> Just had a look at this snippet, and wrote some quick inline comments.
> 
>> On Thu, 22 Feb 2018, commits at source.squeak.org wrote:
>> 
>> Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
>> http://source.squeak.org/VMMaker/VMMaker.oscog-eem.2338.mcz
>> 
>> ==================== Summary ====================
>> 
>> Name: VMMaker.oscog-eem.2338
>> Author: eem
>> Time: 22 February 2018, 10:25:17.794166 am
>> UUID: 1672c678-41b4-41f2-a061-e201562fc75c
>> Ancestors: VMMaker.oscog-eem.2337
>> 
>> Fix a slip in primitiveDecompressFromByteArray caught by IncludedMethodsTests.  Thank you David!
>> 
>> =============== Diff against VMMaker.oscog-eem.2337 ===============
>> 
>> Item was changed:
>> ----- Method: MiscPrimitivePlugin>>primitiveDecompressFromByteArray (in category 'primitives') -----
>> primitiveDecompressFromByteArray
>>    "Bitmap decompress: bm fromByteArray: ba at: index"
>>    <export: true>
>>    | bm ba index i anInt code data end k n pastEnd |
>>    <var: 'ba' type: #'unsigned char *'>
>>    <var: 'bm' type: #'int *'>
>>    <var: 'anInt' type: #'unsigned int'>
>>    <var: 'code' type: #'unsigned int'>
>>    <var: 'data' type: #'unsigned int'>
>>    <var: 'n' type: #'unsigned int'>
> 
> Shouldn't i be declared as unsigned int too? It's used for indexing.
> 
>>    bm := self cCode: [interpreterProxy arrayValueOf: (interpreterProxy stackValue: 2)]
>>                inSmalltalk: [interpreterProxy
>>                                cCoerce: (interpreterProxy arrayValueOf: (interpreterProxy stackValue: 2))
>>                                to: #'int *'].
>>    (interpreterProxy isOopImmutable: (interpreterProxy stackValue: 2)) ifTrue:
>>        [^interpreterProxy primitiveFailFor: PrimErrNoModification].
>>    (interpreterProxy isBytes: (interpreterProxy stackValue: 1)) ifFalse: [^interpreterProxy primitiveFail].
>>    ba := interpreterProxy firstIndexableField: (interpreterProxy stackValue: 1).
>>    index := interpreterProxy stackIntegerValue: 0.
> 
> Can index be negative or 0? If yes, then the value of i will be negative (unless it's implicit type is unsigned) and that will result in out of bounds indexing into ba a few lines below here.
> 
>>    interpreterProxy failed ifTrue: [^nil].
>>    i := index - 1.
>>    k := 0.
>>    end := interpreterProxy sizeOfSTArrayFromCPrimitive: ba.
>>    pastEnd := interpreterProxy sizeOfSTArrayFromCPrimitive: bm.
>>    [i < end] whileTrue:
>>        [anInt := ba at: i.
>>        i := i + 1.
>>        anInt <= 223 ifFalse:
>>            [anInt <= 254
>>                ifTrue:
>>                    [anInt := anInt - 224 * 256 + (ba at: i).
> 
> I would use bitShift: 8 instead of * 256, just to be consistent with the rest of the method.
> 
>>                    i := i + 1]
>>                ifFalse:
>>                    [anInt := 0.
>>                    1 to: 4 by: 1 do:
>>                        [ :j | anInt := (anInt bitShift: 8) + (ba at: i).
>>                        i := i + 1]]].
>>        n := anInt >> 2.
>> +        k + n > pastEnd ifTrue: [^interpreterProxy primitiveFail].
>> -        k + n >= pastEnd ifTrue: [^interpreterProxy primitiveFail].
>>        code := anInt bitAnd: 3.
>>        "code = 0 ifTrue: [nil]."
>>        code = 1 ifTrue:
>>            [data := ba at: i.
>>            i := i + 1.
>>            data := data bitOr: (data bitShift: 8).
>>            data := data bitOr: (data bitShift: 16).
> 
> I don't know what the point of this part of the code is, but I think the above 4 lines could read:
> 
> [data := 16r10101 * (ba at: i).
> i := i + 1.
> 
> Levente
> 
>>            1 to: n do:
>>                [ :j |
>>                bm at: k put: data.
>>                k := k + 1]].
>>        code = 2 ifTrue:
>>            [data := 0.
>>            1 to: 4 do:
>>                [ :j |
>>                data := (data bitShift: 8) bitOr: (ba at: i).
>>                i := i + 1].
>>            1 to: n do:
>>                [ :j |
>>                bm at: k put: data.
>>                k := k + 1]].
>>        code = 3 ifTrue:
>>            [1 to: n do:
>>                [ :m |
>>                data := 0.
>>                1 to: 4 do:
>>                    [ :j |
>>                    data := (data bitShift: 8) bitOr: (ba at: i).
>>                    i := i + 1].
>>                bm at: k put: data.
>>                k := k + 1]]].
>>    interpreterProxy pop: interpreterProxy methodArgumentCount!


More information about the Vm-dev mailing list