TL;DR: I need help changing the message OrderedCollection new to 
OrderedCollection --> newTenured <-- at a specific offset in a compiled block. 
I can do this for regular methods, but I get an error when the method is a 
Block.

Hello everyone,

I'm trying to automatically change message sends in my code, but I'm having 
trouble with compiled blocks.
For example, I want to change the message OrderedCollection new to 
OrderedCollection --> newTenured <-- in a specific method. I have the compiled 
block and the offset (26) for the message I want to change. However, searching 
for the selector new doesn't work because there can be multiple messages with 
the same name, and I only want to change the one at the given offset.

theMethod

    | tmp1 |
    1 = tmp1 something: [ "rewrite this message send" OrderedCollection new ].
    tmp1 otherStruf: [ Dictionary new "do not rewrite this meesage send" ].
    ^ self


I can change the message when there is no block without any problem using the 
IR like this:

transformMessageSend: compiledMethodOrBlock offset: offset

    | oldSelector newSelector irSendNode ir irSequences |
    oldSelector := (compiledMethodOrBlock sourceNode sourceNodeForPC: offset) 
selector.
    newSelector := self makeNewSelector: oldSelector.

    ir := compiledMethodOrBlock ir.
    irSequences := ir allSequences flatCollect: #children.
    irSendNode := (irSequences select: #isSend) detect: [ :e | e selector = 
oldSelector ].
    irSendNode selector: newSelector.

    ^ ir generate
          selector: compiledMethodOrBlock selector;
          yourself


But I get an error with ir generate when the compiledMethodOrBlock is a Block. 
If it's a normal compiled method, it works as expected.
Can anyone help me with this? Thanks!

PS: I'm not forced to do it with the IR, ir can be done by using the AST. The 
only thing is that I'd like to avoid doing string manipulation

Cheers and merry christmas,
Sebastian Jordan

Reply via email to