Hey all
the following code fails to be decompiled by the Decompiler and I have no clue:
retryOnce: aTryBlock | retry | retry := true. [[retry] whileTrue: [|result| result := aTryBlock value. retry := false. ^ result ]] on: Error do: [:e | retry := (e isKindOf: NetworkError) not ].
Apparently, the Decompilers stack is empty but it tries to access its last element, which results in an indexing error.
Best -Tobias
On Mon, 3 Nov 2014, Tobias Pape wrote:
Hey all
the following code fails to be decompiled by the Decompiler and I have no clue:
retryOnce: aTryBlock | retry | retry := true. [[retry] whileTrue: [|result| result := aTryBlock value. retry := false. ^ result ]] on: Error do: [:e | retry := (e isKindOf: NetworkError) not ].
Apparently, the Decompilers stack is empty but it tries to access its last element, which results in an indexing error.
The problem is that BlockLocalTempCounter tempCountForBlockStartingAt: pc in: method returns 67 (the value of its stackPointer) instead of 1 (the number of local temporaries in the first block of the method) in #doClosureCopyCopiedValues:numArgs:blockSize: when pc is 50.
It seems to me that it's a bug in BlockLocalTempCounter >> #doJoin, because it sets its own stackPointer to a pc value. Decompilation works for me with the following implementation:
doJoin scanner pc < blockEnd ifTrue: [ joinOffsets at: scanner pc ifPresent: [ :sp | stackPointer := sp ] ]
The comment of the methods tells something about the #ifAbsent: branch, but I don't see how that should work.
Also the comment in #tempCountForBlockAt:in: says
There are short-cuts. The ones we take here are - if there is no sequence of push nils there can be no local temps - we follow forward jumps to shorten the amount of scanning
But it seems to me that the second part is not implemented.
Levente
Best -Tobias
Hi, is this the right list to post questions about squeak android vm tablet?
Thanks, Carlos
----- Original Message ----- From: "Levente Uzonyi" leves@elte.hu To: "The general-purpose Squeak developers list" squeak-dev@lists.squeakfoundation.org Sent: Monday, November 03, 2014 9:23 PM Subject: Re: [squeak-dev] Decompiler failure
On Mon, 3 Nov 2014, Tobias Pape wrote:
Hey all
the following code fails to be decompiled by the Decompiler and I have no clue:
retryOnce: aTryBlock | retry | retry := true. [[retry] whileTrue: [|result| result := aTryBlock value. retry := false. ^ result ]] on: Error do: [:e | retry := (e isKindOf: NetworkError) not ].
Apparently, the Decompilers stack is empty but it tries to access its last element, which results in an indexing error.
The problem is that BlockLocalTempCounter tempCountForBlockStartingAt: pc in: method returns 67 (the value of its stackPointer) instead of 1 (the number of local temporaries in the first block of the method) in #doClosureCopyCopiedValues:numArgs:blockSize: when pc is 50.
It seems to me that it's a bug in BlockLocalTempCounter >> #doJoin, because it sets its own stackPointer to a pc value. Decompilation works for me with the following implementation:
doJoin scanner pc < blockEnd ifTrue: [ joinOffsets at: scanner pc ifPresent: [ :sp | stackPointer := sp ] ]
The comment of the methods tells something about the #ifAbsent: branch, but I don't see how that should work.
Also the comment in #tempCountForBlockAt:in: says
There are short-cuts. The ones we take here are
- if there is no sequence of push nils there can be no local temps
- we follow forward jumps to shorten the amount of scanning
But it seems to me that the second part is not implemented.
Levente
Best -Tobias
What's the semantics of this piece of Smalltalk code? o.O
If "aTryBlock value" raises an error, retry will be set to "true" for all non-network errors. But then? There is no resume. Hmm... Cannot figure out why this will be retried only once? Should be retried forever then? Is there some implicity magic hidden somewhere? :)
Best, Marcel
-- View this message in context: http://forum.world.st/Decompiler-failure-tp4788251p4788274.html Sent from the Squeak - Dev mailing list archive at Nabble.com.
Hi.
On 04.11.2014, at 06:19, Marcel Taeumel marcel.taeumel@student.hpi.uni-potsdam.de wrote:
What's the semantics of this piece of Smalltalk code? o.O
If "aTryBlock value" raises an error, retry will be set to "true" for all non-network errors. But then? There is no resume. Hmm... Cannot figure out why this will be retried only once? Should be retried forever then? Is there some implicity magic hidden somewhere? :)
The code is plain incorrect. I was debugging it and hence hit the decompiler bug, because “toggle halt on entry” effects the browser to try to decompile it (which is fine). My working implementation is now this:
retryOnce: aTryBlock | again | again := true. [^ aTryBlock value. ] on: Error do: [:e | ((e isKindOf: NetworkError) or: [again not]) ifTrue: [e pass] ifFalse: [again := false. e retry]].
Best -Tobias
squeak-dev@lists.squeakfoundation.org