[squeak-dev] MessageNodes are modified when printed

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Sun Feb 20 21:33:26 UTC 2011


Oh bad bad behaved Nodes, 'hello, I will change when you will debug me'
I guess you must have lost a few hairs on this one.

Of course, it should better be Decompiler responsibility to trigger
this mutation.

Nicolas

2011/2/20 Levente Uzonyi <leves at elte.hu>:
> Hi,
>
> I was looking for loop patterns that can be rewritten to use #repeat:,
> because it became an inlined message (thanks Nicolas). I decided to use
> ParseNodeEnumerator, the swiss army knife, suitable for these kind of tasks.
> As a first step I tried to find method with the following pattern:
> [ ... true ] whileTrue.
> To my surprise, my code didn't find any methods with it. Since I knew that
> there are methods with this pattern, I created the following "test case"
> which shows the problem:
>
> | shouldSelect visitor |
> shouldSelect := false.
> visitor := ParseNodeEnumerator ofBlock: [ :node |
>        shouldSelect := shouldSelect or: [
>                node isMessageNode and: [
>                node selector key == #whileTrue and: [
>                node receiver isBlockNode and: [
>                node receiver statements last isVariableNode and: [
>                        node receiver statements last key = 'true' ] ] ] ] ]
> ].
> shouldSelect := false.
> [ [ true ] whileTrue ] decompile accept: visitor.
> shouldSelect.
>
> It should return true, but it returns false. What's even worse is that if
> you insert a #halt, like in the following example and press proceed when the
> debugger shows up, then the result will be true.
>
> ...
>                node isMessageNode and: [
>                self halt.
>                node selector key == #whileTrue and: [
> ...
>
> The cause of the problem is that the decompiler creates the MessageNode with
> #whileTrue: as selector instead of #whileTrue, but MessageNode >>
> #printWhileOn:indent: or MessageNode >>
> #printWithClosureAnalysisWhileOn:indent: replaces the selector to
> #whileTrue. Since the debugger triggers one of these methods, the code will
> pass in the second case (#halt). The same happens if you open an explorer on
> the MessageNode.
>
> Shouldn't the change be done by the decompiler, instead of some method used
> for printing?
>
>
> Cheers,
> Levente
>
> P.S.: I finished the script and rewrote most methods with these patterns in
> the Trunk. I'll push them soon. Here's the final snippet in case you would
> like to check your own code:
>
> | shouldSelect |
> shouldSelect := false.
> visitor := ParseNodeEnumerator ofBlock: [ :node |
>        shouldSelect := shouldSelect or: [
>                node isMessageNode and: [
>                        (#(whileTrue whileTrue: whileFalse whileFalse:)
> instVarsInclude: node selector key) and: [
>                                | receiver |
>                                (receiver := node receiver) isBlockNode and:
> [
>                                        | lastStatement |
>                                        (lastStatement := receiver statements
> last) isVariableNode and: [
>                                                #('true' 'false') includes:
> lastStatement key ] ] ] ] ] ].
> SystemNavigation default browseAllSelect: [ :method |
>        shouldSelect := false.
>        method decompile accept: visitor.
>        shouldSelect ]
>
>



More information about the Squeak-dev mailing list