[Pharo-project] Instance variables references inside a method
Hi! I'm playing with some metaprogramming, and I'm stuck at trying to find out * which* instance variables are referred inside a method. I've found that a CompiledMethod understands hasInstVarRefs, but I don't recognize a method that could tell just me what I'm looking for. Any leads? Thanks! Carla.
LÃder, you can do something like: class := myCompiledMethod methodClass. class instVarNames select: [ :varName | idx := class instVarIndexFor: varName. myCompiledMethod readsField: idx or: [ myCompiledMethod writesField: idx ] ] because #readsField: and #writesField: are index based. You can also see as an example: Behavior>>#whichSelectorsAccess: that is var named based, but over all class selectors. Guille On Sun, May 6, 2012 at 10:38 AM, Carla F. Griggio <carla.griggio@gmail.com>wrote:
Hi! I'm playing with some metaprogramming, and I'm stuck at trying to find out *which* instance variables are referred inside a method. I've found that a CompiledMethod understands hasInstVarRefs, but I don't recognize a method that could tell just me what I'm looking for.
Any leads?
Thanks! Carla.
Thanks Guille! That gives me more tools to play with :P On Sun, May 6, 2012 at 5:49 AM, Guillermo Polito <guillermopolito@gmail.com>wrote:
LÃder,
you can do something like:
class := myCompiledMethod methodClass. class instVarNames select: [ :varName | idx := class instVarIndexFor: varName. myCompiledMethod readsField: idx or: [ myCompiledMethod writesField: idx ] ]
because #readsField: and #writesField: are index based.
You can also see as an example: Behavior>>#whichSelectorsAccess: that is var named based, but over all class selectors.
Guille
On Sun, May 6, 2012 at 10:38 AM, Carla F. Griggio <carla.griggio@gmail.com
wrote:
Hi! I'm playing with some metaprogramming, and I'm stuck at trying to find out *which* instance variables are referred inside a method. I've found that a CompiledMethod understands hasInstVarRefs, but I don't recognize a method that could tell just me what I'm looking for.
Any leads?
Thanks! Carla.
Yay! It works beautifully :D I added this method in CompiledMethod as an extension of my project: CompiledMethod>>referredInstVars |theClass idx| theClass := self methodClass. ^theClass instVarNames select: [ :varName | idx := theClass instVarIndexFor: varName. (self readsField: idx) or: [ self writesField: idx ] ] On Sun, May 6, 2012 at 6:04 AM, Carla F. Griggio <carla.griggio@gmail.com>wrote:
Thanks Guille! That gives me more tools to play with :P
On Sun, May 6, 2012 at 5:49 AM, Guillermo Polito < guillermopolito@gmail.com> wrote:
LÃder,
you can do something like:
class := myCompiledMethod methodClass. class instVarNames select: [ :varName | idx := class instVarIndexFor: varName. myCompiledMethod readsField: idx or: [ myCompiledMethod writesField: idx ] ]
because #readsField: and #writesField: are index based.
You can also see as an example: Behavior>>#whichSelectorsAccess: that is var named based, but over all class selectors.
Guille
On Sun, May 6, 2012 at 10:38 AM, Carla F. Griggio < carla.griggio@gmail.com> wrote:
Hi! I'm playing with some metaprogramming, and I'm stuck at trying to find out *which* instance variables are referred inside a method. I've found that a CompiledMethod understands hasInstVarRefs, but I don't recognize a method that could tell just me what I'm looking for.
Any leads?
Thanks! Carla.
Hi Carla, On Sun, May 6, 2012 at 2:12 AM, Carla F. Griggio <carla.griggio@gmail.com>wrote:
Yay! It works beautifully :D
I added this method in CompiledMethod as an extension of my project:
CompiledMethod>>referredInstVars |theClass idx| theClass := self methodClass. ^theClass instVarNames select: [ :varName | idx := theClass instVarIndexFor: varName. (self readsField: idx) or: [ self writesField: idx ] ]
Here's an order N way, instead of an order N^2. referredInstVars | allInstVarNames instVarNames | allInstVarNames := self methodClass allInstVarNames. self isReturnField ifTrue: [^Set with: (allInstVarNames at: self returnField + 1)]. instVarNames := Set new. self abstractBytecodeMessagesDo: [:msg| (#(#popIntoReceiverVariable: #pushReceiverVariable: #storeIntoReceiverVariable:) includes: msg selector) ifTrue: [instVarNames add: (allInstVarNames at: msg argument + 1)]]. ^instVarNames "Dictionary newFromPairs: (Point selectors collect: [:s| { s. (Point >> s) referredInstVars}])"
On Sun, May 6, 2012 at 6:04 AM, Carla F. Griggio <carla.griggio@gmail.com>wrote:
Thanks Guille! That gives me more tools to play with :P
On Sun, May 6, 2012 at 5:49 AM, Guillermo Polito < guillermopolito@gmail.com> wrote:
LÃder,
you can do something like:
class := myCompiledMethod methodClass. class instVarNames select: [ :varName | idx := class instVarIndexFor: varName. myCompiledMethod readsField: idx or: [ myCompiledMethod writesField: idx ] ]
because #readsField: and #writesField: are index based.
You can also see as an example: Behavior>>#whichSelectorsAccess: that is var named based, but over all class selectors.
Guille
On Sun, May 6, 2012 at 10:38 AM, Carla F. Griggio < carla.griggio@gmail.com> wrote:
Hi! I'm playing with some metaprogramming, and I'm stuck at trying to find out *which* instance variables are referred inside a method. I've found that a CompiledMethod understands hasInstVarRefs, but I don't recognize a method that could tell just me what I'm looking for.
Any leads?
Thanks! Carla.
-- best, Eliot
Thanks you!! El 07/05/2012, a las 15:27, Eliot Miranda <eliot.miranda@gmail.com> escribió:
Hi Carla,
On Sun, May 6, 2012 at 2:12 AM, Carla F. Griggio <carla.griggio@gmail.com> wrote: Yay! It works beautifully :D
I added this method in CompiledMethod as an extension of my project:
CompiledMethod>>referredInstVars |theClass idx| theClass := self methodClass. ^theClass instVarNames select: [ :varName | idx := theClass instVarIndexFor: varName. (self readsField: idx) or: [ self writesField: idx ] ]
Here's an order N way, instead of an order N^2.
referredInstVars | allInstVarNames instVarNames | allInstVarNames := self methodClass allInstVarNames. self isReturnField ifTrue: [^Set with: (allInstVarNames at: self returnField + 1)]. instVarNames := Set new. self abstractBytecodeMessagesDo: [:msg| (#(#popIntoReceiverVariable: #pushReceiverVariable: #storeIntoReceiverVariable:) includes: msg selector) ifTrue: [instVarNames add: (allInstVarNames at: msg argument + 1)]]. ^instVarNames
"Dictionary newFromPairs: (Point selectors collect: [:s| { s. (Point >> s) referredInstVars}])"
On Sun, May 6, 2012 at 6:04 AM, Carla F. Griggio <carla.griggio@gmail.com> wrote: Thanks Guille! That gives me more tools to play with :P
On Sun, May 6, 2012 at 5:49 AM, Guillermo Polito <guillermopolito@gmail.com> wrote: LÃder,
you can do something like:
class := myCompiledMethod methodClass. class instVarNames select: [ :varName | idx := class instVarIndexFor: varName. myCompiledMethod readsField: idx or: [ myCompiledMethod writesField: idx ] ]
because #readsField: and #writesField: are index based.
You can also see as an example: Behavior>>#whichSelectorsAccess: that is var named based, but over all class selectors.
Guille
On Sun, May 6, 2012 at 10:38 AM, Carla F. Griggio <carla.griggio@gmail.com> wrote: Hi! I'm playing with some metaprogramming, and I'm stuck at trying to find out which instance variables are referred inside a method. I've found that a CompiledMethod understands hasInstVarRefs, but I don't recognize a method that could tell just me what I'm looking for.
Any leads?
Thanks! Carla.
-- best, Eliot
<CompiledMethod-referredInstVars.st>
participants (4)
-
Carla F. Griggio -
Carla Griggio -
Eliot Miranda -
Guillermo Polito