On 12 Oct 2014, at 11:49, Nicolai Hess <nicolaihess@web.de> 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