Re: [Pharo-project] Block questions

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-project] Block questions

Eliot Miranda-2


On Sun, Apr 15, 2012 at 1:22 AM, Guillermo Polito <[hidden email]> wrote:
b := [ |a| a:=2 ].
b asContext tempNames ->  #('a')
b asContext tempNamed: 'a' -> Boom in MethodContext>>#tempAt: primitive

tempAt: in Method context uses <primitive: 210>, which is failing.  Maybe there is a new primitive we are not aware of for Blocks...

No, 210 is what is needed.   The issue is my implementation of temporary initialization in blocks, which simply uses pushNil to allocate and initialize each temp. So if one inspects [|a|a:=2] and sends it self method symbolic you get:

13 <8F 00 00 05> closureNumCopied: 0 numArgs: 0 bytes 17 to 21
17 <73> pushConstant: nil
18 <77> pushConstant: 2
19 <81 40> storeIntoTemp: 0
21 <7D> blockReturn
22 <7C> returnTop

And when you say self asContext pc you get 17, which is *before* the nil is pushed.  So you'll want to modify tempNamed: to compare the index of the temporary with the stack pointer and answer nil if the index is beyond the stack pointer.

The same bug exists in Squeak, e.g. the below gave an error until I fixed DebuggerMethodMap>>namedTempAt:in:


| b |
b := [ |a| a:=2 ].
{ b asContext tempNames. b method debuggerMap tempsAndValuesForContext: b asContext }
#(#('b' 'a') 'b: [closure] in UndefinedObject>>DoIt
a: nil
')


Why did I use pushNil to allocate temps?  It was not a good choice; it means for example that to determine how many temps a block has one has to parse all the bytecodes and see where the stack pointer is at the end (since initial pushNils are ambiguous; an initial pushNil might be producing a parameter or result or initializing a temp).  But not using pushNil would have meant a more complex bytecode for closure creation plus another inst var in BlockClosure.  I made another similar misstep in not storing the method in a BlockClosure, hence preventing simple implementation of clean blocks (one needs to synthesize an outerContext also).  We live and learn.



On Sat, Apr 14, 2012 at 1:09 PM, Stéphane Ducasse <[hidden email]> wrote:
I'm taking some times to go back the block closure chapter and I was wondering how I can get access to block temporaries

[ |a | a :=2.  a]

for example I tried

[ |a | a :=2.  a]

outerContext contextForLocalVariables tempAt: 1 and variations but none worked.

Stef







--
best,
Eliot