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