Fixed _GETSTATIC_R: / _PUTSTATIC_R: - initialize class if not already.
"
COPYRIGHT (c) 1996-2011 by Claus Gittinger
New code and modifications done at SWING Research Group [1]:
COPYRIGHT (c) 2010-2011 by Jan Vrany, Jan Kurs and Marcel Hlopko
SWING Research Group, Czech Technical University in Prague
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
inclusion of the above copyright notice. This software may not
be provided or otherwise made available to, or used by, any
other person. No title to or ownership of the software is
hereby transferred.
[1] Code written at SWING Research Group contains a signature
of one of the above copright owners. For exact set of such code,
see the differences between this version and version stx:libjava
as of 1.9.2010
"
"{ Package: 'stx:libjava' }"
JavaByteCodeProcessorAdapter subclass:#JavaMethodAnalyzer
instanceVariableNames:'fieldsAccessed fieldsRead fieldsWritten staticsAccessed
staticsRead staticsWritten methodsInvoked refdClasses'
classVariableNames:''
poolDictionaries:''
category:'Languages-Java-Support-Decompiling'
!
!JavaMethodAnalyzer class methodsFor:'documentation'!
copyright
"
COPYRIGHT (c) 1996-2011 by Claus Gittinger
New code and modifications done at SWING Research Group [1]:
COPYRIGHT (c) 2010-2011 by Jan Vrany, Jan Kurs and Marcel Hlopko
SWING Research Group, Czech Technical University in Prague
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
inclusion of the above copyright notice. This software may not
be provided or otherwise made available to, or used by, any
other person. No title to or ownership of the software is
hereby transferred.
[1] Code written at SWING Research Group contains a signature
of one of the above copright owners. For exact set of such code,
see the differences between this version and version stx:libjava
as of 1.9.2010
"
!
documentation
"
A helper class to analyze method's bytecode and keep some statistics
like read/written fields, sent messages, referenced classes...
[author:]
Jan Vrany <jan.vrany@fit.cvut.cz>
[instance variables:]
[class variables:]
[see also:]
"
! !
!JavaMethodAnalyzer class methodsFor:'analyzing'!
analyze: aJavaMethod
"Analyzes the given method and return the analyzer,
which can be in turn asked for various informstion"
^ self new
process: aJavaMethod
receiver: nil
arguments: (Array new: aJavaMethod javaNumArgs);
yourself
"Created: / 30-08-2013 / 13:33:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!JavaMethodAnalyzer methodsFor:'instructions'!
anewarray
| classRef |
classRef := constantPool at: self fetchIndex2.
refdClasses add: classRef.
"Created: / 09-09-2013 / 12:21:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
getfield
| fieldRef |
fieldRef := constantPool at: self fetchIndex2.
fieldsRead add: fieldRef.
fieldsAccessed add: fieldRef.
"Created: / 30-08-2013 / 13:25:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 05-09-2013 / 16:19:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
getstatic
| fieldRef |
fieldRef := constantPool at: self fetchIndex2.
staticsRead add: fieldRef.
staticsAccessed add: fieldRef.
refdClasses add: fieldRef classRef.
"Created: / 05-09-2013 / 16:19:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 09-09-2013 / 12:16:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
invinterface
methodsInvoked add: (constantPool at: self fetchBytes2).
self fetchBytes2 "/ count
"Created: / 30-08-2013 / 17:05:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 30-08-2013 / 20:28:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
invnonvirt
methodsInvoked add: (constantPool at: self fetchBytes2)
"Created: / 30-08-2013 / 17:05:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
invstatic
methodsInvoked add: (constantPool at: self fetchBytes2)
"Created: / 30-08-2013 / 17:05:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
invvirt
methodsInvoked add: (constantPool at: self fetchBytes2)
"Created: / 30-08-2013 / 17:05:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
multianewarray
| classRef |
classRef := constantPool at: self fetchIndex2.
self fetchIndex. "/ dimensions
refdClasses add: classRef.
"Created: / 09-09-2013 / 12:21:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
new
| classRef |
classRef := constantPool at: self fetchIndex2.
refdClasses add: classRef.
"Created: / 09-09-2013 / 12:18:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
putfield
| fieldRef |
fieldRef := constantPool at: self fetchIndex2.
fieldsAccessed add: fieldRef.
fieldsWritten add: fieldRef.
"Created: / 30-08-2013 / 13:26:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 30-08-2013 / 17:02:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
putstatic
| fieldRef |
fieldRef := constantPool at: self fetchIndex2.
staticsWritten add: fieldRef.
staticsAccessed add: fieldRef.
refdClasses add: fieldRef classRef.
"Created: / 09-09-2013 / 12:16:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!JavaMethodAnalyzer methodsFor:'processing loop'!
process: aMethod receiver: aReceiver arguments: args
fieldsAccessed := Set new.
fieldsRead := Set new.
fieldsWritten := Set new.
staticsAccessed := Set new.
staticsRead := Set new.
staticsWritten := Set new.
methodsInvoked := Set new.
refdClasses := Set new.
"/ Abstract, native or other funny method
aMethod byteCode isNil ifTrue:[ ^ self ].
^ super process: aMethod receiver: aReceiver arguments: args.
"Created: / 30-08-2013 / 13:23:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 09-09-2013 / 12:15:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!JavaMethodAnalyzer methodsFor:'queries'!
sends: selector
^ self sendsAny: (Array with: selector)
"Created: / 31-08-2013 / 11:38:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
sends:selector1 or:selector2
^ self sendsAny: (Array with: selector1 with: selector2)
"Modified: / 31-08-2013 / 11:39:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
sendsAny: selectors
selectors do:[:pair|
methodsInvoked do:[:methodRef |
methodRef selector = pair first ifTrue:[
^ true
]
]
].
^ false
"Created: / 02-12-2011 / 23:05:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 31-08-2013 / 21:33:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!JavaMethodAnalyzer methodsFor:'queries-statistic'!
messagesPossiblySent
^ #()
"Created: / 30-08-2013 / 14:05:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 31-08-2013 / 10:44:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
messagesSent
^ methodsInvoked collect:[:methodRef |methodRef selector ]
"Created: / 31-08-2013 / 10:44:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 31-08-2013 / 21:32:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
messagesSentToSelf
^#()
"Created: / 31-08-2013 / 09:31:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
messagesSentToSuper
^#()
"Created: / 30-03-2013 / 09:59:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
modifiedClassVars
^#() "/ No class vars in Java
"Created: / 30-08-2013 / 13:16:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
modifiedInstVars
^ method isStatic ifTrue:[
staticsWritten collect:[:ref | ref name ]
] ifFalse:[
fieldsWritten collect:[:ref | ref name ]
]
"Created: / 30-08-2013 / 13:18:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 05-09-2013 / 16:23:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
readGlobals
| names |
names := refdClasses collect:[:ref | ref name ].
"/ (names includes: 'sun/misc/Unsafe') ifTrue:[
"/ self halt.
"/ ].
^ names
"Created: / 05-09-2013 / 15:27:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 09-09-2013 / 12:33:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
readInstVars
^ method isStatic ifTrue:[
staticsRead collect:[:ref | ref name ]
] ifFalse:[
fieldsRead collect:[:ref | ref name ]
]
"Created: / 05-09-2013 / 15:27:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
usedClassVars
^ #() "/ No class vars in Java
"Created: / 30-08-2013 / 13:18:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
usedGlobals
^ self readGlobals
"Created: / 05-09-2013 / 15:27:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
usedInstVars
^ method isStatic ifTrue:[
staticsAccessed collect:[:ref | ref name ]
] ifFalse:[
fieldsAccessed collect:[:ref | ref name ]
]
"Created: / 30-08-2013 / 13:18:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 05-09-2013 / 16:22:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!JavaMethodAnalyzer methodsFor:'queries-statistic-Java'!
methodsInvoked
"Return a set of method invoked by the analyzed
method.
Unlike #messagesSent, which return only
selectors, this method returns a list of method refs,
so the receivers' declared class is also accessible
(through ref classRef)"
^ methodsInvoked
"Created: / 31-08-2013 / 23:22:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!JavaMethodAnalyzer class methodsFor:'documentation'!
version_HG
^ '$Changeset: <not expanded> $'
! !