On 06 Dec 2013, at 10:01, Roberto Minelli <roberto.minelli@usi.ch> wrote:
Hi guys,
I am using Spy for my project, and I need to do something which, on top of my knowledge, is not supported.
Here is the point: Spy allows to insert code before (#beforeRun:with:in:) and after (#afterRun:with:in:) and works perfectly.
Now suppose I want to inject some code *inside* the method, e.g.,
aMethodToBeProfiled
do something
"Injected code accessing some fields of the current instance of this objectâ Transcript show: self field asString.
Is there any support for this?
Here is how to do it on the IR level: A class TestMy with test ^x + 1 + x byte code is: 13 <00> pushRcvr: 0 14 <76> pushConstant: 1 15 <B0> send: + 16 <00> pushRcvr: 0 17 <B0> send: + 18 <7C> returnTop âget a copy of the IR tree" irMethod := (TestMy>>#test) ir copy. âget all instance variable access IR instructionsâ allIvarAccesses := irMethod allInstructionsMatching: [ :ir |ir isInstVarAccess]. âinsert code for â1 haltâ before all of them" allIvarAccesses do: [ :each | each addInstructionsBefore: { IRInstruction pushLiteral: 1. IRInstruction send: #halt. IRInstruction popTop }]. âgenerate a new compiledMethod" cm := irMethod generate: (TestMy>>#test) trailer. âinstall in the class" TestMy addSelector: #test withMethod: cm. 17 <76> pushConstant: 1 18 <D0> send: halt 19 <87> pop 20 <00> pushRcvr: 0 21 <76> pushConstant: 1 22 <B0> send: + 23 <76> pushConstant: 1 24 <D0> send: halt 25 <87> pop 26 <00> pushRcvr: 0 27 <B0> send: + 28 <7C> returnTop â> TestMy new test What is now yet wiring is quick return methods â> need to clear the primitive in that case, should not be hard to do.