Uko
Uko

Reputation: 13396

Get receiver of the chain from sender context

Imagine I have a method like

someMethod

  ^ instVar class getProperty

Can I somehow implement the getPropertymethod in a way

getProperty

  thisContext sender ...

to get the object to which class is being sent? I'e value of instVar but without knowing that it's an instance variable, maybe it is a parameter or a literal in some other cases.

Upvotes: 1

Views: 176

Answers (4)

John Aspinall
John Aspinall

Reputation: 51

This is horrible and probably won't work in all cases, but may give you a starting point if you absolutely have to do this (and is also a nice demonstration of the level of reflectivity possible in Smalltalk):

getProperty 

    | sender message receiver |

    sender := thisContext sender.
    message := sender method abstractBytecodeMessageAt: (sender pc - 3).

    message selector = #pushReceiverVariable: ifTrue: [receiver := sender receiver instVarAt: (message arguments first + 1)].
    message selector = #pushTemporaryVariable: ifTrue: [receiver := sender tempAt: (message arguments first + 1)].
    message selector = #pushConstant: ifTrue: [receiver := message arguments first].

    receiver isNil ifTrue: [self error: 'unknown'].

    ^receiver

Upvotes: 1

Max Leske
Max Leske

Reputation: 5125

You could instrument the slots to return a wrapper or proxy when answering to class. The proxy would know the object held by the slot.

Upvotes: 0

James Foster
James Foster

Reputation: 136

Can you refactor someMethod as follows?

someMethod

  ^ instVar class getPropertyOf: instVar

Upvotes: 0

aka.nice
aka.nice

Reputation: 9572

I don't see anything obvious, instVar is no more on the execution stack, it's been replaced by the return value of message 'class'.

Maybe you could cheat and instrument all senders of 'class getProperty' chain to do something special like replacing with 'MyAnalyzer getClassPropertyOf: instVar'. It sounds like evil.

Upvotes: 1

Related Questions