[squeak-dev] decompiler testing

Florin Mateoc florin.mateoc at gmail.com
Thu Aug 14 03:41:31 UTC 2014


Hi,

I made some changes to the decompiler tests to do some more thorough checking after noticing that sometimes the result
of decompilation was uncompileable.
I had also noticed that class-side methods were skipped, so I added them to the check.

Then, since all this lead to errors and many more failures, I also tried to make the check a little more forgiving than
simple string comparison for sources, mainly by using abstractSymbolic, which I conjecture also means that the methods
are "the same".
I then also had to fix abstractSymbolic generation itself.
One other avoidable source of differences was the fact that, although Character space is a literal and is used as such
in many method sources, Character>>printOn: and Character>>shouldBePrintedAsLiteral claimed that it was not a literal,
so they were generating 'Character space' instead of '$ '.

And then I also pushed some decompiler fixes.

Still, the end result for now is that there are many more failures.
Some of them seem related to the methodNode generation, e.g.
LargeNegativeIntegerTest>>testReplaceFromToWithStartingAt has in the source

    | lni20 lni7 |
....
    (1 to: 5) , (11 to: 20) do: [:e | | digit |
        digit := lni20 digitAt: e.
        self assert: e equals: digit].
    6 to: 10 do: [:e | | digit replacementDigit |
        digit := lni20 digitAt: e.
        replacementDigit := lni7 digitAt: e - 4.
        self assert: replacementDigit equals: digit]

so the tempName digit is used both in an optimized block and in a non-optimized block.
But in the parsed methodNode this gets replaced by
    | lni20 lni7 digit |
....
    (1 to: 5) , (11 to: 20) do: [:e | | digit |
            digit := lni20 digitAt: e.
            self assert: e equals: digit].
    6 to: 10 do: [
            digit := lni20 digitAt: e.
            replacementDigit := lni7 digitAt: e - 4.
            self assert: replacementDigit equals: digit]

Apparently code generation has no problem with this parsed methodNode, but the decompiled source is not compileable.
Unfortunately, the methodNode obtained through decompilation can not re-generate a compiled method either, so there is
no way to claim that decompilation succeeded.

Othertimes it seems that we peek behind the curtain:
parsing ArchiveViewer>>extractAllPossibleInDirectory: gives a MethodNode with a first statement that reads:
    <0-26> := a NewArrayNode.
which seems ignored at code generation, although as source it would be uncompileable, and this is the only difference in
the decompiled source and the formatted source.


Well, it was bound to get a little worse before it got better :)

Florin








More information about the Squeak-dev mailing list