Hi Steph,

� � this is an interesting bug with Debugger doits inside Debugger doits. �So at the outer level one has some method m0 in the debugger:

nextEvent
"Return the next event from the receiver."
eventQueue == nil�
ifTrue:[^self nextEventSynthesized]
ifFalse:[^self nextEventFromQueue]

and in the right-hand context inspector one evaluates the following (which will cause a subscript bounds because there are no temps)

ThisContext namedTempAt: 1

�to create m1:

DoItIn: ThisContext�
^ ThisContext namedTempAt: 1

If in the debugger on m1 I evaluate e.g. ThisContext I get the below error in the compiler as it is trying to create m2

The underlying bug is that in m2 ThisContext is ambiguous. �It can refer to the context for m1 or, as the programmer intends, the context for m0. �What the programmer means to achieve is an m2 that reads

DoItIn: ThisContext�
^ (ThisContext tempAt: 0) namedTempAt: 1

where ThisContext tempAt: 0 accesses thisContext in m0.

The symptom is due to Encoder>>init:context:notifying: binding ThisContext twice in

aContext ~~ nil ifTrue:
[| homeNode |
homeNode := self bindTemp: self doItInContextName.
"0th temp = aContext passed as arg"
aContext tempNames withIndexDo:
[:variable :index|
scopeTable
at: variable
put: (MessageAsTempNode new
receiver: homeNode
selector: #namedTempAt:
arguments: (Array with: (self encodeLiteral: index))
precedence: 3
from: self)]].

since aContext tempNames includes 'ThisContext' which is also�self doItInContextName.

I'm not sure how to fix this. �One way is for the above loop to encode 'ThisContext' as 'ThisContext tempAt: 0', but that only works one level deep. �Once one has an m3 it will access the wrong ThisContext, but it'll be better than the current situation as there will be no exception.
� ��
On Tue, Jul 26, 2011 at 7:02 AM, St�phane Ducasse <Stephane.Ducasse@inria.fr> wrote:
Hi guys

I was debugging some bug and I got the following


DoItIn: ThisContext
� � � �^ self
� � � � � � � �do: [:each | ((ThisContext namedTempAt: 1)
� � � � � � � � � � � � � � � � � � � �includes: each)
� � � � � � � � � � � � � � � �ifFalse: [^ false]]


I selected (ThisContext namedTempAt: 1

and I got MessageAsTempNode does not understand beMethodArg

method: doit context: ctxt
� � � �" pattern [ | temporaries ] block => MethodNode."

� � � �| sap blk prim temps messageComment methodNode |
� � � �properties := AdditionalMethodState new.
� � � �sap := self pattern: doit inContext: ctxt.
� � � �"sap={selector, arguments, precedence}"
� � � �properties selector: (sap at: 1).
� � � �encoder selector: (sap at: 1).
� � � �(sap at: 2) do: [:argNode | argNode beMethodArg].
� � � � � � � � � � � � � � � � � � � � � � � �^^^^
� � � �doit ifFalse: [self pragmaSequence].
� � � �temps := self temporaries.
� � � �messageComment := currentComment.
� � � �currentComment := nil.
� � � �doit ifFalse: [self pragmaSequence].
� � � �prim := self pragmaPrimitives.
� � � �self statements: #() innerBlock: doit.
� � � �blk := parseNode.
� � � �doit ifTrue: [blk returnLast]
� � � � � � � �ifFalse: [blk returnSelfIfNoOther: encoder].
� � � �hereType == #doIt ifFalse: [^self expected: 'Nothing more'].
� � � �self interactive ifTrue: [self removeUnusedTemps].
� � � �methodNode := self newMethodNode comment: messageComment.
� � � �^methodNode
� � � � � � � �selector: (sap at: 1)
� � � � � � � �arguments: (sap at: 2)
� � � � � � � �precedence: (sap at: 3)
� � � � � � � �temporaries: temps
� � � � � � � �block: blk
� � � � � � � �encoder: encoder
� � � � � � � �primitive: prim
� � � � � � � �properties: properties


argNode is a MessageAsTempNode and beMethodArg is only defined on TempVariableNode


http://code.google.com/p/pharo/issues/detail?id=4551

Stef





--
best,
Eliot