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 signature.asc (1K) Download Attachment |
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" <[hidden email]> To: "The general-purpose Squeak developers list" <[hidden email]> 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 >> > |
In reply to this post by Tobias Pape
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 |
Hi.
On 04.11.2014, at 06:19, Marcel Taeumel <[hidden email]> 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 signature.asc (1K) Download Attachment |
Free forum by Nabble | Edit this page |