Hello,
Is there a way to map the temp variables stored in a BlockClosure with their names as they appear in the decompileString? For example we have: | y | y := 10. [:x | y + x] basicAt: 1 "returns 10" and | y | y := 10. [:x | y + x] decompileString "returns '[:x | y + x]'" What I would like is something like | y | y := 10. [:x | y + x] tempBindingAt: 1 "would return #y -> 10" Stef |
Hi Stef,
good question. You can get the argument names via aBlock decompile arguments, and if you also care about the temp names, you can append aBlock decompile temporaries. But you probably knew that already :)
If you have the possibility to invoke the block, you could also try something like:
If you cannot invoke the block, here would an even more hacky alternative:
Best,
Christoph
Von: Squeak-dev <[hidden email]> im Auftrag von Stéphane Rollandin <[hidden email]>
Gesendet: Sonntag, 19. April 2020 18:18 Uhr An: liste [Squeak-dev] Betreff: [squeak-dev] Accessing temp variables bindings in a BlockClosure Hello,
Is there a way to map the temp variables stored in a BlockClosure with their names as they appear in the decompileString? For example we have: | y | y := 10. [:x | y + x] basicAt: 1 "returns 10" and | y | y := 10. [:x | y + x] decompileString "returns '[:x | y + x]'" What I would like is something like | y | y := 10. [:x | y + x] tempBindingAt: 1 "would return #y -> 10" Stef
Carpe Squeak!
|
> But I agree that these are no nice solutions at all. I suppose the point
> is that in contrast to literal bindings, temporary variables are never > actually stored as bindings in the block method. For what purpose do you > need the bindings? For inspection - I would like the var names to appear in the explorer as the keys (instead of the #basicAt: indexes). The code I am dealing with at the moment is choke-full of nested blocks, and it is a pain to see the values of the temp vars in the closures. I am hacking a modified Explorer to better display this particular info, but I'm having a hard time... Stef |
In reply to this post by Christoph Thiede
At the moment I have something working in many cases, but not all (attached)
It can do | y | y := 10. [:x | y + x] tempBindings "returns {'y'->10}" and | y x | y := 10. x := 8. [:a :b | a + y + x] tempBindings " {'y'->10 . 'x'->8} " but fails for example here: |blockSourceStream methodNode compiledMethod block | blockSourceStream := '|x y| [:a :b | x := b. y := a. x + y]' readStream. methodNode := nil class evaluatorClass new compileNoPattern: blockSourceStream in: nil class notifying: nil ifFail: [nil]. compiledMethod := methodNode generateWithTempNames. block := nil withArgs: #() executeMethod: compiledMethod. block tempBindings "Error !!" because the block basicAt: 1 is actually a list with the value of both x and y - and I do not see how to detect this case. Stef BlockClosure-tempBindings.st (558 bytes) Download Attachment |
> At the moment I have something working in many cases, but not all (attached)
> > It can do > | y x | > y := 10. > x := 8. > [:a :b | a + y + x] tempBindings " {'y'->10 . 'x'->8} " ... well in fact it can't, because just switching x and y in the block leads to: | y x | y := 10. x := 8. [:a :b | a + x + y] tempBindings " {'x'->10 . 'y'->8} " So I'm stuck. Stef |
In reply to this post by Stéphane Rollandin
> For inspection - I would like the var names to appear in the explorer as the keys (instead of the #basicAt: indexes). Are you sure you are not actually inspecting a context object?
This is how the explorer on a FullBlockClosure looks in my image:
This is how its corresponding Context looks like:
But these indexes cannot be mapped directly to the temporaries. Here is a counter-example:
Contexts also hold "anonymous temps" that are only visible on the stack during execution and depend on the bytecode set.
But we could probably override Context >> #explorerContents in the following way:
Best,
Christoph
Von: Squeak-dev <[hidden email]> im Auftrag von Stéphane Rollandin <[hidden email]>
Gesendet: Sonntag, 19. April 2020 23:56 Uhr An: [hidden email] Betreff: Re: [squeak-dev] Accessing temp variables bindings in a BlockClosure > But I agree that these are no nice solutions at all. I suppose the point
> is that in contrast to literal bindings, temporary variables are never > actually stored as bindings in the block method. For what purpose do you > need the bindings? For inspection - I would like the var names to appear in the explorer as the keys (instead of the #basicAt: indexes). The code I am dealing with at the moment is choke-full of nested blocks, and it is a pain to see the values of the temp vars in the closures. I am hacking a modified Explorer to better display this particular info, but I'm having a hard time... Stef Context-explorerContents.st (880 bytes) Download Attachment
Carpe Squeak!
|
Here is a picture of what I want (it is from my custom explorer which
happens to give an ok result in this specific case) You can see that in there the 'alarms' set of blocks is displayed as a list of decompileStrings, and each temp vars such as 'aBlock' or 'aTimeLapse' is featured with its corresponding value. Stef explorer.png (179K) Download Attachment |
In reply to this post by Stéphane Rollandin
Hi Stef,
> because the block basicAt: 1 is actually a list with the value of both x and y - and I do not see how to detect this case.
I may be wrong, but sending #basicAt: to BlockClosures should access its closured objects only, in the way their sender wrote them on it. I suppose this is not a reliable way to access temporaries from it?
The array you found is a remote temp vector, which is basically an implementation detail of how closures work. In a nutshell, a BlockClosure holds a copy of each variable it accesses ("closures") from its outerContext, in order to optimize the execution of blocks. However, if a block must be supposed to reassign some of these variables, we would need to sync these copies with their originals. To avoid this expensive operation, variables that are assigned from within the block are stored in an extra remote temp vector that is common to the block and its outer context(s). You can study the following observations if you're interested:
| a b c d e |
a := 1.
b := 2.
c := 3.
d := 4.
e := 5.
[a. b. c := 6. d := 7]
| x |
x := 2.
[
thisContext sender tempAt: 1 put: 3.
x
] value. "2"
Disclaimer: I played some time around with this amazing stuff and received a number of valuable explanations from the community, but I'm still new to the domain. Nothing I try to explain must be correct or make sense and others can probably tell you better :-)
Here is a really nice explanation by Eliot: http://forum.world.st/BUG-Cannot-compile-cascade-sent-to-block-tp5108942p5109012.html
Best, Christoph
PS: Just saw your screenshot. If you do not need to access temporaries/args that are local to the blocks, shouldn't you be fine with aBlock outerContext tempsAndValues?
Von: Squeak-dev <[hidden email]> im Auftrag von Stéphane Rollandin <[hidden email]>
Gesendet: Montag, 20. April 2020 00:24:45 An: [hidden email] Betreff: Re: [squeak-dev] Accessing temp variables bindings in a BlockClosure > At the moment I have something working in many cases, but not all (attached)
> > It can do > | y x | > y := 10. > x := 8. > [:a :b | a + y + x] tempBindings " {'y'->10 . 'x'->8} " ... well in fact it can't, because just switching x and y in the block leads to: | y x | y := 10. x := 8. [:a :b | a + x + y] tempBindings " {'x'->10 . 'y'->8} " So I'm stuck. Stef
Carpe Squeak!
|
> PS: Just saw your screenshot. If you do not need to access > temporaries/args that are local to the blocks, shouldn't you be fine > with aBlock outerContext tempsAndValues? Yes, thanks for this pointer. It seems that the #tempBindings implementation I got from it works for me at this point (it is attached). Stef |
In reply to this post by Christoph Thiede
> PS: Just saw your screenshot. If you do not need to access
> temporaries/args that are local to the blocks, shouldn't you be fine > with aBlock outerContext tempsAndValues? Yes, thanks for this pointer. It seems that the #tempBindings implementation I got from it works for me at this point (it is attached, this time...). Stef BlockClosure-tempBindings.st (518 bytes) Download Attachment |
In reply to this post by Stéphane Rollandin
Hi Stef,
take a look at ContextInspector and DebuggerMethodMap. The clue is that the debugger correctly displays the names of block temporaries and values in the hi text inspector in the bottom left of a debugger. The interface is not easy because of the indirect temp vector implementation of modified closed over temporaries. I apologize for the complexity and inconvenience but it is key to achieving high performance context-to-stack mapping, which itself is key to efficient execution while retaining contexts with their many benefits. Note that the indirect temp vector implementation of modified closed over temporaries is a standard one taken from lisp implementations. _,,,^..^,,,_ (phone) > On Apr 19, 2020, at 9:18 AM, Stéphane Rollandin <[hidden email]> wrote: > > Hello, > > Is there a way to map the temp variables stored in a BlockClosure with their names as they appear in the decompileString? > > For example we have: > > | y | > y := 10. > [:x | y + x] basicAt: 1 "returns 10" > > and > > | y | > y := 10. > [:x | y + x] decompileString "returns '[:x | y + x]'" > > > What I would like is something like > > | y | > y := 10. > [:x | y + x] tempBindingAt: 1 "would return #y -> 10" > > > Stef > |
In reply to this post by Stéphane Rollandin
Interesting class names! Care to give some hints?
Herbert Am 20.04.2020 um 00:47 schrieb Stéphane
Rollandin:
Here is a picture of what I want (it is from my custom explorer which happens to give an ok result in this specific case) |
> Interesting class names! Care to give some hints?
Ahah:) It's from a 2D, top-down morphic roguelike game engine. What you are seeing is the components-based AI architecture responsible for the behavior of a snake. Stef |
Free forum by Nabble | Edit this page |