Thank you eliot, marcus

Yes I know your blog it is a great source of information.
I am curious how the squeak compiler/debugger handles this (I'll look into
it).

About opal and optimized block scope:
Yes, I like the way this "special" non-scope is modelled with
its own scope class.
But somehow the whileTrue: receiver block is handled different than
the ifTrue: block argument.





2014-10-14 17:41 GMT+02:00 Eliot Miranda <[email protected]>:

> Hi Marcus,
>
> On Tue, Oct 14, 2014 at 4:09 AM, Marcus Denker <[email protected]>
> wrote:
>
>>
>> > On 12 Oct 2014, at 11:49, Nicolai Hess <[email protected]> wrote:
>> >
>> > I tried to solve issues
>> > "13260 inspecting variables in the debugger fails in some cases" and
>> > "14058 Inconsistent information in debugger"
>> > and found some oddities in the way opal (compiler and the debuggermap)
>> > handles tempory variables.
>> > I am not sure if these are bugs.
>> >
>> > 1. order of temporaries:
>> > Evaluating this method
>> > |a b c|
>> > a:=1.
>> > b:=2.
>> > c:=3.
>> > thisContext tempNames logCr.
>> > ["in a block ! " thisContext tempNames logCr . a+b+c ] value.
>> >
>> > prints in the transcript
>> > #(#a #b #c)
>> > #(#a #b #c)
>> >
>> > - ok, both contexts, the method and block context, use the same
>> > ordering for the tempories
>> >
>> > writing on one variable in the block context require an indirection
>> vector for
>> > the variable
>> >
>> > |a b c|
>> > a:=1.
>> > b:=2.
>> > c:=3.
>> > thisContext tempNames logCr.
>> > [b:=1. thisContext tempNames  logCr. a+b+c ] value.
>> >
>> > here the variable b is written within the block context. This method
>> prints
>> > #(#b #a #c)
>> > #(#a #c #b)
>> >
>> > - strange the variable order has changed and is not the same in both
>> contexts.
>> >
>>
>> Yes, but behind the scenes a lot is going on… when you assign a variable
>> in a block, this
>> variable can not be allocated like a normal temp. There is instead an
>> array (temp vector) allocated where this
>> variable lives. Then *this array* has a “temp” and is accessed in the
>> block like the variables
>> in the case of no assignment.
>>
>
> Niolai, you're probably aware of it but there's an extensive write up of
> the design on my blog:
>
> http://www.mirandabanda.org/cogblog/2008/06/07/closures-part-i/
>
> http://www.mirandabanda.org/cogblog/2008/07/22/closures-part-ii-the-bytecodes/
>
> http://www.mirandabanda.org/cogblog/2008/07/24/closures-part-iii-the-compiler/
>  (especially
> section "The Closure Analysis")
>
> This means that there can not be an order: some variables live in arrays,
>> others in the context.
>> The only thing that you have is a scope that nows how a name maps to a
>> specific offset or two
>> (offset of temp of the “temp vector + offset inside this temp vector).
>>
>
> I disagree slightly.  The Squeak compiler maintains order, both in temps
> and in indirect temps.  But whether a temp is direct or indirect depends on
> a simple analysis of a single method.  I still think it is part of the
> Smalltalk culture to KISS and e.g. maintain the order of temps.
>
> One could beautify it a bit by sorting the names according to the original
>> definition order, though.
>> (we should look onto that).
>>
>
> The current exception system needs to access temps, e.g. ensure:'s and
> ifCurtailed:'s complete and on:do:'s handlerActive.  Isn't it really
> important to maintain ordering?  It certainly makes introspection easier.
> One can go through a name-based interface but that is likely to be much
> much slower in what is a perfrmance-critical part of the system.
>
>
>>
>> But even if we do, this does not mean that b has offset 2 in the example,
>> as it lives in an array...
>>
>
> Right.
>
>
>>
>>
>> > 2. OCOptimizedBlockScope
>> >
>> > Consider a whileTrue: call
>> > ["A-Block"] whileTrue:["B-Block"]
>> > or an ifTrue:
>> > ("some boolean value") ifTrue:["C-Block"]
>> > stepping into the blocks with the debugger and reading the
>> > values for a tempoariy variable shows that every block has
>> > an OCOpotimizedBlockScope as its scope.
>> > Are all  3 blocks the same kind of "optimized blocks"? because ->
>> >
>> Yes, we tried two ideas
>> The first move only real existing scopes, that means, instead of an
>> optimised scope
>> point to the scope that all these optimized blocks are flattened into.
>> But that was not nice and we could not get it to work.
>> Instead, we opted into modelling the concept of  the optimised scope: on
>> the AST
>> level, the block has a scope (like all blocks), but when you add an entry
>> (or query),
>> it will forward to the “real” existing scope.
>>
>> I still like it, it makes things very explicit.
>>
>> > 3. Blocks within optimized blocks
>> > This method prints the number of tempories on the Transcript
>> > (the on:do: call is just a dummy for an "block within a block"
>> > but the important part is the usage of the three variables
>> > in the do-block)
>> >
>> > |a b c|
>> > a:=1.
>> > b:=2.
>> > c:=3.
>> > (c>0) ifTrue:[
>> >     [ a asString ] on:Error do:[:ex | a value:a value:b value:c].
>> > ].
>> > thisContext method numTemps logCr.
>> > a
>> >
>> > The output on the transcript is "3"
>> > - ok
>> >
>> > This method is like the one above, but the nested block
>> > is in the receiver of the whileTrue:[] call (again, an optimized block,
>> right?)
>> >
>> > |a b c|
>> > a:=1.
>> > b:=2.
>> > c:=3.
>> >
>> > [
>> >     [ a asString ] on:Error do:[:ex | a value:a value:b value:c].
>> >      c <0 ] whileTrue:[].
>> > thisContext method numTemps logCr.
>> > a
>> >
>> > The output on the Transcript is "1"
>> > And it depends on the number of used variables in the do-Block
>> > The same method but with the do-Block
>> > do:[:ex | a value:a value:b]
>> > would print 2 as number of temporaries.
>> >
>>
>>
>> Hmm… I need to think about this one. It looks strange, yes.
>>
>>         Marcus
>>
>>
>>
>>
>>
>
>
> --
> best,
> Eliot
>

Reply via email to