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