> 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.
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).
One could beautify it a bit by sorting the names according to the original
definition order, though.
(we should look onto that).
But even if we do, this does not mean that b has offset 2 in the example, as it
lives in an array...
> 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