Initial contribution of core script analysis code
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@616 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
386cb9e3ad
commit
3d9390a397
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="source/java"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
|
@ -0,0 +1,2 @@
|
|||
bin
|
||||
domo-trace.txt*
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<launchConfiguration type="org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType">
|
||||
<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="'${resource_loc:/com.ibm.domo.php/source/c/cbuild.sh}' '${resource_loc:/com.ibm.domo.php/source/c/winbuild.vbs}'"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="full,incremental,"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${build_project}/source/c"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${bash}"/>
|
||||
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
|
||||
</launchConfiguration>
|
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.ibm.wala.cast</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>LaunchConfigHandle</key>
|
||||
<value><project>/.externalToolBuilders/make DOMO.Ast.launch</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -0,0 +1,25 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: WALA CAst core Plug-in
|
||||
Bundle-SymbolicName: com.ibm.wala.cast
|
||||
Bundle-Version: 1.0.0
|
||||
Bundle-Activator: com.ibm.wala.cast.plugin.AstPlugin
|
||||
Bundle-Vendor: IBM
|
||||
Bundle-Localization: plugin
|
||||
Require-Bundle: org.eclipse.core.runtime,
|
||||
com.ibm.wala.core
|
||||
Eclipse-AutoStart: true
|
||||
Export-Package: com.ibm.wala.cast.analysis.typeInference,
|
||||
com.ibm.wala.cast.ipa.callgraph,
|
||||
com.ibm.wala.cast.ir.cfg,
|
||||
com.ibm.wala.cast.ir.ssa,
|
||||
com.ibm.wala.cast.ir.ssa.analysis,
|
||||
com.ibm.wala.cast.ir.translator,
|
||||
com.ibm.wala.cast.loader,
|
||||
com.ibm.wala.cast.plugin,
|
||||
com.ibm.wala.cast.tree,
|
||||
com.ibm.wala.cast.tree.impl,
|
||||
com.ibm.wala.cast.tree.visit,
|
||||
com.ibm.wala.cast.types,
|
||||
com.ibm.wala.cast.util
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
source.. = source/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.
|
|
@ -0,0 +1,40 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
=======================================================================
|
||||
CAPA Domo build file
|
||||
=======================================================================
|
||||
-->
|
||||
<project name="com.ibm.wala.cast" default="build-everything" basedir=".">
|
||||
<!-- Software version details -->
|
||||
<property name="name" value="walacast" />
|
||||
<property name="module_name" value="com.ibm.wala.cast" />
|
||||
<property name="Name" value="walacast" />
|
||||
<property name="version" value="1-alpha" />
|
||||
|
||||
<!-- Compilation switches -->
|
||||
<property name="debug" value="true" />
|
||||
<property name="deprecation" value="false" />
|
||||
<property name="optimize" value="true" />
|
||||
<property name="javacFailOnError" value="true" />
|
||||
<property name="javacDebugInfo" value="on" />
|
||||
<property name="javacVerbose" value="false" />
|
||||
|
||||
|
||||
<!-- Set global properties for this build -->
|
||||
<property name="src" value="source/java" />
|
||||
<property name="src.tests" value="tests" />
|
||||
<property name="build" value="build" />
|
||||
<property name="build.result" value="${basedir}" />
|
||||
<property name="build.tests" value="build/tests" />
|
||||
<property name="build.javadocs" value="${build}/javadocs" />
|
||||
<property name="publish.javadocs" value="javadocs/com.ibm.wala.cast" />
|
||||
<property name="dist" value="dist" />
|
||||
<property name="etc" value="etc" />
|
||||
<property name="docs" value="docs" />
|
||||
<property name="lib" value="lib" />
|
||||
<property name="mainlib" value="../mainlib" />
|
||||
<property name="sharedlib" value="../sharedlib" />
|
||||
|
||||
<import file="${sharedlib}/scripts/common-targets.xml"/>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,749 @@
|
|||
%!PS-Adobe-3.0 EPSF-3.0
|
||||
%%Creator: GIMP PostScript file plugin V 1.17 by Peter Kirchgessner
|
||||
%%Title: the-cast-system.eps
|
||||
%%CreationDate: Tue Apr 18 07:55:26 2006
|
||||
%%DocumentData: Clean7Bit
|
||||
%%LanguageLevel: 2
|
||||
%%Pages: 1
|
||||
%%BoundingBox: 14 14 175 177
|
||||
%%EndComments
|
||||
%%BeginProlog
|
||||
% Use own dictionary to avoid conflicts
|
||||
10 dict begin
|
||||
%%EndProlog
|
||||
%%Page: 1 1
|
||||
% Translate for offset
|
||||
14.173228346456694 14.173228346456694 translate
|
||||
% Translate to begin of first scanline
|
||||
0 161.98724409448818 translate
|
||||
159.98740157480313 -161.98724409448818 scale
|
||||
% Image geometry
|
||||
160 162 8
|
||||
% Transformation matrix
|
||||
[ 160 0 0 162 0 0 ]
|
||||
% Strings to hold RGB-samples per scanline
|
||||
/rstr 160 string def
|
||||
/gstr 160 string def
|
||||
/bstr 160 string def
|
||||
{currentfile /ASCII85Decode filter /RunLengthDecode filter rstr readstring pop}
|
||||
{currentfile /ASCII85Decode filter /RunLengthDecode filter gstr readstring pop}
|
||||
{currentfile /ASCII85Decode filter /RunLengthDecode filter bstr readstring pop}
|
||||
true 3
|
||||
%%BeginData: 34016 ASCII Bytes
|
||||
colorimage
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
]`/*%0HJiHs*t~>
|
||||
]`/*%0HJiHs*t~>
|
||||
]`/*%0HJiHs*t~>
|
||||
]`/)P!!'1%s*t~>
|
||||
]`/)P!!'1%s*t~>
|
||||
]`/)P!!'1%s*t~>
|
||||
]`/*1!!)kqs*t~>
|
||||
]`/*1!!)kqs*t~>
|
||||
]`/*1!!)kqs*t~>
|
||||
ci4+FSrWI5s8N(us*t~>
|
||||
ci4+FSrWI5s8N(us*t~>
|
||||
ci4+FSrWI5s8N(us*t~>
|
||||
ci4*p!!'t-s8N(us*t~>
|
||||
ci4*p!!'t-s8N(us*t~>
|
||||
ci4*p!!'t-s8N(us*t~>
|
||||
ci4+G!!)ufs8N(us*t~>
|
||||
ci4+G!!)ufs8N(us*t~>
|
||||
ci4+G!!)ufs8N(us*t~>
|
||||
cN!nEnGiLgWW.J~>
|
||||
cN!nEnGiLgWW.J~>
|
||||
cN!nEnGiLgWW.J~>
|
||||
cN!nEnGiLgWW.J~>
|
||||
cN!nEnGiLgWW.J~>
|
||||
cN!nEnGiLgWW.J~>
|
||||
cN!nEqu6cfVDFk@s8N(us*t~>
|
||||
cN!nEqu6cfVDFk@s8N(us*t~>
|
||||
cN!nEqu6cfVDFk@s8N(us*t~>
|
||||
cN!nErr32aQ:;#X!)!+frrB%uJ,~>
|
||||
cN!nErr32aQ:;#X!)!+frrB%uJ,~>
|
||||
cN!nErr32aQ:;#X!)!+frrB%uJ,~>
|
||||
e,KdBaeaPo!!(W+2Z`gV!.OeErrB%uJ,~>
|
||||
e,KdBaeaPo!!(W+2Z`gV!.OeErrB%uJ,~>
|
||||
e,KdBaeaPo!!(W+2Z`gV!.OeErrB%uJ,~>
|
||||
ec,Yc"o/-'$S>5!R_Ie\q>^HpqYpcRJiFJP7dfmJ#M!T8"Ulr"gs,kL~>
|
||||
ec,Yc"o/-'$S>5!R_Ie\q>^HpqYpcRJiFJP7dfmJ#M!T8"Ulr"gs,kL~>
|
||||
ec,Yc"o/-'$S>5!R_Ie\q>^HpqYpcRJiFJP7dfmJ#M!T8"Ulr"gs,kL~>
|
||||
ec,qX#"W?YTY1=*jmiBN!;uiudSU&C!!%<;rrV\%!rDru#Fj$=J,~>
|
||||
ec,qX#"W?YTY1=*jmiBN!;uiudSU&C!!%<;rrV\%!rDru#Fj$=J,~>
|
||||
ec,qX#"W?YTY1=*jmiBN!;uiudSU&C!!%<;rrV\%!rDru#Fj$=J,~>
|
||||
eGfOHr;ZcsnGiLgrr3?"EWQ4jRH"+I!&sWO%+QR&"_>RDn[("N!2e*BJ,~>
|
||||
eGfOHr;ZcsnGiLgrr3?"EWQ4jRH"+I!&sWO%+QR&"_>RDn[("N!2e*BJ,~>
|
||||
eGfOHr;ZcsnGiLgrr3?"EWQ4jRH"+I!&sWO%+QR&"_>RDn[("N!2e*BJ,~>
|
||||
cN!nEnGiLgs8N8T-iaR8r;Q]tp&H!)rrgRZ!%H@orri$X!#PFWs*t~>
|
||||
cN!nEnGiLgs8N8T-iaR8r;Q]tp&H!)rrgRZ!%H@orri$X!#PFWs*t~>
|
||||
cN!nEnGiLgs8N8T-iaR8r;Q]tp&H!)rrgRZ!%H@orri$X!#PFWs*t~>
|
||||
cN!nEnGiLg"ol:J!&)t$rrE*,q#:KQ'`^DeqYpZ.!!'7Ms*t~>
|
||||
cN!nEnGiLg"ol:J!&)t$rrE*,q#:KQ'`^DeqYpZ.!!'7Ms*t~>
|
||||
cN!nEnGiLg"ol:J!&)t$rrE*,q#:KQ'`^DeqYpZ.!!'7Ms*t~>
|
||||
cN!nEnGiLg"NCcK9_8,\!<<5trri*M!&O9Frs%hnBbUOIR*bk`~>
|
||||
cN!nEnGiLg"NCcK9_8,\!<<5trri*M!&O9Frs%hnBbUOIR*bk`~>
|
||||
cN!nEnGiLg"NCcK9_8,\!<<5trri*M!&O9Frs%hnBbUOIR*bk`~>
|
||||
cN!nEnGiLg!tbNBrV?Kn!;ZX%H2nfEs8(!,@4;6V!!3^Wq9].l~>
|
||||
cN!nEnGiLg!tbNBrV?Kn!;ZX%H2nfEs8(!,@4;6V!!3^Wq9].l~>
|
||||
cN!nEnGiLg!tbNBrV?Kn!;ZX%H2nfEs8(!,@4;6V!!3^Wq9].l~>
|
||||
cN!nEnGiIf!Fu-(s8N)qrs%?c!,-=3#lO`+!@hljps/ni~>
|
||||
cN!nEnGiIf!Fu-(s8N)qrs%?c!,-=3#lO`+!@hljps/ni~>
|
||||
cN!nEnGiIf!Fu-(s8N)qrs%?c!,-=3#lO`+!@hljps/ni~>
|
||||
cN!nEnGiLg!Drahs8N)qrr?^/!!F9:J[b'is*t~>
|
||||
cN!nEnGiLg!Drahs8N)qrr?^/!!F9:J[b'is*t~>
|
||||
cN!nEnGiLg!Drahs8N)qrr?^/!!F9:J[b'is*t~>
|
||||
cN!nEnGiLg!;?-drrDrr#Or*#+B!p&lG`dR~>
|
||||
cN!nEnGiLg!;?-drrDrr#Or*#+B!p&lG`dR~>
|
||||
cN!nEnGiLg!;?-drrDrr#Or*#+B!p&lG`dR~>
|
||||
cN!nEp\t<^YO_YlrrD`lrrDrr!hfTK_#Jo~>
|
||||
cN!nEp\t<^YO_YlrrD`lrrDrr!hfTK_#Jo~>
|
||||
cN!nEp\t<^YO_YlrrD`lrrDrr!hfTK_#Jo~>
|
||||
cN!nEp\t;/!*T:#rrD`lrrDrr!aYk^_#Jo~>
|
||||
cN!nEp\t;/!*T:#rrD`lrrDrr!aYk^_#Jo~>
|
||||
cN!nEp\t;/!*T:#rrD`lrrDrr!aYk^_#Jo~>
|
||||
cN!nEq#:HK$ijH/s8N)ls8N)rrrObPaS#Q8d3(F:d/SU~>
|
||||
cN!nEq#:HK$ijH/s8N)ls8N)rrrObPaS#Q8d3(F:d/SU~>
|
||||
cN!nEq#:HK$ijH/s8N)ls8N)rrrObPaS#Q8d3(F:d/SU~>
|
||||
cN!nEq>UT_-NGFVrVultp&G$lqu6^-!:fa^"-*?]`mFa9~>
|
||||
cN!nEq>UT_-NGFVrVultp&G$lqu6^-!:fa^"-*?]`mFa9~>
|
||||
cN!nEq>UT_-NGFVrVultp&G$lqu6^-!:fa^"-*?]`mFa9~>
|
||||
cN!nEqYp]\0*!E\r;Zcsp&G$lqu6^"!;uQj"6:*q>gNG#~>
|
||||
cN!nEqYp]\0*!E\r;Zcsp&G$lqu6^"!;uQj"6:*q>gNG#~>
|
||||
cN!nEqYp]\0*!E\r;Zcsp&G$lqu6^"!;uQj"6:*q>gNG#~>
|
||||
cN!nEqu6f:)urCoqu?Zrp&G$lqu6^/!:0CZ"Rn#D2YGDrJ,~>
|
||||
cN!nEqu6f:)urCoqu?Zrp&G$lqu6^/!:0CZ"Rn#D2YGDrJ,~>
|
||||
cN!nEqu6f:)urCoqu?Zrp&G$lqu6^/!:0CZ"Rn#D2YGDrJ,~>
|
||||
cN!nErVm&mEruD_r;-Hn!;6Bl!;lct3<6Vbrrh@7!&O)hs*t~>
|
||||
cN!nErVm&mEruD_r;-Hn!;6Bl!;lct3<6Vbrrh@7!&O)hs*t~>
|
||||
cN!nErVm&mEruD_r;-Hn!;6Bl!;lct3<6Vbrrh@7!&O)hs*t~>
|
||||
cN!nEs8N9"RMc)@Xn_qr!;6Bl!;lctM?$9Frrr=l&HGJpc2W:~>
|
||||
cN!nEs8N9"RMc)@Xn_qr!;6Bl!;lctM?$9Frrr=l&HGJpc2W:~>
|
||||
cN!nEs8N9"RMc)@Xn_qr!;6Bl!;lctM?$9Frrr=l&HGJpc2W:~>
|
||||
cN!nE#2c1$!!$'cp](6np&G$lqu7/r*<8dHmelOoKI$U$JGm^lJ,~>
|
||||
cN!nE#2c1$!!$'cp](6np&G$lqu7/r*<8dHmelOoKI$U$JGm^lJ,~>
|
||||
cN!nE#2c1$!!$'cp](6np&G$lqu7/r*<8dHmelOoKI$U$JGm^lJ,~>
|
||||
cMn(\!!`K(.CAgK"7-!fg@tUL`;fnuqu6]A(A\"4!DLtbs*t~>
|
||||
cMn(\!!`K(.CAgK"7-!fg@tUL`;fnuqu6]A(A\"4!DLtbs*t~>
|
||||
cMn(\!!`K(.CAgK"7-!fg@tUL`;fnuqu6]A(A\"4!DLtbs*t~>
|
||||
cMn'+&/%^>rUp0mi!h'rp\t??&3fsers7t?1CjR$5(VG/s*t~>
|
||||
cMn'+&/%^>rUp0mi!h'rp\t??&3fsers7t?1CjR$5(VG/s*t~>
|
||||
cMn'+&/%^>rUp0mi!h'rp\t??&3fsers7t?1CjR$5(VG/s*t~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcG6>!W:F=s*t~>
|
||||
JcG6>!W:F=s*t~>
|
||||
JcG6>!W:F=s*t~>
|
||||
JcG<@"Rq"M9%rt<J,~>
|
||||
JcG<@"Rq"M9%rt<J,~>
|
||||
JcG<@"Rq"M9%rt<J,~>
|
||||
JcG?A#0S;-'b<M)pA]X~>
|
||||
JcG?A#0S;-'b<M)pA]X~>
|
||||
JcG?A#0S;-'b<M)pA]X~>
|
||||
nGboQmGljD_S*:XYH=gnR\6agWNND4N.?Y0C1L^M:JYY)<`_aX5!VG,6qL'L8kVcM@U<&C9M8?$
|
||||
=_M8aJ7(uC:e!oPr_,CG8OG^46UOFF90ka-5W_M@?@uEG6;C?Q8Ol376VC3P;cm+)C3"E,CjV><
|
||||
R%pXhP)P`j,9J!>&epW)s*t~>
|
||||
nGboQmGljD_S*:XYH=gnR\6agWNND4N.?Y0C1L^M:JYY)<`_aX5!VG,6qL'L8kVcM@U<&C9M8?$
|
||||
=_M8aJ7(uC:e!oPr_,CG8OG^46UOFF90ka-5W_M@?@uEG6;C?Q8Ol376VC3P;cm+)C3"E,CjV><
|
||||
R%pXhP)P`j,9J!>&epW)s*t~>
|
||||
nGboQmGljD_S*:XYH=gnR\6agWNND4N.?Y0C1L^M:JYY)<`_aX5!VG,6qL'L8kVcM@U<&C9M8?$
|
||||
=_M8aJ7(uC:e!oPr_,CG8OG^46UOFF90ka-5W_M@?@uEG6;C?Q8Ol376VC3P;cm+)C3"E,CjV><
|
||||
R%pXhP)P`j,9J!>&epW)s*t~>
|
||||
pA\gnZ@>b2)&F,&%hK3]&JQ9i@NZ6n&1KY3=_Air)BL^r7kbo",<-eg*u>J!(D%W1)]KSN,UFfb
|
||||
0/P@5-QtrG0/H..-m9]S(+LXO*$?@F*$?CE)&aP4&/#T\%4=#)8IH1K-6X?K+V>M-&e>N`%hTKs
|
||||
>%/Td%hL0N8Qf[K)]BbS3_(kD(adi.s*t~>
|
||||
pA\gnZ@>b2)&F,&%hK3]&JQ9i@NZ6n&1KY3=_Air)BL^r7kbo",<-eg*u>J!(D%W1)]KSN,UFfb
|
||||
0/P@5-QtrG0/H..-m9]S(+LXO*$?@F*$?CE)&aP4&/#T\%4=#)8IH1K-6X?K+V>M-&e>N`%hTKs
|
||||
>%/Td%hL0N8Qf[K)]BbS3_(kD(adi.s*t~>
|
||||
pA\gnZ@>b2)&F,&%hK3]&JQ9i@NZ6n&1KY3=_Air)BL^r7kbo",<-eg*u>J!(D%W1)]KSN,UFfb
|
||||
0/P@5-QtrG0/H..-m9]S(+LXO*$?@F*$?CE)&aP4&/#T\%4=#)8IH1K-6X?K+V>M-&e>N`%hTKs
|
||||
>%/Td%hL0N8Qf[K)]BbS3_(kD(adi.s*t~>
|
||||
p]#T[;'?Ye%hK9b(D@K$((q]ACf25d&/#Tr-6<s<'G:s!+<iR,4%r15-6aBB&K_l2+s%O;)'L%L
|
||||
.3^6$4Z+W;7ohQ2;H>\",p=BY*#]e<(Dn5:(*k7E*[;pJ&eu$.5s$(u&g7u&%hK9b(D@K$((q]A
|
||||
Cf25d&/#Te*@;gD'bh8l+!;a_5s%bPqY:)@~>
|
||||
p]#T[;'?Ye%hK9b(D@K$((q]ACf25d&/#Tr-6<s<'G:s!+<iR,4%r15-6aBB&K_l2+s%O;)'L%L
|
||||
.3^6$4Z+W;7ohQ2;H>\",p=BY*#]e<(Dn5:(*k7E*[;pJ&eu$.5s$(u&g7u&%hK9b(D@K$((q]A
|
||||
Cf25d&/#Te*@;gD'bh8l+!;a_5s%bPqY:)@~>
|
||||
p]#T[;'?Ye%hK9b(D@K$((q]ACf25d&/#Tr-6<s<'G:s!+<iR,4%r15-6aBB&K_l2+s%O;)'L%L
|
||||
.3^6$4Z+W;7ohQ2;H>\",p=BY*#]e<(Dn5:(*k7E*[;pJ&eu$.5s$(u&g7u&%hK9b(D@K$((q]A
|
||||
Cf25d&/#Te*@;gD'bh8l+!;a_5s%bPqY:)@~>
|
||||
p]#M$'H7o()'Tt:+!D[pCfDZ#+%dar)E&uX,UXZT*#K2"-Pd[X.OcQ--lsEG&/Q&t+<qdA*?udW
|
||||
/L2Pj3&`<98R5\'5!2\*.P*8#+;u4;&0)Q)'+l$&,:"<T-R'<@/4(IA'H7o()'Tt:+!D[pCfDZ#
|
||||
+%dar)A4qV'I5%J*ZQ"-'.4P81Fagtb4u!e~>
|
||||
p]#M$'H7o()'Tt:+!D[pCfDZ#+%dar)E&uX,UXZT*#K2"-Pd[X.OcQ--lsEG&/Q&t+<qdA*?udW
|
||||
/L2Pj3&`<98R5\'5!2\*.P*8#+;u4;&0)Q)'+l$&,:"<T-R'<@/4(IA'H7o()'Tt:+!D[pCfDZ#
|
||||
+%dar)A4qV'I5%J*ZQ"-'.4P81Fagtb4u!e~>
|
||||
p]#M$'H7o()'Tt:+!D[pCfDZ#+%dar)E&uX,UXZT*#K2"-Pd[X.OcQ--lsEG&/Q&t+<qdA*?udW
|
||||
/L2Pj3&`<98R5\'5!2\*.P*8#+;u4;&0)Q)'+l$&,:"<T-R'<@/4(IA'H7o()'Tt:+!D[pCfDZ#
|
||||
+%dar)A4qV'I5%J*ZQ"-'.4P81Fagtb4u!e~>
|
||||
p]"W(<&Q!B-n6r33(PVR6TZe2'1l\E=\)=h2a'5f3%Qd2*YT,4-T`h"0,5$8'GqW</K5]B&g\YB
|
||||
+"K#k.5W_&2ENK63]8oi5rUAL.3L&_*#fb-&JPrr(apg[1aa1[.j-Pq=]@:)*@NBl3B0P]/jh]N
|
||||
&ediHA6DH!<]<0'5WC;L-6<g4-7:l*S,!#6~>
|
||||
p]"W(<&Q!B-n6r33(PVR6TZe2'1l\E=\)=h2a'5f3%Qd2*YT,4-T`h"0,5$8'GqW</K5]B&g\YB
|
||||
+"K#k.5W_&2ENK63]8oi5rUAL.3L&_*#fb-&JPrr(apg[1aa1[.j-Pq=]@:)*@NBl3B0P]/jh]N
|
||||
&ediHA6DH!<]<0'5WC;L-6<g4-7:l*S,!#6~>
|
||||
p]"W(<&Q!B-n6r33(PVR6TZe2'1l\E=\)=h2a'5f3%Qd2*YT,4-T`h"0,5$8'GqW</K5]B&g\YB
|
||||
+"K#k.5W_&2ENK63]8oi5rUAL.3L&_*#fb-&JPrr(apg[1aa1[.j-Pq=]@:)*@NBl3B0P]/jh]N
|
||||
&ediHA6DH!<]<0'5WC;L-6<g4-7:l*S,!#6~>
|
||||
p]"#;(E4,$',V?%'eVp65Xmms.o14>(cb&::c^EtC11Kq()%5u,<dt)'."2$)BotM3[H+#(*"G9
|
||||
*?m0h.kj@V3^YA3+Ykc00e>O=,:Fs&,pt;l(`+#/'b1ir-R(,Y%hKQs-l3g<&/,ln*#1(p2aBhq
|
||||
3@dmH0,Q]=/5SAa5AFV7,Sh%))^@O(NVNO(~>
|
||||
p]"#;(E4,$',V?%'eVp65Xmms.o14>(cb&::c^EtC11Kq()%5u,<dt)'."2$)BotM3[H+#(*"G9
|
||||
*?m0h.kj@V3^YA3+Ykc00e>O=,:Fs&,pt;l(`+#/'b1ir-R(,Y%hKQs-l3g<&/,ln*#1(p2aBhq
|
||||
3@dmH0,Q]=/5SAa5AFV7,Sh%))^@O(NVNO(~>
|
||||
p]"#;(E4,$',V?%'eVp65Xmms.o14>(cb&::c^EtC11Kq()%5u,<dt)'."2$)BotM3[H+#(*"G9
|
||||
*?m0h.kj@V3^YA3+Ykc00e>O=,:Fs&,pt;l(`+#/'b1ir-R(,Y%hKQs-l3g<&/,ln*#1(p2aBhq
|
||||
3@dmH0,Q]=/5SAa5AFV7,Sh%))^@O(NVNO(~>
|
||||
p]"V=,S(k9/NQ0_0fi')5#EFJ-o4:R1J^"F+sJ'L.6:ir)A!T80g.92&g9%C(`sYD4=2@'*YSu*
|
||||
*ZuLC'H.fB6:ELE*@E]o.2WpI+rqXH+=83E&J?#r&Io3c(DJ23rX^Fp,S(k9/NQ0_0fi')5#EFJ
|
||||
-o4:R1J^"F+sJ'L.6:ir)A!T81kk/fs*t~>
|
||||
p]"V=,S(k9/NQ0_0fi')5#EFJ-o4:R1J^"F+sJ'L.6:ir)A!T80g.92&g9%C(`sYD4=2@'*YSu*
|
||||
*ZuLC'H.fB6:ELE*@E]o.2WpI+rqXH+=83E&J?#r&Io3c(DJ23rX^Fp,S(k9/NQ0_0fi')5#EFJ
|
||||
-o4:R1J^"F+sJ'L.6:ir)A!T81kk/fs*t~>
|
||||
p]"V=,S(k9/NQ0_0fi')5#EFJ-o4:R1J^"F+sJ'L.6:ir)A!T80g.92&g9%C(`sYD4=2@'*YSu*
|
||||
*ZuLC'H.fB6:ELE*@E]o.2WpI+rqXH+=83E&J?#r&Io3c(DJ23rX^Fp,S(k9/NQ0_0fi')5#EFJ
|
||||
-o4:R1J^"F+sJ'L.6:ir)A!T81kk/fs*t~>
|
||||
o)DKS2&-o>'Gqi/*#]kH1H%-P4=V<h+<_L<(`l0g&h5Xb-n?,U*[i`[-57XY/28Y&*Y&Z$*$Q@F
|
||||
*#BP;6Ui:D-7p/[.39]P*?-"6'c.J]&2P%F$kja*+W_C3&.fF&-k7Oh2&-o>'Gqi/*#]kH1H%-P
|
||||
4=V<h+<_L<(`l0g&h5Xb.)u#]J,~>
|
||||
o)DKS2&-o>'Gqi/*#]kH1H%-P4=V<h+<_L<(`l0g&h5Xb-n?,U*[i`[-57XY/28Y&*Y&Z$*$Q@F
|
||||
*#BP;6Ui:D-7p/[.39]P*?-"6'c.J]&2P%F$kja*+W_C3&.fF&-k7Oh2&-o>'Gqi/*#]kH1H%-P
|
||||
4=V<h+<_L<(`l0g&h5Xb.)u#]J,~>
|
||||
o)DKS2&-o>'Gqi/*#]kH1H%-P4=V<h+<_L<(`l0g&h5Xb-n?,U*[i`[-57XY/28Y&*Y&Z$*$Q@F
|
||||
*#BP;6Ui:D-7p/[.39]P*?-"6'c.J]&2P%F$kja*+W_C3&.fF&-k7Oh2&-o>'Gqi/*#]kH1H%-P
|
||||
4=V<h+<_L<(`l0g&h5Xb.)u#]J,~>
|
||||
o)Eem)AEer&eP`g'GW>],p=Zb.5*7n(_mYn&/QT[4Z>/C+=8-K*ucRq,S:\?)Cm6k///X/(`O8:
|
||||
+rhXH/5&>a/05K?/MA=r(_n&.()\&*)&sG0+:f2=3[>RX*>8u#AmQu-)AEer&eP`g'GW>],p=Zb
|
||||
&Lf@b*>fM(%M0F%6p3Ib,r,>ls*t~>
|
||||
o)Eem)AEer&eP`g'GW>],p=Zb.5*7n(_mYn&/QT[4Z>/C+=8-K*ucRq,S:\?)Cm6k///X/(`O8:
|
||||
+rhXH/5&>a/05K?/MA=r(_n&.()\&*)&sG0+:f2=3[>RX*>8u#AmQu-)AEer&eP`g'GW>],p=Zb
|
||||
&Lf@b*>fM(%M0F%6p3Ib,r,>ls*t~>
|
||||
o)Eem)AEer&eP`g'GW>],p=Zb.5*7n(_mYn&/QT[4Z>/C+=8-K*ucRq,S:\?)Cm6k///X/(`O8:
|
||||
+rhXH/5&>a/05K?/MA=r(_n&.()\&*)&sG0+:f2=3[>RX*>8u#AmQu-)AEer&eP`g'GW>],p=Zb
|
||||
&Lf@b*>fM(%M0F%6p3Ib,r,>ls*t~>
|
||||
o)ErN,U=?D&/5in(aV3\*>]S5,9.F5&fN);,q:i1;cbb2*$6:I*YTVS65:4J)C6a]/g1iB)C$%4
|
||||
(E+MF0fq9b8h(eu(Gn0/-5dsE'c.o0*$c[E(`Er!(EO,)*Z,Iu*HZ?E,U=?D&/5in(aV3\*>]S5
|
||||
,9.F5$kaI**@30o1fII31NrKlJ,~>
|
||||
o)ErN,U=?D&/5in(aV3\*>]S5,9.F5&fN);,q:i1;cbb2*$6:I*YTVS65:4J)C6a]/g1iB)C$%4
|
||||
(E+MF0fq9b8h(eu(Gn0/-5dsE'c.o0*$c[E(`Er!(EO,)*Z,Iu*HZ?E,U=?D&/5in(aV3\*>]S5
|
||||
,9.F5$kaI**@30o1fII31NrKlJ,~>
|
||||
o)ErN,U=?D&/5in(aV3\*>]S5,9.F5&fN);,q:i1;cbb2*$6:I*YTVS65:4J)C6a]/g1iB)C$%4
|
||||
(E+MF0fq9b8h(eu(Gn0/-5dsE'c.o0*$c[E(`Er!(EO,)*Z,Iu*HZ?E,U=?D&/5in(aV3\*>]S5
|
||||
,9.F5$kaI**@30o1fII31NrKlJ,~>
|
||||
o)B<9-S6Pb*?67J0K^`t%hK<j'`JXe*@3-_0M4c'7Smc';+a8F8k2BQJT>43C0OqSB2i/5<EfAt
|
||||
*)KmY?s@D^@!$U/<`s'KAmAJG;GU7r>$kH7=&T#l.ooqW>Zb-+:gfPu<`r3j7moj::fp1B/1W5)
|
||||
.O?;_-7L>e,Wd_5-nn1M`V0=^~>
|
||||
o)B<9-S6Pb*?67J0K^`t%hK<j'`JXe*@3-_0M4c'7Smc';+a8F8k2BQJT>43C0OqSB2i/5<EfAt
|
||||
*)KmY?s@D^@!$U/<`s'KAmAJG;GU7r>$kH7=&T#l.ooqW>Zb-+:gfPu<`r3j7moj::fp1B/1W5)
|
||||
.O?;_-7L>e,Wd_5-nn1M`V0=^~>
|
||||
o)B<9-S6Pb*?67J0K^`t%hK<j'`JXe*@3-_0M4c'7Smc';+a8F8k2BQJT>43C0OqSB2i/5<EfAt
|
||||
*)KmY?s@D^@!$U/<`s'KAmAJG;GU7r>$kH7=&T#l.ooqW>Zb-+:gfPu<`r3j7moj::fp1B/1W5)
|
||||
.O?;_-7L>e,Wd_5-nn1M`V0=^~>
|
||||
o)BC&Fc)TWYI;9lg"kB>k3;=)p%\HKrr`5sqYp3gJ,~>
|
||||
o)BC&Fc)TWYI;9lg"kB>k3;=)p%\HKrr`5sqYp3gJ,~>
|
||||
o)BC&Fc)TWYI;9lg"kB>k3;=)p%\HKrr`5sqYp3gJ,~>
|
||||
_Z'c<>ms!XV>l&~>
|
||||
_Z'c<>ms!XV>l&~>
|
||||
_Z'c<>ms!XV>l&~>
|
||||
_Z'V8rVuq.V>l&~>
|
||||
_Z'V8rVuq.V>l&~>
|
||||
_Z'V8rVuq.V>l&~>
|
||||
li.@9JOgsn";E=VK>I?Drr>^k!!%MFs*t~>
|
||||
li.@9JOgsn";E=VK>I?Drr>^k!!%MFs*t~>
|
||||
li.@9JOgsn";E=VK>I?Drr>^k!!%MFs*t~>
|
||||
mf*@dT.9O7!Y8b_kPkSU#lXf(etrCs~>
|
||||
mf*@dT.9O7!Y8b_kPkSU#lXf(etrCs~>
|
||||
mf*@dT.9O7!Y8b_kPkSU#lXf(etrCs~>
|
||||
n,EF50_#,D7b$]&!2]Vo!61l8J,~>
|
||||
n,EF50_#,D7b$]&!2]Vo!61l8J,~>
|
||||
n,EF50_#,D7b$]&!2]Vo!61l8J,~>
|
||||
nG`NX#Q=]2$=9CUlh]krZ?JJ9rVus&OQuiG2Z3UUM5C6&~>
|
||||
nG`NX#Q=]2$=9CUlh]krZ?JJ9rVus&OQuiG2Z3UUM5C6&~>
|
||||
nG`NX#Q=]2$=9CUlh]krZ?JJ9rVus&OQuiG2Z3UUM5C6&~>
|
||||
nc&T@rW!!*JaN43!pY7@rVuq_m/I:-!!!N5!'R1YJ,~>
|
||||
nc&T@rW!!*JaN43!pY7@rVuq_m/I:-!!!N5!'R1YJ,~>
|
||||
nc&T@rW!!*JaN43!pY7@rVuq_m/I:-!!!N5!'R1YJ,~>
|
||||
o)A]QrVusTf^o+G]`J06*UNe2;#gT8:&k@X`r?21;]mC$k5Tr~>
|
||||
o)A]QrVusTf^o+G]`J06*UNe2;#gT8:&k@X`r?21;]mC$k5Tr~>
|
||||
o)A]QrVusTf^o+G]`J06*UNe2;#gT8:&k@X`r?21;]mC$k5Tr~>
|
||||
oD\uq!WW3pp$r%a:&k8EmJdIJ!WW8SXoJH]`r?%TrVur;k5Tr~>
|
||||
oD\uq!WW3pp$r%a:&k8EmJdIJ!WW8SXoJH]`r?%TrVur;k5Tr~>
|
||||
oD\uq!WW3pp$r%a:&k8EmJdIJ!WW8SXoJH]`r?%TrVur;k5Tr~>
|
||||
o`#*D#QOj$r:'^g`XirsmJdH/!!#Feq%E`]`r?&7rW)'[J,~>
|
||||
o`#*D#QOj$r:'^g`XirsmJdH/!!#Feq%E`]`r?&7rW)'[J,~>
|
||||
o`#*D#QOj$r:'^g`XirsmJdH/!!#Feq%E`]`r?&7rW)'[J,~>
|
||||
p&>3j/H>c5q!S.^rTsOkmgK0rXoJE<!!(6_s8E#[s*t~>
|
||||
p&>3j/H>c5q!S.^rTsOkmgK0rXoJE<!!(6_s8E#[s*t~>
|
||||
p&>3j/H>c5q!S.^rTsOkmgK0rXoJE<!!(6_s8E#[s*t~>
|
||||
p&>/7!!!esfDc27!!!u8s8U=D!,'=OrW)'[J,~>
|
||||
p&>/7!!!esfDc27!!!u8s8U=D!,'=OrW)'[J,~>
|
||||
p&>/7!!!esfDc27!!!u8s8U=D!,'=OrW)'[J,~>
|
||||
pAY9E!rr>-fDc!N*<6(irVlsO!"JP?s8E#[s*t~>
|
||||
pAY9E!rr>-fDc!N*<6(irVlsO!"JP?s8E#[s*t~>
|
||||
pAY9E!rr>-fDc!N*<6(irVlsO!"JP?s8E#[s*t~>
|
||||
pAY4b!!#gGrrf2!!!MH_rr\2[!1Cn-rW)`n"SLH]N3W!SJ,~>
|
||||
pAY4b!!#gGrrf2!!!MH_rr\2[!1Cn-rW)`n"SLH]N3W!SJ,~>
|
||||
pAY4b!!#gGrrf2!!!MH_rr\2[!1Cn-rW)`n"SLH]N3W!SJ,~>
|
||||
p\tB/!!!/Wf)Gh0!!$!rrr_Hf!&2InrW!5oe[_6%AP"Hcqu?`7o`'F~>
|
||||
p\tB/!!!/Wf)Gh0!!$!rrr_Hf!&2InrW!5oe[_6%AP"Hcqu?`7o`'F~>
|
||||
p\tB/!!!/Wf)Gh0!!$!rrr_Hf!&2InrW!5oe[_6%AP"Hcqu?`7o`'F~>
|
||||
p\t=c!!$KZrrBq8!!'_0rrYmo!5mgr$i.i1C-F$_#R`,2nFQ\L!!&bcs*t~>
|
||||
p\t=c!!$KZrrBq8!!'_0rrYmo!5mgr$i.i1C-F$_#R`,2nFQ\L!!&bcs*t~>
|
||||
p\t=c!!$KZrrBq8!!'_0rrYmo!5mgr$i.i1C-F$_#R`,2nFQ\L!!&bcs*t~>
|
||||
q#:KN!<<2Uf)GhK!!"GDrr];%!*84]"7Dpa%JKi&1&CnSr7ncED+Gl@!!*qso`'F~>
|
||||
q#:KN!<<2Uf)GhK!!"GDrr];%!*84]"7Dpa%JKi&1&CnSr7ncED+Gl@!!*qso`'F~>
|
||||
q#:KN!<<2Uf)GhK!!"GDrr];%!*84]"7Dpa%JKi&1&CnSr7ncED+Gl@!!*qso`'F~>
|
||||
q#:G8!!#^Drrh*Y!!&,Wrri-1!!M?GrrV%l$1n2t)Z9U9\Jk#=#89!uI%J18rpp)>~>
|
||||
q#:G8!!#^Drrh*Y!!&,Wrri-1!!M?GrrV%l$1n2t)Z9U9\Jk#=#89!uI%J18rpp)>~>
|
||||
q#:G8!!#^Drrh*Y!!&,Wrri-1!!M?GrrV%l$1n2t)Z9U9\Jk#=#89!uI%J18rpp)>~>
|
||||
q>UTr(B=HCf)Gkh!!!Aqq>UP3!!%6.rrV.`"8r3-'2=4acKOirgN6Z8r;QaRp&G5+LT8VglMlA~>
|
||||
q>UTr(B=HCf)Gkh!!!Aqq>UP3!!%6.rrV.`"8r3-'2=4acKOirgN6Z8r;QaRp&G5+LT8VglMlA~>
|
||||
q>UTr(B=HCf)Gkh!!!Aqq>UP3!!%6.rrV.`"8r3-'2=4acKOirgN6Z8r;QaRp&G5+LT8VglMlA~>
|
||||
q>UT5!!!f3fDc!B$NL0;q#:K>!!!W'm/I*P$iU,.$>.!Lnc&l"!!!<R88!^UrW)'[J,~>
|
||||
q>UT5!!!f3fDc!B$NL0;q#:K>!!!W'm/I*P$iU,.$>.!Lnc&l"!!!<R88!^UrW)'[J,~>
|
||||
q>UT5!!!f3fDc!B$NL0;q#:K>!!!W'm/I*P$iU,.$>.!Lnc&l"!!!<R88!^UrW)'[J,~>
|
||||
q>UP6!!$]`rr@oT!!(:<rrX_N!0cjN!W$+$!!3IVmI'uUp7')!s8E#[s*t~>
|
||||
q>UP6!!$]`rr@oT!!(:<rrX_N!0cjN!W$+$!!3IVmI'uUp7')!s8E#[s*t~>
|
||||
q>UP6!!$]`rr@oT!!(:<rrX_N!0cjN!W$+$!!3IVmI'uUp7')!s8E#[s*t~>
|
||||
q>UOC!!'@Wrri3=!!"tOrre/Y!$_@1rrN!lrVusdiT't;!9O62~>
|
||||
q>UOC!!'@Wrri3=!!"tOrre/Y!$_@1rrN!lrVusdiT't;!9O62~>
|
||||
q>UOC!!'@Wrri3=!!"tOrre/Y!$_@1rrN!lrVusdiT't;!9O62~>
|
||||
qYp][!!!2qfDbiIrVuqkpAY9X!rr>"nG`K'rVut<r8RbU!9O62~>
|
||||
qYp][!!!2qfDbiIrVuqkpAY9X!rr>"nG`K'rVut<r8RbU!9O62~>
|
||||
qYp][!!!2qfDbiIrVuqkpAY9X!rr>"nG`K'rVut<r8RbU!9O62~>
|
||||
qYpYp!!"t/rtI9i!#,"jfYt.gNI#5:5qX,X!!"eErrB>'!!$rqs8E#[s*t~>
|
||||
qYpYp!!"t/rtI9i!#,"jfYt.gNI#5:5qX,X!!"eErrB>'!!$rqs8E#[s*t~>
|
||||
qYpYp!!"t/rtI9i!#,"jfYt.gNI#5:5qX,X!!"eErrB>'!!$rqs8E#[s*t~>
|
||||
qYpY?!!$rhrrBn7!!*-%nGiR$oD]!l+92C*rS[_T!9O62~>
|
||||
qYpY?!!$rhrrBn7!!*-%nGiR$oD]!l+92C*rS[_T!9O62~>
|
||||
qYpY?!!$rhrrBn7!!*-%nGiR$oD]!l+92C*rS[_T!9O62~>
|
||||
qYpXj!!&VBrr>ja!!E?1!!#@WrrfM*!!M'Lrs._N6lcIQ@aFZGrW)'[J,~>
|
||||
qYpXj!!&VBrr>ja!!E?1!!#@WrrfM*!!M'Lrs._N6lcIQ@aFZGrW)'[J,~>
|
||||
qYpXj!!&VBrr>ja!!E?1!!#@WrrfM*!!M'Lrs._N6lcIQ@aFZGrW)'[J,~>
|
||||
qYpXE!!('lrtsJl!!!cd4A/jlH&.fa[D^STo)@hY!!(+4rrZR-!*]*r!nL]^qZ$ZuD>Nr*rW)'[
|
||||
J,~>
|
||||
qYpXE!!('lrtsJl!!!cd4A/jlH&.fa[D^STo)@hY!!(+4rrZR-!*]*r!nL]^qZ$ZuD>Nr*rW)'[
|
||||
J,~>
|
||||
qYpXE!!('lrtsJl!!!cd4A/jlH&.fa[D^STo)@hY!!(+4rrZR-!*]*r!nL]^qZ$ZuD>Nr*rW)'[
|
||||
J,~>
|
||||
qYpX3!!)-5rrd-<!"/&^rrZm6!)<+c""+'KXn_nthHBsS!!,jopAb*ljo9i~>
|
||||
qYpX3!!)-5rrd-<!"/&^rrZm6!)<+c""+'KXn_nthHBsS!!,jopAb*ljo9i~>
|
||||
qYpX3!!)-5rrd-<!"/&^rrZm6!)<+c""+'KXn_nthHBsS!!,jopAb*ljo9i~>
|
||||
qYpX$!!)cHrrhcu!!$j)rrh*Z!!1O@rrW]1!9F"V!psq2r;[-`QeD)bF9;LCU%\Nc!9O62~>
|
||||
qYpX$!!)cHrrhcu!!$j)rrh*Z!!1O@rrW]1!9F"V!psq2r;[-`QeD)bF9;LCU%\Nc!9O62~>
|
||||
qYpX$!!)cHrrhcu!!$j)rrh*Z!!1O@rrW]1!9F"V!psq2r;[-`QeD)bF9;LCU%\Nc!9O62~>
|
||||
qYpX#!!)uNrre,X!!M3JrrZ:%!*Ajn!sAT(q>C6oq2Z0e!!,L,qu6bJ!!#:Xs8E#[s*t~>
|
||||
qYpX#!!)uNrre,X!!M3JrrZ:%!*Ajn!sAT(q>C6oq2Z0e!!,L,qu6bJ!!#:Xs8E#[s*t~>
|
||||
qYpX#!!)uNrre,X!!M3JrrZ:%!*Ajn!sAT(q>C6oq2Z0e!!,L,qu6bJ!!#:Xs8E#[s*t~>
|
||||
qYpX-!!)ZFrri0<!!$6krrgRH!!:jIrrX,=!:'R`!r\o=r;ZjW^\Rm3jo>AppAb*ljo9i~>
|
||||
qYpX-!!)ZFrri0<!!$6krrgRH!!:jIrrX,=!:'R`!r\o=r;ZjW^\Rm3jo>AppAb*ljo9i~>
|
||||
qYpX-!!)ZFrri0<!!$6krrgRH!!:jIrrX,=!:'R`!r\o=r;ZjW^\Rm3jo>AppAb*ljo9i~>
|
||||
qYpX?!!)-7rrAko!!(I7rrY[i!+5I"#>bC#Hh>sK-2dfE,,t>:"8)Wo"nquq!9O62~>
|
||||
qYpX?!!)-7rrAko!!(I7rrY[i!+5I"#>bC#Hh>sK-2dfE,,t>:"8)Wo"nquq!9O62~>
|
||||
qYpX?!!)-7rrAko!!(I7rrY[i!+5I"#>bC#Hh>sK-2dfE,,t>:"8)Wo"nquq!9O62~>
|
||||
qYpX]!!($mrrY%W!(uVX"MFd8"Q&nQ!3Z(s!Z$popAY6K!!!c-s8E#hrr_>?X8_noJ,~>
|
||||
qYpX]!!($mrrY%W!(uVX"MFd8"Q&nQ!3Z(s!Z$popAY6K!!!c-s8E#hrr_>?X8_noJ,~>
|
||||
qYpX]!!($mrrY%W!(uVX"MFd8"Q&nQ!3Z(s!Z$popAY6K!!!c-s8E#hrr_>?X8_noJ,~>
|
||||
qYpY+!!&YTrrL^)pAY-.rVur7li.&E!!$U)rrN*eqZ$[9MtHZA"/#Vo1%tYH!:p-l8,rXIq#>j~>
|
||||
qYpY+!!&YTrrL^)pAY-.rVur7li.&E!!$U)rrN*eqZ$[9MtHZA"/#Vo1%tYH!:p-l8,rXIq#>j~>
|
||||
qYpY+!!&YTrrL^)pAY-.rVur7li.&E!!$U)rrN*eqZ$[9MtHZA"/#Vo1%tYH!:p-l8,rXIq#>j~>
|
||||
qYpY^!!$`trrdTI!*0!mrrZ!r!'0?E"KVS'#3,CW#P<'X"s?sLq==Of7fWO%pAb*loD\sO%0-B*
|
||||
q#>j~>
|
||||
qYpY^!!$`trrdTI!*0!mrrZ!r!'0?E"KVS'#3,CW#P<'X"s?sLq==Of7fWO%pAb*loD\sO%0-B*
|
||||
q#>j~>
|
||||
qYpY^!!$`trrdTI!*0!mrrZ!r!'0?E"KVS'#3,CW#P<'X"s?sLq==Of7fWO%pAb*loD\sO%0-B*
|
||||
q#>j~>
|
||||
qYpZ@!!"A2rrMs%rVurFq>UTP!WW5)lMh"c-3+$\iVs&'!<<,'pAb*lo`"sd1]@@SX8)^F~>
|
||||
qYpZ@!!"A2rrMs%rVurFq>UTP!WW5)lMh"c-3+$\iVs&'!<<,'pAb*lo`"sd1]@@SX8)^F~>
|
||||
qYpZ@!!"A2rrMs%rVurFq>UTP!WW5)lMh"c-3+$\iVs&'!<<,'pAb*lo`"sd1]@@SX8)^F~>
|
||||
qYp]s('"?`li-t1rVus$kP>,\CB+>`rosFcRfEEnk2ZIFpFuXJ(]3q+rW)Wk!W#Rj!!%NCs*t~>
|
||||
qYp]s('"?`li-t1rVus$kP>,\CB+>`rosFcRfEEnk2ZIFpFuXJ(]3q+rW)Wk!W#Rj!!%NCs*t~>
|
||||
qYp]s('"?`li-t1rVus$kP>,\CB+>`rosFcRfEEnk2ZIFpFuXJ(]3q+rW)Wk!W#Rj!!%NCs*t~>
|
||||
q>UP+!!$d#rrM+%rVuqJq>UTc$NL0ukl1eZ&HDfNj8T*frVuqap&G!kpAY0f:]:=oKD,=q~>
|
||||
q>UP+!!$d#rrM+%rVuqJq>UTc$NL0ukl1eZ&HDfNj8T*frVuqap&G!kpAY0f:]:=oKD,=q~>
|
||||
q>UP+!!$d#rrM+%rVuqJq>UTc$NL0ukl1eZ&HDfNj8T*frVuqap&G!kpAY0f:]:=oKD,=q~>
|
||||
q>UT;!!!Admf*=:+T;?@FSPk=LB%;gpuhY[ErZ1JmcFHKL].8S2Z37JrW)]m"m.]C!!](gs*t~>
|
||||
q>UT;!!!Admf*=:+T;?@FSPk=LB%;gpuhY[ErZ1JmcFHKL].8S2Z37JrW)]m"m.]C!!](gs*t~>
|
||||
q>UT;!!!Admf*=:+T;?@FSPk=LB%;gpuhY[ErZ1JmcFHKL].8S2Z37JrW)]m"m.]C!!](gs*t~>
|
||||
q#:FS!!#pcrrK,/rVuqQq#:Kn)ZTk[k5PG5rVuqOq>UN8K\uA#!W?g5!!*eno`+mjq#:N'('"=T
|
||||
aRoL_~>
|
||||
q#:FS!!#pcrrK,/rVuqQq#:Kn)ZTk[k5PG5rVuqOq>UN8K\uA#!W?g5!!*eno`+mjq#:N'('"=T
|
||||
aRoL_~>
|
||||
q#:FS!!#pcrrK,/rVuqQq#:Kn)ZTk[k5PG5rVuqOq>UN8K\uA#!W?g5!!*eno`+mjq#:N'('"=T
|
||||
aRoL_~>
|
||||
q#:?3rVuqZo)AaU=oJC%#G:bj!2KMn!7p93"?-;\*;o^6"53hW:%SAciCEkI!>!EGs8E#prrM=g
|
||||
rVusglgt.,~>
|
||||
q#:?3rVuqZo)AaU=oJC%#G:bj!2KMn!7p93"?-;\*;o^6"53hW:%SAciCEkI!>!EGs8E#prrM=g
|
||||
rVusglgt.,~>
|
||||
q#:?3rVuqZo)AaU=oJC%#G:bj!2KMn!7p93"?-;\*;o^6"53hW:%SAciCEkI!>!EGs8E#prrM=g
|
||||
rVusglgt.,~>
|
||||
p\tA,!!!(dp&>*dL(=1_!>riMrrY"V!&!@4!/^[T!4)M%".0&g;t^.lqiD6c!!*qZo)J[hr;R#r
|
||||
LCX@b"FpC@s*t~>
|
||||
p\tA,!!!(dp&>*dL(=1_!>riMrrY"V!&!@4!/^[T!4)M%".0&g;t^.lqiD6c!!*qZo)J[hr;R#r
|
||||
LCX@b"FpC@s*t~>
|
||||
p\tA,!!!(dp&>*dL(=1_!>riMrrY"V!&!@4!/^[T!4)M%".0&g;t^.lqiD6c!!*qZo)J[hr;R#r
|
||||
LCX@b"FpC@s*t~>
|
||||
p\t9g2#[IU?L7Lf!pP4Lr;ZjhkP"oU`Voi;ETI-"ao28?=o84%RfEErVYL/mo8ask!!,:Cnc/Rg
|
||||
"oeQ%pQ?Ho!!+k#nGe"~>
|
||||
p\t9g2#[IU?L7Lf!pP4Lr;ZjhkP"oU`Voi;ETI-"ao28?=o84%RfEErVYL/mo8ask!!,:Cnc/Rg
|
||||
"oeQ%pQ?Ho!!+k#nGe"~>
|
||||
p\t9g2#[IU?L7Lf!pP4Lr;ZjhkP"oU`Voi;ETI-"ao28?=o84%RfEErVYL/mo8ask!!,:Cnc/Rg
|
||||
"oeQ%pQ?Ho!!+k#nGe"~>
|
||||
pAY0X0E(qX$=p<up%?q*9Eb:o!Y1Fnp&>#,rVuqhjSo5*rVup:qu6]a(]FC@16ToJqWcCq:^m:&
|
||||
!Z77&nGiIf"5EI-)#aL:$B"cMs*t~>
|
||||
pAY0X0E(qX$=p<up%?q*9Eb:o!Y1Fnp&>#,rVuqhjSo5*rVup:qu6]a(]FC@16ToJqWcCq:^m:&
|
||||
!Z77&nGiIf"5EI-)#aL:$B"cMs*t~>
|
||||
pAY0X0E(qX$=p<up%?q*9Eb:o!Y1Fnp&>#,rVuqhjSo5*rVup:qu6]a(]FC@16ToJqWcCq:^m:&
|
||||
!Z77&nGiIf"5EI-)#aL:$B"cMs*t~>
|
||||
p&>']:%J>d"(:?arr=;C!!':brrADb!!!N*rrLRlo)Jh)M"U39"9ni+.MVg]!E%\?s*t~>
|
||||
p&>']:%J>d"(:?arr=;C!!':brrADb!!!N*rrLRlo)Jh)M"U39"9ni+.MVg]!E%\?s*t~>
|
||||
p&>']:%J>d"(:?arr=;C!!':brrADb!!!N*rrLRlo)Jh)M"U39"9ni+.MVg]!E%\?s*t~>
|
||||
oD\id-MIKA%;=Perr<9&!!(%"rr@HG!!#UdrrVh>&,6,,!_0!Ym/I&Aqu?d!9?6AuJ,~>
|
||||
oD\id-MIKA%;=Perr<9&!!(%"rr@HG!!#UdrrVh>&,6,,!_0!Ym/I&Aqu?d!9?6AuJ,~>
|
||||
oD\id-MIKA%;=Perr<9&!!(%"rr@HG!!#UdrrVh>&,6,,!_0!Ym/I&Aqu?d!9?6AuJ,~>
|
||||
o)B*s]6-1T$3_2'CTdF#rrc7+#upc^rrgk.#Vt61rsJ=n>qQWi$nl%_kNW!Nbs;dM3.]f\rrN&H
|
||||
nc++~>
|
||||
o)B*s]6-1T$3_2'CTdF#rrc7+#upc^rrgk.#Vt61rsJ=n>qQWi$nl%_kNW!Nbs;dM3.]f\rrN&H
|
||||
nc++~>
|
||||
o)B*s]6-1T$3_2'CTdF#rrc7+#upc^rrgk.#Vt61rsJ=n>qQWi$nl%_kNW!Nbs;dM3.]f\rrN&H
|
||||
nc++~>
|
||||
JcGEC"Rq"M9%rk9J,~>
|
||||
JcGEC"Rq"M9%rk9J,~>
|
||||
JcGEC"Rq"M9%rk9J,~>
|
||||
JcGHD#0S;-'b<M)oDa=~>
|
||||
JcGHD#0S;-'b<M)oDa=~>
|
||||
JcGHD#0S;-'b<M)oDa=~>
|
||||
oD_5TmGljD_S*:XYH=gnR\6agWNND4N.?Y0C1L^M:JYY)<`_aX5!VG,6qL'L8kVcM@U<&C9M8?$
|
||||
=_M8aJ7(uC:e!oPr_,CG8OG^46UOFF90ka-5W_M@?@uEG6;C?Q8Ol376VC3P;cm+)C3"E,CjV><
|
||||
R%pXhP)P`j,9J!>&epW&s*t~>
|
||||
oD_5TmGljD_S*:XYH=gnR\6agWNND4N.?Y0C1L^M:JYY)<`_aX5!VG,6qL'L8kVcM@U<&C9M8?$
|
||||
=_M8aJ7(uC:e!oPr_,CG8OG^46UOFF90ka-5W_M@?@uEG6;C?Q8Ol376VC3P;cm+)C3"E,CjV><
|
||||
R%pXhP)P`j,9J!>&epW&s*t~>
|
||||
oD_5TmGljD_S*:XYH=gnR\6agWNND4N.?Y0C1L^M:JYY)<`_aX5!VG,6qL'L8kVcM@U<&C9M8?$
|
||||
=_M8aJ7(uC:e!oPr_,CG8OG^46UOFF90ka-5W_M@?@uEG6;C?Q8Ol376VC3P;cm+)C3"E,CjV><
|
||||
R%pXhP)P`j,9J!>&epW&s*t~>
|
||||
q>Y-qZ@>b2)&F,&%hK3]&JQ9i@NZ6n&1KY3=_Air)BL^r7kbo",<-eg*u>J!(D%W1)]KSN,UFfb
|
||||
0/P@5-QtrG0/H..-m9]S(+LXO*$?@F*$?CE)&aP4&/#T\%4=#)8IH1K-6X?K+V>M-&e>N`%hTKs
|
||||
>%/Td%hL0N8Qf[K)]BbS3_(kD(adi+s*t~>
|
||||
q>Y-qZ@>b2)&F,&%hK3]&JQ9i@NZ6n&1KY3=_Air)BL^r7kbo",<-eg*u>J!(D%W1)]KSN,UFfb
|
||||
0/P@5-QtrG0/H..-m9]S(+LXO*$?@F*$?CE)&aP4&/#T\%4=#)8IH1K-6X?K+V>M-&e>N`%hTKs
|
||||
>%/Td%hL0N8Qf[K)]BbS3_(kD(adi+s*t~>
|
||||
q>Y-qZ@>b2)&F,&%hK3]&JQ9i@NZ6n&1KY3=_Air)BL^r7kbo",<-eg*u>J!(D%W1)]KSN,UFfb
|
||||
0/P@5-QtrG0/H..-m9]S(+LXO*$?@F*$?CE)&aP4&/#T\%4=#)8IH1K-6X?K+V>M-&e>N`%hTKs
|
||||
>%/Td%hL0N8Qf[K)]BbS3_(kD(adi+s*t~>
|
||||
qYto^;'?Ye%hK9b(D@K$((q]ACf25d&/#Tr-6<s<'G:s!+<iR,4%r15-6aBB&K_l2+s%O;)'L%L
|
||||
.3^6$4Z+W;7ohQ2;H>\",p=BY*#]e<(Dn5:(*k7E*[;pJ&eu$.5s$(u&g7u&%hK9b(D@K$((q]A
|
||||
Cf25d&/#Te*@;gD'bh8l+!;a_5s%bPqXsl=~>
|
||||
qYto^;'?Ye%hK9b(D@K$((q]ACf25d&/#Tr-6<s<'G:s!+<iR,4%r15-6aBB&K_l2+s%O;)'L%L
|
||||
.3^6$4Z+W;7ohQ2;H>\",p=BY*#]e<(Dn5:(*k7E*[;pJ&eu$.5s$(u&g7u&%hK9b(D@K$((q]A
|
||||
Cf25d&/#Te*@;gD'bh8l+!;a_5s%bPqXsl=~>
|
||||
qYto^;'?Ye%hK9b(D@K$((q]ACf25d&/#Tr-6<s<'G:s!+<iR,4%r15-6aBB&K_l2+s%O;)'L%L
|
||||
.3^6$4Z+W;7ohQ2;H>\",p=BY*#]e<(Dn5:(*k7E*[;pJ&eu$.5s$(u&g7u&%hK9b(D@K$((q]A
|
||||
Cf25d&/#Te*@;gD'bh8l+!;a_5s%bPqXsl=~>
|
||||
qYth''H7o()'Tt:+!D[pCfDZ#+%dar)E&uX,UXZT*#K2"-Pd[X.OcQ--lsEG&/Q&t+<qdA*?udW
|
||||
/L2Pj3&`<98R5\'5!2\*.P*8#+;u4;&0)Q)'+l$&,:"<T-R'<@/4(IA'H7o()'Tt:+!D[pCfDZ#
|
||||
+%dar)A4qV'I5%J*ZQ"-'.4P81Fagtb4Ydb~>
|
||||
qYth''H7o()'Tt:+!D[pCfDZ#+%dar)E&uX,UXZT*#K2"-Pd[X.OcQ--lsEG&/Q&t+<qdA*?udW
|
||||
/L2Pj3&`<98R5\'5!2\*.P*8#+;u4;&0)Q)'+l$&,:"<T-R'<@/4(IA'H7o()'Tt:+!D[pCfDZ#
|
||||
+%dar)A4qV'I5%J*ZQ"-'.4P81Fagtb4Ydb~>
|
||||
qYth''H7o()'Tt:+!D[pCfDZ#+%dar)E&uX,UXZT*#K2"-Pd[X.OcQ--lsEG&/Q&t+<qdA*?udW
|
||||
/L2Pj3&`<98R5\'5!2\*.P*8#+;u4;&0)Q)'+l$&,:"<T-R'<@/4(IA'H7o()'Tt:+!D[pCfDZ#
|
||||
+%dar)A4qV'I5%J*ZQ"-'.4P81Fagtb4Ydb~>
|
||||
qYsr+<&Q!B-n6r33(PVR6TZe2'1l\E=\)=h2a'5f3%Qd2*YT,4-T`h"0,5$8'GqW</K5]B&g\YB
|
||||
+"K#k.5W_&2ENK63]8oi5rUAL.3L&_*#fb-&JPrr(apg[1aa1[.j-Pq=]@:)*@NBl3B0P]/jh]N
|
||||
&ediHA6DH!<]<0'5WC;L-6<g4-7:l*S+Zf3~>
|
||||
qYsr+<&Q!B-n6r33(PVR6TZe2'1l\E=\)=h2a'5f3%Qd2*YT,4-T`h"0,5$8'GqW</K5]B&g\YB
|
||||
+"K#k.5W_&2ENK63]8oi5rUAL.3L&_*#fb-&JPrr(apg[1aa1[.j-Pq=]@:)*@NBl3B0P]/jh]N
|
||||
&ediHA6DH!<]<0'5WC;L-6<g4-7:l*S+Zf3~>
|
||||
qYsr+<&Q!B-n6r33(PVR6TZe2'1l\E=\)=h2a'5f3%Qd2*YT,4-T`h"0,5$8'GqW</K5]B&g\YB
|
||||
+"K#k.5W_&2ENK63]8oi5rUAL.3L&_*#fb-&JPrr(apg[1aa1[.j-Pq=]@:)*@NBl3B0P]/jh]N
|
||||
&ediHA6DH!<]<0'5WC;L-6<g4-7:l*S+Zf3~>
|
||||
qYs>>(E4,$',V?%'eVp65Xmms.o14>(cb&::c^EtC11Kq()%5u,<dt)'."2$)BotM3[H+#(*"G9
|
||||
*?m0h.kj@V3^YA3+Ykc00e>O=,:Fs&,pt;l(`+#/'b1ir-R(,Y%hKQs-l3g<&/,ln*#1(p2aBhq
|
||||
3@dmH0,Q]=/5SAa5AFV7,Sh%))^@O(NV3=%~>
|
||||
qYs>>(E4,$',V?%'eVp65Xmms.o14>(cb&::c^EtC11Kq()%5u,<dt)'."2$)BotM3[H+#(*"G9
|
||||
*?m0h.kj@V3^YA3+Ykc00e>O=,:Fs&,pt;l(`+#/'b1ir-R(,Y%hKQs-l3g<&/,ln*#1(p2aBhq
|
||||
3@dmH0,Q]=/5SAa5AFV7,Sh%))^@O(NV3=%~>
|
||||
qYs>>(E4,$',V?%'eVp65Xmms.o14>(cb&::c^EtC11Kq()%5u,<dt)'."2$)BotM3[H+#(*"G9
|
||||
*?m0h.kj@V3^YA3+Ykc00e>O=,:Fs&,pt;l(`+#/'b1ir-R(,Y%hKQs-l3g<&/,ln*#1(p2aBhq
|
||||
3@dmH0,Q]=/5SAa5AFV7,Sh%))^@O(NV3=%~>
|
||||
qYsq@,S(k9/NQ0_0fi')5#EFJ-o4:R1J^"F+sJ'L.6:ir)A!T80g.92&g9%C(`sYD4=2@'*YSu*
|
||||
*ZuLC'H.fB6:ELE*@E]o.2WpI+rqXH+=83E&J?#r&Io3c(DJ23rX^Fp,S(k9/NQ0_0fi')5#EFJ
|
||||
-o4:R1J^"F+sJ'L.6:ir)A!T81kk/cs*t~>
|
||||
qYsq@,S(k9/NQ0_0fi')5#EFJ-o4:R1J^"F+sJ'L.6:ir)A!T80g.92&g9%C(`sYD4=2@'*YSu*
|
||||
*ZuLC'H.fB6:ELE*@E]o.2WpI+rqXH+=83E&J?#r&Io3c(DJ23rX^Fp,S(k9/NQ0_0fi')5#EFJ
|
||||
-o4:R1J^"F+sJ'L.6:ir)A!T81kk/cs*t~>
|
||||
qYsq@,S(k9/NQ0_0fi')5#EFJ-o4:R1J^"F+sJ'L.6:ir)A!T80g.92&g9%C(`sYD4=2@'*YSu*
|
||||
*ZuLC'H.fB6:ELE*@E]o.2WpI+rqXH+=83E&J?#r&Io3c(DJ23rX^Fp,S(k9/NQ0_0fi')5#EFJ
|
||||
-o4:R1J^"F+sJ'L.6:ir)A!T81kk/cs*t~>
|
||||
p&@fV2&-o>'Gqi/*#]kH1H%-P4=V<h+<_L<(`l0g&h5Xb-n?,U*[i`[-57XY/28Y&*Y&Z$*$Q@F
|
||||
*#BP;6Ui:D-7p/[.39]P*?-"6'c.J]&2P%F$kja*+W_C3&.fF&-k7Oh2&-o>'Gqi/*#]kH1H%-P
|
||||
4=V<h+<_L<(`l0g&h5Xb.)toZJ,~>
|
||||
p&@fV2&-o>'Gqi/*#]kH1H%-P4=V<h+<_L<(`l0g&h5Xb-n?,U*[i`[-57XY/28Y&*Y&Z$*$Q@F
|
||||
*#BP;6Ui:D-7p/[.39]P*?-"6'c.J]&2P%F$kja*+W_C3&.fF&-k7Oh2&-o>'Gqi/*#]kH1H%-P
|
||||
4=V<h+<_L<(`l0g&h5Xb.)toZJ,~>
|
||||
p&@fV2&-o>'Gqi/*#]kH1H%-P4=V<h+<_L<(`l0g&h5Xb-n?,U*[i`[-57XY/28Y&*Y&Z$*$Q@F
|
||||
*#BP;6Ui:D-7p/[.39]P*?-"6'c.J]&2P%F$kja*+W_C3&.fF&-k7Oh2&-o>'Gqi/*#]kH1H%-P
|
||||
4=V<h+<_L<(`l0g&h5Xb.)toZJ,~>
|
||||
p&B+p)AEer&eP`g'GW>],p=Zb.5*7n(_mYn&/QT[4Z>/C+=8-K*ucRq,S:\?)Cm6k///X/(`O8:
|
||||
+rhXH/5&>a/05K?/MA=r(_n&.()\&*)&sG0+:f2=3[>RX*>8u#AmQu-)AEer&eP`g'GW>],p=Zb
|
||||
&Lf@b*>fM(%M0F%6p3Ib,r,>is*t~>
|
||||
p&B+p)AEer&eP`g'GW>],p=Zb.5*7n(_mYn&/QT[4Z>/C+=8-K*ucRq,S:\?)Cm6k///X/(`O8:
|
||||
+rhXH/5&>a/05K?/MA=r(_n&.()\&*)&sG0+:f2=3[>RX*>8u#AmQu-)AEer&eP`g'GW>],p=Zb
|
||||
&Lf@b*>fM(%M0F%6p3Ib,r,>is*t~>
|
||||
p&B+p)AEer&eP`g'GW>],p=Zb.5*7n(_mYn&/QT[4Z>/C+=8-K*ucRq,S:\?)Cm6k///X/(`O8:
|
||||
+rhXH/5&>a/05K?/MA=r(_n&.()\&*)&sG0+:f2=3[>RX*>8u#AmQu-)AEer&eP`g'GW>],p=Zb
|
||||
&Lf@b*>fM(%M0F%6p3Ib,r,>is*t~>
|
||||
p&B8Q,U=?D&/5in(aV3\*>]S5,9.F5&fN);,q:i1;cbb2*$6:I*YTVS65:4J)C6a]/g1iB)C$%4
|
||||
(E+MF0fq9b8h(eu(Gn0/-5dsE'c.o0*$c[E(`Er!(EO,)*Z,Iu*HZ?E,U=?D&/5in(aV3\*>]S5
|
||||
,9.F5$kaI**@30o1fII31NrBiJ,~>
|
||||
p&B8Q,U=?D&/5in(aV3\*>]S5,9.F5&fN);,q:i1;cbb2*$6:I*YTVS65:4J)C6a]/g1iB)C$%4
|
||||
(E+MF0fq9b8h(eu(Gn0/-5dsE'c.o0*$c[E(`Er!(EO,)*Z,Iu*HZ?E,U=?D&/5in(aV3\*>]S5
|
||||
,9.F5$kaI**@30o1fII31NrBiJ,~>
|
||||
p&B8Q,U=?D&/5in(aV3\*>]S5,9.F5&fN);,q:i1;cbb2*$6:I*YTVS65:4J)C6a]/g1iB)C$%4
|
||||
(E+MF0fq9b8h(eu(Gn0/-5dsE'c.o0*$c[E(`Er!(EO,)*Z,Iu*HZ?E,U=?D&/5in(aV3\*>]S5
|
||||
,9.F5$kaI**@30o1fII31NrBiJ,~>
|
||||
p&>W<-S6Pb*?67J0K^`t%hK<j'`JXe*@3-_0M4c'7Smc';+a8F8k2BQJT>43C0OqSB2i/5<EfAt
|
||||
*)KmY?s@D^@!$U/<`s'KAmAJG;GU7r>$kH7=&T#l.ooqW>Zb-+:gfPu<`r3j7moj::fp1B/1W5)
|
||||
.O?;_-7L>e,Wd_5-nn1M`Uj+[~>
|
||||
p&>W<-S6Pb*?67J0K^`t%hK<j'`JXe*@3-_0M4c'7Smc';+a8F8k2BQJT>43C0OqSB2i/5<EfAt
|
||||
*)KmY?s@D^@!$U/<`s'KAmAJG;GU7r>$kH7=&T#l.ooqW>Zb-+:gfPu<`r3j7moj::fp1B/1W5)
|
||||
.O?;_-7L>e,Wd_5-nn1M`Uj+[~>
|
||||
p&>W<-S6Pb*?67J0K^`t%hK<j'`JXe*@3-_0M4c'7Smc';+a8F8k2BQJT>43C0OqSB2i/5<EfAt
|
||||
*)KmY?s@D^@!$U/<`s'KAmAJG;GU7r>$kH7=&T#l.ooqW>Zb-+:gfPu<`r3j7moj::fp1B/1W5)
|
||||
.O?;_-7L>e,Wd_5-nn1M`Uj+[~>
|
||||
p&>^)Fc)TWYI;9lg"kB>k3;=)p%\HKrr`5sqYp*dJ,~>
|
||||
p&>^)Fc)TWYI;9lg"kB>k3;=)p%\HKrr`5sqYp*dJ,~>
|
||||
p&>^)Fc)TWYI;9lg"kB>k3;=)p%\HKrr`5sqYp*dJ,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
Z2Xq(SrWHNs*t~>
|
||||
Z2Xq(SrWHNs*t~>
|
||||
Z2Xq(SrWHNs*t~>
|
||||
Z2XpR!!'sFs*t~>
|
||||
Z2XpR!!'sFs*t~>
|
||||
Z2XpR!!'sFs*t~>
|
||||
Z2Xq)!!)u*s*t~>
|
||||
Z2Xq)!!)u*s*t~>
|
||||
Z2Xq)!!)u*s*t~>
|
||||
YlF_'[/YX~>
|
||||
YlF_'[/YX~>
|
||||
YlF_'[/YX~>
|
||||
YlF_'[/YX~>
|
||||
YlF_'[/YX~>
|
||||
YlF_'[/YX~>
|
||||
YlF_'qu6cfVDFjYs*t~>
|
||||
YlF_'qu6cfVDFjYs*t~>
|
||||
YlF_'qu6cfVDFjYs*t~>
|
||||
o`#3XSn9u##6lcYg]%Q?Sn9u##6lcYp&G$lrr32aQ:;#X!(uAQ"6_0Jjneu[c!hP+a8,`<nUMW'
|
||||
anPgc~>
|
||||
o`#3XSn9u##6lcYg]%Q?Sn9u##6lcYp&G$lrr32aQ:;#X!(uAQ"6_0Jjneu[c!hP+a8,`<nUMW'
|
||||
anPgc~>
|
||||
o`#3XSn9u##6lcYg]%Q?Sn9u##6lcYp&G$lrr32aQ:;#X!(uAQ"6_0Jjneu[c!hP+a8,`<nUMW'
|
||||
anPgc~>
|
||||
p\t?mUc\\S!!!Garr`.o49>9Y!"A`($LPs3JR&6Uf7u9cqu?_Gjo5Fr!!'t8rrL_Fr;ZgrqYpSj
|
||||
(&e152>@-$~>
|
||||
p\t?mUc\\S!!!Garr`.o49>9Y!"A`($LPs3JR&6Uf7u9cqu?_Gjo5Fr!!'t8rrL_Fr;ZgrqYpSj
|
||||
(&e152>@-$~>
|
||||
p\t?mUc\\S!!!Garr`.o49>9Y!"A`($LPs3JR&6Uf7u9cqu?_Gjo5Fr!!'t8rrL_Fr;ZgrqYpSj
|
||||
(&e152>@-$~>
|
||||
q#:c.,QIfbCo>VHq;lgpqu6_T$XE9&!d"Z<qYpu0,QIfbCo>VHq;lgpr;Qe5"o/-'$S>5!R_Ie\
|
||||
oD]'GCEs&l/8j8>rr_fl!<)os#kW3A!!"`+!%.XD!TluO!!!8us*t~>
|
||||
q#:c.,QIfbCo>VHq;lgpqu6_T$XE9&!d"Z<qYpu0,QIfbCo>VHq;lgpr;Qe5"o/-'$S>5!R_Ie\
|
||||
oD]'GCEs&l/8j8>rr_fl!<)os#kW3A!!"`+!%.XD!TluO!!!8us*t~>
|
||||
q#:c.,QIfbCo>VHq;lgpqu6_T$XE9&!d"Z<qYpu0,QIfbCo>VHq;lgpr;Qe5"o/-'$S>5!R_Ie\
|
||||
oD]'GCEs&l/8j8>rr_fl!<)os#kW3A!!"`+!%.XD!TluO!!!8us*t~>
|
||||
qYpcqA,lTn\c24#"&8grlLb)Yr"f>jr;QusA,lTn\c27$$!7C&AqQbi!!)-JrrV\%!rDru#FkSi
|
||||
rrE&u$+_2Y!$SWIpAba&rs5Y=!!#O(hZ*ZNs*t~>
|
||||
qYpcqA,lTn\c24#"&8grlLb)Yr"f>jr;QusA,lTn\c27$$!7C&AqQbi!!)-JrrV\%!rDru#FkSi
|
||||
rrE&u$+_2Y!$SWIpAba&rs5Y=!!#O(hZ*ZNs*t~>
|
||||
qYpcqA,lTn\c24#"&8grlLb)Yr"f>jr;QusA,lTn\c27$$!7C&AqQbi!!)-JrrV\%!rDru#FkSi
|
||||
rrE&u$+_2Y!$SWIpAba&rs5Y=!!#O(hZ*ZNs*t~>
|
||||
qu6fr9`PNmnG`U>"9<]=rr]k5!7(QC"T(mn$D6hf!;ucprrDHd%+QR&"_>RDn[("N!2fYnrr<<(
|
||||
ok4=*!cdo4rs8Z/s8V^u!!!\5rr;uup]#a~>
|
||||
qu6fr9`PNmnG`U>"9<]=rr]k5!7(QC"T(mn$D6hf!;ucprrDHd%+QR&"_>RDn[("N!2fYnrr<<(
|
||||
ok4=*!cdo4rs8Z/s8V^u!!!\5rr;uup]#a~>
|
||||
qu6fr9`PNmnG`U>"9<]=rr]k5!7(QC"T(mn$D6hf!;ucprrDHd%+QR&"_>RDn[("N!2fYnrr<<(
|
||||
ok4=*!cdo4rs8Z/s8V^u!!!\5rr;uup]#a~>
|
||||
qu6b@!"I*=rrZm6#iYIV!b23Zr;QkA!"I*8s8N)errgRZ!%H@orri$X!#PG.s8N'&eL:Iu,K0N[
|
||||
rr<9'e0t@t5iqtErrDfnJ,~>
|
||||
qu6b@!"I*=rrZm6#iYIV!b23Zr;QkA!"I*8s8N)errgRZ!%H@orri$X!#PG.s8N'&eL:Iu,K0N[
|
||||
rr<9'e0t@t5iqtErrDfnJ,~>
|
||||
qu6b@!"I*=rrZm6#iYIV!b23Zr;QkA!"I*8s8N)errgRZ!%H@orri$X!#PG.s8N'&eL:Iu,K0N[
|
||||
rr<9'e0t@t5iqtErrDfnJ,~>
|
||||
r;QlK!s#Rmrr_Ek!*f0s"8NN/Jc5TNe,o]Tkl:Y_n,EOH'`^DeqYpZ.!!'8$s8N'%$NL06oDARf
|
||||
!!Su%!!.KGr;Zcsp]#a~>
|
||||
r;QlK!s#Rmrr_Ek!*f0s"8NN/Jc5TNe,o]Tkl:Y_n,EOH'`^DeqYpZ.!!'8$s8N'%$NL06oDARf
|
||||
!!Su%!!.KGr;Zcsp]#a~>
|
||||
r;QlK!s#Rmrr_Ek!*f0s"8NN/Jc5TNe,o]Tkl:Y_n,EOH'`^DeqYpZ.!!'8$s8N'%$NL06oDARf
|
||||
!!Su%!!.KGr;Zcsp]#a~>
|
||||
r;Qh5!)2_Y"+1(LbP2#=Z2amYrVlq6!)2SUrrDQg"SaVM1\CVF#4/O-'EA-#r;Z`r!=GUts8;ou
|
||||
'"7Z:rrDfnJ,~>
|
||||
r;Qh5!)2_Y"+1(LbP2#=Z2amYrVlq6!)2SUrrDQg"SaVM1\CVF#4/O-'EA-#r;Z`r!=GUts8;ou
|
||||
'"7Z:rrDfnJ,~>
|
||||
r;Qh5!)2_Y"+1(LbP2#=Z2amYrVlq6!)2SUrrDQg"SaVM1\CVF#4/O-'EA-#r;Z`r!=GUts8;ou
|
||||
'"7Z:rrDfnJ,~>
|
||||
r;QgG!42P%#Pb/o(^)+8pA4dkneD-gp\t:u!&FKP![duSqYpfqVG\66,_>[_s8N)grsF&P)!:kp
|
||||
c'Mif!WE'#&:+*Ls8N'"+k-5drVusUi;*EQ!;HMD~>
|
||||
r;QgG!42P%#Pb/o(^)+8pA4dkneD-gp\t:u!&FKP![duSqYpfqVG\66,_>[_s8N)grsF&P)!:kp
|
||||
c'Mif!WE'#&:+*Ls8N'"+k-5drVusUi;*EQ!;HMD~>
|
||||
r;QgG!42P%#Pb/o(^)+8pA4dkneD-gp\t:u!&FKP![duSqYpfqVG\66,_>[_s8N)grsF&P)!:kp
|
||||
c'Mif!WE'#&:+*Ls8N'"+k-5drVusUi;*EQ!;HMD~>
|
||||
r;Qg(!:9X`!pP%GqZ$XJlMCM_OT5Bbq>UQj$il4`rrNH+m/6kbl$F-A!!+Y9p](6nnc&gN#68FV
|
||||
3=,Q`"9BufZM=:rrr<&cp](6n!GV?(s8N)ns*t~>
|
||||
r;Qg(!:9X`!pP%GqZ$XJlMCM_OT5Bbq>UQj$il4`rrNH+m/6kbl$F-A!!+Y9p](6nnc&gN#68FV
|
||||
3=,Q`"9BufZM=:rrr<&cp](6n!GV?(s8N)ns*t~>
|
||||
r;Qg(!:9X`!pP%GqZ$XJlMCM_OT5Bbq>UQj$il4`rrNH+m/6kbl$F-A!!+Y9p](6nnc&gN#68FV
|
||||
3=,Q`"9BufZM=:rrr<&cp](6n!GV?(s8N)ns*t~>
|
||||
r;Qg(!;c]p%,Yk,!!":#f)",c!+Pg)"Sj5A-2RK<"0)>%ir&fX#QX`#rs[e$#QOiMLt;FW56,0e
|
||||
s8N)hrr?^/!!F9:J[b(@s8N)ms8N)ms8N)ns*t~>
|
||||
r;Qg(!;c]p%,Yk,!!":#f)",c!+Pg)"Sj5A-2RK<"0)>%ir&fX#QX`#rs[e$#QOiMLt;FW56,0e
|
||||
s8N)hrr?^/!!F9:J[b(@s8N)ms8N)ms8N)ns*t~>
|
||||
r;Qg(!;c]p%,Yk,!!":#f)",c!+Pg)"Sj5A-2RK<"0)>%ir&fX#QX`#rs[e$#QOiMLt;FW56,0e
|
||||
s8N)hrr?^/!!F9:J[b(@s8N)ms8N)ms8N)ns*t~>
|
||||
r;R-]!4D='<<E4$40eb_rrV-Z(&@k3VZ6^ZqYpUp!'L/Y$T%jkn?c0t!!#*crVc`ti;aVes8N)i
|
||||
rs/'#!$G0n\*EM`rrDcmrrDcmrrDfnJ,~>
|
||||
r;R-]!4D='<<E4$40eb_rrV-Z(&@k3VZ6^ZqYpUp!'L/Y$T%jkn?c0t!!#*crVc`ti;aVes8N)i
|
||||
rs/'#!$G0n\*EM`rrDcmrrDcmrrDfnJ,~>
|
||||
r;R-]!4D='<<E4$40eb_rrV-Z(&@k3VZ6^ZqYpUp!'L/Y$T%jkn?c0t!!#*crVc`ti;aVes8N)i
|
||||
rs/'#!$G0n\*EM`rrDcmrrDcmrrDfnJ,~>
|
||||
r;Qbaqu?d";8i>2!quZuq>UTs1B8*Wr;Qli#QU.errAGa!!34!`;9K8pAbBks8N)nrs.qpo)J``
|
||||
!&<j?rrDcmrrDcmrrDfnJ,~>
|
||||
r;Qbaqu?d";8i>2!quZuq>UTs1B8*Wr;Qli#QU.errAGa!!34!`;9K8pAbBks8N)nrs.qpo)J``
|
||||
!&<j?rrDcmrrDcmrrDfnJ,~>
|
||||
r;Qbaqu?d";8i>2!quZuq>UTs1B8*Wr;Qli#QU.errAGa!!34!`;9K8pAbBks8N)nrs.qpo)J``
|
||||
!&<j?rrDcmrrDcmrrDfnJ,~>
|
||||
r;R!#EtJ[6JDg5&!mgoaq#:H/!!%-=rr\qp"R>ma#6&ZU#W%"hq#:EB!#YJ1rrDfn#AF0@s8QC*
|
||||
L[>'@!;?Hm!;?Hm!;HMD~>
|
||||
r;R!#EtJ[6JDg5&!mgoaq#:H/!!%-=rr\qp"R>ma#6&ZU#W%"hq#:EB!#YJ1rrDfn#AF0@s8QC*
|
||||
L[>'@!;?Hm!;?Hm!;HMD~>
|
||||
r;R!#EtJ[6JDg5&!mgoaq#:H/!!%-=rr\qp"R>ma#6&ZU#W%"hq#:EB!#YJ1rrDfn#AF0@s8QC*
|
||||
L[>'@!;?Hm!;?Hm!;HMD~>
|
||||
m/I-9!(cka"%N=rhYmHU8H;6FrrRWL8GE/a!;QR"fF.a_s8OYNaS#Q8d3(F:r;ZcspAb-mpAb-m
|
||||
p]#a~>
|
||||
m/I-9!(cka"%N=rhYmHU8H;6FrrRWL8GE/a!;QR"fF.a_s8OYNaS#Q8d3(F:r;ZcspAb-mpAb-m
|
||||
p]#a~>
|
||||
m/I-9!(cka"%N=rhYmHU8H;6FrrRWL8GE/a!;QR"fF.a_s8OYNaS#Q8d3(F:r;ZcspAb-mpAb-m
|
||||
p]#a~>
|
||||
mJd:R&-/-mrr^RJ!*9+!"7-0kTBlLZl4<r`p](6nq>Ucd-NGFVs8NQ/nb)naNW9(!r;ZcspAb-m
|
||||
pAb-mp]#a~>
|
||||
mJd:R&-/-mrr^RJ!*9+!"7-0kTBlLZl4<r`p](6nq>Ucd-NGFVs8NQ/nb)naNW9(!r;ZcspAb-m
|
||||
pAb-mp]#a~>
|
||||
mJd:R&-/-mrr^RJ!*9+!"7-0kTBlLZl4<r`p](6nq>Ucd-NGFVs8NQ/nb)naNW9(!r;ZcspAb-m
|
||||
pAb-mp]#a~>
|
||||
mf*Fg9)p"*pAYG(!!(%=s-WilnEg/XrC[,2p%SLd!;c]ujt?]_j8T&[!s&8mrr_<q!*oF$rrDcm
|
||||
rrDcmrrDfnJ,~>
|
||||
mf*Fg9)p"*pAYG(!!(%=s-WilnEg/XrC[,2p%SLd!;c]ujt?]_j8T&[!s&8mrr_<q!*oF$rrDcm
|
||||
rrDcmrrDfnJ,~>
|
||||
mf*Fg9)p"*pAYG(!!(%=s-WilnEg/XrC[,2p%SLd!;c]ujt?]_j8T&[!s&8mrr_<q!*oF$rrDcm
|
||||
rrDcmrrDfnJ,~>
|
||||
r;QigLu7t,"T2a0!k7k&#iGpf3WK+F!)WLk!qD*(p\tBo@fQS>pAb-mqu6f:)urCorVlp1!:0CZ
|
||||
"Rn#D2YHtIrrDcmrrDcmrrDfnJ,~>
|
||||
r;QigLu7t,"T2a0!k7k&#iGpf3WK+F!)WLk!qD*(p\tBo@fQS>pAb-mqu6f:)urCorVlp1!:0CZ
|
||||
"Rn#D2YHtIrrDcmrrDcmrrDfnJ,~>
|
||||
r;QigLu7t,"T2a0!k7k&#iGpf3WK+F!)WLk!qD*(p\tBo@fQS>pAb-mqu6f:)urCorVlp1!:0CZ
|
||||
"Rn#D2YHtIrrDcmrrDcmrrDfnJ,~>
|
||||
r;QhJ!.+G?"Qr2R!0?aO#BBeEWojE`WVQPqIfOfirrhLR!!&)Qs8N)trrr"8!s!B>r;QgY!4hn)
|
||||
"QM*71[k2?rrDcmrrDcmrrDfnJ,~>
|
||||
r;QhJ!.+G?"Qr2R!0?aO#BBeEWojE`WVQPqIfOfirrhLR!!&)Qs8N)trrr"8!s!B>r;QgY!4hn)
|
||||
"QM*71[k2?rrDcmrrDcmrrDfnJ,~>
|
||||
r;QhJ!.+G?"Qr2R!0?aO#BBeEWojE`WVQPqIfOfirrhLR!!&)Qs8N)trrr"8!s!B>r;QgY!4hn)
|
||||
"QM*71[k2?rrDcmrrDcmrrDfnJ,~>
|
||||
r;Qh0!*oC#"o"&i!!S_[rs.p%!$[=$$ha>q!bD@:qYp`nNtD?qQh:=X!<<'&qjJB&(9RH5!f?tM
|
||||
qYp`sSe1rqo(i=c!;?Hm!;?Hm!;HMD~>
|
||||
r;Qh0!*oC#"o"&i!!S_[rs.p%!$[=$$ha>q!bD@:qYp`nNtD?qQh:=X!<<'&qjJB&(9RH5!f?tM
|
||||
qYp`sSe1rqo(i=c!;?Hm!;?Hm!;HMD~>
|
||||
r;Qh0!*oC#"o"&i!!S_[rs.p%!$[=$$ha>q!bD@:qYp`nNtD?qQh:=X!<<'&qjJB&(9RH5!f?tM
|
||||
qYp`sSe1rqo(i=c!;?Hm!;?Hm!;HMD~>
|
||||
r;R8>!WYHgkkje]E"i9P1X5Fh"c!'X#67s&rsl[C!'d[NqsM.:'EA+hc1Cu8!!_>U,QIgFlhUPj
|
||||
nJqU'^$bgea+P`="G$IHrr_uq!;lQk!r)`qpAb-mp]#a~>
|
||||
r;R8>!WYHgkkje]E"i9P1X5Fh"c!'X#67s&rsl[C!'d[NqsM.:'EA+hc1Cu8!!_>U,QIgFlhUPj
|
||||
nJqU'^$bgea+P`="G$IHrr_uq!;lQk!r)`qpAb-mp]#a~>
|
||||
r;R8>!WYHgkkje]E"i9P1X5Fh"c!'X#67s&rsl[C!'d[NqsM.:'EA+hc1Cu8!!_>U,QIgFlhUPj
|
||||
nJqU'^$bgea+P`="G$IHrr_uq!;lQk!r)`qpAb-mp]#a~>
|
||||
qu6\u');M/1o^KCrrMg4rVur)p\t8q');M/1o^KFrrs&8#64`Q[.aM#bng-U!Wc!Dp\t?1!!'e/
|
||||
rrRlS#5A-"eGoTWq#>j~>
|
||||
qu6\u');M/1o^KCrrMg4rVur)p\t8q');M/1o^KFrrs&8#64`Q[.aM#bng-U!Wc!Dp\t?1!!'e/
|
||||
rrRlS#5A-"eGoTWq#>j~>
|
||||
qu6\u');M/1o^KCrrMg4rVur)p\t8q');M/1o^KFrrs&8#64`Q[.aM#bng-U!Wc!Dp\t?1!!'e/
|
||||
rrRlS#5A-"eGoTWq#>j~>
|
||||
qYpijNBe-Z'LIE"li.*X!!!W-pAYEfNBe-Z'LIE"n,EQL&/%^>rUg*qm!^`$!u!kLg@bIJkTU\s
|
||||
q#:E!%70ag"6C4Ch>%##~>
|
||||
qYpijNBe-Z'LIE"li.*X!!!W-pAYEfNBe-Z'LIE"n,EQL&/%^>rUg*qm!^`$!u!kLg@bIJkTU\s
|
||||
q#:E!%70ag"6C4Ch>%##~>
|
||||
qYpijNBe-Z'LIE"li.*X!!!W-pAYEfNBe-Z'LIE"n,EQL&/%^>rUg*qm!^`$!u!kLg@bIJkTU\s
|
||||
q#:E!%70ag"6C4Ch>%##~>
|
||||
g]%BR*WT`/s*t~>
|
||||
g]%BR*WT`/s*t~>
|
||||
g]%BR*WT`/s*t~>
|
||||
g]%BE"ou>ps*t~>
|
||||
g]%BE"ou>ps*t~>
|
||||
g]%BE"ou>ps*t~>
|
||||
g]%AE!#YZms*t~>
|
||||
g]%AE!#YZms*t~>
|
||||
g]%AE!#YZms*t~>
|
||||
k5POY7sb12rrP(YDMnIE~>
|
||||
k5POY7sb12rrP(YDMnIE~>
|
||||
k5POY7sb12rrP(YDMnIE~>
|
||||
k5PMq!!Mcfrr^4?!6^9"J,~>
|
||||
k5PMq!!Mcfrr^4?!6^9"J,~>
|
||||
k5PMq!!Mcfrr^4?!6^9"J,~>
|
||||
k5PK`!$_:>!^?Z?M>r)~>
|
||||
k5PK`!$_:>!^?Z?M>r)~>
|
||||
k5PK`!$_:>!^?Z?M>r)~>
|
||||
k5PPA"TYe)rr\5\!3:tVJ,~>
|
||||
k5PPA"TYe)rr\5\!3:tVJ,~>
|
||||
k5PPA"TYe)rr\5\!3:tVJ,~>
|
||||
jo5[+!"=qKp<maX!(MeEJ,~>
|
||||
jo5[+!"=qKp<maX!(MeEJ,~>
|
||||
jo5[+!"=qKp<maX!(MeEJ,~>
|
||||
jo5AV3;NUU2"6>$J,~>
|
||||
jo5AV3;NUU2"6>$J,~>
|
||||
jo5AV3;NUU2"6>$J,~>
|
||||
jSoMWGpW_$)+U"iL];l~>
|
||||
jSoMWGpW_$)+U"iL];l~>
|
||||
jSoMWGpW_$)+U"iL];l~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
JcF^/J,~>
|
||||
%%EndData
|
||||
showpage
|
||||
%%Trailer
|
||||
end
|
||||
%%EOF
|
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
Binary file not shown.
|
@ -0,0 +1,3 @@
|
|||
Makefile.configuration
|
||||
CAstWrapper.lib
|
||||
CAstWrapper.exp
|
|
@ -0,0 +1,90 @@
|
|||
# 2006/08/03 Naoshi Tabuchi: tabee@jp.ibm.com
|
||||
# Adjusted to building with MSVC++.
|
||||
# NOTE: PLATFORM=cygwin now implies using MSVC,
|
||||
# thus pathnames must be given in "Windows style,"
|
||||
# e.g. "c:/path/to/something", path separators can be
|
||||
# slashes, though.
|
||||
|
||||
include Makefile.configuration
|
||||
|
||||
#
|
||||
# in theory, these definitions should not need to be changed
|
||||
#
|
||||
|
||||
# 2006/08/03 Naoshi Tabuchi: tabee@jp.ibm.com
|
||||
# Recent versions of Cygwin's uname return "Cygwin", instead of "cygwin."
|
||||
PLATFORM=$(shell uname -o | sed -e 's/C/c/')
|
||||
|
||||
C_GENERATED=$(DOMO_AST_BIN)libcast/
|
||||
|
||||
ifeq ($(PLATFORM),cygwin)
|
||||
JAVAH_GENERATED=$(shell cygpath -w $(DOMO_AST_BIN)/libcast)
|
||||
CC=cl
|
||||
else
|
||||
JAVAH_GENERATED=$(C_GENERATED)
|
||||
CC=g++
|
||||
endif
|
||||
|
||||
vpath %.cpp jni
|
||||
|
||||
ifeq ($(PLATFORM),cygwin)
|
||||
PLATFORM_JNI_DIR = win32
|
||||
else
|
||||
PLATFORM_JNI_DIR = $(shell cd $(JAVA_SDK); find include -mindepth 1 -maxdepth 1 -type d)
|
||||
endif
|
||||
JAVA_INCLUDES = -I$(JAVA_SDK)include -I$(JAVA_SDK)$(PLATFORM_JNI_DIR) -I$(JAVA_SDK)include/$(PLATFORM_JNI_DIR)
|
||||
|
||||
CAPA_INCLUDE_DIR = include/
|
||||
CAPA_INCLUDES = -I$(CAPA_INCLUDE_DIR) -I$(C_GENERATED)
|
||||
|
||||
CAPA_JNI_HEADER = $(C_GENERATED)com_ibm_wala_cast_ir_translator_NativeBridge.h
|
||||
|
||||
INCLUDES = $(CAPA_INCLUDES) $(JAVA_INCLUDES)
|
||||
|
||||
CAPA_SOURCES = $(notdir $(wildcard jni/*.cpp))
|
||||
CAPA_OBJECTS = $(patsubst %.cpp,$(C_GENERATED)%.o,$(CAPA_SOURCES))
|
||||
|
||||
ifeq ($(PLATFORM),cygwin)
|
||||
ALL_FLAGS = /WL /MD /EHsc /D ZTS /D YY_NO_UNISTD_H /D _USE_32BIT_TIME_T /D __WIN32__ /D WIN32 /D BUILD_CAST_DLL $(INCLUDES)
|
||||
DLLEXT = dll
|
||||
else
|
||||
ALL_FLAGS = -pthread -gstabs+ $(TRACE) $(INCLUDES) -fpic
|
||||
DLLEXT = so
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),cygwin)
|
||||
CC_OUTFLAG = /Fo
|
||||
LD_OUTFLAG = /link /IMPLIB:$(DOMO_AST_BIN)cast.lib /OUT:
|
||||
CC_LDFLAGS = /LDd /MD
|
||||
LIBPREFIX =
|
||||
POSTPROCESS = && cd $(DOMO_AST_BIN) && mt /manifest $(LIBPREFIX)cast.$(DLLEXT).manifest /outputresource:"$(LIBPREFIX)cast.$(DLLEXT);\#2"
|
||||
else
|
||||
CC_OUTFLAG = -o
|
||||
CC_LDFLAGS = -pthread -shared
|
||||
LD_OUTFLAG = -o
|
||||
LIBPREFIX = lib
|
||||
POSTPROCESS =
|
||||
endif
|
||||
|
||||
#
|
||||
# rules
|
||||
#
|
||||
|
||||
default: $(DOMO_AST_BIN)$(LIBPREFIX)cast.$(DLLEXT)
|
||||
|
||||
bindir:
|
||||
mkdir -p $(C_GENERATED)
|
||||
|
||||
$(CAPA_JNI_HEADER): $(DOMO_AST_BIN)com/ibm/wala/cast/ir/translator/NativeBridge.class bindir
|
||||
$(JAVA_SDK)bin/javah -classpath "$(DOMO_AST_BIN)$(JAVAH_CLASS_PATH)" -d "$(JAVAH_GENERATED)" com.ibm.wala.cast.ir.translator.NativeBridge
|
||||
|
||||
$(CAPA_OBJECTS): $(C_GENERATED)%.o: %.cpp $(CAPA_JNI_HEADER) bindir
|
||||
echo $(CAPA_OBJECTS)
|
||||
$(CC) $(ALL_FLAGS) $(CC_OUTFLAG)$@ -c $<
|
||||
|
||||
$(DOMO_AST_BIN)$(LIBPREFIX)cast.$(DLLEXT): $(CAPA_OBJECTS)
|
||||
$(CC) $(CC_LDFLAGS) $^ $(LD_OUTFLAG)$@ $(POSTPROCESS)
|
||||
|
||||
clean:
|
||||
rm -rf $(DOMO_AST_BIN)$(LIBPREFIX)cast.$(DLLEXT) $(C_GENERATED) hs_err_pid*
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
#
|
||||
# global configuration. adjust for your system.
|
||||
#
|
||||
|
||||
# The root of the java SDK to use (must end in /)
|
||||
JAVA_SDK = /opt/sun-jdk-1.5.0.08/
|
||||
|
||||
# Path .class files of the com.ibm.domo.ast Java code (must end in /)
|
||||
DOMO_AST_BIN = /my/workspace/path/com.ibm.domo.ast/bin/
|
||||
|
||||
# Extra stuff needed in the classpath of javah (must start with path separator)
|
||||
JAVAH_CLASS_PATH = :/my/workspace/path/com.ibm.capa.ast/bin/
|
||||
|
||||
# enable debugging flags
|
||||
TRACE =
|
|
@ -0,0 +1,179 @@
|
|||
#ifndef _CAST_WRAPPER_H
|
||||
#define _CAST_WRAPPER_H
|
||||
|
||||
#include <list>
|
||||
#include <jni.h>
|
||||
#include "Exceptions.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
#ifdef TRACE_CAST_WRAPPER
|
||||
#define LOG(x) log(x);
|
||||
|
||||
#else
|
||||
#define LOG(x)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifdef BUILD_CAST_DLL
|
||||
#define DLLEXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define DLLEXPORT __declspec(dllimport)
|
||||
#endif
|
||||
class DLLEXPORT CAstWrapper {
|
||||
#else
|
||||
|
||||
/**
|
||||
* This class is a simple wrapper that provides a C++ object veneer
|
||||
* over JNI calls to a CAst object in Javaland. This wrapper is used
|
||||
* by the grammar rules of the bison grammar that defines PHP to build
|
||||
* a CAst tree in Javaland.
|
||||
*/
|
||||
class CAstWrapper {
|
||||
#endif
|
||||
|
||||
|
||||
protected:
|
||||
jobject Ast;
|
||||
JNIEnv *env;
|
||||
Exceptions &java_ex;
|
||||
jclass HashSet;
|
||||
jmethodID hashSetInit;
|
||||
jmethodID hashSetAdd;
|
||||
jclass LinkedList;
|
||||
jmethodID linkedListInit;
|
||||
jmethodID linkedListAdd;
|
||||
|
||||
private:
|
||||
jclass CAstNode;
|
||||
jclass CAstInterface;
|
||||
jclass CAstPrinter;
|
||||
jmethodID castPrint;
|
||||
jmethodID makeNode0;
|
||||
jmethodID makeNode1;
|
||||
jmethodID makeNode2;
|
||||
jmethodID makeNode3;
|
||||
jmethodID makeNode4;
|
||||
jmethodID makeNode5;
|
||||
jmethodID makeNode6;
|
||||
jmethodID makeNodeNary;
|
||||
jmethodID makeNode1Nary;
|
||||
jmethodID makeBool;
|
||||
jmethodID makeChar;
|
||||
jmethodID makeShort;
|
||||
jmethodID makeInt;
|
||||
jmethodID makeLong;
|
||||
jmethodID makeDouble;
|
||||
jmethodID makeFloat;
|
||||
jmethodID makeObject;
|
||||
jmethodID getChild;
|
||||
jmethodID _getChildCount;
|
||||
jmethodID getValue;
|
||||
jmethodID _getKind;
|
||||
jmethodID toString;
|
||||
jmethodID getClass;
|
||||
jmethodID intValue;
|
||||
jmethodID _getEntityName;
|
||||
|
||||
jobject callReference;
|
||||
|
||||
public:
|
||||
|
||||
#define _INCLUDE_CONSTANTS
|
||||
#include "cast_constants.h"
|
||||
|
||||
#define _INCLUDE_OPERATORS
|
||||
#include "cast_operators.h"
|
||||
|
||||
#define _INCLUDE_QUALIFIERS
|
||||
#include "cast_qualifiers.h"
|
||||
|
||||
#define _INCLUDE_CFM
|
||||
#include "cast_control_flow_map.h"
|
||||
|
||||
public:
|
||||
|
||||
CAstWrapper(JNIEnv *env, Exceptions &ex, jobject Ast);
|
||||
|
||||
void assertIsCAstNode(jobject, int);
|
||||
|
||||
jobject makeNode(int);
|
||||
|
||||
jobject makeNode(int, jobject);
|
||||
|
||||
jobject makeNode(int, jobject, jobject);
|
||||
|
||||
jobject makeNode(int, jobject, jobject, jobject);
|
||||
|
||||
jobject makeNode(int, jobject, jobject, jobject, jobject);
|
||||
|
||||
jobject makeNode(int, jobject, jobject, jobject, jobject, jobject);
|
||||
|
||||
jobject makeNode(int, jobject, jobject, jobject, jobject, jobject, jobject);
|
||||
|
||||
jobject makeNode(int, jobjectArray);
|
||||
|
||||
jobject makeNode(int, jobject, jobjectArray);
|
||||
|
||||
jobject makeConstant(bool);
|
||||
|
||||
jobject makeConstant(char);
|
||||
|
||||
jobject makeConstant(short);
|
||||
|
||||
jobject makeConstant(int);
|
||||
|
||||
jobject makeConstant(long);
|
||||
|
||||
jobject makeConstant(double);
|
||||
|
||||
jobject makeConstant(float);
|
||||
|
||||
jobject makeConstant(jobject);
|
||||
|
||||
jobject makeConstant(const char *);
|
||||
|
||||
jobject makeConstant(const char *, int);
|
||||
|
||||
jobject getNthChild(jobject, int);
|
||||
|
||||
int getChildCount(jobject);
|
||||
|
||||
int getKind(jobject);
|
||||
|
||||
bool isConstantValue(jobject);
|
||||
|
||||
bool isConstantOfType(jobject, const char *);
|
||||
|
||||
bool isConstantOfType(jobject, jclass);
|
||||
|
||||
bool isSwitchDefaultConstantValue(jobject);
|
||||
|
||||
const char *getStringConstantValue(jobject);
|
||||
|
||||
jobject getConstantValue(jobject);
|
||||
|
||||
int getIntConstantValue(jobject);
|
||||
|
||||
jobjectArray makeArray(list<jobject> *);
|
||||
|
||||
jobjectArray makeArray(jclass, list<jobject> *);
|
||||
|
||||
jobjectArray makeArray(int, jobject[]);
|
||||
|
||||
jobjectArray makeArray(jclass, int, jobject[]);
|
||||
|
||||
jobject makeSet(list<jobject> *);
|
||||
|
||||
jobject makeList(list<jobject> *);
|
||||
|
||||
jobject getCallReference();
|
||||
|
||||
const char *getEntityName(jobject);
|
||||
|
||||
void log(jobject);
|
||||
};
|
||||
#endif
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
#ifndef EXCEPTIONS_H
|
||||
#define EXCEPTIONS_H
|
||||
|
||||
/**
|
||||
* The combination of the macroes and the Exceptions class declared
|
||||
* in this file is used to provide a (shaky) veneer of exception handling
|
||||
* to JNI code.
|
||||
*
|
||||
* The idea is that a C function called from JNI will be enclosed with
|
||||
* TRY/CATCH macroes, and the CPP_EXP_NAME variable defined will be passed
|
||||
* to callees who might want to throw an exception. The callees will use
|
||||
* the THROW macro to throw exceptions. When a THROW is executed, control
|
||||
* is transferred to the CATCH, and a RuntimeException is thrown to the
|
||||
* calling Java code when the C code returns.
|
||||
*
|
||||
* WARNING: this is C code, so you should know better than to expect any
|
||||
* kind of robust, high-level exception-handling semantics. The way to use
|
||||
* this code is to put a TRY/CATCH combination in the JNI entry point, to do
|
||||
* only trivial things after the CATCH, and to use only THROW anywhere else.
|
||||
*
|
||||
* The implementation does the obvious dance with setjmp and longjmp, which
|
||||
* is one reason it is rather shaky. For instance, TRY has to be a macro,
|
||||
* because otherwise the jump buffer would be invalidated when the TRY function
|
||||
* returned.
|
||||
*/
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
extern "C" {
|
||||
#include <setjmp.h>
|
||||
}
|
||||
|
||||
#define TRY(CPP_EXP_NAME, JAVA_ENV_VAR) \
|
||||
{ jmp_buf jump_buffer; \
|
||||
if (setjmp(jump_buffer) == 0) { \
|
||||
Exceptions CPP_EXP_NAME(JAVA_ENV_VAR, jump_buffer);
|
||||
|
||||
#define CATCH() \
|
||||
} \
|
||||
} \
|
||||
|
||||
#define THROW(CPP_EXP_NAME, MESSAGE) \
|
||||
(CPP_EXP_NAME).throwException(__FILE__, __LINE__, MESSAGE)
|
||||
|
||||
#define THROW_ANY_EXCEPTION(CPP_EXP_NAME) \
|
||||
(CPP_EXP_NAME).throwAnyException(__FILE__, __LINE__)
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifdef BUILD_CAST_DLL
|
||||
#define DLLEXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define DLLEXPORT __declspec(dllimport)
|
||||
#endif
|
||||
class DLLEXPORT Exceptions {
|
||||
|
||||
#else
|
||||
class Exceptions {
|
||||
#endif
|
||||
|
||||
private:
|
||||
JNIEnv *_java_env;
|
||||
jmp_buf& _c_env;
|
||||
jclass _jre;
|
||||
jmethodID _ctr;
|
||||
jmethodID _wrapper_ctr;
|
||||
|
||||
public:
|
||||
Exceptions(JNIEnv *java_env, jmp_buf& c_env);
|
||||
|
||||
void throwException(char *file_name, int line_number);
|
||||
void throwAnyException(char *file_name, int line_number);
|
||||
void throwException(char *file_name, int line_number, char *c_message);
|
||||
};
|
||||
#endif
|
|
@ -0,0 +1,90 @@
|
|||
#if defined( _INCLUDE_CONSTANTS )
|
||||
#define _CAstNodeType( __id ) static jint __id;
|
||||
|
||||
#elif defined( _CPP_CONSTANTS )
|
||||
#define _CAstNodeType( __id ) jint CAstWrapper::__id;
|
||||
|
||||
#elif defined( _CODE_CONSTANTS )
|
||||
#define _CAstNodeType( __id ) \
|
||||
{ \
|
||||
jfieldID f##__id = env->GetStaticFieldID(CAstNode, #__id, "I"); \
|
||||
CAstWrapper::__id = env->GetStaticIntField(CAstNode, f##__id); \
|
||||
THROW_ANY_EXCEPTION(exp); \
|
||||
}
|
||||
|
||||
#else
|
||||
#error "bad use of CAst constants
|
||||
|
||||
#endif
|
||||
|
||||
#if __WIN32__
|
||||
#undef VOID
|
||||
#undef CONST
|
||||
#undef ERROR
|
||||
#endif
|
||||
|
||||
_CAstNodeType(ASSERT)
|
||||
_CAstNodeType(SWITCH)
|
||||
_CAstNodeType(LOOP)
|
||||
_CAstNodeType(BLOCK_STMT)
|
||||
_CAstNodeType(TRY)
|
||||
_CAstNodeType(EXPR_STMT)
|
||||
_CAstNodeType(DECL_STMT)
|
||||
_CAstNodeType(RETURN)
|
||||
_CAstNodeType(GOTO)
|
||||
_CAstNodeType(BREAK)
|
||||
_CAstNodeType(CONTINUE)
|
||||
_CAstNodeType(IF_STMT)
|
||||
_CAstNodeType(THROW)
|
||||
_CAstNodeType(FUNCTION_STMT)
|
||||
_CAstNodeType(ASSIGN)
|
||||
_CAstNodeType(ASSIGN_PRE_OP)
|
||||
_CAstNodeType(ASSIGN_POST_OP)
|
||||
_CAstNodeType(LABEL_STMT)
|
||||
_CAstNodeType(IFGOTO)
|
||||
_CAstNodeType(EMPTY)
|
||||
_CAstNodeType(RETURN_WITHOUT_BRANCH)
|
||||
_CAstNodeType(CATCH)
|
||||
_CAstNodeType(UNWIND)
|
||||
_CAstNodeType(MONITOR_ENTER)
|
||||
_CAstNodeType(MONITOR_EXIT)
|
||||
_CAstNodeType(FUNCTION_EXPR)
|
||||
_CAstNodeType(EXPR_LIST)
|
||||
_CAstNodeType(CALL)
|
||||
_CAstNodeType(GET_CAUGHT_EXCEPTION)
|
||||
_CAstNodeType(BLOCK_EXPR)
|
||||
_CAstNodeType(BINARY_EXPR)
|
||||
_CAstNodeType(UNARY_EXPR)
|
||||
_CAstNodeType(IF_EXPR)
|
||||
_CAstNodeType(ANDOR_EXPR)
|
||||
_CAstNodeType(NEW)
|
||||
_CAstNodeType(OBJECT_LITERAL)
|
||||
_CAstNodeType(VAR)
|
||||
_CAstNodeType(OBJECT_REF)
|
||||
_CAstNodeType(CHOICE_EXPR)
|
||||
_CAstNodeType(CHOICE_CASE)
|
||||
_CAstNodeType(SUPER)
|
||||
_CAstNodeType(THIS)
|
||||
_CAstNodeType(ARRAY_LITERAL)
|
||||
_CAstNodeType(CAST)
|
||||
_CAstNodeType(INSTANCEOF)
|
||||
_CAstNodeType(ARRAY_REF)
|
||||
_CAstNodeType(ARRAY_LENGTH)
|
||||
_CAstNodeType(TYPE_OF)
|
||||
_CAstNodeType(LOCAL_SCOPE)
|
||||
_CAstNodeType(CONSTANT)
|
||||
_CAstNodeType(OPERATOR)
|
||||
_CAstNodeType(PRIMITIVE)
|
||||
_CAstNodeType(ERROR)
|
||||
_CAstNodeType(VOID)
|
||||
_CAstNodeType(ECHO)
|
||||
_CAstNodeType(EACH_ELEMENT_GET)
|
||||
_CAstNodeType(EACH_ELEMENT_HAS_NEXT)
|
||||
_CAstNodeType(LIST_EXPR);
|
||||
_CAstNodeType(EMPTY_LIST_EXPR);
|
||||
|
||||
#undef _CODE_CONSTANTS
|
||||
#undef _CPP_CONSTANTS
|
||||
#undef _INCLUDE_CONSTANTS
|
||||
#undef _CAstNodeType
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
#if defined( _INCLUDE_CFM )
|
||||
#define _CAstControlFlowMap( __id, __type ) static jobject __id;
|
||||
|
||||
#elif defined( _CPP_CFM )
|
||||
#define _CAstControlFlowMap( __id, __type ) jobject CAstWrapper::__id;
|
||||
|
||||
#elif defined( _CODE_CFM )
|
||||
#define _CAstControlFlowMap( __id, __type ) \
|
||||
{ \
|
||||
jfieldID f##__id = env->GetStaticFieldID(CAstControlFlowMap, #__id, __type); \
|
||||
THROW_ANY_EXCEPTION(exp); \
|
||||
jobject o##__id = env->GetStaticObjectField(CAstControlFlowMap, f##__id); \
|
||||
CAstWrapper::__id = env->NewGlobalRef(o##__id); \
|
||||
THROW_ANY_EXCEPTION(exp); \
|
||||
}
|
||||
|
||||
#else
|
||||
#error "bad use of CAst control flow map"
|
||||
|
||||
#endif
|
||||
|
||||
_CAstControlFlowMap(SWITCH_DEFAULT, "Ljava/lang/Object;")
|
||||
_CAstControlFlowMap(EXCEPTION_TO_EXIT, "Lcom/ibm/wala/cast/tree/CAstNode;")
|
||||
|
||||
#undef _CODE_CFM
|
||||
#undef _CPP_CFM
|
||||
#undef _INCLUDE_CFM
|
||||
#undef _CAstControlFlowMap
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
#if defined( _INCLUDE_OPERATORS )
|
||||
#define _CAstOperator( __id ) static jobject __id;
|
||||
|
||||
#elif defined( _CPP_OPERATORS )
|
||||
#define _CAstOperator( __id ) jobject CAstWrapper::__id;
|
||||
|
||||
#elif defined( _CODE_OPERATORS )
|
||||
#define _CAstOperator( __id ) \
|
||||
{ \
|
||||
jfieldID f##__id = env->GetStaticFieldID(CAstOperator, #__id, "Lcom/ibm/wala/cast/tree/impl/CAstOperator;"); \
|
||||
THROW_ANY_EXCEPTION(exp); \
|
||||
jobject o##__id = env->GetStaticObjectField(CAstOperator, f##__id); \
|
||||
CAstWrapper::__id = env->NewGlobalRef(o##__id); \
|
||||
THROW_ANY_EXCEPTION(exp); \
|
||||
}
|
||||
|
||||
#else
|
||||
#error "bad use of CAst operators"
|
||||
|
||||
#endif
|
||||
|
||||
_CAstOperator(OP_ADD)
|
||||
_CAstOperator(OP_CONCAT)
|
||||
_CAstOperator(OP_DIV)
|
||||
_CAstOperator(OP_LSH)
|
||||
_CAstOperator(OP_MOD)
|
||||
_CAstOperator(OP_MUL)
|
||||
_CAstOperator(OP_RSH)
|
||||
_CAstOperator(OP_URSH)
|
||||
_CAstOperator(OP_SUB)
|
||||
_CAstOperator(OP_EQ)
|
||||
_CAstOperator(OP_GE)
|
||||
_CAstOperator(OP_GT)
|
||||
_CAstOperator(OP_LE)
|
||||
_CAstOperator(OP_LT)
|
||||
_CAstOperator(OP_NE)
|
||||
_CAstOperator(OP_NOT)
|
||||
_CAstOperator(OP_BITNOT)
|
||||
_CAstOperator(OP_BIT_AND)
|
||||
_CAstOperator(OP_REL_AND)
|
||||
_CAstOperator(OP_BIT_OR)
|
||||
_CAstOperator(OP_REL_OR)
|
||||
_CAstOperator(OP_BIT_XOR)
|
||||
_CAstOperator(OP_REL_XOR)
|
||||
|
||||
#undef _CODE_OPERATORS
|
||||
#undef _CPP_OPERATORS
|
||||
#undef _INCLUDE_OPERATORS
|
||||
#undef _CAstOperator
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
#if defined( _INCLUDE_QUALIFIERS )
|
||||
#define _CAstQualifier( __id ) static jobject __id;
|
||||
|
||||
#elif defined( _CPP_QUALIFIERS )
|
||||
#define _CAstQualifier( __id ) jobject CAstWrapper::__id;
|
||||
|
||||
#elif defined( _CODE_QUALIFIERS )
|
||||
#define _CAstQualifier( __id ) \
|
||||
{ \
|
||||
jfieldID f##__id = env->GetStaticFieldID(CAstQualifier, #__id, "Lcom/ibm/wala/cast/CAstQualifier;"); \
|
||||
jobject o##__id = env->GetStaticObjectField(CAstNode, f##__id); \
|
||||
CAstWrapper::__id = env->NewGlobalRef(o##__id); \
|
||||
THROW_ANY_EXCEPTION(exp); \
|
||||
}
|
||||
|
||||
#else
|
||||
#error "bad use of CAst qualifiers"
|
||||
|
||||
#endif
|
||||
|
||||
_CAstQualifier(STRICTFP)
|
||||
_CAstQualifier(VOLATILE)
|
||||
_CAstQualifier(ABSTRACT)
|
||||
_CAstQualifier(INTERFACE)
|
||||
_CAstQualifier(NATIVE)
|
||||
_CAstQualifier(TRANSIENT)
|
||||
_CAstQualifier(SYNCHRONIZED)
|
||||
_CAstQualifier(FINAL)
|
||||
_CAstQualifier(STATIC)
|
||||
_CAstQualifier(PRIVATE)
|
||||
_CAstQualifier(PROTECTED)
|
||||
_CAstQualifier(PUBLIC)
|
||||
_CAstQualifier(CONST)
|
||||
|
||||
#undef _CODE_QUALIFIERS
|
||||
#undef _CPP_QUALIFIERS
|
||||
#undef _INCLUDE_QUALIFIERS
|
||||
#undef _CAstQualifier
|
||||
|
|
@ -0,0 +1,460 @@
|
|||
#include <jni.h>
|
||||
|
||||
#include <iterator>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <CAstWrapper.h>
|
||||
|
||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||
#define strndup(s,n) strdup(s)
|
||||
#endif
|
||||
|
||||
#define __SIG( __nm ) "L" __nm ";"
|
||||
|
||||
#define __CTN "com/ibm/wala/cast/CAst"
|
||||
#define __CTS __SIG( __CTN )
|
||||
|
||||
#define __CNN "com/ibm/wala/cast/CAstNode"
|
||||
#define __CNS __SIG( __CNN )
|
||||
|
||||
#define __CRN "com/ibm/wala/cast/CAstMemberReference"
|
||||
#define __CRS __SIG( __CRN )
|
||||
|
||||
#define __OBJN "java/lang/Object"
|
||||
#define __OBJS __SIG( __OBJN )
|
||||
|
||||
static const char *__MN = "makeNode";
|
||||
static const char *__MC = "makeConstant";
|
||||
|
||||
static const char *zeroSig = "(I)" __CNS;
|
||||
static const char *oneSig = "(I" __CNS ")" __CNS;
|
||||
static const char *twoSig = "(I" __CNS __CNS ")" __CNS;
|
||||
static const char *threeSig = "(I" __CNS __CNS __CNS ")" __CNS;
|
||||
static const char *fourSig = "(I" __CNS __CNS __CNS __CNS ")" __CNS;
|
||||
static const char *fiveSig = "(I" __CNS __CNS __CNS __CNS __CNS ")" __CNS;
|
||||
static const char *sixSig = "(I" __CNS __CNS __CNS __CNS __CNS __CNS ")" __CNS;
|
||||
static const char *narySig = "(I[" __CNS ")" __CNS;
|
||||
static const char *oneNarySig = "(I" __CNS "[" __CNS ")" __CNS;
|
||||
|
||||
static const char *boolSig = "(Z)" __CNS;
|
||||
static const char *charSig = "(C)" __CNS;
|
||||
static const char *shortSig = "(S)" __CNS;
|
||||
static const char *intSig = "(I)" __CNS;
|
||||
static const char *longSig = "(J)" __CNS;
|
||||
static const char *doubleSig = "(D)" __CNS;
|
||||
static const char *floatSig = "(F)" __CNS;
|
||||
static const char *objectSig = "(" __OBJS ")" __CNS;
|
||||
|
||||
CAstWrapper::CAstWrapper(JNIEnv *env, Exceptions &ex, jobject Ast)
|
||||
: java_ex(ex), env(env), Ast(Ast)
|
||||
{
|
||||
this->CAstNode = env->FindClass( __CNN );
|
||||
this->CAstInterface = env->FindClass( __CTN );
|
||||
this->HashSet = env->FindClass("java/util/HashSet");
|
||||
this->LinkedList = env->FindClass("java/util/LinkedList");
|
||||
|
||||
this->makeNode0 = env->GetMethodID(CAstInterface, __MN, zeroSig);
|
||||
this->makeNode1 = env->GetMethodID(CAstInterface, __MN, oneSig);
|
||||
this->makeNode2 = env->GetMethodID(CAstInterface, __MN, twoSig);
|
||||
this->makeNode3 = env->GetMethodID(CAstInterface, __MN, threeSig);
|
||||
this->makeNode4 = env->GetMethodID(CAstInterface, __MN, fourSig);
|
||||
this->makeNode5 = env->GetMethodID(CAstInterface, __MN, fiveSig);
|
||||
this->makeNode6 = env->GetMethodID(CAstInterface, __MN, sixSig);
|
||||
this->makeNodeNary = env->GetMethodID(CAstInterface, __MN, narySig);
|
||||
this->makeNode1Nary = env->GetMethodID(CAstInterface, __MN, oneNarySig);
|
||||
|
||||
this->makeBool = env->GetMethodID(CAstInterface, __MC, boolSig);
|
||||
this->makeChar = env->GetMethodID(CAstInterface, __MC, charSig);
|
||||
this->makeShort = env->GetMethodID(CAstInterface, __MC, shortSig);
|
||||
this->makeInt = env->GetMethodID(CAstInterface, __MC, intSig);
|
||||
this->makeLong = env->GetMethodID(CAstInterface, __MC, longSig);
|
||||
this->makeDouble = env->GetMethodID(CAstInterface, __MC, doubleSig);
|
||||
this->makeFloat = env->GetMethodID(CAstInterface, __MC, floatSig);
|
||||
this->makeObject = env->GetMethodID(CAstInterface, __MC, objectSig);
|
||||
|
||||
this->getChild = env->GetMethodID(CAstNode, "getChild", "(I)" __CNS);
|
||||
this->_getChildCount = env->GetMethodID(CAstNode, "getChildCount", "()I");
|
||||
this->getValue = env->GetMethodID(CAstNode, "getValue", "()" __OBJS);
|
||||
this->_getKind = env->GetMethodID(CAstNode, "getKind", "()I");
|
||||
|
||||
jclass CAstMemberReference = env->FindClass( __CRN );
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
jfieldID ff = env->GetStaticFieldID(CAstMemberReference, "FUNCTION", __CRS);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
this->callReference = env->GetStaticObjectField(CAstMemberReference, ff);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
|
||||
this->CAstPrinter = env->FindClass("com/ibm/wala/cast/tree/impl/CAstPrinter");
|
||||
this->castPrint = env->GetStaticMethodID(CAstPrinter, "print", "(Lcom/ibm/wala/cast/tree/CAstNode;)Ljava/lang/String;");
|
||||
|
||||
this->hashSetInit = env->GetMethodID(HashSet, "<init>", "()V");
|
||||
this->hashSetAdd = env->GetMethodID(HashSet, "add", "(Ljava/lang/Object;)Z");
|
||||
|
||||
this->linkedListInit = env->GetMethodID(LinkedList, "<init>", "()V");
|
||||
this->linkedListAdd = env->GetMethodID(LinkedList, "add", "(Ljava/lang/Object;)Z");
|
||||
|
||||
jclass obj = env->FindClass( __OBJN );
|
||||
this->toString = env->GetMethodID(obj, "toString", "()Ljava/lang/String;");
|
||||
this->getClass = env->GetMethodID(obj, "getClass", "()Ljava/lang/Class;");
|
||||
|
||||
jclass intcls = env->FindClass("java/lang/Integer");
|
||||
this->intValue = env->GetMethodID(intcls, "intValue", "()I");
|
||||
|
||||
jclass castEntity = env->FindClass("com/ibm/wala/cast/tree/CAstEntity");
|
||||
this->_getEntityName = env->GetMethodID(castEntity, "getName", "()Ljava/lang/String;");
|
||||
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
}
|
||||
|
||||
#define _CPP_CONSTANTS
|
||||
#include "cast_constants.h"
|
||||
|
||||
#define _CPP_OPERATORS
|
||||
#include "cast_operators.h"
|
||||
|
||||
#define _CPP_QUALIFIERS
|
||||
#include "cast_qualifiers.h"
|
||||
|
||||
#define _CPP_CFM
|
||||
#include "cast_control_flow_map.h"
|
||||
|
||||
void CAstWrapper::log(jobject castTree) {
|
||||
jstring jstr = (jstring)env->CallStaticObjectMethod(CAstPrinter, castPrint, castTree);
|
||||
const char *cstr = env->GetStringUTFChars(jstr, NULL);
|
||||
fprintf(stderr, "%s\n", cstr);
|
||||
env->ReleaseStringUTFChars(jstr, cstr);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
}
|
||||
|
||||
void CAstWrapper::assertIsCAstNode(jobject obj, int n) {
|
||||
if (! env->IsInstanceOf(obj, CAstNode)) {
|
||||
jstring jstr = (jstring)env->CallObjectMethod(obj, toString);
|
||||
const char *cstr = env->GetStringUTFChars(jstr, NULL);
|
||||
|
||||
jobject cls = env->CallObjectMethod(obj, getClass);
|
||||
jstring jclsstr = (jstring)env->CallObjectMethod(cls, toString);
|
||||
const char *cclsstr = env->GetStringUTFChars(jclsstr, NULL);
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
char* buf = (char*)_alloca(strlen(cstr) + strlen(cclsstr) + 100);
|
||||
#else
|
||||
char buf[ strlen(cstr) + strlen(cclsstr) + 100 ];
|
||||
#endif
|
||||
sprintf(buf, "argument %d (%s of type %s) is not a CAstNode\n", n, cstr, cclsstr);
|
||||
|
||||
env->ReleaseStringUTFChars(jstr, cstr);
|
||||
env->ReleaseStringUTFChars(jclsstr, cclsstr);
|
||||
THROW(java_ex, buf);
|
||||
}
|
||||
}
|
||||
|
||||
jobject CAstWrapper::makeNode(int kind) {
|
||||
jobject r = env->CallObjectMethod(Ast, makeNode0, (jint) kind);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
LOG(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
jobject CAstWrapper::makeNode(int kind, jobject c1) {
|
||||
assertIsCAstNode(c1, 1);
|
||||
jobject r = env->CallObjectMethod(Ast, makeNode1, (jint) kind, c1);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
LOG(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
jobject CAstWrapper::makeNode(int kind, jobject c1, jobject c2) {
|
||||
assertIsCAstNode(c1, 1);
|
||||
assertIsCAstNode(c2, 2);
|
||||
jobject r = env->CallObjectMethod(Ast, makeNode2, (jint) kind, c1, c2);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
LOG(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
jobject CAstWrapper::makeNode(int kind, jobject c1, jobject c2, jobject c3) {
|
||||
assertIsCAstNode(c1, 1);
|
||||
assertIsCAstNode(c2, 2);
|
||||
assertIsCAstNode(c3, 3);
|
||||
jobject r = env->CallObjectMethod(Ast, makeNode3, (jint) kind, c1, c2, c3);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
LOG(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
jobject CAstWrapper::makeNode(int kind, jobject c1, jobject c2, jobject c3, jobject c4) {
|
||||
assertIsCAstNode(c1, 1);
|
||||
assertIsCAstNode(c2, 2);
|
||||
assertIsCAstNode(c3, 3);
|
||||
assertIsCAstNode(c4, 4);
|
||||
jobject r = env->CallObjectMethod(Ast, makeNode4, (jint) kind, c1, c2, c3, c4);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
LOG(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
jobject CAstWrapper::makeNode(int kind, jobject c1, jobject c2, jobject c3, jobject c4, jobject c5) {
|
||||
assertIsCAstNode(c1, 1);
|
||||
assertIsCAstNode(c2, 2);
|
||||
assertIsCAstNode(c3, 3);
|
||||
assertIsCAstNode(c4, 4);
|
||||
assertIsCAstNode(c5, 5);
|
||||
jobject r = env->CallObjectMethod(Ast, makeNode5, (jint) kind, c1, c2, c3, c4, c5);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
LOG(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
jobject CAstWrapper::makeNode(int kind, jobject c1, jobject c2, jobject c3, jobject c4, jobject c5, jobject c6) {
|
||||
assertIsCAstNode(c1, 1);
|
||||
assertIsCAstNode(c2, 2);
|
||||
assertIsCAstNode(c3, 3);
|
||||
assertIsCAstNode(c4, 4);
|
||||
assertIsCAstNode(c5, 5);
|
||||
assertIsCAstNode(c6, 6);
|
||||
jobject r = env->CallObjectMethod(Ast, makeNode6, (jint) kind, c1, c2, c3, c4, c5, c6);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
LOG(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
jobject CAstWrapper::makeNode(int kind, jobjectArray cs) {
|
||||
jobject r = env->CallObjectMethod(Ast, makeNodeNary, (jint) kind, cs);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
LOG(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
jobject CAstWrapper::makeNode(int kind, jobject n, jobjectArray cs) {
|
||||
jobject r = env->CallObjectMethod(Ast, makeNode1Nary, (jint) kind, n, cs);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
LOG(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
jobject CAstWrapper::makeConstant(bool val) {
|
||||
jobject r = env->CallObjectMethod(Ast, makeBool, (jboolean)val);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
LOG(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
jobject CAstWrapper::makeConstant(char val) {
|
||||
jobject r = env->CallObjectMethod(Ast, makeChar, (jchar)val);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
LOG(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
jobject CAstWrapper::makeConstant(short val) {
|
||||
jobject r = env->CallObjectMethod(Ast, makeShort, (jshort)val);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
LOG(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
jobject CAstWrapper::makeConstant(int val) {
|
||||
jobject r = env->CallObjectMethod(Ast, makeInt, (jint)val);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
LOG(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
jobject CAstWrapper::makeConstant(long val) {
|
||||
jobject r = env->CallObjectMethod(Ast, makeLong, (jlong)val);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
LOG(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
jobject CAstWrapper::makeConstant(double val) {
|
||||
jobject r = env->CallObjectMethod(Ast, makeDouble, (jdouble)val);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
LOG(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
jobject CAstWrapper::makeConstant(float val) {
|
||||
jobject r = env->CallObjectMethod(Ast, makeFloat, (jfloat)val);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
LOG(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
jobject CAstWrapper::makeConstant(jobject val) {
|
||||
jobject r = env->CallObjectMethod(Ast, makeObject, val);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
LOG(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
jobject CAstWrapper::makeConstant(const char *strData) {
|
||||
return makeConstant(strData, strlen(strData));
|
||||
}
|
||||
|
||||
jobject CAstWrapper::makeConstant(const char *strData, int strLen) {
|
||||
char *safeData = strndup(strData, strLen);
|
||||
jobject val = env->NewStringUTF( safeData );
|
||||
delete safeData;
|
||||
jobject r = env->CallObjectMethod(Ast, makeObject, val);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
LOG(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
jobject CAstWrapper::getNthChild(jobject castNode, int index) {
|
||||
jobject result = env->CallObjectMethod(castNode, getChild, index);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
return result;
|
||||
}
|
||||
|
||||
int CAstWrapper::getChildCount(jobject castNode) {
|
||||
int result = env->CallIntMethod(castNode, _getChildCount);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
return result;
|
||||
}
|
||||
|
||||
int CAstWrapper::getKind(jobject castNode) {
|
||||
jint result = env->CallIntMethod(castNode, _getKind);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool CAstWrapper::isConstantValue(jobject castNode) {
|
||||
jobject jval = env->CallObjectMethod(castNode, getValue);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
return jval != NULL;
|
||||
}
|
||||
|
||||
bool CAstWrapper::isConstantOfType(jobject castNode, const char *typeName) {
|
||||
jclass type = env->FindClass( typeName );
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
|
||||
return isConstantOfType(castNode, type);
|
||||
}
|
||||
|
||||
bool CAstWrapper::isConstantOfType(jobject castNode, jclass type) {
|
||||
//
|
||||
// one might think this test against null is not needed, since
|
||||
// IsInstanceoOf ought to return false given null and any type at
|
||||
// all, which is what happens with the `instanceof'operator in Java.
|
||||
// This does not seem to be the case however.
|
||||
//
|
||||
if (isConstantValue(castNode)) {
|
||||
jobject jval = env->CallObjectMethod(castNode, getValue);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
jboolean result = env->IsInstanceOf(jval, type);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
|
||||
return (bool) result;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool CAstWrapper::isSwitchDefaultConstantValue(jobject castNode) {
|
||||
jobject jval = env->CallObjectMethod(castNode, getValue);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
|
||||
return env->IsSameObject(jval, SWITCH_DEFAULT);
|
||||
}
|
||||
|
||||
const char *CAstWrapper::getStringConstantValue(jobject castNode) {
|
||||
jstring jstr = (jstring)env->CallObjectMethod(castNode, getValue);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
const char *cstr1 = env->GetStringUTFChars(jstr, NULL);
|
||||
const char *cstr2 = strdup( cstr1 );
|
||||
env->ReleaseStringUTFChars(jstr, cstr1);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
|
||||
return cstr2;
|
||||
}
|
||||
|
||||
int CAstWrapper::getIntConstantValue(jobject castNode) {
|
||||
jobject jval = env->CallObjectMethod(castNode, getValue);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
int cval = env->CallIntMethod(jval, intValue);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
|
||||
return cval;
|
||||
}
|
||||
|
||||
jobject CAstWrapper::getConstantValue(jobject castNode) {
|
||||
jobject jval = env->CallObjectMethod(castNode, getValue);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
return jval;
|
||||
}
|
||||
|
||||
jobjectArray CAstWrapper::makeArray(list<jobject> *elts) {
|
||||
return makeArray(CAstNode, elts);
|
||||
}
|
||||
|
||||
jobjectArray CAstWrapper::makeArray(jclass type, list<jobject> *elts) {
|
||||
jobjectArray result = env->NewObjectArray(elts->size(), type, NULL);
|
||||
int i = 0;
|
||||
for(list<jobject>::iterator it=elts->begin(); it!=elts->end(); it++) {
|
||||
env->SetObjectArrayElement(result, i++, *it);
|
||||
}
|
||||
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
return result;
|
||||
}
|
||||
|
||||
jobjectArray CAstWrapper::makeArray(int count, jobject elts[]) {
|
||||
return makeArray(CAstNode, count, elts);
|
||||
}
|
||||
|
||||
jobjectArray CAstWrapper::makeArray(jclass type, int count, jobject elts[]) {
|
||||
jobjectArray result = env->NewObjectArray(count, type, NULL);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
|
||||
for(int i = 0; i < count; i++) {
|
||||
env->SetObjectArrayElement(result, i, elts[i]);
|
||||
}
|
||||
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
return result;
|
||||
}
|
||||
|
||||
jobject CAstWrapper::makeSet(list<jobject> *elts) {
|
||||
jobject set = env->NewObject(HashSet, hashSetInit);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
|
||||
if (elts == NULL) return set;
|
||||
|
||||
for(list<jobject>::iterator it=elts->begin(); it!=elts->end(); it++) {
|
||||
env->CallVoidMethod(set, hashSetAdd, *it);
|
||||
}
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
jobject CAstWrapper::makeList(list<jobject> *elts) {
|
||||
jobject set = env->NewObject(LinkedList, linkedListInit);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
|
||||
if (elts == NULL) return set;
|
||||
|
||||
for(list<jobject>::iterator it=elts->begin(); it!=elts->end(); it++) {
|
||||
env->CallVoidMethod(set, linkedListAdd, *it);
|
||||
}
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
jobject CAstWrapper::getCallReference() {
|
||||
return callReference;
|
||||
}
|
||||
|
||||
const char *CAstWrapper::getEntityName(jobject entity) {
|
||||
jstring jstr = (jstring) env->CallObjectMethod(entity, _getEntityName);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
|
||||
const char *cstr1 = env->GetStringUTFChars(jstr, NULL);
|
||||
const char *cstr2 = strdup( cstr1 );
|
||||
env->ReleaseStringUTFChars(jstr, cstr1);
|
||||
THROW_ANY_EXCEPTION(java_ex);
|
||||
|
||||
return cstr2;
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
#include <jni.h>
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
#include "Exceptions.h"
|
||||
|
||||
Exceptions::Exceptions(JNIEnv *java_env, jmp_buf& c_env) :
|
||||
_java_env(java_env),
|
||||
_c_env(c_env)
|
||||
{
|
||||
_jre = java_env->FindClass("java/lang/RuntimeException");
|
||||
_ctr = java_env->GetMethodID(_jre, "<init>", "(Ljava/lang/String;)V");
|
||||
_wrapper_ctr =
|
||||
java_env->GetMethodID(_jre,
|
||||
"<init>",
|
||||
"(Ljava/lang/String;Ljava/lang/Throwable;)V");
|
||||
}
|
||||
|
||||
void Exceptions::throwAnyException(char *file_name, int line_number) {
|
||||
if (_java_env->ExceptionCheck()) throwException(file_name, line_number);
|
||||
}
|
||||
|
||||
void Exceptions::throwException(char *file_name, int line_number) {
|
||||
jthrowable real_ex = _java_env->ExceptionOccurred();
|
||||
_java_env->ExceptionClear();
|
||||
|
||||
char msg[strlen(file_name) + 1024];
|
||||
bzero(msg, strlen(file_name) + 1024);
|
||||
sprintf(msg, "exception at %s:%d", file_name, line_number);
|
||||
jstring java_message = _java_env->NewStringUTF(msg);
|
||||
|
||||
jthrowable ex = (jthrowable)
|
||||
_java_env->NewObject(_jre, _wrapper_ctr, java_message, real_ex);
|
||||
|
||||
if (_java_env->ExceptionCheck()) {
|
||||
jthrowable new_real_ex = _java_env->ExceptionOccurred();
|
||||
_java_env->Throw(new_real_ex);
|
||||
} else {
|
||||
_java_env->Throw(ex);
|
||||
}
|
||||
|
||||
longjmp( _c_env, -1 );
|
||||
}
|
||||
|
||||
void
|
||||
Exceptions::throwException(char *file_name, int line_number, char *c_message) {
|
||||
char msg[strlen(file_name) + strlen(c_message) + 1024];
|
||||
bzero(msg, strlen(file_name) + strlen(c_message) + 1024);
|
||||
sprintf(msg, "exception at %s:%d: %s", file_name, line_number, c_message);
|
||||
jstring java_message = _java_env->NewStringUTF(msg);
|
||||
jthrowable ex = (jthrowable)_java_env->NewObject(_jre, _ctr, java_message);
|
||||
_java_env->Throw(ex);
|
||||
|
||||
longjmp( _c_env, -1 );
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
|
||||
#include <jni.h>
|
||||
|
||||
#include "CAstWrapper.h"
|
||||
#include "Exceptions.h"
|
||||
#include "com_ibm_wala_cast_ir_translator_NativeBridge.h"
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_ibm_wala_cast_ir_translator_NativeBridge_initialize(
|
||||
JNIEnv *env,
|
||||
jclass cls)
|
||||
{
|
||||
TRY(exp, env)
|
||||
|
||||
jclass CAstNode = env->FindClass( "com/ibm/wala/cast/tree/CAstNode" );
|
||||
THROW_ANY_EXCEPTION(exp);
|
||||
jclass CAstOperator = env->FindClass( "com/ibm/wala/cast/tree/impl/CAstOperator" );
|
||||
THROW_ANY_EXCEPTION(exp);
|
||||
jclass CAstQualifier = env->FindClass( "com/ibm/wala/cast/tree/CAstQualifier" );
|
||||
THROW_ANY_EXCEPTION(exp);
|
||||
jclass CAstControlFlowMap = env->FindClass( "com/ibm/wala/cast/tree/CAstControlFlowMap" );
|
||||
THROW_ANY_EXCEPTION(exp);
|
||||
|
||||
#define _CODE_CONSTANTS
|
||||
#include "cast_constants.h"
|
||||
|
||||
#define _CODE_OPERATORS
|
||||
#include "cast_operators.h"
|
||||
|
||||
#define _CODE_QUALIFIERS
|
||||
#include "cast_qualifiers.h"
|
||||
|
||||
#define _CODE_CFM
|
||||
#include "cast_control_flow_map.h"
|
||||
|
||||
CATCH()
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.analysis.typeInference;
|
||||
|
||||
import com.ibm.wala.analysis.typeInference.*;
|
||||
import com.ibm.wala.cast.ir.ssa.*;
|
||||
import com.ibm.wala.ipa.cha.*;
|
||||
import com.ibm.wala.ssa.*;
|
||||
|
||||
public class AstTypeInference extends TypeInference {
|
||||
|
||||
protected class AstTypeOperatorFactory
|
||||
extends TypeOperatorFactory
|
||||
implements AstInstructionVisitor
|
||||
{
|
||||
public void visitAstLexicalRead(AstLexicalRead inst) {
|
||||
result = new DeclaredTypeOperator(new ConeType(cha.getRootClass(), cha));
|
||||
}
|
||||
public void visitAstLexicalWrite(AstLexicalWrite inst) {
|
||||
}
|
||||
public void visitAstGlobalRead(AstGlobalRead instruction) {
|
||||
result = new DeclaredTypeOperator(new ConeType(cha.getRootClass(), cha));
|
||||
}
|
||||
public void visitAstGlobalWrite(AstGlobalWrite instruction) {
|
||||
}
|
||||
public void visitNonExceptingThrow(NonExceptingThrowInstruction inst) {
|
||||
}
|
||||
public void visitAssert(AstAssertInstruction instruction) {
|
||||
}
|
||||
public void visitEachElementGet(EachElementGetInstruction inst) {
|
||||
result = new DeclaredTypeOperator(new ConeType(cha.getRootClass(), cha));
|
||||
}
|
||||
public void visitEachElementHasNext(EachElementHasNextInstruction inst) {
|
||||
}
|
||||
};
|
||||
|
||||
public AstTypeInference(IR ir, ClassHierarchy cha, boolean doPrimitives) {
|
||||
super(ir, cha, doPrimitives);
|
||||
}
|
||||
|
||||
protected void initialize() {
|
||||
init(ir, new TypeVarFactory(), new AstTypeOperatorFactory());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ipa.callgraph;
|
||||
|
||||
import com.ibm.wala.ipa.callgraph.propagation.cfa.*;
|
||||
|
||||
public class AstCFAPointerKeys extends DelegatingAstPointerKeys {
|
||||
|
||||
public AstCFAPointerKeys() {
|
||||
super(new CFAPointerKeys());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ipa.callgraph;
|
||||
|
||||
|
||||
import com.ibm.wala.cast.ir.cfg.*;
|
||||
import com.ibm.wala.cast.ir.ssa.*;
|
||||
import com.ibm.wala.cfg.*;
|
||||
import com.ibm.wala.classLoader.*;
|
||||
import com.ibm.wala.ipa.callgraph.*;
|
||||
import com.ibm.wala.ipa.callgraph.impl.*;
|
||||
import com.ibm.wala.ipa.cha.*;
|
||||
import com.ibm.wala.ssa.*;
|
||||
import com.ibm.wala.util.*;
|
||||
import com.ibm.wala.util.collections.*;
|
||||
import com.ibm.wala.util.graph.traverse.DFS;
|
||||
import com.ibm.wala.util.warnings.WarningSet;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class AstCallGraph extends ExplicitCallGraph {
|
||||
private final WarningSet warnings;
|
||||
|
||||
public AstCallGraph(ClassHierarchy cha, AnalysisOptions options, WarningSet warnings) {
|
||||
super(cha, options);
|
||||
this.warnings = warnings;
|
||||
}
|
||||
|
||||
public class AstFakeRoot extends FakeRootMethod {
|
||||
|
||||
public AstFakeRoot(ClassHierarchy cha, AnalysisOptions options) {
|
||||
super(cha, options);
|
||||
}
|
||||
|
||||
public InducedCFG makeControlFlowGraph() {
|
||||
return new AstInducedCFG(getStatements(warnings), this, Everywhere.EVERYWHERE);
|
||||
}
|
||||
|
||||
public AstLexicalRead addGlobalRead(String name) {
|
||||
AstLexicalRead s = new AstLexicalRead(nextLocal++, null, name);
|
||||
statements.add(s);
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class ScriptFakeRoot extends AstFakeRoot {
|
||||
|
||||
public ScriptFakeRoot(ClassHierarchy cha, AnalysisOptions options) {
|
||||
super(cha, options);
|
||||
}
|
||||
|
||||
public abstract SSAAbstractInvokeInstruction addDirectCall(int functionVn, int[] argVns, CallSiteReference callSite);
|
||||
|
||||
}
|
||||
|
||||
class AstCGNode extends ExplicitNode {
|
||||
private Set callbacks;
|
||||
|
||||
private AstCGNode(IMethod method, Context context) {
|
||||
super(method, context);
|
||||
}
|
||||
|
||||
private void fireCallbacks() {
|
||||
if (callbacks != null) {
|
||||
boolean done = false;
|
||||
while (!done) {
|
||||
try {
|
||||
for (Iterator x = callbacks.iterator(); x.hasNext();) {
|
||||
((Function) x.next()).apply(null);
|
||||
}
|
||||
} catch (ConcurrentModificationException e) {
|
||||
done = false;
|
||||
continue;
|
||||
}
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addCallback(Function callback) {
|
||||
if (callbacks == null)
|
||||
callbacks = new HashSet(1);
|
||||
callbacks.add(callback);
|
||||
}
|
||||
|
||||
private void fireCallbacksTransitive() {
|
||||
for(Iterator nodes = DFS.iterateFinishTime(AstCallGraph.this, new NonNullSingletonIterator<CGNode>(this));
|
||||
nodes.hasNext(); )
|
||||
{
|
||||
((AstCGNode)nodes.next()).fireCallbacks();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean addTarget(CallSiteReference site, CGNode node) {
|
||||
if (super.addTarget(site, node)) {
|
||||
fireCallbacksTransitive();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected ExplicitNode makeNode(IMethod method, Context context) {
|
||||
return new AstCGNode(method, context);
|
||||
}
|
||||
|
||||
protected CGNode makeFakeRootNode() {
|
||||
return findOrCreateNode(new AstFakeRoot(cha, options), Everywhere.EVERYWHERE);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ipa.callgraph;
|
||||
|
||||
import com.ibm.wala.cast.loader.*;
|
||||
import com.ibm.wala.classLoader.*;
|
||||
import com.ibm.wala.ipa.callgraph.*;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.cfa.*;
|
||||
import com.ibm.wala.ipa.cha.*;
|
||||
import com.ibm.wala.ssa.*;
|
||||
import com.ibm.wala.util.collections.EmptyIterator;
|
||||
import com.ibm.wala.util.warnings.WarningSet;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class AstContextInsensitiveSSAContextInterpreter
|
||||
extends ContextInsensitiveSSAInterpreter
|
||||
{
|
||||
|
||||
public AstContextInsensitiveSSAContextInterpreter(AnalysisOptions options, ClassHierarchy cha) {
|
||||
super(options, cha);
|
||||
}
|
||||
|
||||
public boolean understands(IMethod method, Context context) {
|
||||
return method instanceof AstMethod;
|
||||
}
|
||||
|
||||
public Iterator iterateCallSites(CGNode N, WarningSet warnings) {
|
||||
IR ir = getIR(N, warnings);
|
||||
if (ir == null) {
|
||||
return EmptyIterator.instance();
|
||||
} else {
|
||||
return ir.iterateCallSites();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ipa.callgraph;
|
||||
|
||||
import com.ibm.wala.ipa.callgraph.propagation.*;
|
||||
|
||||
public class AstGlobalPointerKey extends AbstractPointerKey {
|
||||
private final String globalName;
|
||||
public String getName() {
|
||||
return globalName;
|
||||
}
|
||||
|
||||
public AstGlobalPointerKey(String globalName) {
|
||||
this.globalName = globalName;
|
||||
}
|
||||
|
||||
public boolean equals(Object x) {
|
||||
return (x instanceof AstGlobalPointerKey) &&
|
||||
((AstGlobalPointerKey)x).globalName.equals(globalName);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return globalName.hashCode();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "[global: " + globalName + "]";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ipa.callgraph;
|
||||
|
||||
import com.ibm.wala.ipa.callgraph.propagation.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public interface AstPointerKeyFactory extends PointerKeyFactory {
|
||||
|
||||
Iterator getPointerKeysForReflectedFieldRead(InstanceKey I, InstanceKey F);
|
||||
|
||||
Iterator getPointerKeysForReflectedFieldWrite(InstanceKey I, InstanceKey F);
|
||||
|
||||
PointerKey getPointerKeyForObjectCatalog(InstanceKey I);
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,144 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
// Licensed Materials - Property of IBM
|
||||
// 5724-D15
|
||||
// (C) Copyright IBM Corporation 2004. All Rights Reserved.
|
||||
// Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
package com.ibm.wala.cast.ipa.callgraph;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.ibm.wala.cast.loader.*;
|
||||
import com.ibm.wala.classLoader.*;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.util.Atom;
|
||||
import com.ibm.wala.util.collections.NonNullSingletonIterator;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
public class CAstAnalysisScope extends AnalysisScope {
|
||||
private final ClassLoaderReference theLoader;
|
||||
|
||||
public CAstAnalysisScope(SingleClassLoaderFactory loaders) {
|
||||
this.theLoader = loaders.getTheReference();
|
||||
}
|
||||
|
||||
public CAstAnalysisScope(String[] sourceFileNames, SingleClassLoaderFactory loaders) throws IOException {
|
||||
this(loaders);
|
||||
for(int i = 0; i < sourceFileNames.length; i++) {
|
||||
File F = new File( sourceFileNames[i] );
|
||||
addSourceFileToScope(theLoader, F, F.getParent());
|
||||
}
|
||||
}
|
||||
|
||||
public CAstAnalysisScope(URL[] sources, SingleClassLoaderFactory loaders) throws IOException {
|
||||
this(loaders);
|
||||
for(int i = 0; i < sources.length; i++) {
|
||||
addToScope(theLoader, new SourceURLModule(sources[i]));
|
||||
}
|
||||
}
|
||||
|
||||
public CAstAnalysisScope(SourceFileModule[] sources, SingleClassLoaderFactory loaders) throws IOException {
|
||||
this(loaders);
|
||||
for(int i = 0; i < sources.length; i++) {
|
||||
addToScope(theLoader, sources[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the information regarding the primordial loader.
|
||||
*
|
||||
* @return ClassLoaderReference
|
||||
*/
|
||||
public ClassLoaderReference getPrimordialLoader() {
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the information regarding the extension loader.
|
||||
*
|
||||
* @return ClassLoaderReference
|
||||
*/
|
||||
public ClassLoaderReference getExtensionLoader() {
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the information regarding the application loader.
|
||||
*
|
||||
* @return ClassLoaderReference
|
||||
*/
|
||||
public ClassLoaderReference getApplicationLoader() {
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the arrayClassLoader.
|
||||
*/
|
||||
public ArrayClassLoader getArrayClassLoader() {
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the information regarding the application loader.
|
||||
*
|
||||
* @return ClassLoaderReference
|
||||
*/
|
||||
public ClassLoaderReference getSyntheticLoader() {
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a class file to the scope for a loader
|
||||
*
|
||||
* @param loader
|
||||
* @param file
|
||||
*/
|
||||
public void addClassFileToScope(ClassLoaderReference loader, File file) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the ClassLoaderReference specified by <code>name</code>.
|
||||
*/
|
||||
public ClassLoaderReference getLoader(Atom name) {
|
||||
if (Assertions.verifyAssertions) {
|
||||
Assertions._assert(name.equals(theLoader.getName()));
|
||||
}
|
||||
return theLoader;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an Iterator <ClassLoaderReference>over the loaders.
|
||||
*/
|
||||
public Iterator getLoaders() {
|
||||
return new NonNullSingletonIterator( theLoader );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number of loaders.
|
||||
*/
|
||||
public int getNumberOfLoaders() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ipa.callgraph;
|
||||
|
||||
import com.ibm.wala.classLoader.*;
|
||||
import com.ibm.wala.ipa.callgraph.*;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.*;
|
||||
import com.ibm.wala.util.*;
|
||||
import com.ibm.wala.util.collections.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class DelegatingAstPointerKeys implements AstPointerKeyFactory {
|
||||
private final PointerKeyFactory base;
|
||||
|
||||
public DelegatingAstPointerKeys(PointerKeyFactory base) {
|
||||
this.base = base;
|
||||
}
|
||||
|
||||
public PointerKey getPointerKeyForLocal(CGNode node, int valueNumber) {
|
||||
return base.getPointerKeyForLocal(node, valueNumber);
|
||||
}
|
||||
|
||||
public FilteredPointerKey getFilteredPointerKeyForLocal(CGNode node, int valueNumber, IClass filter) {
|
||||
return base.getFilteredPointerKeyForLocal(node, valueNumber, filter);
|
||||
}
|
||||
|
||||
public InstanceFilteredPointerKey getFilteredPointerKeyForLocal(CGNode node, int valueNumber, InstanceKey filter) {
|
||||
return base.getFilteredPointerKeyForLocal(node, valueNumber, filter);
|
||||
}
|
||||
|
||||
public PointerKey getPointerKeyForReturnValue(CGNode node){
|
||||
return base.getPointerKeyForReturnValue(node);
|
||||
}
|
||||
|
||||
public PointerKey getPointerKeyForExceptionalReturnValue(CGNode node) {
|
||||
return base.getPointerKeyForExceptionalReturnValue(node);
|
||||
}
|
||||
|
||||
public PointerKey getPointerKeyForStaticField(IField f) {
|
||||
return base.getPointerKeyForStaticField(f);
|
||||
}
|
||||
|
||||
public PointerKey getPointerKeyForObjectCatalog(InstanceKey I) {
|
||||
return new ObjectPropertyCatalogKey(I);
|
||||
}
|
||||
|
||||
private final Map specificStringKeys = new HashMap();
|
||||
private final Map specificIndexKeys = new HashMap();
|
||||
|
||||
public PointerKey getPointerKeyForInstanceField(InstanceKey I, IField f) {
|
||||
PointerKey fk = base.getPointerKeyForInstanceField(I, f);
|
||||
if (! specificStringKeys.containsKey(f)) {
|
||||
specificStringKeys.put(f, new HashSet());
|
||||
}
|
||||
|
||||
((Set)specificStringKeys.get(f)).add(fk);
|
||||
|
||||
return fk;
|
||||
}
|
||||
|
||||
public PointerKey getPointerKeyForArrayContents(InstanceKey I) {
|
||||
return base.getPointerKeyForArrayContents(I);
|
||||
}
|
||||
|
||||
public Iterator getPointerKeysForReflectedFieldRead(InstanceKey I, InstanceKey F) {
|
||||
List result = new LinkedList();
|
||||
|
||||
// FIXME: current only constant string are handled
|
||||
if (F instanceof ConstantKey) {
|
||||
Object v = ((ConstantKey)F).getValue();
|
||||
if (v instanceof String) {
|
||||
IField f =
|
||||
I.getConcreteType().getField(Atom.findOrCreateUnicodeAtom((String)v));
|
||||
result.add( getPointerKeyForInstanceField(I, f) );
|
||||
}
|
||||
}
|
||||
|
||||
result.add(ReflectedFieldPointerKey.mapped(new ConcreteTypeKey(F.getConcreteType()), I));
|
||||
|
||||
return result.iterator();
|
||||
}
|
||||
|
||||
public Iterator getPointerKeysForReflectedFieldWrite(InstanceKey I, InstanceKey F) {
|
||||
// FIXME: current only constant string are handled
|
||||
if (F instanceof ConstantKey) {
|
||||
Object v = ((ConstantKey)F).getValue();
|
||||
if (v instanceof String) {
|
||||
IField f =
|
||||
I.getConcreteType().getField(Atom.findOrCreateUnicodeAtom((String)v));
|
||||
return new NonNullSingletonIterator(getPointerKeyForInstanceField(I, f));
|
||||
}
|
||||
}
|
||||
|
||||
return new NonNullSingletonIterator(ReflectedFieldPointerKey.mapped(new ConcreteTypeKey(F.getConcreteType()), I));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ipa.callgraph;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.Context;
|
||||
import com.ibm.wala.ipa.callgraph.ContextSelector;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.types.*;
|
||||
import com.ibm.wala.util.Atom;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.warnings.WarningSet;
|
||||
|
||||
public class MiscellaneousHacksContextSelector implements ContextSelector
|
||||
{
|
||||
|
||||
private final Set methodsToSpecialize;
|
||||
|
||||
private final ContextSelector specialPolicy;
|
||||
private final ContextSelector basePolicy;
|
||||
|
||||
public MiscellaneousHacksContextSelector(ContextSelector special,
|
||||
ContextSelector base,
|
||||
ClassHierarchy cha,
|
||||
String[][] descriptors)
|
||||
{
|
||||
basePolicy = base;
|
||||
specialPolicy = special;
|
||||
methodsToSpecialize = new HashSet();
|
||||
for(int i = 0; i < descriptors.length; i++) {
|
||||
String[] descr = descriptors[i];
|
||||
switch (descr.length) {
|
||||
|
||||
// loader name, classname, method name, method descr
|
||||
case 4: {
|
||||
MethodReference ref =
|
||||
MethodReference.findOrCreate(
|
||||
TypeReference.findOrCreate(
|
||||
new ClassLoaderReference(
|
||||
Atom.findOrCreateUnicodeAtom( descr[0] )),
|
||||
TypeName.string2TypeName( descr[1] ) ),
|
||||
Atom.findOrCreateUnicodeAtom( descr[2] ),
|
||||
Descriptor.findOrCreateUTF8( descr[3] ));
|
||||
|
||||
methodsToSpecialize.add( cha.resolveMethod( ref ).getReference() );
|
||||
break;
|
||||
}
|
||||
|
||||
// classname, method name, method descr
|
||||
case 3: {
|
||||
MethodReference ref =
|
||||
MethodReference.findOrCreate(
|
||||
TypeReference.findOrCreate(
|
||||
new ClassLoaderReference(
|
||||
Atom.findOrCreateUnicodeAtom("Application")),
|
||||
TypeName.string2TypeName( descr[0] ) ),
|
||||
Atom.findOrCreateUnicodeAtom( descr[1] ),
|
||||
Descriptor.findOrCreateUTF8( descr[2] ));
|
||||
|
||||
methodsToSpecialize.add( cha.resolveMethod( ref ).getReference() );
|
||||
break;
|
||||
}
|
||||
|
||||
// loader name, classname, meaning all methods of that class
|
||||
case 2: {
|
||||
IClass klass =
|
||||
cha.lookupClass(
|
||||
TypeReference.findOrCreate(
|
||||
new ClassLoaderReference(
|
||||
Atom.findOrCreateUnicodeAtom( descr[0] )),
|
||||
TypeName.string2TypeName( descr[1] ) ) );
|
||||
|
||||
for(Iterator M = klass.getDeclaredMethods().iterator(); M.hasNext(); ) {
|
||||
methodsToSpecialize.add( ((IMethod)M.next()).getReference() );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// classname, meaning all methods of that class
|
||||
case 1: {
|
||||
IClass klass =
|
||||
cha.lookupClass(
|
||||
TypeReference.findOrCreate(
|
||||
new ClassLoaderReference(
|
||||
Atom.findOrCreateUnicodeAtom("Application")),
|
||||
TypeName.string2TypeName( descr[0] ) ) );
|
||||
|
||||
for(Iterator M = klass.getDeclaredMethods().iterator(); M.hasNext(); ) {
|
||||
methodsToSpecialize.add( ((IMethod)M.next()).getReference() );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Context getCalleeTarget(CGNode caller, CallSiteReference site, IMethod callee, InstanceKey receiver) {
|
||||
if (methodsToSpecialize.contains( callee.getReference() ))
|
||||
return specialPolicy.getCalleeTarget(caller, site, callee, receiver);
|
||||
else
|
||||
return basePolicy.getCalleeTarget(caller, site, callee, receiver);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.ibm.wala.ipa.callgraph.ContextSelector#contextIsIrrelevant(com.ibm.wala.ipa.callgraph.CGNode, com.ibm.wala.classLoader.CallSiteReference)
|
||||
*/
|
||||
public boolean contextIsIrrelevant(CGNode node, CallSiteReference site) {
|
||||
return basePolicy.contextIsIrrelevant(node,site);
|
||||
}
|
||||
|
||||
public int getBoundOnNumberOfTargets(CGNode caller, CallSiteReference reference, IMethod targetMethod) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public boolean mayUnderstand(CGNode caller, CallSiteReference site, IMethod targetMethod, InstanceKey instance) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setWarnings(WarningSet newWarnings) {
|
||||
// no-op, not bound to warnings
|
||||
}
|
||||
|
||||
public boolean allSitesDispatchIdentically(CGNode node, CallSiteReference site) {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ipa.callgraph;
|
||||
|
||||
import com.ibm.wala.ipa.callgraph.propagation.AbstractPointerKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
|
||||
public class ObjectPropertyCatalogKey extends AbstractPointerKey {
|
||||
private final InstanceKey object;
|
||||
|
||||
public String getName() {
|
||||
return "catalog of "+object.toString();
|
||||
}
|
||||
|
||||
public ObjectPropertyCatalogKey(InstanceKey object) {
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
public boolean equals(Object x) {
|
||||
return (x instanceof ObjectPropertyCatalogKey) &&
|
||||
((ObjectPropertyCatalogKey)x).object.equals(object);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return object.hashCode();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "[" + getName() + "]";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ipa.callgraph;
|
||||
|
||||
import com.ibm.wala.ipa.callgraph.propagation.AbstractFieldPointerKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
|
||||
public abstract class ReflectedFieldPointerKey extends AbstractFieldPointerKey {
|
||||
|
||||
ReflectedFieldPointerKey(InstanceKey container) {
|
||||
super(container);
|
||||
}
|
||||
|
||||
public abstract Object getFieldIdentifier();
|
||||
|
||||
private static final Object arrayStateKey = new Object() {
|
||||
public String toString() { return "ArrayStateKey"; }
|
||||
};
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof ReflectedFieldPointerKey) {
|
||||
ReflectedFieldPointerKey other = (ReflectedFieldPointerKey) obj;
|
||||
return
|
||||
getFieldIdentifier().equals(other.getFieldIdentifier()) &&
|
||||
getInstanceKey().equals(other.getInstanceKey());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return getFieldIdentifier().hashCode();
|
||||
}
|
||||
|
||||
public String toString() { return "field:" + getFieldIdentifier(); }
|
||||
|
||||
public static ReflectedFieldPointerKey literal(final String lit, InstanceKey instance) {
|
||||
return new ReflectedFieldPointerKey(instance) {
|
||||
public Object getFieldIdentifier() {
|
||||
return lit;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static ReflectedFieldPointerKey mapped(final InstanceKey mapFrom, InstanceKey instance) {
|
||||
return new ReflectedFieldPointerKey(instance) {
|
||||
public Object getFieldIdentifier() {
|
||||
return mapFrom;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static ReflectedFieldPointerKey index(InstanceKey instance) {
|
||||
return new ReflectedFieldPointerKey(instance) {
|
||||
public Object getFieldIdentifier() {
|
||||
return arrayStateKey;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,172 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ipa.callgraph;
|
||||
|
||||
|
||||
import com.ibm.wala.cast.ir.translator.*;
|
||||
import com.ibm.wala.cast.loader.AstMethod.*;
|
||||
import com.ibm.wala.classLoader.*;
|
||||
import com.ibm.wala.ipa.callgraph.*;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.*;
|
||||
import com.ibm.wala.types.*;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.debug.Trace;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
abstract public class ScopeMappingInstanceKeys implements InstanceKeyFactory {
|
||||
|
||||
protected abstract LexicalParent[] getParents(InstanceKey base);
|
||||
|
||||
protected abstract boolean needsScopeMappingKey(InstanceKey base);
|
||||
|
||||
private final PropagationCallGraphBuilder builder;
|
||||
private final InstanceKeyFactory basic;
|
||||
|
||||
public class ScopeMappingInstanceKey implements InstanceKey {
|
||||
private final InstanceKey base;
|
||||
private final CGNode creator;
|
||||
private final ScopeMap map;
|
||||
|
||||
private class ScopeMap extends HashMap {
|
||||
|
||||
private static final long serialVersionUID = 3645910671551712906L;
|
||||
|
||||
private void scan(int level, int toDo, LexicalParent parents[], CGNode node, Set parentNodes) {
|
||||
if (toDo > 0) {
|
||||
int restoreIndex = -1;
|
||||
LexicalParent restoreParent = null;
|
||||
|
||||
if (AstTranslator.DEBUG_LEXICAL)
|
||||
Trace.println(level + ": searching " + node + " for parents");
|
||||
|
||||
for(int i = 0; i < parents.length; i++) {
|
||||
|
||||
if (parents[i] == null) continue;
|
||||
|
||||
if (AstTranslator.DEBUG_LEXICAL)
|
||||
Trace.println(level + ": searching " + parents[i]);
|
||||
|
||||
if (node.getMethod() == parents[i].getMethod()) {
|
||||
if (containsKey(parents[i].getName()))
|
||||
Assertions._assert(get(parents[i].getName()) == node);
|
||||
else {
|
||||
put( parents[i].getName(), node );
|
||||
if (AstTranslator.DEBUG_LEXICAL)
|
||||
Trace.println(level + ": Adding lexical parent " + parents[i].getName() + " for " + base + " at " + creator + "(toDo is now " + toDo +")");
|
||||
}
|
||||
|
||||
toDo--;
|
||||
restoreIndex = i;
|
||||
restoreParent = parents[i];
|
||||
parents[i] = null;
|
||||
}
|
||||
}
|
||||
|
||||
CallGraph CG = builder.getCallGraph();
|
||||
|
||||
Assertions._assert(CG.getPredNodes(node).hasNext() || toDo==0);
|
||||
|
||||
for(Iterator PS = CG.getPredNodes(node); PS.hasNext(); ) {
|
||||
CGNode pred = (CGNode) PS.next();
|
||||
if (pred != creator && !parentNodes.contains(pred)) {
|
||||
parentNodes.add( pred );
|
||||
scan(level+1, toDo, parents, pred, parentNodes);
|
||||
parentNodes.remove(pred);
|
||||
}
|
||||
}
|
||||
|
||||
if (restoreIndex != -1) {
|
||||
parents[restoreIndex] = restoreParent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ScopeMap() {
|
||||
LexicalParent[] parents = getParents(base);
|
||||
|
||||
if (AstTranslator.DEBUG_LEXICAL)
|
||||
Trace.println("starting search for parents at " + creator);
|
||||
|
||||
scan( 0, parents.length, parents, creator, new HashSet(5));
|
||||
}
|
||||
|
||||
CGNode getDefiningNode(String definer) {
|
||||
return (CGNode) get(definer);
|
||||
}
|
||||
}
|
||||
|
||||
private ScopeMappingInstanceKey(CGNode creator, InstanceKey base) {
|
||||
this.creator = creator;
|
||||
this.base = base;
|
||||
this.map = new ScopeMap();
|
||||
}
|
||||
|
||||
public IClass getConcreteType() {
|
||||
return base.getConcreteType();
|
||||
}
|
||||
|
||||
CGNode getDefiningNode(String definer) {
|
||||
return map.getDefiningNode( definer );
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return base.hashCode()*creator.hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return (o instanceof ScopeMappingInstanceKey) &&
|
||||
((ScopeMappingInstanceKey)o).base.equals(base) &&
|
||||
((ScopeMappingInstanceKey)o).creator.equals(creator);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "SMIK:"+base+"@"+creator;
|
||||
}
|
||||
}
|
||||
|
||||
public InstanceKey getInstanceKeyForAllocation(CGNode node, NewSiteReference allocation) {
|
||||
InstanceKey base = basic.getInstanceKeyForAllocation(node, allocation);
|
||||
if (base != null && needsScopeMappingKey(base)) {
|
||||
return new ScopeMappingInstanceKey(node, base);
|
||||
} else {
|
||||
return base;
|
||||
}
|
||||
}
|
||||
|
||||
public InstanceKey getInstanceKeyForMultiNewArray(CGNode node, NewSiteReference allocation, int dim) {
|
||||
return basic.getInstanceKeyForMultiNewArray(node, allocation, dim);
|
||||
}
|
||||
|
||||
public InstanceKey getInstanceKeyForConstant(Object S) {
|
||||
return basic.getInstanceKeyForConstant(S);
|
||||
}
|
||||
|
||||
public String getStringConstantForInstanceKey(InstanceKey I) {
|
||||
return basic.getStringConstantForInstanceKey(I);
|
||||
}
|
||||
|
||||
public InstanceKey getInstanceKeyForPEI(CGNode node, ProgramCounter instr, TypeReference type) {
|
||||
return basic.getInstanceKeyForPEI(node, instr, type);
|
||||
}
|
||||
|
||||
public InstanceKey getInstanceKeyForClassObject(TypeReference type) {
|
||||
return basic.getInstanceKeyForClassObject(type);
|
||||
}
|
||||
|
||||
public ScopeMappingInstanceKeys(
|
||||
PropagationCallGraphBuilder builder,
|
||||
InstanceKeyFactory basic)
|
||||
{
|
||||
this.basic = basic;
|
||||
this.builder = builder;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ipa.callgraph;
|
||||
|
||||
import com.ibm.wala.cast.ipa.callgraph.AstCallGraph.*;
|
||||
import com.ibm.wala.classLoader.*;
|
||||
import com.ibm.wala.ipa.callgraph.*;
|
||||
import com.ibm.wala.ipa.callgraph.impl.*;
|
||||
import com.ibm.wala.ipa.cha.*;
|
||||
import com.ibm.wala.ssa.*;
|
||||
import com.ibm.wala.types.*;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.warnings.WarningSet;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public abstract class ScriptEntryPoints implements Entrypoints {
|
||||
|
||||
private final ClassHierarchy cha;
|
||||
private final IClass scriptType;
|
||||
|
||||
private class ScriptEntryPoint extends Entrypoint {
|
||||
ScriptEntryPoint(IMethod scriptCodeBody) {
|
||||
super( scriptCodeBody );
|
||||
}
|
||||
|
||||
public TypeReference[] getParameterTypes(int i) {
|
||||
Assertions._assert(i == 0);
|
||||
return
|
||||
new TypeReference[]{ getMethod().getDeclaringClass().getReference() };
|
||||
}
|
||||
|
||||
public int getNumberOfParameters() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public SSAAbstractInvokeInstruction addCall(FakeRootMethod m,
|
||||
WarningSet warnings)
|
||||
{
|
||||
CallSiteReference site = makeSite(0);
|
||||
|
||||
if (site == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int functionVn = makeArgument(m, 0, warnings);
|
||||
int paramVns[] = new int[getNumberOfParameters() - 1];
|
||||
for (int j = 0; j < paramVns.length; j++) {
|
||||
paramVns[j] = makeArgument(m, j+1, warnings);
|
||||
}
|
||||
|
||||
return ((ScriptFakeRoot)m).addDirectCall(functionVn, paramVns, site);
|
||||
}
|
||||
}
|
||||
|
||||
public ScriptEntryPoints(ClassHierarchy cha, IClass scriptType) {
|
||||
this.cha = cha;
|
||||
this.scriptType = scriptType;
|
||||
}
|
||||
|
||||
public Iterator iterator() {
|
||||
Set ES = new HashSet();
|
||||
Iterator classes = scriptType.getClassLoader().iterateAllClasses();
|
||||
while ( classes.hasNext() ) {
|
||||
IClass cls = (IClass)classes.next();
|
||||
if (cha.isSubclassOf(cls, scriptType)) {
|
||||
for (Iterator methods = cls.getDeclaredMethods().iterator(); methods.hasNext();) {
|
||||
ES.add(new ScriptEntryPoint(((IMethod)methods.next())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ES.iterator();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ipa.callgraph;
|
||||
|
||||
import com.ibm.wala.cast.types.*;
|
||||
import com.ibm.wala.classLoader.*;
|
||||
import com.ibm.wala.ipa.callgraph.*;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.types.*;
|
||||
|
||||
public class StandardFunctionTargetSelector implements MethodTargetSelector {
|
||||
private final ClassHierarchy cha;
|
||||
private final MethodTargetSelector base;
|
||||
|
||||
public StandardFunctionTargetSelector(ClassHierarchy cha, MethodTargetSelector base) {
|
||||
this.cha = cha;
|
||||
this.base = base;
|
||||
}
|
||||
|
||||
public IMethod getCalleeTarget(CGNode caller, CallSiteReference site, IClass receiver) {
|
||||
if (receiver != null) {
|
||||
ClassLoaderReference loader = receiver.getClassLoader().getReference();
|
||||
TypeReference functionTypeRef =
|
||||
TypeReference.findOrCreate(loader, AstTypeReference.functionTypeName);
|
||||
|
||||
if (cha.isSubclassOf(receiver, cha.lookupClass(functionTypeRef))) {
|
||||
return receiver.getMethod(AstMethodReference.fnSelector);
|
||||
}
|
||||
}
|
||||
|
||||
return base.getCalleeTarget(caller, site, receiver);
|
||||
}
|
||||
|
||||
public boolean mightReturnSyntheticMethod(CGNode caller, CallSiteReference site) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean mightReturnSyntheticMethod(MethodReference declaredTarget) {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ipa.callgraph;
|
||||
|
||||
|
||||
import com.ibm.wala.classLoader.*;
|
||||
import com.ibm.wala.ipa.callgraph.*;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.*;
|
||||
import com.ibm.wala.ssa.*;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.debug.Trace;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
|
||||
public class Util {
|
||||
|
||||
public static SourceFileModule makeSourceModule(URL script, String dir, String name) {
|
||||
// DO NOT use File.separator here, since this name is matched against
|
||||
// URLs. It seems that, in DOS, URL.getFile() does not return a
|
||||
// \-separated file name, but rather one with /'s. Rather makes one
|
||||
// wonder why the function is called get_File_ :(
|
||||
return makeSourceModule(script, dir + "/" + name);
|
||||
}
|
||||
|
||||
public static SourceFileModule makeSourceModule(URL script, String scriptName) {
|
||||
String hackedName =
|
||||
script.getFile().replaceAll("%5c", "/").replaceAll("%20", " ");
|
||||
|
||||
File scriptFile = new File( hackedName );
|
||||
|
||||
Assertions._assert( hackedName.endsWith( scriptName ),
|
||||
scriptName + " does not match file " + script.getFile());
|
||||
|
||||
return new SourceFileModule( scriptFile, scriptName );
|
||||
}
|
||||
|
||||
public static void dumpCG(PropagationCallGraphBuilder builder, CallGraph CG) {
|
||||
Trace.println( CG );
|
||||
|
||||
for(Iterator x = CG.iterateNodes(); x.hasNext(); ) {
|
||||
CGNode N = (CGNode) x.next();
|
||||
Trace.println("\nIR of node " + N);
|
||||
IR ir = ((SSAContextInterpreter)CG.getInterpreter(N)).getIR(N, builder.getWarnings());
|
||||
if (ir != null) {
|
||||
Trace.println( ir );
|
||||
} else {
|
||||
Trace.println( "no IR!" );
|
||||
}
|
||||
}
|
||||
|
||||
PointerAnalysis PA = builder.getPointerAnalysis();
|
||||
for(Iterator x = PA.getPointerKeys().iterator(); x.hasNext(); ) {
|
||||
PointerKey n = (PointerKey)x.next();
|
||||
Trace.println(n + " --> " + PA.getPointsToSet(n));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ir.cfg;
|
||||
|
||||
import com.ibm.wala.cast.ir.ssa.*;
|
||||
import com.ibm.wala.cfg.*;
|
||||
import com.ibm.wala.classLoader.*;
|
||||
import com.ibm.wala.ipa.callgraph.*;
|
||||
import com.ibm.wala.ssa.*;
|
||||
|
||||
public class AstInducedCFG extends InducedCFG {
|
||||
|
||||
public AstInducedCFG(SSAInstruction[] instructions, IMethod method, Context context) {
|
||||
super(instructions, method, context);
|
||||
}
|
||||
|
||||
protected class AstPEIVisitor extends PEIVisitor implements AstInstructionVisitor {
|
||||
|
||||
protected AstPEIVisitor(boolean[] r) {
|
||||
super(r);
|
||||
}
|
||||
|
||||
public void visitAstLexicalRead(AstLexicalRead inst) {
|
||||
}
|
||||
|
||||
public void visitAstLexicalWrite(AstLexicalWrite inst) {
|
||||
}
|
||||
|
||||
public void visitAstGlobalRead(AstGlobalRead instruction) {
|
||||
}
|
||||
|
||||
public void visitAstGlobalWrite(AstGlobalWrite instruction) {
|
||||
}
|
||||
|
||||
public void visitNonExceptingThrow(NonExceptingThrowInstruction inst) {
|
||||
breakBasicBlock();
|
||||
}
|
||||
|
||||
public void visitAssert(AstAssertInstruction instruction) {
|
||||
|
||||
}
|
||||
|
||||
public void visitEachElementHasNext(EachElementHasNextInstruction inst) {
|
||||
|
||||
}
|
||||
|
||||
public void visitEachElementGet(EachElementGetInstruction inst) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected class AstBranchVisitor extends BranchVisitor implements AstInstructionVisitor {
|
||||
|
||||
protected AstBranchVisitor(boolean[] r) {
|
||||
super(r);
|
||||
}
|
||||
|
||||
public void visitAstLexicalRead(AstLexicalRead inst) {
|
||||
}
|
||||
|
||||
public void visitAstLexicalWrite(AstLexicalWrite inst) {
|
||||
}
|
||||
|
||||
public void visitAstGlobalRead(AstGlobalRead instruction) {
|
||||
}
|
||||
|
||||
public void visitAstGlobalWrite(AstGlobalWrite instruction) {
|
||||
}
|
||||
|
||||
public void visitNonExceptingThrow(NonExceptingThrowInstruction inst) {
|
||||
}
|
||||
|
||||
public void visitAssert(AstAssertInstruction instruction) {
|
||||
}
|
||||
|
||||
public void visitEachElementHasNext(EachElementHasNextInstruction inst) {
|
||||
}
|
||||
|
||||
public void visitEachElementGet(EachElementGetInstruction inst) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected BranchVisitor makeBranchVisitor(boolean[] r) {
|
||||
return new AstBranchVisitor(r);
|
||||
}
|
||||
|
||||
protected PEIVisitor makePEIVisitor(boolean[] r) {
|
||||
return new AstPEIVisitor(r);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ir.cfg;
|
||||
|
||||
import com.ibm.wala.cfg.*;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.shrikeBT.IInstruction;
|
||||
import com.ibm.wala.util.graph.*;
|
||||
import com.ibm.wala.util.intset.BitVector;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class DelegatingCFG extends AbstractNumberedGraph<IBasicBlock>
|
||||
implements ControlFlowGraph
|
||||
{
|
||||
|
||||
protected final ControlFlowGraph parent;
|
||||
|
||||
public DelegatingCFG(ControlFlowGraph parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
protected NodeManager getNodeManager() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
protected EdgeManager getEdgeManager() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public IBasicBlock entry() { return parent.entry(); }
|
||||
|
||||
public IBasicBlock exit() { return parent.exit(); }
|
||||
|
||||
public BitVector getCatchBlocks() { return parent.getCatchBlocks(); }
|
||||
|
||||
public IBasicBlock getBlockForInstruction(int index) {
|
||||
return parent.getBlockForInstruction( index );
|
||||
}
|
||||
|
||||
public IInstruction[] getInstructions() { return parent.getInstructions(); }
|
||||
|
||||
public int getProgramCounter(int index) {
|
||||
return parent.getProgramCounter( index );
|
||||
}
|
||||
|
||||
public IMethod getMethod() { return parent.getMethod(); }
|
||||
|
||||
public Collection getExceptionalSuccessors(IBasicBlock b) {
|
||||
return parent.getExceptionalSuccessors( b );
|
||||
}
|
||||
|
||||
public Collection getNormalSuccessors(IBasicBlock b) {
|
||||
return parent.getNormalSuccessors( b );
|
||||
}
|
||||
|
||||
public Collection getExceptionalPredecessors(IBasicBlock b) {
|
||||
return parent.getExceptionalPredecessors( b );
|
||||
}
|
||||
|
||||
public Collection getNormalPredecessors(IBasicBlock b) {
|
||||
return parent.getNormalPredecessors( b );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,319 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ir.cfg;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
|
||||
import com.ibm.wala.cfg.ControlFlowGraph;
|
||||
import com.ibm.wala.cfg.IBasicBlock;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.shrikeBT.IInstruction;
|
||||
import com.ibm.wala.util.CompoundIterator;
|
||||
import com.ibm.wala.util.collections.Filter;
|
||||
import com.ibm.wala.util.collections.FilterIterator;
|
||||
import com.ibm.wala.util.collections.Iterator2Collection;
|
||||
import com.ibm.wala.util.graph.AbstractNumberedGraph;
|
||||
import com.ibm.wala.util.graph.EdgeManager;
|
||||
import com.ibm.wala.util.graph.Graph;
|
||||
import com.ibm.wala.util.graph.NodeManager;
|
||||
import com.ibm.wala.util.graph.NumberedEdgeManager;
|
||||
import com.ibm.wala.util.graph.NumberedNodeManager;
|
||||
import com.ibm.wala.util.graph.impl.GraphInverter;
|
||||
import com.ibm.wala.util.graph.traverse.DFS;
|
||||
import com.ibm.wala.util.intset.BitVector;
|
||||
import com.ibm.wala.util.intset.IntSet;
|
||||
import com.ibm.wala.util.intset.IntSetUtil;
|
||||
import com.ibm.wala.util.intset.MutableIntSet;
|
||||
|
||||
public class PrunedCFG extends AbstractNumberedGraph<IBasicBlock> implements ControlFlowGraph {
|
||||
|
||||
public interface EdgeFilter {
|
||||
|
||||
boolean hasNormalEdge(IBasicBlock src, IBasicBlock dst);
|
||||
|
||||
boolean hasExceptionalEdge(IBasicBlock src, IBasicBlock dst);
|
||||
|
||||
}
|
||||
|
||||
private static class FilteredCFGEdges implements NumberedEdgeManager {
|
||||
private final ControlFlowGraph cfg;
|
||||
|
||||
private final NumberedNodeManager currentCFGNodes;
|
||||
|
||||
private final EdgeFilter filter;
|
||||
|
||||
FilteredCFGEdges(ControlFlowGraph cfg, NumberedNodeManager currentCFGNodes, EdgeFilter filter) {
|
||||
this.cfg = cfg;
|
||||
this.filter = filter;
|
||||
this.currentCFGNodes = currentCFGNodes;
|
||||
}
|
||||
|
||||
public Iterator getExceptionalSuccessors(final IBasicBlock N) {
|
||||
return new FilterIterator(cfg.getExceptionalSuccessors(N).iterator(), new Filter() {
|
||||
public boolean accepts(Object o) {
|
||||
return currentCFGNodes.containsNode(o) && filter.hasExceptionalEdge((IBasicBlock) N, (IBasicBlock) o);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Iterator getNormalSuccessors(final IBasicBlock N) {
|
||||
return new FilterIterator(cfg.getNormalSuccessors(N).iterator(), new Filter() {
|
||||
public boolean accepts(Object o) {
|
||||
return currentCFGNodes.containsNode(o) && filter.hasNormalEdge((IBasicBlock) N, (IBasicBlock) o);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Iterator getExceptionalPredecessors(final IBasicBlock N) {
|
||||
return new FilterIterator(cfg.getExceptionalPredecessors(N).iterator(), new Filter() {
|
||||
public boolean accepts(Object o) {
|
||||
return currentCFGNodes.containsNode(o) && filter.hasExceptionalEdge((IBasicBlock) o, (IBasicBlock) N);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Iterator getNormalPredecessors(final IBasicBlock N) {
|
||||
return new FilterIterator(cfg.getNormalPredecessors(N).iterator(), new Filter() {
|
||||
public boolean accepts(Object o) {
|
||||
return currentCFGNodes.containsNode(o) && filter.hasNormalEdge((IBasicBlock) o, (IBasicBlock) N);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Iterator getSuccNodes(Object N) {
|
||||
return new CompoundIterator(getNormalSuccessors((IBasicBlock) N), getExceptionalSuccessors((IBasicBlock) N));
|
||||
}
|
||||
|
||||
public int getSuccNodeCount(Object N) {
|
||||
return new Iterator2Collection(getSuccNodes(N)).size();
|
||||
}
|
||||
|
||||
public IntSet getSuccNodeNumbers(Object N) {
|
||||
MutableIntSet bits = IntSetUtil.make();
|
||||
for (Iterator EE = getSuccNodes(N); EE.hasNext();) {
|
||||
bits.add(((IBasicBlock) EE.next()).getNumber());
|
||||
}
|
||||
|
||||
return bits;
|
||||
}
|
||||
|
||||
public Iterator getPredNodes(Object N) {
|
||||
return new CompoundIterator(getNormalPredecessors((IBasicBlock) N), getExceptionalPredecessors((IBasicBlock) N));
|
||||
}
|
||||
|
||||
public int getPredNodeCount(Object N) {
|
||||
return new Iterator2Collection(getPredNodes(N)).size();
|
||||
}
|
||||
|
||||
public IntSet getPredNodeNumbers(Object N) {
|
||||
MutableIntSet bits = IntSetUtil.make();
|
||||
for (Iterator EE = getPredNodes(N); EE.hasNext();) {
|
||||
bits.add(((IBasicBlock) EE.next()).getNumber());
|
||||
}
|
||||
|
||||
return bits;
|
||||
}
|
||||
|
||||
public boolean hasEdge(Object src, Object dst) {
|
||||
for (Iterator EE = getSuccNodes(src); EE.hasNext();) {
|
||||
if (EE.next().equals(dst)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void addEdge(Object src, Object dst) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void removeEdge(Object src, Object dst) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void removeAllIncidentEdges(Object node) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void removeIncomingEdges(Object node) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void removeOutgoingEdges(Object node) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
private static class FilteredNodes implements NumberedNodeManager {
|
||||
private final NumberedNodeManager nodes;
|
||||
|
||||
private final Set subset;
|
||||
|
||||
FilteredNodes(NumberedNodeManager nodes, Set subset) {
|
||||
this.nodes = nodes;
|
||||
this.subset = subset;
|
||||
}
|
||||
|
||||
public int getNumber(Object N) {
|
||||
if (subset.contains(N))
|
||||
return nodes.getNumber(N);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
public Object getNode(int number) {
|
||||
Object N = nodes.getNode(number);
|
||||
if (subset.contains(N))
|
||||
return N;
|
||||
else
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
public int getMaxNumber() {
|
||||
int max = -1;
|
||||
for (Iterator NS = nodes.iterateNodes(); NS.hasNext();) {
|
||||
Object N = NS.next();
|
||||
if (subset.contains(N) && getNumber(N) > max) {
|
||||
max = getNumber(N);
|
||||
}
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
private Iterator filterNodes(Iterator nodeIterator) {
|
||||
return new FilterIterator(nodeIterator, new Filter() {
|
||||
public boolean accepts(Object o) {
|
||||
return subset.contains(o);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Iterator iterateNodes(IntSet s) {
|
||||
return filterNodes(nodes.iterateNodes(s));
|
||||
}
|
||||
|
||||
public Iterator iterateNodes() {
|
||||
return filterNodes(nodes.iterateNodes());
|
||||
}
|
||||
|
||||
public int getNumberOfNodes() {
|
||||
return subset.size();
|
||||
}
|
||||
|
||||
public void addNode(Object n) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void removeNode(Object n) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public boolean containsNode(Object N) {
|
||||
return subset.contains(N);
|
||||
}
|
||||
}
|
||||
|
||||
private final ControlFlowGraph cfg;
|
||||
|
||||
private final FilteredNodes nodes;
|
||||
|
||||
private final FilteredCFGEdges edges;
|
||||
|
||||
public PrunedCFG(final ControlFlowGraph cfg, final EdgeFilter filter) {
|
||||
this.cfg = cfg;
|
||||
Graph<IBasicBlock> temp = new AbstractNumberedGraph<IBasicBlock>() {
|
||||
private final EdgeManager edges = new FilteredCFGEdges(cfg, cfg, filter);
|
||||
|
||||
protected NodeManager getNodeManager() {
|
||||
return cfg;
|
||||
}
|
||||
|
||||
protected EdgeManager getEdgeManager() {
|
||||
return edges;
|
||||
}
|
||||
};
|
||||
|
||||
Set reachable = DFS.getReachableNodes(temp, Collections.singleton(cfg.entry()));
|
||||
Set back = DFS.getReachableNodes(GraphInverter.invert(temp), Collections.singleton(cfg.exit()));
|
||||
reachable.retainAll(back);
|
||||
|
||||
this.nodes = new FilteredNodes(cfg, reachable);
|
||||
this.edges = new FilteredCFGEdges(cfg, nodes, filter);
|
||||
}
|
||||
|
||||
protected NodeManager getNodeManager() {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
protected EdgeManager getEdgeManager() {
|
||||
return edges;
|
||||
}
|
||||
|
||||
public Collection getExceptionalSuccessors(final IBasicBlock N) {
|
||||
return new Iterator2Collection(edges.getExceptionalSuccessors(N));
|
||||
}
|
||||
|
||||
public Collection getNormalSuccessors(final IBasicBlock N) {
|
||||
return new Iterator2Collection(edges.getNormalSuccessors(N));
|
||||
}
|
||||
|
||||
public Collection getExceptionalPredecessors(final IBasicBlock N) {
|
||||
return new Iterator2Collection(edges.getExceptionalPredecessors(N));
|
||||
}
|
||||
|
||||
public Collection getNormalPredecessors(final IBasicBlock N) {
|
||||
return new Iterator2Collection(edges.getNormalPredecessors(N));
|
||||
}
|
||||
|
||||
public IBasicBlock entry() {
|
||||
return cfg.entry();
|
||||
}
|
||||
|
||||
public IBasicBlock exit() {
|
||||
return cfg.exit();
|
||||
}
|
||||
|
||||
public IBasicBlock getBlockForInstruction(int index) {
|
||||
return cfg.getBlockForInstruction(index);
|
||||
}
|
||||
|
||||
public IInstruction[] getInstructions() {
|
||||
return cfg.getInstructions();
|
||||
}
|
||||
|
||||
public int getProgramCounter(int index) {
|
||||
return cfg.getProgramCounter(index);
|
||||
}
|
||||
|
||||
public IMethod getMethod() {
|
||||
return cfg.getMethod();
|
||||
}
|
||||
|
||||
public BitVector getCatchBlocks() {
|
||||
BitVector result = new BitVector();
|
||||
BitVector blocks = cfg.getCatchBlocks();
|
||||
int i = 0;
|
||||
while ((i = blocks.nextSetBit(i)) != -1) {
|
||||
if (nodes.containsNode(getNode(i))) {
|
||||
result.set(i);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ir.cfg;
|
||||
|
||||
import com.ibm.wala.cfg.*;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class Util {
|
||||
|
||||
public static int whichPred(ControlFlowGraph CFG,
|
||||
IBasicBlock Y,
|
||||
IBasicBlock X)
|
||||
{
|
||||
int i = 0;
|
||||
for (Iterator N = CFG.getPredNodes(Y); N.hasNext(); i++)
|
||||
if (N.next() == X)
|
||||
return i;
|
||||
|
||||
Assertions.UNREACHABLE();
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ir.ssa;
|
||||
|
||||
|
||||
import com.ibm.wala.cast.ir.ssa.AstLexicalAccess.Access;
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.ssa.*;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
public abstract class AbstractLexicalInvoke
|
||||
extends SSAAbstractInvokeInstruction
|
||||
{
|
||||
|
||||
protected Access[] lexicalReads = null;
|
||||
|
||||
protected Access[] lexicalWrites = null;
|
||||
|
||||
protected AbstractLexicalInvoke(int result,
|
||||
int exception,
|
||||
CallSiteReference site)
|
||||
{
|
||||
super(result, exception, site);
|
||||
}
|
||||
|
||||
protected AbstractLexicalInvoke(int result,
|
||||
int exception,
|
||||
CallSiteReference site,
|
||||
Access[] lexicalReads,
|
||||
Access[] lexicalWrites)
|
||||
{
|
||||
this(result, exception, site);
|
||||
this.lexicalReads = lexicalReads;
|
||||
this.lexicalWrites = lexicalWrites;
|
||||
}
|
||||
|
||||
public int getNumberOfUses() {
|
||||
if (lexicalReads == null)
|
||||
return getNumberOfParameters();
|
||||
else
|
||||
return getNumberOfParameters() + lexicalReads.length;
|
||||
}
|
||||
|
||||
public int getUse(int j) {
|
||||
Assertions._assert(j >= getNumberOfParameters());
|
||||
Assertions._assert(lexicalReads != null);
|
||||
Assertions._assert(lexicalReads[j - getNumberOfParameters()] != null);
|
||||
return lexicalReads[j - getNumberOfParameters()].valueNumber;
|
||||
}
|
||||
|
||||
public int getNumberOfDefs() {
|
||||
if (lexicalWrites == null)
|
||||
return super.getNumberOfDefs();
|
||||
else
|
||||
return super.getNumberOfDefs() + lexicalWrites.length;
|
||||
}
|
||||
|
||||
public int getDef(int j) {
|
||||
if (j < super.getNumberOfDefs())
|
||||
return super.getDef(j);
|
||||
else
|
||||
return lexicalWrites[j-super.getNumberOfDefs()].valueNumber;
|
||||
}
|
||||
|
||||
private Access[] addAccess(Access[] array, Access access) {
|
||||
if (array == null)
|
||||
return new Access[]{ access };
|
||||
else {
|
||||
Access[] result = new Access[ array.length + 1 ];
|
||||
System.arraycopy(array, 0, result, 0, array.length);
|
||||
result[ array.length ] = access;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isLexicalUse(int use) {
|
||||
return use >= super.getNumberOfUses();
|
||||
}
|
||||
|
||||
public void addLexicalUse(Access use) {
|
||||
lexicalReads = addAccess(lexicalReads, use);
|
||||
}
|
||||
|
||||
public Access getLexicalUse(int i) {
|
||||
return lexicalReads[i-getNumberOfParameters()];
|
||||
}
|
||||
|
||||
public boolean isLexicalDef(int def) {
|
||||
return def >= super.getNumberOfDefs();
|
||||
}
|
||||
|
||||
public void addLexicalDef(Access def) {
|
||||
lexicalWrites = addAccess(lexicalWrites, def);
|
||||
}
|
||||
|
||||
public Access getLexicalDef(int i) {
|
||||
return lexicalWrites[i-super.getNumberOfDefs()];
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return site.hashCode() * 7529;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj != null && getClass().equals(obj.getClass())) {
|
||||
SSAAbstractInvokeInstruction other = (SSAAbstractInvokeInstruction)obj;
|
||||
return site.equals(other.getCallSite());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString(SymbolTable symbolTable, ValueDecorator d) {
|
||||
StringBuffer s = new StringBuffer(super.toString(symbolTable, d));
|
||||
|
||||
if (lexicalReads != null) {
|
||||
s.append(" (reads:");
|
||||
for(int i = 0; i < lexicalReads.length; i++) {
|
||||
s.append(" ").append(lexicalReads[i].variableName).append(":").append( getValueString(symbolTable, d, lexicalReads[i].valueNumber) );
|
||||
}
|
||||
s.append(")");
|
||||
}
|
||||
|
||||
if (lexicalWrites != null) {
|
||||
s.append(" (writes:");
|
||||
for(int i = 0; i < lexicalWrites.length; i++) {
|
||||
s.append(" ").append(lexicalWrites[i].variableName).append(":").append( getValueString(symbolTable, d, lexicalWrites[i].valueNumber) );
|
||||
}
|
||||
s.append(")");
|
||||
}
|
||||
|
||||
return s.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ir.ssa;
|
||||
|
||||
import com.ibm.wala.ssa.*;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
public abstract class AbstractReflectiveGet extends ReflectiveMemberAccess {
|
||||
private final int result;
|
||||
|
||||
public AbstractReflectiveGet(int result, int objectRef, int memberRef) {
|
||||
super(objectRef, memberRef);
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public String toString(SymbolTable symbolTable, ValueDecorator d) {
|
||||
return getValueString(symbolTable, d, result) +
|
||||
" = " +
|
||||
super.toString(symbolTable, d);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.ibm.wala.ssa.Instruction#getDef()
|
||||
*/
|
||||
public boolean hasDef() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getDef() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public int getDef(int i) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.ibm.wala.ssa.Instruction#getNumberOfUses()
|
||||
*/
|
||||
public int getNumberOfUses() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
public int getNumberOfDefs() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ir.ssa;
|
||||
|
||||
|
||||
import com.ibm.wala.ssa.*;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
public abstract class AbstractReflectivePut extends ReflectiveMemberAccess {
|
||||
private final int value;
|
||||
|
||||
public AbstractReflectivePut(int objectRef, int memberRef, int value) {
|
||||
super(objectRef, memberRef);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String toString(SymbolTable symbolTable, ValueDecorator d) {
|
||||
return super.toString(symbolTable, d) +
|
||||
" = " +
|
||||
getValueString(symbolTable, d, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.ibm.wala.ssa.Instruction#getDef()
|
||||
*/
|
||||
public int getDef() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.ibm.wala.ssa.Instruction#getNumberOfUses()
|
||||
*/
|
||||
public int getNumberOfUses() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return getUse(2);
|
||||
}
|
||||
|
||||
public int getUse(int index) {
|
||||
if (index == 2)
|
||||
return value;
|
||||
else
|
||||
return super.getUse(index);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,399 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ir.ssa;
|
||||
|
||||
import com.ibm.wala.cast.loader.*;
|
||||
import com.ibm.wala.cfg.*;
|
||||
import com.ibm.wala.ssa.*;
|
||||
import com.ibm.wala.ssa.SSAOptions.*;
|
||||
import com.ibm.wala.util.collections.IntStack;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.graph.DominanceFrontiers;
|
||||
import com.ibm.wala.util.graph.Graph;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
/**
|
||||
* Abstract core of traditional SSA conversion (Cytron et al.).
|
||||
*
|
||||
* This implementation is abstract in the sense that it is designed
|
||||
* to work over the instrutions and CFG of a Domo IR, but it is
|
||||
* abstract with respect to several integral portions of the
|
||||
* traditional algorithm:
|
||||
* <UL>
|
||||
* <LI> The notion of uses and defs of a given instruction.
|
||||
* <LI> Assignments (<def> := <use>) that are be copy-propagated away
|
||||
* <LI> Which values are constants---i.e. have no definition.
|
||||
* <LI> Any value numbers to be skipped during SSA construction
|
||||
* <LI> Special initialization and exit block processing.
|
||||
* </UL>
|
||||
*
|
||||
* @author Julian dolby (dolby@us.ibm.com)
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractSSAConversion {
|
||||
|
||||
protected abstract int getNumberOfDefs(SSAInstruction inst);
|
||||
|
||||
protected abstract int getDef(SSAInstruction inst, int index);
|
||||
|
||||
protected abstract int getNumberOfUses(SSAInstruction inst);
|
||||
|
||||
protected abstract int getUse(SSAInstruction inst, int index);
|
||||
|
||||
|
||||
protected abstract boolean isAssignInstruction(SSAInstruction inst);
|
||||
|
||||
|
||||
protected abstract int getMaxValueNumber();
|
||||
|
||||
protected abstract boolean isLive(SSACFG.BasicBlock Y, int V);
|
||||
|
||||
protected abstract boolean skip(int vn);
|
||||
|
||||
protected abstract boolean isConstant(int valueNumber);
|
||||
|
||||
|
||||
protected abstract int getNextNewValueNumber();
|
||||
|
||||
|
||||
protected abstract void initializeVariables();
|
||||
|
||||
protected abstract void repairExit();
|
||||
|
||||
|
||||
protected abstract void placeNewPhiAt(int value, SSACFG.BasicBlock Y);
|
||||
|
||||
protected abstract SSAPhiInstruction getPhi(SSACFG.BasicBlock B, int index);
|
||||
|
||||
protected abstract void setPhi(SSACFG.BasicBlock B, int index, SSAPhiInstruction inst);
|
||||
|
||||
protected abstract SSAPhiInstruction repairPhiDefs(SSAPhiInstruction phi, int[] newDefs);
|
||||
|
||||
protected abstract void repairPhiUse(SSACFG.BasicBlock BB, int phiIndex, int rvalIndex, int newRval);
|
||||
|
||||
|
||||
protected abstract void repairInstructionUses(SSAInstruction inst, int index, int[] newUses);
|
||||
|
||||
protected abstract void repairInstructionDefs(SSAInstruction inst, int index, int[] newDefs, int[] newUses);
|
||||
|
||||
|
||||
protected abstract void pushAssignment(SSAInstruction inst, int index, int newRhs);
|
||||
|
||||
protected abstract void popAssignment(SSAInstruction inst, int index);
|
||||
|
||||
|
||||
protected final SSACFG CFG;
|
||||
protected final DominanceFrontiers<IBasicBlock> DF;
|
||||
private final Graph dominatorTree;
|
||||
protected final int[] phiCounts;
|
||||
protected final SSAInstruction[] instructions;
|
||||
private final int flags[];
|
||||
protected final SymbolTable symbolTable;
|
||||
protected final DefaultValues defaultValues;
|
||||
|
||||
protected IntStack S[];
|
||||
protected int C[];
|
||||
protected int valueMap[];
|
||||
private Set[] assignmentMap;
|
||||
|
||||
protected AbstractSSAConversion(IR ir, SSAOptions options) {
|
||||
this.CFG = ir.getControlFlowGraph();
|
||||
this.DF = new DominanceFrontiers(ir.getControlFlowGraph(), ir.getControlFlowGraph().entry());
|
||||
this.dominatorTree = DF.dominatorTree();
|
||||
this.flags = new int[2 * ir.getControlFlowGraph().getNumberOfNodes()];
|
||||
this.instructions = ir.getInstructions();
|
||||
this.phiCounts = new int[CFG.getNumberOfNodes()];
|
||||
this.symbolTable = ir.getSymbolTable();
|
||||
this.defaultValues = options.getDefaultValues();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// top-level control
|
||||
//
|
||||
protected void perform() {
|
||||
init();
|
||||
placePhiNodes();
|
||||
renameVariables();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// initialization
|
||||
//
|
||||
protected void init() {
|
||||
this.S = new IntStack[getMaxValueNumber() + 1];
|
||||
this.C = new int[getMaxValueNumber() + 1];
|
||||
this.valueMap = new int[getMaxValueNumber() + 1];
|
||||
makeAssignmentMap();
|
||||
}
|
||||
|
||||
private void makeAssignmentMap() {
|
||||
this.assignmentMap = new Set[getMaxValueNumber() + 1];
|
||||
for (Iterator BBs = CFG.iterateNodes(); BBs.hasNext();) {
|
||||
SSACFG.BasicBlock BB = (SSACFG.BasicBlock) BBs.next();
|
||||
if (BB.getFirstInstructionIndex() >= 0) {
|
||||
for(Iterator IS = BB.iterateAllInstructions(); IS.hasNext(); ) {
|
||||
SSAInstruction inst = (SSAInstruction)IS.next();
|
||||
if (inst != null) {
|
||||
for (int j = 0; j < getNumberOfDefs(inst); j++) {
|
||||
addDefiningBlock(assignmentMap, BB, getDef(inst, j));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addDefiningBlock(Set[] A, SSACFG.BasicBlock BB, int i) {
|
||||
if (! skip(i)) {
|
||||
if (A[i] == null) {
|
||||
A[i] = new LinkedHashSet(2);
|
||||
}
|
||||
A[i].add(BB);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// place phi nodes phase of traditional algorithm
|
||||
//
|
||||
protected void placePhiNodes() {
|
||||
int IterCount = 0;
|
||||
|
||||
for (Iterator Xs = CFG.iterateNodes(); Xs.hasNext();) {
|
||||
SSACFG.BasicBlock X = (SSACFG.BasicBlock) Xs.next();
|
||||
setHasAlready(X, 0);
|
||||
setWork(X, 0);
|
||||
}
|
||||
|
||||
Set W = new LinkedHashSet();
|
||||
for (int V = 0; V < assignmentMap.length; V++) {
|
||||
|
||||
// some things (e.g. constants) have no defs at all
|
||||
if (assignmentMap[V] == null)
|
||||
continue;
|
||||
|
||||
// ignore values as requested
|
||||
if (skip(V))
|
||||
continue;
|
||||
|
||||
IterCount++;
|
||||
|
||||
for (Iterator XS = assignmentMap[V].iterator(); XS.hasNext();) {
|
||||
SSACFG.BasicBlock X = (SSACFG.BasicBlock) XS.next();
|
||||
setWork(X, IterCount);
|
||||
W.add(X);
|
||||
}
|
||||
|
||||
while (!W.isEmpty()) {
|
||||
SSACFG.BasicBlock X = (SSACFG.BasicBlock) W.iterator().next();
|
||||
W.remove(X);
|
||||
for (Iterator YS = DF.getDominanceFrontier(X); YS.hasNext();) {
|
||||
SSACFG.BasicBlock Y = (SSACFG.BasicBlock) YS.next();
|
||||
if (getHasAlready(Y) < IterCount) {
|
||||
if (isLive(Y, V)) {
|
||||
placeNewPhiAt(V, Y);
|
||||
phiCounts[Y.getGraphNodeId()]++;
|
||||
}
|
||||
setHasAlready(Y, IterCount);
|
||||
if (getWork(Y) < IterCount) {
|
||||
setWork(Y, IterCount);
|
||||
W.add(Y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int getWork(SSACFG.BasicBlock BB) {
|
||||
return flags[BB.getGraphNodeId() * 2 + 1];
|
||||
}
|
||||
|
||||
private void setWork(SSACFG.BasicBlock BB, int v) {
|
||||
flags[BB.getGraphNodeId() * 2 + 1] = v;
|
||||
}
|
||||
|
||||
private int getHasAlready(SSACFG.BasicBlock BB) {
|
||||
return flags[BB.getGraphNodeId() * 2];
|
||||
}
|
||||
|
||||
private void setHasAlready(SSACFG.BasicBlock BB, int v) {
|
||||
flags[BB.getGraphNodeId() * 2] = v;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// rename variables phase of traditional algorithm
|
||||
//
|
||||
private void renameVariables() {
|
||||
for (int V = 1; V <= getMaxValueNumber(); V++) {
|
||||
if (! skip(V)) {
|
||||
C[V] = 0;
|
||||
S[V] = new IntStack();
|
||||
}
|
||||
}
|
||||
|
||||
initializeVariables();
|
||||
|
||||
SEARCH((SSACFG.BasicBlock) CFG.entry());
|
||||
}
|
||||
|
||||
private void SEARCH(SSACFG.BasicBlock X) {
|
||||
int id = X.getGraphNodeId();
|
||||
int Xf = X.getFirstInstructionIndex();
|
||||
|
||||
// first loop
|
||||
for (int i = 0; i < phiCounts[id]; i++) {
|
||||
SSAPhiInstruction phi = getPhi(X, i);
|
||||
if (! skipRepair(phi, -1)) {
|
||||
setPhi(X, i, repairPhiDefs(phi, makeNewDefs(phi)));
|
||||
}
|
||||
}
|
||||
for (int i = Xf; i <= X.getLastInstructionIndex(); i++) {
|
||||
SSAInstruction inst = instructions[i];
|
||||
if (isAssignInstruction(inst)) {
|
||||
int lhs = getDef(inst, 0);
|
||||
int rhs = getUse(inst, 0);
|
||||
int newRhs = skip(rhs)? rhs: top(rhs);
|
||||
S[lhs].push( newRhs );
|
||||
|
||||
pushAssignment(inst, i, newRhs);
|
||||
|
||||
} else {
|
||||
if (! skipRepair(inst, i)) {
|
||||
int[] newUses = makeNewUses(inst);
|
||||
repairInstructionUses(inst, i, newUses);
|
||||
int[] newDefs = makeNewDefs(inst);
|
||||
repairInstructionDefs(inst, i, newDefs, newUses);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (X.isExitBlock()) {
|
||||
repairExit();
|
||||
}
|
||||
|
||||
for (Iterator YS = CFG.getSuccNodes(X); YS.hasNext();) {
|
||||
SSACFG.BasicBlock Y = (SSACFG.BasicBlock) YS.next();
|
||||
int Y_id = Y.getGraphNodeId();
|
||||
int j = com.ibm.wala.cast.ir.cfg.Util.whichPred(CFG, Y, X);
|
||||
for (int i = 0; i < phiCounts[Y_id]; i++) {
|
||||
SSAPhiInstruction phi = getPhi(Y, i);
|
||||
int oldUse = getUse(phi, j);
|
||||
int newUse = skip(oldUse) ? oldUse: top(oldUse);
|
||||
repairPhiUse(Y, i, j, newUse);
|
||||
}
|
||||
}
|
||||
|
||||
for (Iterator YS = dominatorTree.getSuccNodes(X); YS.hasNext();) {
|
||||
SEARCH((SSACFG.BasicBlock) YS.next());
|
||||
}
|
||||
|
||||
for (int i = 0; i < phiCounts[id]; i++) {
|
||||
SSAInstruction A = getPhi(X, i);
|
||||
for (int j = 0; j < getNumberOfDefs(A); j++) {
|
||||
if (! skip(getDef(A, j))) {
|
||||
S[valueMap[getDef(A, j)]].pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = Xf; i <= X.getLastInstructionIndex(); i++) {
|
||||
SSAInstruction A = instructions[i];
|
||||
if (isAssignInstruction(A)) {
|
||||
S[ getDef(A, 0) ].pop();
|
||||
popAssignment(A, i);
|
||||
} else if (A != null) {
|
||||
for (int j = 0; j < getNumberOfDefs(A); j++) {
|
||||
if (! skip(getDef(A, j))) {
|
||||
S[valueMap[getDef(A, j)]].pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int[] makeNewUses(SSAInstruction inst) {
|
||||
int[] newUses = new int[getNumberOfUses(inst)];
|
||||
for (int j = 0; j < getNumberOfUses(inst); j++) {
|
||||
newUses[j] =
|
||||
skip(getUse(inst, j))? getUse(inst, j): top(getUse(inst, j));
|
||||
}
|
||||
|
||||
return newUses;
|
||||
}
|
||||
|
||||
private int[] makeNewDefs(SSAInstruction inst) {
|
||||
int[] newDefs = new int[getNumberOfDefs(inst)];
|
||||
|
||||
for (int j = 0; j < getNumberOfDefs(inst); j++) {
|
||||
if (skip(getDef(inst, j))) {
|
||||
newDefs[j] = getDef(inst, j);
|
||||
} else {
|
||||
int ii = getNextNewValueNumber();
|
||||
|
||||
if (valueMap.length <= ii) {
|
||||
int[] nvm = new int[valueMap.length * 2 + ii + 1];
|
||||
System.arraycopy(valueMap, 0, nvm, 0, valueMap.length);
|
||||
valueMap = nvm;
|
||||
}
|
||||
|
||||
valueMap[ii] = getDef(inst, j);
|
||||
S[getDef(inst, j)].push(ii);
|
||||
newDefs[j] = ii;
|
||||
}
|
||||
}
|
||||
|
||||
return newDefs;
|
||||
}
|
||||
|
||||
protected boolean skipRepair(SSAInstruction inst, int index) {
|
||||
if (inst == null)
|
||||
return true;
|
||||
for(int i = 0; i < getNumberOfDefs(inst); i++)
|
||||
if (! skip(getDef(inst, i))) return false;
|
||||
for(int i = 0; i < getNumberOfUses(inst); i++)
|
||||
if (! skip(getUse(inst, i))) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void fail(int v) {
|
||||
Assertions._assert(
|
||||
isConstant(v) || !S[v].isEmpty(),
|
||||
"bad stack for " + v + " while SSA converting");
|
||||
}
|
||||
|
||||
protected boolean hasDefaultValue(int valueNumber) {
|
||||
return
|
||||
(defaultValues != null)
|
||||
&&
|
||||
(defaultValues.getDefaultValue(symbolTable, valueNumber) != -1);
|
||||
}
|
||||
|
||||
protected int getDefaultValue(int valueNumber) {
|
||||
return defaultValues.getDefaultValue(symbolTable, valueNumber);
|
||||
}
|
||||
|
||||
protected int top(int v) {
|
||||
if (! (isConstant(v) || !S[v].isEmpty())) {
|
||||
if (hasDefaultValue(v)) {
|
||||
return getDefaultValue(v);
|
||||
} else {
|
||||
fail(v);
|
||||
}
|
||||
}
|
||||
|
||||
return (isConstant(v)) ? v : S[v].peek();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ir.ssa;
|
||||
|
||||
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.ssa.SSAUnaryOpInstruction;
|
||||
import com.ibm.wala.ssa.SymbolTable;
|
||||
import com.ibm.wala.ssa.ValueDecorator;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
/**
|
||||
* @author Julian Dolby
|
||||
*
|
||||
* A simple assignment statement. Only appears in the IR before SSA conversion
|
||||
*
|
||||
*/
|
||||
public class AssignInstruction extends SSAUnaryOpInstruction {
|
||||
|
||||
/**
|
||||
* create the assignment v_result := v_val
|
||||
* @param result
|
||||
* @param val
|
||||
*/
|
||||
public AssignInstruction(int result, int val) {
|
||||
super(null, result, val);
|
||||
if (Assertions.verifyAssertions) {
|
||||
Assertions._assert(result != val);
|
||||
Assertions._assert(result != -1);
|
||||
Assertions._assert(val != -1);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.ibm.wala.ssa.SSAInstruction#copyForSSA(int[], int[])
|
||||
*/
|
||||
public SSAInstruction copyForSSA(int[] defs, int[] uses) {
|
||||
return new AssignInstruction(defs == null ? getDef(0) : defs[0], uses == null ? getUse(0) : uses[0]);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.ibm.wala.ssa.SSAInstruction#toString(com.ibm.wala.ssa.SymbolTable, com.ibm.wala.ssa.ValueDecorator)
|
||||
*/
|
||||
public String toString(SymbolTable symbolTable, ValueDecorator d) {
|
||||
return getValueString(symbolTable, d, result) + " := " + getValueString(symbolTable, d, val);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.ibm.wala.ssa.SSAInstruction#visit(com.ibm.wala.ssa.SSAInstruction.Visitor)
|
||||
*/
|
||||
public void visit(IVisitor v) {
|
||||
((AstPreInstructionVisitor) v).visitAssign(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public int getVal() {
|
||||
return getUse(0);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ir.ssa;
|
||||
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
|
||||
public abstract class AstAbstractInstructionVisitor
|
||||
extends SSAInstruction.Visitor
|
||||
implements AstInstructionVisitor
|
||||
{
|
||||
|
||||
public void visitAstLexicalRead(AstLexicalRead instruction) {
|
||||
|
||||
}
|
||||
|
||||
public void visitAstLexicalWrite(AstLexicalWrite instruction) {
|
||||
|
||||
}
|
||||
|
||||
public void visitAstGlobalRead(AstGlobalRead instruction) {
|
||||
|
||||
}
|
||||
|
||||
public void visitAstGlobalWrite(AstGlobalWrite instruction) {
|
||||
|
||||
}
|
||||
|
||||
public void visitNonExceptingThrow(NonExceptingThrowInstruction inst) {
|
||||
|
||||
}
|
||||
|
||||
public void visitAssert(AstAssertInstruction instruction) {
|
||||
|
||||
}
|
||||
|
||||
public void visitEachElementGet(EachElementGetInstruction inst) {
|
||||
|
||||
}
|
||||
|
||||
public void visitEachElementHasNext(EachElementHasNextInstruction inst) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ir.ssa;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.ssa.SymbolTable;
|
||||
import com.ibm.wala.ssa.ValueDecorator;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
public class AstAssertInstruction extends SSAInstruction {
|
||||
private final int value;
|
||||
private final boolean fromSpecification;
|
||||
|
||||
public AstAssertInstruction(int value, boolean fromSpecification) {
|
||||
this.value = value;
|
||||
this.fromSpecification = fromSpecification;
|
||||
}
|
||||
|
||||
public int getNumberOfUses() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public int getUse(int i) {
|
||||
Assertions._assert(i == 0);
|
||||
return value;
|
||||
}
|
||||
|
||||
public SSAInstruction copyForSSA(int[] defs, int[] uses) {
|
||||
return new AstAssertInstruction(uses==null? value: uses[0], fromSpecification);
|
||||
}
|
||||
|
||||
public String toString(SymbolTable symbolTable, ValueDecorator d) {
|
||||
return "assert " + getValueString(symbolTable, d, value) +
|
||||
" (fromSpec: " + fromSpecification + ")";
|
||||
}
|
||||
|
||||
public void visit(IVisitor v) {
|
||||
((AstInstructionVisitor)v).visitAssert(this);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return 2177*value;
|
||||
}
|
||||
|
||||
public Collection getExceptionTypes() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isFallThrough() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isFromSpecification() {
|
||||
return fromSpecification;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ir.ssa;
|
||||
|
||||
import com.ibm.wala.shrikeBT.BinaryOpInstruction;
|
||||
import com.ibm.wala.shrikeBT.UnaryOpInstruction;
|
||||
|
||||
public interface AstConstants {
|
||||
|
||||
public enum BinaryOp implements BinaryOpInstruction.IOperator {
|
||||
CONCAT, EQ, NE, LT, GE, GT, LE;
|
||||
|
||||
public String toString() {
|
||||
return super.toString().toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
public enum UnaryOp implements UnaryOpInstruction.IOperator {
|
||||
MINUS;
|
||||
|
||||
public String toString() {
|
||||
return super.toString().toLowerCase();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ir.ssa;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.ibm.wala.ssa.*;
|
||||
import com.ibm.wala.types.*;
|
||||
|
||||
public class AstGlobalRead extends SSAGetInstruction {
|
||||
|
||||
public AstGlobalRead(int lhs, FieldReference global) {
|
||||
super(lhs, global);
|
||||
}
|
||||
|
||||
public SSAInstruction copyForSSA(int[] defs, int[] uses) {
|
||||
return new AstGlobalRead((defs==null)? getDef(): defs[0], getDeclaredField());
|
||||
}
|
||||
|
||||
public String toString(SymbolTable symbolTable, ValueDecorator d) {
|
||||
return getValueString(symbolTable, d, getDef()) + " = global:" + getGlobalName();
|
||||
}
|
||||
|
||||
public void visit(IVisitor v) {
|
||||
if (v instanceof AstInstructionVisitor)
|
||||
((AstInstructionVisitor)v).visitAstGlobalRead(this);
|
||||
}
|
||||
|
||||
public boolean isFallThrough() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Collection getExceptionTypes() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getGlobalName() {
|
||||
return getDeclaredField().getName().toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ir.ssa;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.ibm.wala.ssa.*;
|
||||
import com.ibm.wala.types.*;
|
||||
|
||||
public class AstGlobalWrite extends SSAPutInstruction {
|
||||
|
||||
public AstGlobalWrite(FieldReference global, int rhs) {
|
||||
super(rhs, global);
|
||||
}
|
||||
|
||||
public SSAInstruction copyForSSA(int[] defs, int[] uses) {
|
||||
return new AstGlobalWrite(getDeclaredField(), (uses==null)? getVal(): uses[0]);
|
||||
}
|
||||
|
||||
public String toString(SymbolTable symbolTable, ValueDecorator d) {
|
||||
return "global:" + getGlobalName() + " = " + getValueString(symbolTable, d, getVal());
|
||||
}
|
||||
|
||||
public void visit(IVisitor v) {
|
||||
if (v instanceof AstInstructionVisitor)
|
||||
((AstInstructionVisitor)v).visitAstGlobalWrite(this);
|
||||
}
|
||||
|
||||
public boolean isFallThrough() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Collection getExceptionTypes() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getGlobalName() {
|
||||
return getDeclaredField().getName().toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ir.ssa;
|
||||
|
||||
|
||||
import com.ibm.wala.cast.loader.*;
|
||||
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
|
||||
import com.ibm.wala.cfg.*;
|
||||
import com.ibm.wala.classLoader.*;
|
||||
import com.ibm.wala.ipa.callgraph.*;
|
||||
import com.ibm.wala.ipa.cha.*;
|
||||
import com.ibm.wala.ssa.*;
|
||||
import com.ibm.wala.ssa.SSACFG.*;
|
||||
import com.ibm.wala.types.*;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.warnings.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class AstIRFactory implements IRFactory {
|
||||
private final boolean keepIR;
|
||||
private final Map keptIRs;
|
||||
|
||||
AstIRFactory(boolean keepIR) {
|
||||
this.keepIR = keepIR;
|
||||
this.keptIRs = (keepIR)? new HashMap(): null;
|
||||
}
|
||||
|
||||
public ControlFlowGraph makeCFG(final IMethod method,
|
||||
final Context context,
|
||||
final ClassHierarchy cha,
|
||||
final WarningSet warnings)
|
||||
{
|
||||
return ((AstMethod)method).getControlFlowGraph();
|
||||
}
|
||||
|
||||
public class AstIR extends IR {
|
||||
private final SSA2LocalMap localMap;
|
||||
|
||||
private void setCatchInstructions(SSACFG ssacfg, AbstractCFG oldcfg) {
|
||||
for (int i = 0; i < oldcfg.getNumberOfNodes(); i++)
|
||||
if (oldcfg.isCatchBlock(i)) {
|
||||
ExceptionHandlerBasicBlock B =
|
||||
(ExceptionHandlerBasicBlock) ssacfg.getNode(i);
|
||||
B.setCatchInstruction((SSAGetCaughtExceptionInstruction)
|
||||
getInstructions()[B.getFirstInstructionIndex()]);
|
||||
}
|
||||
}
|
||||
|
||||
private void setupCatchTypes(SSACFG cfg, TypeReference[][] catchTypes) {
|
||||
for (int i = 0; i < catchTypes.length; i++) {
|
||||
if (catchTypes[i] != null) {
|
||||
ExceptionHandlerBasicBlock bb =
|
||||
(ExceptionHandlerBasicBlock) cfg.getNode(i);
|
||||
for (int j = 0; j < catchTypes[i].length; j++) {
|
||||
bb.addCaughtExceptionType(catchTypes[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected SSA2LocalMap getLocalMap() {
|
||||
return localMap;
|
||||
}
|
||||
|
||||
protected String instructionPosition(int instructionIndex) {
|
||||
Position pos =
|
||||
((AstMethod)getMethod()).getSourcePosition(instructionIndex);
|
||||
if (pos == null) {
|
||||
return "";
|
||||
} else {
|
||||
return pos.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private AstIR(AstMethod method,
|
||||
SSAInstruction[] instructions,
|
||||
SymbolTable symbolTable,
|
||||
SSACFG cfg,
|
||||
SSAOptions options)
|
||||
{
|
||||
super(method, instructions, symbolTable, cfg, options);
|
||||
|
||||
setCatchInstructions(getControlFlowGraph(), method.cfg);
|
||||
|
||||
localMap = SSAConversion.convert(method, this, options);
|
||||
|
||||
setupCatchTypes(getControlFlowGraph(), method.catchTypes);
|
||||
|
||||
setupLocationMap();
|
||||
}
|
||||
}
|
||||
|
||||
public IR makeIR(final IMethod method,
|
||||
final Context context,
|
||||
final ClassHierarchy cha,
|
||||
final SSAOptions options,
|
||||
final WarningSet warnings)
|
||||
{
|
||||
Assertions._assert(method instanceof AstMethod, method.toString());
|
||||
if (keepIR) {
|
||||
if (keptIRs.containsKey(method)) {
|
||||
return (IR) keptIRs.get(method);
|
||||
}
|
||||
}
|
||||
|
||||
AbstractCFG oldCfg = ((AstMethod)method).cfg;
|
||||
SSAInstruction[] instrs = (SSAInstruction[])oldCfg.getInstructions();
|
||||
|
||||
IR newIR =
|
||||
new AstIR((AstMethod)method,
|
||||
instrs,
|
||||
((AstMethod)method).symtab,
|
||||
new SSACFG(method, oldCfg, instrs, warnings),
|
||||
options);
|
||||
|
||||
if (keepIR) {
|
||||
keptIRs.put(method, newIR);
|
||||
}
|
||||
|
||||
return newIR;
|
||||
}
|
||||
|
||||
public static IRFactory makeDefaultFactory(final boolean keepAstIRs) {
|
||||
return new DefaultIRFactory() {
|
||||
private final AstIRFactory astFactory = new AstIRFactory(keepAstIRs);
|
||||
|
||||
public IR makeIR(IMethod method,
|
||||
Context context,
|
||||
ClassHierarchy cha,
|
||||
SSAOptions options,
|
||||
WarningSet warnings)
|
||||
{
|
||||
if (method instanceof AstMethod) {
|
||||
return astFactory.makeIR(method, context, cha, options, warnings);
|
||||
} else {
|
||||
return super.makeIR(method, context, cha, options, warnings);
|
||||
}
|
||||
}
|
||||
|
||||
public ControlFlowGraph makeCFG(IMethod method,
|
||||
Context context,
|
||||
ClassHierarchy cha,
|
||||
WarningSet warnings)
|
||||
{
|
||||
if (method instanceof AstMethod) {
|
||||
return astFactory.makeCFG(method, context, cha, warnings);
|
||||
} else {
|
||||
return super.makeCFG(method, context, cha, warnings);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ir.ssa;
|
||||
|
||||
import com.ibm.wala.ssa.*;
|
||||
|
||||
public interface AstInstructionVisitor extends SSAInstruction.IVisitor {
|
||||
|
||||
public void visitAstLexicalRead(AstLexicalRead instruction);
|
||||
|
||||
public void visitAstLexicalWrite(AstLexicalWrite instruction);
|
||||
|
||||
public void visitAstGlobalRead(AstGlobalRead instruction);
|
||||
|
||||
public void visitAstGlobalWrite(AstGlobalWrite instruction);
|
||||
|
||||
public void visitNonExceptingThrow(NonExceptingThrowInstruction inst);
|
||||
|
||||
public void visitAssert(AstAssertInstruction instruction);
|
||||
|
||||
public void visitEachElementGet(EachElementGetInstruction inst);
|
||||
|
||||
public void visitEachElementHasNext(EachElementHasNextInstruction inst);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ir.ssa;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
|
||||
public abstract class AstLexicalAccess extends SSAInstruction {
|
||||
|
||||
public static class Access {
|
||||
public final String variableName;
|
||||
public final String variableDefiner;
|
||||
public final int valueNumber;
|
||||
|
||||
public Access(String name, String definer, int lhsOrRhs) {
|
||||
variableName = name;
|
||||
variableDefiner = definer;
|
||||
valueNumber = lhsOrRhs;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return variableName.hashCode() * valueNumber;
|
||||
}
|
||||
|
||||
public boolean equals(Object other) {
|
||||
return (other instanceof Access) &&
|
||||
variableName.equals( ((Access)other).variableName ) &&
|
||||
valueNumber == ((Access)other).valueNumber &&
|
||||
( variableDefiner == null?
|
||||
((Access)other).variableDefiner == null:
|
||||
variableDefiner.equals(((Access)other).variableDefiner) );
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Access(" + variableName + "@" + variableDefiner + ":" + valueNumber + ")";
|
||||
}
|
||||
}
|
||||
|
||||
private Access[] accesses;
|
||||
|
||||
AstLexicalAccess(Access[] accesses) {
|
||||
setAccesses( accesses );
|
||||
}
|
||||
|
||||
public void setAccesses(Access[] accesses) {
|
||||
this.accesses = accesses;
|
||||
}
|
||||
|
||||
public Access[] getAccesses() {
|
||||
return accesses;
|
||||
}
|
||||
|
||||
public Access getAccess(int i) {
|
||||
return accesses[i];
|
||||
}
|
||||
|
||||
public int getAccessCount() {
|
||||
return accesses.length;
|
||||
}
|
||||
|
||||
public boolean isFallThrough() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Collection getExceptionTypes() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int v = 1;
|
||||
for(int i = 0; i < accesses.length; i++)
|
||||
v *= accesses[i].variableName.hashCode();
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ir.ssa;
|
||||
|
||||
|
||||
import com.ibm.wala.ssa.*;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
public class AstLexicalRead extends AstLexicalAccess {
|
||||
|
||||
public AstLexicalRead(Access[] accesses) {
|
||||
super(accesses);
|
||||
}
|
||||
|
||||
public AstLexicalRead(Access access) {
|
||||
this(new Access[]{ access });
|
||||
}
|
||||
|
||||
public AstLexicalRead(int lhs, String definer, String globalName) {
|
||||
this(new Access(globalName, definer, lhs));
|
||||
}
|
||||
|
||||
public SSAInstruction copyForSSA(int[] defs, int[] uses) {
|
||||
if (defs==null) {
|
||||
return new AstLexicalRead( getAccesses() );
|
||||
} else {
|
||||
Access[] accesses = new Access[ getAccessCount() ];
|
||||
for(int i = 0; i < accesses.length; i++) {
|
||||
Access oldAccess = getAccess(i);
|
||||
accesses[i] = new Access(oldAccess.variableName, oldAccess.variableDefiner, defs[i]);
|
||||
}
|
||||
|
||||
return new AstLexicalRead(accesses);
|
||||
}
|
||||
}
|
||||
|
||||
public int getNumberOfDefs() { return getAccessCount(); }
|
||||
|
||||
public int getDef(int i) { return getAccess(i).valueNumber; }
|
||||
|
||||
public int getNumberOfUses() { return 0; }
|
||||
|
||||
public int getUse(int i) { throw new UnsupportedOperationException(); }
|
||||
|
||||
public String toString(SymbolTable symbolTable, ValueDecorator d) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for(int i = 0; i < getAccessCount(); i++) {
|
||||
Access A = getAccess(i);
|
||||
if (i != 0) sb.append(", ");
|
||||
sb.append(getValueString(symbolTable, d, A.valueNumber));
|
||||
sb.append(" = lexical:");
|
||||
sb.append(A.variableName);
|
||||
sb.append("@");
|
||||
sb.append(A.variableDefiner);
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public void visit(IVisitor v) {
|
||||
Assertions._assert(v instanceof AstInstructionVisitor);
|
||||
((AstInstructionVisitor)v).visitAstLexicalRead(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ir.ssa;
|
||||
|
||||
|
||||
import com.ibm.wala.ssa.*;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
public class AstLexicalWrite extends AstLexicalAccess {
|
||||
|
||||
public AstLexicalWrite(String definer, String globalName, int rhs) {
|
||||
this(new Access(globalName, definer, rhs));
|
||||
}
|
||||
|
||||
public AstLexicalWrite(Access access) {
|
||||
this(new Access[]{access});
|
||||
}
|
||||
|
||||
public AstLexicalWrite(Access[] accesses) {
|
||||
super(accesses);
|
||||
}
|
||||
|
||||
public SSAInstruction copyForSSA(int[] defs, int[] uses) {
|
||||
if (uses==null) {
|
||||
return new AstLexicalWrite( getAccesses() );
|
||||
} else {
|
||||
Access[] accesses = new Access[ getAccessCount() ];
|
||||
for(int i = 0; i < accesses.length; i++) {
|
||||
Access oldAccess = getAccess(i);
|
||||
accesses[i] = new Access(oldAccess.variableName, oldAccess.variableDefiner, uses[i]);
|
||||
}
|
||||
|
||||
return new AstLexicalWrite(accesses);
|
||||
}
|
||||
}
|
||||
|
||||
public int getNumberOfUses() { return getAccessCount(); }
|
||||
|
||||
public int getUse(int i) { return getAccess(i).valueNumber; }
|
||||
|
||||
public int getNumberOfDefs() { return 0; }
|
||||
|
||||
public int getDef(int i) { throw new UnsupportedOperationException(); }
|
||||
|
||||
public String toString(SymbolTable symbolTable, ValueDecorator d) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for(int i = 0; i < getAccessCount(); i++) {
|
||||
Access A = getAccess(i);
|
||||
if (i != 0) sb.append(", ");
|
||||
sb.append("lexical:");
|
||||
sb.append(A.variableName);
|
||||
sb.append("@");
|
||||
sb.append(A.variableDefiner);
|
||||
sb.append(" = ");
|
||||
sb.append(getValueString(symbolTable, d, A.valueNumber));
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public void visit(IVisitor v) {
|
||||
Assertions._assert(v instanceof AstInstructionVisitor);
|
||||
((AstInstructionVisitor)v).visitAstLexicalWrite(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ir.ssa;
|
||||
|
||||
public interface AstPreInstructionVisitor extends AstInstructionVisitor {
|
||||
|
||||
public void visitAssign(AssignInstruction inst);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ir.ssa;
|
||||
|
||||
import com.ibm.wala.ssa.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class EachElementGetInstruction extends SSAAbstractUnaryInstruction {
|
||||
|
||||
public EachElementGetInstruction(int lValue, int objectRef) {
|
||||
super(lValue, objectRef);
|
||||
}
|
||||
|
||||
public SSAInstruction copyForSSA(int[] defs, int[] uses) {
|
||||
return new EachElementGetInstruction(
|
||||
(defs==null)? getDef(0): defs[0],
|
||||
(uses == null)? getUse(0): uses[0]);
|
||||
}
|
||||
|
||||
public String toString(SymbolTable symbolTable, ValueDecorator d) {
|
||||
return getValueString(symbolTable, d, getDef(0)) + " = a property name of " + getValueString(symbolTable, d, getUse(0));
|
||||
}
|
||||
|
||||
public void visit(IVisitor v) {
|
||||
((AstInstructionVisitor) v).visitEachElementGet(this);
|
||||
}
|
||||
|
||||
public Collection getExceptionTypes() {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ir.ssa;
|
||||
|
||||
import com.ibm.wala.ssa.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class EachElementHasNextInstruction extends SSAAbstractUnaryInstruction {
|
||||
|
||||
public EachElementHasNextInstruction(int lValue, int objectRef) {
|
||||
super(lValue, objectRef);
|
||||
}
|
||||
|
||||
public SSAInstruction copyForSSA(int[] defs, int[] uses) {
|
||||
return new EachElementHasNextInstruction(
|
||||
(defs==null)? getDef(0): defs[0],
|
||||
(uses == null)? getUse(0): uses[0]);
|
||||
}
|
||||
|
||||
public String toString(SymbolTable symbolTable, ValueDecorator d) {
|
||||
return getValueString(symbolTable, d, getDef(0)) + " = has next property: " + getValueString(symbolTable, d, getUse(0));
|
||||
}
|
||||
|
||||
public void visit(IVisitor v) {
|
||||
((AstInstructionVisitor) v).visitEachElementHasNext(this);
|
||||
}
|
||||
|
||||
public Collection getExceptionTypes() {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ir.ssa;
|
||||
|
||||
import com.ibm.wala.cast.ir.ssa.AstLexicalAccess.Access;
|
||||
import com.ibm.wala.classLoader.*;
|
||||
import com.ibm.wala.ssa.*;
|
||||
|
||||
public abstract class FixedParametersLexicalInvokeInstruction
|
||||
extends AbstractLexicalInvoke
|
||||
{
|
||||
|
||||
/**
|
||||
* The value numbers of the arguments passed to the call. For non-static methods,
|
||||
* params[0] == this. If params == null, this should be a static method with
|
||||
* no parameters.
|
||||
*/
|
||||
private final int[] params;
|
||||
|
||||
public FixedParametersLexicalInvokeInstruction(int result, int[] params, int exception, CallSiteReference site) {
|
||||
super(result, exception, site);
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor InvokeInstruction. This case for void return values
|
||||
* @param i
|
||||
* @param params
|
||||
*/
|
||||
public FixedParametersLexicalInvokeInstruction(int[] params, int exception, CallSiteReference site) {
|
||||
this(-1, params, exception, site);
|
||||
}
|
||||
|
||||
protected FixedParametersLexicalInvokeInstruction(int result, int[] params, int exception, CallSiteReference site, Access[] lexicalReads, Access[] lexicalWrites) {
|
||||
super(result, exception, site, lexicalReads, lexicalWrites);
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
protected abstract SSAInstruction copyInstruction(int result, int[] params, int exception, Access[] lexicalReads, Access[] lexicalWrites);
|
||||
|
||||
public SSAInstruction copyForSSA(int[] defs, int[] uses) {
|
||||
int newParams[] = params;
|
||||
Access[] reads = lexicalReads;
|
||||
|
||||
if (uses != null) {
|
||||
int i = 0;
|
||||
|
||||
newParams = new int[ params.length ];
|
||||
for(int j = 0; j < newParams.length; j++)
|
||||
newParams[j] = uses[i++];
|
||||
|
||||
if (lexicalReads != null) {
|
||||
reads = new Access[ lexicalReads.length ];
|
||||
for(int j = 0; j < reads.length; j++)
|
||||
reads[j] = new Access(lexicalReads[j].variableName, lexicalReads[j].variableDefiner, uses[i++]);
|
||||
}
|
||||
}
|
||||
|
||||
int newLval = result;
|
||||
int newExp = exception;
|
||||
Access[] writes = lexicalWrites;
|
||||
|
||||
if (defs != null) {
|
||||
int i = 0;
|
||||
if (result != -1) newLval = defs[i++];
|
||||
newExp = defs[i++];
|
||||
|
||||
if (lexicalWrites != null) {
|
||||
writes = new Access[ lexicalWrites.length ];
|
||||
for(int j = 0; j < writes.length; j++)
|
||||
writes[j] = new Access(lexicalWrites[j].variableName, lexicalWrites[j].variableDefiner, defs[i++]);
|
||||
}
|
||||
}
|
||||
|
||||
return copyInstruction(newLval, newParams, newExp, reads, writes);
|
||||
}
|
||||
|
||||
public int getNumberOfParameters() {
|
||||
if (params == null) {
|
||||
return 0;
|
||||
} else {
|
||||
return params.length;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.ibm.wala.ssa.Instruction#getUse(int)
|
||||
*/
|
||||
public int getUse(int j) {
|
||||
if (j < getNumberOfParameters())
|
||||
return params[j];
|
||||
else {
|
||||
return super.getUse(j);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ir.ssa;
|
||||
|
||||
import com.ibm.wala.ssa.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class NonExceptingThrowInstruction extends SSAAbstractThrowInstruction {
|
||||
|
||||
public NonExceptingThrowInstruction(int exception) {
|
||||
super( exception);
|
||||
}
|
||||
|
||||
public SSAInstruction copyForSSA(int[] defs, int[] uses) {
|
||||
return new NonExceptingThrowInstruction(uses==null? getException(): uses[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.ibm.wala.ssa.SSAInstruction#visit(Visitor)
|
||||
*/
|
||||
public void visit(IVisitor v) {
|
||||
((AstInstructionVisitor)v).visitNonExceptingThrow(this);
|
||||
}
|
||||
|
||||
public Collection getExceptionTypes() {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,602 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ir.ssa;
|
||||
|
||||
import com.ibm.wala.cast.ir.ssa.AstIRFactory.AstIR;
|
||||
import com.ibm.wala.cast.ir.ssa.analysis.LiveAnalysis;
|
||||
import com.ibm.wala.cast.loader.*;
|
||||
import com.ibm.wala.cast.loader.AstMethod.*;
|
||||
import com.ibm.wala.shrikeBT.IInstruction;
|
||||
import com.ibm.wala.ssa.*;
|
||||
import com.ibm.wala.ssa.IR.SSA2LocalMap;
|
||||
import com.ibm.wala.util.collections.IntStack;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.debug.Trace;
|
||||
import com.ibm.wala.util.graph.Graph;
|
||||
import com.ibm.wala.util.intset.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Julian Dolby
|
||||
*
|
||||
* Standard SSA conversion for local value numbers.
|
||||
*/
|
||||
public class SSAConversion extends AbstractSSAConversion {
|
||||
|
||||
public static boolean DEBUG = false;
|
||||
public static boolean DEBUG_UNDO = true;
|
||||
public static boolean DEBUG_NAMES = true;
|
||||
public static boolean DUMP = false;
|
||||
|
||||
private final AstIR ir;
|
||||
|
||||
private int nextSSAValue;
|
||||
|
||||
private final DebuggingInformation debugInfo;
|
||||
|
||||
private final LexicalInformation lexicalInfo;
|
||||
|
||||
private final SymbolTable symtab;
|
||||
|
||||
private final LiveAnalysis.Result liveness;
|
||||
|
||||
private SSA2LocalMap computedLocalMap;
|
||||
|
||||
//
|
||||
// Copy propagation history
|
||||
//
|
||||
|
||||
private final Map copyPropagationMap;
|
||||
private final Stack R[];
|
||||
|
||||
private static class UseRecord {
|
||||
final int instructionIndex;
|
||||
final int useNumber;
|
||||
|
||||
private UseRecord(int instructionIndex, int useNumber) {
|
||||
this.useNumber = useNumber;
|
||||
this.instructionIndex = instructionIndex;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return useNumber*instructionIndex;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return (o instanceof UseRecord) &&
|
||||
instructionIndex==((UseRecord)o).instructionIndex &&
|
||||
useNumber==((UseRecord)o).useNumber;
|
||||
}
|
||||
}
|
||||
|
||||
private class PhiUseRecord {
|
||||
final int BBnumber;
|
||||
final int phiNumber;
|
||||
final int useNumber;
|
||||
|
||||
private PhiUseRecord(int BBnumber, int phiNumber, int useNumber) {
|
||||
this.BBnumber = BBnumber;
|
||||
this.phiNumber = phiNumber;
|
||||
this.useNumber = useNumber;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return phiNumber*BBnumber*useNumber;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return (o instanceof PhiUseRecord) &&
|
||||
BBnumber==((PhiUseRecord)o).BBnumber &&
|
||||
phiNumber==((PhiUseRecord)o).phiNumber &&
|
||||
useNumber==((PhiUseRecord)o).useNumber;
|
||||
}
|
||||
}
|
||||
|
||||
private class CopyPropagationRecord {
|
||||
final int lhs;
|
||||
final int rhs;
|
||||
final int instructionIndex;
|
||||
final Set renamedUses = new HashSet(2);
|
||||
private final Set childRecords = new HashSet(1);
|
||||
|
||||
public int hashCode() {
|
||||
return instructionIndex;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return (o instanceof CopyPropagationRecord) &&
|
||||
instructionIndex==((CopyPropagationRecord)o).instructionIndex;
|
||||
}
|
||||
|
||||
private CopyPropagationRecord(int instructionIndex, int lhs, int rhs) {
|
||||
if (DEBUG_UNDO) Trace.println("new copy record for instruction #" + instructionIndex + ", rhs value is " + rhs);
|
||||
this.lhs = lhs;
|
||||
this.rhs = rhs;
|
||||
this.instructionIndex = instructionIndex;
|
||||
}
|
||||
|
||||
private void addChild(CopyPropagationRecord rec) {
|
||||
if (DEBUG_UNDO) Trace.println("("+rec.instructionIndex+","+rec.rhs+") is a child of ("+instructionIndex+","+rhs+")");
|
||||
childRecords.add(rec);
|
||||
}
|
||||
|
||||
private void addUse(int instructionIndex, int use) {
|
||||
if (DEBUG_UNDO) Trace.println("propagated use of (" + this.instructionIndex + "," + this.rhs + ") at use #" + use + " of instruction #" + instructionIndex);
|
||||
UseRecord rec = new UseRecord(instructionIndex, use);
|
||||
copyPropagationMap.put(rec, this);
|
||||
renamedUses.add( rec );
|
||||
}
|
||||
|
||||
private void addUse(int BB, int phiNumber, int use) {
|
||||
PhiUseRecord rec = new PhiUseRecord(BB, phiNumber, use);
|
||||
copyPropagationMap.put(rec, this);
|
||||
renamedUses.add( rec );
|
||||
}
|
||||
|
||||
private SSAInstruction undo(SSAInstruction inst, int use, int val) {
|
||||
int c = getNumberOfUses(inst);
|
||||
int[] newUses = new int[ c ];
|
||||
for(int i = 0; i < c; i++) {
|
||||
if (i == use)
|
||||
newUses[i] = val;
|
||||
else
|
||||
newUses[i] = getUse(inst, i);
|
||||
}
|
||||
|
||||
return inst.copyForSSA(null, newUses);
|
||||
}
|
||||
|
||||
private void undo(int rhs) {
|
||||
int lhs = symtab.newSymbol();
|
||||
|
||||
instructions[ instructionIndex ] = new AssignInstruction(lhs, rhs);
|
||||
|
||||
if (DEBUG_UNDO) Trace.println("recreating assignment at " + instructionIndex + " as " + lhs + " = " + rhs);
|
||||
|
||||
for(Iterator uses = renamedUses.iterator(); uses.hasNext(); ) {
|
||||
Object x = uses.next();
|
||||
if (x instanceof UseRecord) {
|
||||
UseRecord use = (UseRecord)x;
|
||||
int idx = use.instructionIndex;
|
||||
SSAInstruction inst = instructions[ idx ];
|
||||
|
||||
if (DEBUG_UNDO) Trace.println("Changing use #" + use.useNumber + " of inst #" + idx + " to val " + lhs);
|
||||
|
||||
if (use.useNumber >= 0) {
|
||||
instructions[idx] = undo(inst, use.useNumber, lhs);
|
||||
} else {
|
||||
lexicalInfo.getExposedUses(idx)[-use.useNumber - 1] = lhs;
|
||||
}
|
||||
copyPropagationMap.remove( use );
|
||||
} else {
|
||||
PhiUseRecord use = (PhiUseRecord)x;
|
||||
int bb = use.BBnumber;
|
||||
int phi = use.phiNumber;
|
||||
SSACFG.BasicBlock BB = (SSACFG.BasicBlock)CFG.getNode(bb);
|
||||
BB.addPhiForLocal(phi, (SSAPhiInstruction)undo(BB.getPhiForLocal(phi), use.useNumber, lhs));
|
||||
copyPropagationMap.remove( use );
|
||||
}
|
||||
}
|
||||
|
||||
for(Iterator cs = childRecords.iterator(); cs.hasNext(); ) {
|
||||
((CopyPropagationRecord)cs.next()).undo( lhs );
|
||||
}
|
||||
}
|
||||
|
||||
public void undo() {
|
||||
undo( this.rhs );
|
||||
copyPropagationMap.remove( new UseRecord(instructionIndex, rhs) );
|
||||
}
|
||||
}
|
||||
|
||||
public static void undoCopyPropagation(AstIR ir, int instruction, int use) {
|
||||
SSAInformation info = (SSAInformation) ir.getLocalMap();
|
||||
info.undoCopyPropagation(instruction, use);
|
||||
}
|
||||
|
||||
public static void copyUse(AstIR ir, int fromInst, int fromUse, int toInst, int toUse) {
|
||||
SSAInformation info = (SSAInformation) ir.getLocalMap();
|
||||
info.copyUse(fromInst, fromUse, toInst, toUse);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// SSA2LocalMap implementation for SSAConversion
|
||||
//
|
||||
private class SSAInformation implements com.ibm.wala.ssa.IR.SSA2LocalMap {
|
||||
|
||||
public String[] getLocalNames(int pc, int vn) {
|
||||
int v = skip(vn)||vn>=valueMap.length? vn: valueMap[vn];
|
||||
String[][] namesData = debugInfo.getSourceNamesForValues();
|
||||
if (namesData == null || namesData.length <= v)
|
||||
return new String[0];
|
||||
else
|
||||
return namesData[v];
|
||||
}
|
||||
|
||||
private void undoCopyPropagation(int instructionIndex, int useNumber) {
|
||||
|
||||
if (DEBUG_UNDO)
|
||||
Trace.println("undoing for use #" + useNumber + " of inst #" + instructionIndex);
|
||||
|
||||
UseRecord use = new UseRecord(instructionIndex, useNumber);
|
||||
if (copyPropagationMap.containsKey(use)) {
|
||||
((CopyPropagationRecord)copyPropagationMap.get(use)).undo();
|
||||
}
|
||||
}
|
||||
|
||||
private void copyUse(int fromInst, int fromUse, int toInst, int toUse) {
|
||||
UseRecord use = new UseRecord(fromInst, fromUse);
|
||||
if (copyPropagationMap.containsKey(use)) {
|
||||
((CopyPropagationRecord)copyPropagationMap.get(use)).addUse(toInst, toUse);
|
||||
}
|
||||
}
|
||||
|
||||
private Map getCopyHistory() {
|
||||
return copyPropagationMap;
|
||||
}
|
||||
}
|
||||
|
||||
private CopyPropagationRecord topR(int v) {
|
||||
if (R[v] != null && !R[v].isEmpty()) {
|
||||
CopyPropagationRecord rec = (CopyPropagationRecord)R[v].peek();
|
||||
if (top(v) == rec.rhs) {
|
||||
return rec;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// implementation of AbstractSSAConversion hooks
|
||||
//
|
||||
|
||||
protected int getNumberOfDefs(SSAInstruction inst) {
|
||||
return inst.getNumberOfDefs();
|
||||
}
|
||||
|
||||
protected int getDef(SSAInstruction inst, int index) {
|
||||
return inst.getDef(index);
|
||||
}
|
||||
|
||||
protected int getNumberOfUses(SSAInstruction inst) {
|
||||
return inst.getNumberOfUses();
|
||||
}
|
||||
|
||||
protected int getUse(SSAInstruction inst, int index) {
|
||||
return inst.getUse(index);
|
||||
}
|
||||
|
||||
protected boolean isAssignInstruction(SSAInstruction inst) {
|
||||
return inst instanceof AssignInstruction;
|
||||
}
|
||||
|
||||
protected int getMaxValueNumber() {
|
||||
return symtab.getMaxValueNumber();
|
||||
}
|
||||
|
||||
protected boolean skip(int vn) {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean isLive(SSACFG.BasicBlock Y, int V) {
|
||||
return (liveness.isLiveEntry(Y, V));
|
||||
}
|
||||
|
||||
private void addPhi(SSACFG.BasicBlock BB, SSAPhiInstruction phi) {
|
||||
BB.addPhiForLocal(phiCounts[BB.getGraphNodeId()], phi);
|
||||
}
|
||||
|
||||
protected void placeNewPhiAt(int value, SSACFG.BasicBlock Y) {
|
||||
int[] params = new int[CFG.getPredNodeCount(Y)];
|
||||
for (int i = 0; i < params.length; i++)
|
||||
params[i] = value;
|
||||
|
||||
SSAPhiInstruction phi = new SSAPhiInstruction(value, params);
|
||||
|
||||
if (DEBUG)
|
||||
Trace.println("Placing " + phi + " at " + Y);
|
||||
|
||||
addPhi(Y, phi);
|
||||
}
|
||||
|
||||
protected SSAPhiInstruction getPhi(SSACFG.BasicBlock B, int index) {
|
||||
return B.getPhiForLocal(index);
|
||||
}
|
||||
|
||||
protected void setPhi(SSACFG.BasicBlock B, int index, SSAPhiInstruction inst) {
|
||||
B.addPhiForLocal(index, inst);
|
||||
}
|
||||
|
||||
protected SSAPhiInstruction repairPhiDefs(SSAPhiInstruction phi, int[] newDefs) {
|
||||
return (SSAPhiInstruction)phi.copyForSSA(newDefs, null);
|
||||
}
|
||||
|
||||
protected void repairPhiUse(SSACFG.BasicBlock BB, int phiIndex, int rvalIndex, int newRval) {
|
||||
SSAPhiInstruction phi = getPhi(BB, phiIndex);
|
||||
|
||||
int[] newUses = new int[getNumberOfUses(phi)];
|
||||
for (int v = 0; v < newUses.length; v++) {
|
||||
int oldUse = getUse(phi, v);
|
||||
int newUse = (v==rvalIndex)? newRval: oldUse;
|
||||
newUses[v] = newUse;
|
||||
|
||||
if (v==rvalIndex && topR(oldUse) != null) {
|
||||
topR(oldUse).addUse(BB.getGraphNodeId(), phiIndex, v);
|
||||
}
|
||||
}
|
||||
|
||||
phi.setValues(newUses);
|
||||
}
|
||||
|
||||
protected void pushAssignment(SSAInstruction inst, int index, int newRhs) {
|
||||
int lhs = getDef(inst, 0);
|
||||
int rhs = getUse(inst, 0);
|
||||
|
||||
copyNames(rhs, lhs);
|
||||
|
||||
CopyPropagationRecord rec = new CopyPropagationRecord(index, lhs, newRhs);
|
||||
R[lhs].push( rec );
|
||||
if (topR(rhs) != null) {
|
||||
topR(rhs).addChild( rec );
|
||||
}
|
||||
}
|
||||
|
||||
protected void repairInstructionUses(SSAInstruction inst, int index, int[] newUses){
|
||||
for (int j = 0; j < getNumberOfUses(inst); j++) {
|
||||
if (topR(getUse(inst, j)) != null) {
|
||||
topR(getUse(inst, j)).addUse(index, j);
|
||||
}
|
||||
}
|
||||
|
||||
int[] lexicalUses = lexicalInfo.getExposedUses(index);
|
||||
if (lexicalUses != null) {
|
||||
for(int j = 0; j < lexicalUses.length; j++) {
|
||||
int lexicalUse = lexicalUses[j];
|
||||
if (lexicalUse != -1 && !skip(lexicalUse)) {
|
||||
if (S[lexicalUse].isEmpty()) {
|
||||
lexicalUses[j] = -1;
|
||||
} else {
|
||||
int newUse = top(lexicalUse);
|
||||
|
||||
lexicalUses[j] = newUse;
|
||||
|
||||
if (topR(lexicalUse) != null) {
|
||||
topR(lexicalUse).addUse(index, -j - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void repairInstructionDefs(SSAInstruction inst, int index, int[] newDefs, int[] newUses) {
|
||||
instructions[index] = inst.copyForSSA(newDefs, newUses);
|
||||
}
|
||||
|
||||
protected void popAssignment(SSAInstruction inst, int index) {
|
||||
instructions[index] = null;
|
||||
}
|
||||
|
||||
protected boolean isConstant(int valueNumber) {
|
||||
return symtab.isConstant(valueNumber);
|
||||
}
|
||||
|
||||
protected boolean skipRepair(SSAInstruction inst, int index) {
|
||||
if (! super.skipRepair(inst, index)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (index == -1) return true;
|
||||
|
||||
int[] lexicalUses = lexicalInfo.getExposedUses(index);
|
||||
if (lexicalUses != null) {
|
||||
for(int j = 0; j < lexicalUses.length; j++) {
|
||||
if (! skip(lexicalUses[j])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ir
|
||||
* @param options
|
||||
*/
|
||||
private SSAConversion(AstMethod M, AstIR ir, SSAOptions options) {
|
||||
super(ir, options);
|
||||
this.copyPropagationMap =
|
||||
(ir.getLocalMap() instanceof SSAInformation)?
|
||||
((SSAInformation)ir.getLocalMap()).getCopyHistory():
|
||||
new HashMap();
|
||||
|
||||
this.ir = ir;
|
||||
this.debugInfo = M.debugInfo;
|
||||
this.lexicalInfo = M.lexicalInfo;
|
||||
this.symtab = ir.getSymbolTable();
|
||||
this.R = new Stack[ir.getSymbolTable().getMaxValueNumber() + 1];
|
||||
|
||||
for(int i = 0; i < CFG.getNumberOfNodes(); i++) {
|
||||
SSACFG.BasicBlock bb = (SSACFG.BasicBlock) CFG.getNode(i);
|
||||
if (bb.hasPhi()) {
|
||||
int n = 0;
|
||||
for(Iterator X = bb.iteratePhis(); X.hasNext(); n++) X.next();
|
||||
phiCounts[i] = n;
|
||||
}
|
||||
}
|
||||
|
||||
this.nextSSAValue = ir.getNumberOfParameters()+1;
|
||||
|
||||
int[] exitLive = lexicalInfo.getExitExposedUses();
|
||||
BitVector v = new BitVector();
|
||||
if (exitLive != null)
|
||||
for(int i = 0; i < exitLive.length; i++)
|
||||
v.set( exitLive[i] );
|
||||
this.liveness = LiveAnalysis.perform(CFG, symtab, v);
|
||||
|
||||
if (DEBUG) {
|
||||
Trace.println(liveness);
|
||||
}
|
||||
}
|
||||
|
||||
protected int getNextNewValueNumber() {
|
||||
while (symtab.isConstant(nextSSAValue) || skip(nextSSAValue))
|
||||
++nextSSAValue;
|
||||
symtab.ensureSymbol( nextSSAValue );
|
||||
return nextSSAValue++;
|
||||
}
|
||||
|
||||
private void copyNames(int to, int from) {
|
||||
String[][] namesData = debugInfo.getSourceNamesForValues();
|
||||
if (namesData != null &&
|
||||
namesData.length > from &&
|
||||
namesData[from] != null)
|
||||
{
|
||||
if (namesData[to] == null) {
|
||||
namesData[to] = namesData[from];
|
||||
} else {
|
||||
String[] newNames = new String[ namesData[from].length+namesData[to].length ];
|
||||
System.arraycopy(namesData[from], 0, newNames, 0, namesData[from].length);
|
||||
System.arraycopy(namesData[to], 0, newNames, namesData[from].length, namesData[to].length);
|
||||
namesData[to] = newNames;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void initializeVariables() {
|
||||
for (int V = 1; V <= getMaxValueNumber(); V++) {
|
||||
if (! skip(V)) {
|
||||
R[V] = new Stack();
|
||||
}
|
||||
}
|
||||
|
||||
int[] params = symtab.getParameterValueNumbers();
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
if (! skip( params[i] )) {
|
||||
S[params[i]].push( params[i] );
|
||||
valueMap[ params[i] ] = params[i];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void repairExit() {
|
||||
int[] exitLives = lexicalInfo.getExitExposedUses();
|
||||
if (exitLives != null) {
|
||||
for(int i = 0; i < exitLives.length; i++) {
|
||||
if (! skip(exitLives[i])) {
|
||||
Assertions._assert(! S[exitLives[i]].isEmpty());
|
||||
exitLives[i] = top(exitLives[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Global control.
|
||||
//
|
||||
|
||||
protected void fail(int v) {
|
||||
System.err.println( "during SSA conversion of the following IR:" );
|
||||
System.err.println( ir );
|
||||
super.fail(v);
|
||||
}
|
||||
|
||||
public SSA2LocalMap getComputedLocalMap() {
|
||||
return computedLocalMap;
|
||||
}
|
||||
|
||||
public void perform() {
|
||||
super.perform();
|
||||
|
||||
if (DUMP) {
|
||||
Trace.println( ir );
|
||||
if (lexicalInfo != null) {
|
||||
for(int i = 0; i < instructions.length; i++) {
|
||||
int[] lexicalUses = lexicalInfo.getExposedUses(i);
|
||||
if (lexicalUses != null) {
|
||||
Trace.print("extra uses for " + instructions[i] + ": ");
|
||||
for(int j = 0; j < lexicalUses.length; j++) {
|
||||
Trace.print( new Integer(lexicalUses[j]).toString() + " " );
|
||||
}
|
||||
Trace.println("");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
computedLocalMap = new SSAInformation();
|
||||
}
|
||||
|
||||
private static IntSet valuesToConvert(AstIR ir) {
|
||||
IInstruction[] insts = ir.getInstructions();
|
||||
MutableIntSet foundOne = new BitVectorIntSet();
|
||||
MutableIntSet foundTwo = new BitVectorIntSet();
|
||||
for(int i = 0; i < insts.length; i++) {
|
||||
SSAInstruction inst = (SSAInstruction) insts[i];
|
||||
if (inst != null) {
|
||||
for(int j = 0; j < inst.getNumberOfDefs(); j++) {
|
||||
int def = inst.getDef(j);
|
||||
if (def != -1) {
|
||||
if (foundOne.contains(def) ||
|
||||
ir.getSymbolTable().isConstant(def) ||
|
||||
def <= ir.getNumberOfParameters() ||
|
||||
inst instanceof AssignInstruction)
|
||||
{
|
||||
foundTwo.add(def);
|
||||
} else {
|
||||
foundOne.add(def);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return foundTwo;
|
||||
}
|
||||
|
||||
public static SSA2LocalMap convert(AstMethod M, AstIR ir, SSAOptions options) {
|
||||
return convert(M, ir, options, valuesToConvert(ir));
|
||||
}
|
||||
|
||||
public static SSA2LocalMap convert(AstMethod M,
|
||||
final AstIR ir,
|
||||
SSAOptions options,
|
||||
final IntSet values)
|
||||
{
|
||||
try {
|
||||
if (DEBUG) {
|
||||
Trace.println("starting conversion for " + values);
|
||||
Trace.println( ir );
|
||||
}
|
||||
if (DEBUG_UNDO) Trace.println(">>> starting " + ir.getMethod());
|
||||
SSAConversion ssa = new SSAConversion(M, ir, options) {
|
||||
final int limit = ir.getSymbolTable().getMaxValueNumber();
|
||||
protected boolean skip(int i) {
|
||||
return (i >= 0) && (i <= limit) && (!values.contains(i));
|
||||
}
|
||||
};
|
||||
ssa.perform();
|
||||
if (DEBUG_UNDO) Trace.println("<<< done " + ir.getMethod());
|
||||
return ssa.getComputedLocalMap();
|
||||
} catch (RuntimeException e) {
|
||||
Trace.println("exception " + e + " while converting:");
|
||||
Trace.println(ir);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,247 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ir.ssa.analysis;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.ibm.wala.cfg.ControlFlowGraph;
|
||||
import com.ibm.wala.dataflow.graph.AbstractMeetOperator;
|
||||
import com.ibm.wala.dataflow.graph.BitVectorSolver;
|
||||
import com.ibm.wala.dataflow.graph.BitVectorUnion;
|
||||
import com.ibm.wala.dataflow.graph.IKilldallFramework;
|
||||
import com.ibm.wala.dataflow.graph.ITransferFunctionProvider;
|
||||
import com.ibm.wala.fixedpoint.impl.UnaryOperator;
|
||||
import com.ibm.wala.fixpoint.BitVectorVariable;
|
||||
import com.ibm.wala.fixpoint.IVariable;
|
||||
import com.ibm.wala.ssa.IR;
|
||||
import com.ibm.wala.ssa.SSACFG;
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.ssa.SSAPhiInstruction;
|
||||
import com.ibm.wala.ssa.SymbolTable;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.graph.Graph;
|
||||
import com.ibm.wala.util.graph.impl.GraphInverter;
|
||||
import com.ibm.wala.util.intset.BitVector;
|
||||
import com.ibm.wala.util.intset.BitVectorIntSet;
|
||||
import com.ibm.wala.util.intset.IntSet;
|
||||
|
||||
/**
|
||||
* @author Julian Dolby
|
||||
*
|
||||
* live-value analysis TODO: document me!
|
||||
*/
|
||||
public class LiveAnalysis {
|
||||
|
||||
public interface Result {
|
||||
boolean isLiveEntry(SSACFG.BasicBlock bb, int valueNumber);
|
||||
|
||||
boolean isLiveExit(SSACFG.BasicBlock bb, int valueNumber);
|
||||
|
||||
BitVector getLiveBefore(int instr);
|
||||
}
|
||||
|
||||
public static LiveAnalysis.Result perform(final ControlFlowGraph cfg, final SymbolTable symtab) {
|
||||
return perform(cfg, symtab, new BitVector());
|
||||
}
|
||||
|
||||
public static LiveAnalysis.Result perform(final ControlFlowGraph cfg, final SymbolTable symtab, final BitVector considerLiveAtExit) {
|
||||
final BitVectorIntSet liveAtExit = new BitVectorIntSet(considerLiveAtExit);
|
||||
final SSAInstruction[] instructions = (SSAInstruction[]) cfg.getInstructions();
|
||||
|
||||
final class ExitBlockGenKillOperator extends UnaryOperator {
|
||||
public String toString() {
|
||||
return "ExitGenKill";
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return o == this;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return 37721;
|
||||
}
|
||||
|
||||
public byte evaluate(IVariable lhs, IVariable rhs) {
|
||||
BitVectorVariable L = (BitVectorVariable) lhs;
|
||||
boolean changed = L.getValue() == null ? !considerLiveAtExit.isZero() : !L.getValue().sameValue(liveAtExit);
|
||||
|
||||
L.addAll(considerLiveAtExit);
|
||||
|
||||
return changed ? CHANGED : NOT_CHANGED;
|
||||
}
|
||||
}
|
||||
|
||||
final class BlockValueGenKillOperator extends UnaryOperator {
|
||||
private final SSACFG.BasicBlock block;
|
||||
|
||||
BlockValueGenKillOperator(SSACFG.BasicBlock block) {
|
||||
this.block = block;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "GenKill:" + block;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return (o instanceof BlockValueGenKillOperator) && ((BlockValueGenKillOperator) o).block.equals(block);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return block.hashCode() * 17;
|
||||
}
|
||||
|
||||
private void processDefs(SSAInstruction inst, BitVector bits) {
|
||||
for (int j = 0; j < inst.getNumberOfDefs(); j++) {
|
||||
bits.clear(inst.getDef(j));
|
||||
}
|
||||
}
|
||||
|
||||
private void processUses(SSAInstruction inst, BitVector bits) {
|
||||
for (int j = 0; j < inst.getNumberOfUses(); j++) {
|
||||
Assertions._assert(inst.getUse(j) != -1, inst.toString());
|
||||
if (!symtab.isConstant(inst.getUse(j))) {
|
||||
bits.set(inst.getUse(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public byte evaluate(IVariable lhs, IVariable rhs) {
|
||||
BitVectorVariable L = (BitVectorVariable) lhs;
|
||||
IntSet s = ((BitVectorVariable) rhs).getValue();
|
||||
BitVectorIntSet bits = new BitVectorIntSet();
|
||||
if (s != null) {
|
||||
bits.addAll(s);
|
||||
}
|
||||
|
||||
for (Iterator sBBs = cfg.getSuccNodes(block); sBBs.hasNext();) {
|
||||
SSACFG.BasicBlock sBB = (SSACFG.BasicBlock) sBBs.next();
|
||||
int rval = com.ibm.wala.cast.ir.cfg.Util.whichPred(cfg, sBB, block);
|
||||
for (Iterator sphis = sBB.iteratePhis(); sphis.hasNext();) {
|
||||
SSAPhiInstruction sphi = (SSAPhiInstruction) sphis.next();
|
||||
bits.add(sphi.getUse(rval));
|
||||
}
|
||||
}
|
||||
for (int i = block.getLastInstructionIndex(); i >= block.getFirstInstructionIndex(); i--) {
|
||||
SSAInstruction inst = instructions[i];
|
||||
if (inst != null) {
|
||||
processDefs(inst, bits.getBitVector());
|
||||
processUses(inst, bits.getBitVector());
|
||||
}
|
||||
}
|
||||
for (Iterator SS = block.iteratePhis(); SS.hasNext();) {
|
||||
processDefs((SSAInstruction) SS.next(), bits.getBitVector());
|
||||
}
|
||||
|
||||
BitVectorVariable U = new BitVectorVariable();
|
||||
U.addAll(bits.getBitVector());
|
||||
|
||||
if (!L.sameValue(U)) {
|
||||
L.copyState(U);
|
||||
return CHANGED;
|
||||
} else {
|
||||
return NOT_CHANGED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final BitVectorSolver S = new BitVectorSolver(new IKilldallFramework() {
|
||||
private final Graph G = GraphInverter.invert(cfg);
|
||||
|
||||
public Graph getFlowGraph() {
|
||||
return G;
|
||||
}
|
||||
|
||||
public ITransferFunctionProvider getTransferFunctionProvider() {
|
||||
return new ITransferFunctionProvider() {
|
||||
|
||||
public boolean hasNodeTransferFunctions() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean hasEdgeTransferFunctions() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public UnaryOperator getNodeTransferFunction(Object node) {
|
||||
if (((SSACFG.BasicBlock) node).isExitBlock()) {
|
||||
return new ExitBlockGenKillOperator();
|
||||
} else {
|
||||
return new BlockValueGenKillOperator((SSACFG.BasicBlock) node);
|
||||
}
|
||||
}
|
||||
|
||||
public UnaryOperator getEdgeTransferFunction(Object s, Object d) {
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
|
||||
public AbstractMeetOperator getMeetOperator() {
|
||||
return BitVectorUnion.instance();
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
S.solve();
|
||||
|
||||
return new Result() {
|
||||
|
||||
public String toString() {
|
||||
StringBuffer s = new StringBuffer();
|
||||
for (int i = 0; i < cfg.getNumberOfNodes(); i++) {
|
||||
SSACFG.BasicBlock bb = (SSACFG.BasicBlock) cfg.getNode(i);
|
||||
s.append("live entering " + bb + ":" + S.getOut(bb) + "\n");
|
||||
s.append("live exiting " + bb + ":" + S.getIn(bb) + "\n");
|
||||
}
|
||||
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
public boolean isLiveEntry(SSACFG.BasicBlock bb, int valueNumber) {
|
||||
return ((BitVectorVariable) S.getOut(bb)).get(valueNumber);
|
||||
}
|
||||
|
||||
public boolean isLiveExit(SSACFG.BasicBlock bb, int valueNumber) {
|
||||
return ((BitVectorVariable) S.getIn(bb)).get(valueNumber);
|
||||
}
|
||||
|
||||
public BitVector getLiveBefore(int instr) {
|
||||
SSACFG.BasicBlock bb = (SSACFG.BasicBlock) cfg.getBlockForInstruction(instr);
|
||||
IntSet s = ((BitVectorVariable) S.getIn(bb)).getValue();
|
||||
BitVectorIntSet bits = new BitVectorIntSet();
|
||||
if (s != null) {
|
||||
bits.addAll(s);
|
||||
}
|
||||
|
||||
for (int i = bb.getLastInstructionIndex(); i >= instr; i--) {
|
||||
SSAInstruction inst = instructions[i];
|
||||
if (inst != null) {
|
||||
for (int j = 0; j < inst.getNumberOfDefs(); j++) {
|
||||
bits.remove(inst.getDef(j));
|
||||
}
|
||||
for (int j = 0; j < inst.getNumberOfUses(); j++) {
|
||||
if (!symtab.isConstant(inst.getUse(j))) {
|
||||
bits.add(inst.getUse(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bits.getBitVector();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static LiveAnalysis.Result perform(IR ir) {
|
||||
return perform(ir.getControlFlowGraph(), ir.getSymbolTable());
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,27 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ir.translator;
|
||||
|
||||
public class NativeBridge {
|
||||
|
||||
protected static native void initialize();
|
||||
|
||||
/*
|
||||
* trying to modularize shared library loading like this seems to
|
||||
* cause trouble on certain VMs. (guess which? :)
|
||||
*
|
||||
static {
|
||||
System.loadLibrary("cast");
|
||||
initialize();
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.ir.translator;
|
||||
|
||||
import com.ibm.wala.classLoader.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
public interface TranslatorToIR {
|
||||
|
||||
void translate(ModuleEntry S, String N) throws IOException;
|
||||
|
||||
void translate(Set modules) throws IOException;
|
||||
|
||||
}
|
|
@ -0,0 +1,219 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.loader;
|
||||
|
||||
|
||||
import com.ibm.wala.cast.tree.*;
|
||||
import com.ibm.wala.classLoader.*;
|
||||
import com.ibm.wala.ipa.cha.*;
|
||||
import com.ibm.wala.shrikeCT.*;
|
||||
import com.ibm.wala.types.*;
|
||||
import com.ibm.wala.util.*;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
|
||||
abstract public class AstClass implements IClass, ClassConstants {
|
||||
private final CAstSourcePositionMap.Position sourcePosition;
|
||||
private final TypeName typeName;
|
||||
private final IClassLoader loader;
|
||||
private final short modifiers;
|
||||
protected final Map declaredFields;
|
||||
protected final Map declaredMethods;
|
||||
|
||||
protected AstClass(CAstSourcePositionMap.Position sourcePosition,
|
||||
TypeName typeName,
|
||||
IClassLoader loader,
|
||||
short modifiers,
|
||||
Map declaredFields,
|
||||
Map declaredMethods)
|
||||
{
|
||||
this.sourcePosition = sourcePosition;
|
||||
this.typeName = typeName;
|
||||
this.loader = loader;
|
||||
this.modifiers = modifiers;
|
||||
this.declaredFields = declaredFields;
|
||||
this.declaredMethods = declaredMethods;
|
||||
}
|
||||
|
||||
public boolean isInterface() {
|
||||
return (modifiers&ACC_INTERFACE) != 0;
|
||||
}
|
||||
|
||||
public boolean isAbstract() {
|
||||
return (modifiers&ACC_ABSTRACT) != 0;
|
||||
}
|
||||
|
||||
public boolean isPublic() {
|
||||
return (modifiers&ACC_PUBLIC) != 0;
|
||||
}
|
||||
|
||||
public boolean isReferenceType() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isArrayClass() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getModifiers() {
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
public CAstSourcePositionMap.Position getSourcePosition() {
|
||||
return sourcePosition;
|
||||
}
|
||||
|
||||
public URL getSourceURL() {
|
||||
return sourcePosition.getURL();
|
||||
}
|
||||
|
||||
public String getSourceFileName() {
|
||||
return sourcePosition.getURL().getFile();
|
||||
}
|
||||
|
||||
public TypeName getName() {
|
||||
return typeName;
|
||||
}
|
||||
|
||||
public TypeReference getReference() {
|
||||
return TypeReference.findOrCreate(loader.getReference(), typeName);
|
||||
}
|
||||
|
||||
public IClassLoader getClassLoader() {
|
||||
return loader;
|
||||
}
|
||||
|
||||
public abstract IClass getSuperclass() throws ClassHierarchyException;
|
||||
|
||||
private Collection gatherInterfaces() throws ClassHierarchyException {
|
||||
Set result = new HashSet();
|
||||
result.addAll( getDirectInterfaces() );
|
||||
if (getSuperclass() != null)
|
||||
result.addAll( getSuperclass().getAllImplementedInterfaces() );
|
||||
return result;
|
||||
}
|
||||
|
||||
public abstract Collection getDirectInterfaces() throws ClassHierarchyException;
|
||||
|
||||
public Collection getAllImplementedInterfaces() throws ClassHierarchyException {
|
||||
Assertions._assert(! isInterface());
|
||||
return gatherInterfaces();
|
||||
}
|
||||
|
||||
public Collection getAllAncestorInterfaces() throws ClassHierarchyException {
|
||||
Assertions._assert(isInterface());
|
||||
return gatherInterfaces();
|
||||
}
|
||||
|
||||
public IMethod getClassInitializer() {
|
||||
return getMethod( MethodReference.clinitSelector );
|
||||
}
|
||||
|
||||
public IMethod getMethod(Selector selector) {
|
||||
try {
|
||||
if (declaredMethods.containsKey(selector)) {
|
||||
return (IMethod)declaredMethods.get(selector);
|
||||
} else if (getSuperclass() != null) {
|
||||
return getSuperclass().getMethod(selector);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch (ClassHierarchyException e) {
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public IField getField(Atom name) {
|
||||
try {
|
||||
if (declaredFields.containsKey(name)) {
|
||||
return (IField)declaredFields.get(name);
|
||||
} else if (getSuperclass() != null) {
|
||||
return getSuperclass().getField(name);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch (ClassHierarchyException e) {
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<IMethod> getDeclaredMethods() {
|
||||
return declaredMethods.values();
|
||||
}
|
||||
|
||||
public Collection getDeclaredInstanceFields() {
|
||||
Set result = new HashSet();
|
||||
for(Iterator FS = declaredFields.values().iterator(); FS.hasNext();) {
|
||||
IField F = (IField) FS.next();
|
||||
if (! F.isStatic()) {
|
||||
result.add( F );
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Collection getDeclaredStaticFields() {
|
||||
Set result = new HashSet();
|
||||
for(Iterator FS = declaredFields.values().iterator(); FS.hasNext();) {
|
||||
IField F = (IField) FS.next();
|
||||
if (F.isStatic()) {
|
||||
result.add( F );
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Collection getAllInstanceFields() throws ClassHierarchyException {
|
||||
Collection result = new HashSet();
|
||||
result.addAll( getDeclaredInstanceFields() );
|
||||
if (getSuperclass() != null) {
|
||||
result.addAll( getSuperclass().getAllInstanceFields() );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Collection getAllStaticFields() throws ClassHierarchyException {
|
||||
Collection result = new HashSet();
|
||||
result.addAll( getDeclaredStaticFields() );
|
||||
if (getSuperclass() != null) {
|
||||
result.addAll( getSuperclass().getAllStaticFields() );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Collection getAllFields() throws ClassHierarchyException {
|
||||
Collection result = new HashSet();
|
||||
result.addAll( getAllInstanceFields() );
|
||||
result.addAll( getAllStaticFields() );
|
||||
return result;
|
||||
}
|
||||
|
||||
public Collection getAllMethods() throws ClassHierarchyException {
|
||||
Collection result = new HashSet();
|
||||
for(Iterator ms = getDeclaredMethods().iterator(); ms.hasNext(); ) {
|
||||
result.add( ms.next() );
|
||||
}
|
||||
if (getSuperclass() != null) {
|
||||
result.addAll( getSuperclass().getAllMethods() );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.loader;
|
||||
|
||||
|
||||
import com.ibm.wala.cast.tree.*;
|
||||
import com.ibm.wala.cast.types.*;
|
||||
import com.ibm.wala.classLoader.*;
|
||||
import com.ibm.wala.ipa.cha.*;
|
||||
import com.ibm.wala.types.*;
|
||||
import com.ibm.wala.util.Atom;
|
||||
import com.ibm.wala.util.collections.*;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public abstract class AstDynamicPropertyClass extends AstClass {
|
||||
private final TypeReference defaultDescriptor;
|
||||
|
||||
protected AstDynamicPropertyClass(CAstSourcePositionMap.Position sourcePosition, TypeName typeName, IClassLoader loader, short modifiers, Map declaredMethods, TypeReference defaultDescriptor) {
|
||||
super(sourcePosition, typeName, loader, modifiers, new HashMap(), declaredMethods);
|
||||
this.defaultDescriptor = defaultDescriptor;
|
||||
}
|
||||
|
||||
public IField getField(final Atom name) {
|
||||
try {
|
||||
if (declaredFields.containsKey(name)) {
|
||||
return (IField) declaredFields.get(name);
|
||||
} else if (getSuperclass() != null) {
|
||||
return getSuperclass().getField(name);
|
||||
} else {
|
||||
final boolean isStatic = isStaticField(name);
|
||||
declaredFields.put(name, new IField() {
|
||||
public String toString() {
|
||||
return "<field " + name + ">";
|
||||
}
|
||||
|
||||
public IClass getDeclaringClass() {
|
||||
return AstDynamicPropertyClass.this;
|
||||
}
|
||||
|
||||
public Atom getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public TypeReference getFieldTypeReference() {
|
||||
return defaultDescriptor;
|
||||
}
|
||||
|
||||
public FieldReference getFieldReference() {
|
||||
return FieldReference.findOrCreate(AstDynamicPropertyClass.this.getReference(), name, defaultDescriptor);
|
||||
}
|
||||
|
||||
public boolean isFinal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPrivate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isProtected() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPublic() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isVolatile() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isStatic() {
|
||||
return isStatic;
|
||||
}
|
||||
|
||||
public ClassHierarchy getClassHierarchy() {
|
||||
return AstDynamicPropertyClass.this.getClassHierarchy();
|
||||
}
|
||||
});
|
||||
|
||||
return (IField) declaredFields.get(name);
|
||||
}
|
||||
} catch (ClassHierarchyException e) {
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isStaticField(Atom name) {
|
||||
return name.toString().startsWith("global ");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.loader;
|
||||
|
||||
|
||||
import com.ibm.wala.cast.tree.*;
|
||||
import com.ibm.wala.classLoader.*;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.types.*;
|
||||
import com.ibm.wala.util.Atom;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class AstField implements IField {
|
||||
private final Collection qualifiers;
|
||||
private final FieldReference ref;
|
||||
private final IClass declaringClass;
|
||||
private final ClassHierarchy cha;
|
||||
|
||||
public AstField(FieldReference ref,
|
||||
Collection qualifiers,
|
||||
IClass declaringClass,
|
||||
ClassHierarchy cha)
|
||||
{
|
||||
this.declaringClass = declaringClass;
|
||||
this.qualifiers = qualifiers;
|
||||
this.ref = ref;
|
||||
this.cha = cha;
|
||||
}
|
||||
|
||||
public IClass getDeclaringClass() {
|
||||
return declaringClass;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "field " + ref.getName();
|
||||
}
|
||||
|
||||
public Atom getName() {
|
||||
return ref.getName();
|
||||
}
|
||||
|
||||
public TypeReference getFieldTypeReference() {
|
||||
return ref.getFieldType();
|
||||
}
|
||||
|
||||
public FieldReference getFieldReference() {
|
||||
return ref;
|
||||
}
|
||||
|
||||
public boolean isStatic() {
|
||||
return qualifiers.contains(CAstQualifier.STATIC);
|
||||
}
|
||||
|
||||
public boolean isFinal() {
|
||||
return qualifiers.contains(CAstQualifier.CONST);
|
||||
}
|
||||
|
||||
public boolean isPrivate() {
|
||||
return qualifiers.contains(CAstQualifier.PRIVATE);
|
||||
}
|
||||
|
||||
public boolean isProtected() {
|
||||
return qualifiers.contains(CAstQualifier.PROTECTED);
|
||||
}
|
||||
|
||||
public boolean isPublic() {
|
||||
return qualifiers.contains(CAstQualifier.PUBLIC);
|
||||
}
|
||||
|
||||
public boolean isVolatile() {
|
||||
return qualifiers.contains(CAstQualifier.VOLATILE);
|
||||
}
|
||||
|
||||
public ClassHierarchy getClassHierarchy() {
|
||||
return cha;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.loader;
|
||||
|
||||
|
||||
import com.ibm.wala.cast.tree.*;
|
||||
import com.ibm.wala.cast.types.*;
|
||||
import com.ibm.wala.classLoader.*;
|
||||
import com.ibm.wala.ipa.cha.*;
|
||||
import com.ibm.wala.shrikeCT.*;
|
||||
import com.ibm.wala.types.*;
|
||||
import com.ibm.wala.util.Atom;
|
||||
import com.ibm.wala.util.collections.*;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
|
||||
abstract public class AstFunctionClass implements IClass, ClassConstants {
|
||||
private final IClassLoader loader;
|
||||
|
||||
protected IMethod functionBody;
|
||||
|
||||
private final CAstSourcePositionMap.Position sourcePosition;
|
||||
|
||||
private final TypeReference reference;
|
||||
|
||||
private final TypeReference superReference;
|
||||
|
||||
protected AstFunctionClass(TypeReference reference, TypeReference superReference, IClassLoader loader,
|
||||
CAstSourcePositionMap.Position sourcePosition) {
|
||||
this.superReference = superReference;
|
||||
this.sourcePosition = sourcePosition;
|
||||
this.reference = reference;
|
||||
this.loader = loader;
|
||||
}
|
||||
|
||||
protected AstFunctionClass(TypeReference reference, IClassLoader loader, CAstSourcePositionMap.Position sourcePosition) {
|
||||
this(reference, TypeReference.findOrCreate(reference.getClassLoader(), AstTypeReference.functionTypeName), loader,
|
||||
sourcePosition);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "function " + functionBody.getReference().getDeclaringClass().getName();
|
||||
}
|
||||
|
||||
public IClassLoader getClassLoader() {
|
||||
return loader;
|
||||
}
|
||||
|
||||
public boolean isInterface() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isAbstract() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPublic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getModifiers() {
|
||||
return ACC_PUBLIC;
|
||||
}
|
||||
|
||||
public IClass getSuperclass() throws ClassHierarchyException {
|
||||
return loader.lookupClass(superReference.getName(), getClassHierarchy());
|
||||
}
|
||||
|
||||
public Collection getDirectInterfaces() {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
|
||||
public Collection getAllImplementedInterfaces() {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
|
||||
public Collection getAllAncestorInterfaces() {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
|
||||
public IMethod getMethod(Selector selector) {
|
||||
if (selector.equals(AstMethodReference.fnSelector)) {
|
||||
return functionBody;
|
||||
} else {
|
||||
return loader.lookupClass(superReference.getName(), getClassHierarchy()).getMethod(selector);
|
||||
}
|
||||
}
|
||||
|
||||
public IField getField(Atom name) {
|
||||
return loader.lookupClass(superReference.getName(), getClassHierarchy()).getField(name);
|
||||
}
|
||||
|
||||
public TypeReference getReference() {
|
||||
return reference;
|
||||
}
|
||||
|
||||
public CAstSourcePositionMap.Position getSourcePosition() {
|
||||
return sourcePosition;
|
||||
}
|
||||
|
||||
public URL getSourceURL() {
|
||||
return sourcePosition.getURL();
|
||||
}
|
||||
|
||||
public String getSourceFileName() {
|
||||
return sourcePosition.getURL().getFile();
|
||||
}
|
||||
|
||||
public IMethod getClassInitializer() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isArrayClass() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Collection<IMethod> getDeclaredMethods() {
|
||||
if (functionBody != null) {
|
||||
return Collections.singleton(functionBody);
|
||||
} else {
|
||||
throw new Error("function " + reference + " has no body!");
|
||||
}
|
||||
}
|
||||
|
||||
public Collection getDeclaredInstanceFields() {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
|
||||
public Collection getDeclaredStaticFields() {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
|
||||
public Collection getAllInstanceFields() {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
|
||||
public Collection getAllStaticFields() {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
|
||||
public Collection getAllFields() {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
|
||||
public Collection getAllMethods() {
|
||||
return Collections.singleton(functionBody);
|
||||
}
|
||||
|
||||
public TypeName getName() {
|
||||
return reference.getName();
|
||||
}
|
||||
|
||||
public boolean isReferenceType() {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,223 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.loader;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.ibm.wala.cast.tree.CAstQualifier;
|
||||
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
|
||||
import com.ibm.wala.cfg.AbstractCFG;
|
||||
import com.ibm.wala.cfg.ControlFlowGraph;
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.ssa.SymbolTable;
|
||||
import com.ibm.wala.types.Descriptor;
|
||||
import com.ibm.wala.types.MethodReference;
|
||||
import com.ibm.wala.types.Selector;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.Atom;
|
||||
import com.ibm.wala.util.collections.Pair;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
public abstract class AstMethod implements IMethod {
|
||||
|
||||
public interface DebuggingInformation {
|
||||
|
||||
Position getInstructionPosition(int instructionOffset);
|
||||
|
||||
String[][] getSourceNamesForValues();
|
||||
|
||||
}
|
||||
|
||||
public interface LexicalInformation {
|
||||
|
||||
public int[] getExitExposedUses();
|
||||
|
||||
public int[] getExposedUses(int instructionOffset);
|
||||
|
||||
public Pair[] getExposedNames();
|
||||
|
||||
public String[] getScopingParents();
|
||||
|
||||
}
|
||||
|
||||
public final IClass cls;
|
||||
public final Collection qualifiers;
|
||||
public final AbstractCFG cfg;
|
||||
public final SymbolTable symtab;
|
||||
public final MethodReference ref;
|
||||
public final boolean hasCatchBlock;
|
||||
public final TypeReference[][] catchTypes;
|
||||
public final LexicalInformation lexicalInfo;
|
||||
public final DebuggingInformation debugInfo;
|
||||
|
||||
protected AstMethod(IClass cls,
|
||||
Collection qualifiers,
|
||||
AbstractCFG cfg,
|
||||
SymbolTable symtab,
|
||||
MethodReference ref,
|
||||
boolean hasCatchBlock,
|
||||
TypeReference[][] catchTypes,
|
||||
LexicalInformation lexicalInfo,
|
||||
DebuggingInformation debugInfo)
|
||||
{
|
||||
this.cls = cls;
|
||||
this.cfg = cfg;
|
||||
this.ref = ref;
|
||||
this.symtab = symtab;
|
||||
this.qualifiers = qualifiers;
|
||||
this.catchTypes = catchTypes;
|
||||
this.hasCatchBlock = hasCatchBlock;
|
||||
this.lexicalInfo = lexicalInfo;
|
||||
this.debugInfo = debugInfo;
|
||||
}
|
||||
|
||||
protected AstMethod(IClass cls,
|
||||
Collection qualifiers,
|
||||
MethodReference ref)
|
||||
{
|
||||
this.cls = cls;
|
||||
this.qualifiers = qualifiers;
|
||||
this.ref = ref;
|
||||
|
||||
this.cfg = null;
|
||||
this.symtab = null;
|
||||
this.catchTypes = null;
|
||||
this.hasCatchBlock = false;
|
||||
this.lexicalInfo = null;
|
||||
this.debugInfo = null;
|
||||
|
||||
Assertions._assert(isAbstract());
|
||||
}
|
||||
|
||||
/**
|
||||
* Parents of this method with respect to lexical scoping, that is,
|
||||
* methods containing state possibly referenced lexically in this
|
||||
* method
|
||||
*/
|
||||
public abstract class LexicalParent {
|
||||
public abstract String getName();
|
||||
public abstract AstMethod getMethod();
|
||||
|
||||
public int hashCode() {
|
||||
return getName().hashCode()*getMethod().hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return (o instanceof LexicalParent) &&
|
||||
getName().equals(((LexicalParent)o).getName()) &&
|
||||
getMethod().equals(((LexicalParent)o).getMethod());
|
||||
}
|
||||
};
|
||||
|
||||
public abstract LexicalParent[] getParents();
|
||||
|
||||
public IClass getDeclaringClass() {
|
||||
return cls;
|
||||
}
|
||||
|
||||
public String getSignature() {
|
||||
return ref.toString();
|
||||
}
|
||||
|
||||
public Selector getSelector() {
|
||||
return ref.getSelector();
|
||||
}
|
||||
|
||||
public boolean isClinit() {
|
||||
return getSelector().equals(MethodReference.clinitSelector);
|
||||
}
|
||||
|
||||
public boolean isInit() {
|
||||
return getSelector().equals(MethodReference.initSelector);
|
||||
}
|
||||
|
||||
public Atom getName() {
|
||||
return ref.getName();
|
||||
}
|
||||
|
||||
public Descriptor getDescriptor() {
|
||||
return ref.getDescriptor();
|
||||
}
|
||||
|
||||
public MethodReference getReference() {
|
||||
return ref;
|
||||
}
|
||||
|
||||
public TypeReference getReturnType() {
|
||||
return ref.getReturnType();
|
||||
}
|
||||
|
||||
public boolean isStatic() {
|
||||
return qualifiers.contains(CAstQualifier.STATIC);
|
||||
}
|
||||
|
||||
public boolean isSynchronized() {
|
||||
return qualifiers.contains(CAstQualifier.SYNCHRONIZED);
|
||||
}
|
||||
|
||||
public boolean isNative() {
|
||||
return qualifiers.contains(CAstQualifier.NATIVE);
|
||||
}
|
||||
|
||||
public boolean isSynthetic() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isAbstract() {
|
||||
return qualifiers.contains(CAstQualifier.ABSTRACT);
|
||||
}
|
||||
|
||||
public boolean isPrivate() {
|
||||
return qualifiers.contains(CAstQualifier.PRIVATE);
|
||||
}
|
||||
|
||||
public boolean isProtected() {
|
||||
return qualifiers.contains(CAstQualifier.PROTECTED);
|
||||
}
|
||||
|
||||
public boolean isPublic() {
|
||||
return qualifiers.contains(CAstQualifier.PUBLIC);
|
||||
}
|
||||
|
||||
public boolean isFinal() {
|
||||
return qualifiers.contains(CAstQualifier.FINAL);
|
||||
}
|
||||
|
||||
public boolean isVolatile() {
|
||||
return qualifiers.contains(CAstQualifier.VOLATILE);
|
||||
}
|
||||
|
||||
public ControlFlowGraph getControlFlowGraph() {
|
||||
return cfg;
|
||||
}
|
||||
|
||||
public boolean hasExceptionHandler() {
|
||||
return hasCatchBlock;
|
||||
}
|
||||
|
||||
public int getNumberOfParameters() {
|
||||
return symtab.getParameterValueNumbers().length;
|
||||
}
|
||||
|
||||
public int getLineNumber(int instructionIndex) {
|
||||
Position pos = debugInfo.getInstructionPosition(instructionIndex);
|
||||
if (pos == null) {
|
||||
return -1;
|
||||
} else {
|
||||
return pos.getFirstLine();
|
||||
}
|
||||
}
|
||||
|
||||
public Position getSourcePosition(int instructionIndex) {
|
||||
return debugInfo.getInstructionPosition(instructionIndex);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.loader;
|
||||
|
||||
import com.ibm.wala.classLoader.ClassLoaderFactory;
|
||||
import com.ibm.wala.classLoader.IClassLoader;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
public abstract class SingleClassLoaderFactory implements ClassLoaderFactory {
|
||||
private IClassLoader THE_LOADER = null;
|
||||
|
||||
public IClassLoader getLoader(ClassLoaderReference classLoaderReference,
|
||||
ClassHierarchy cha,
|
||||
AnalysisScope scope)
|
||||
{
|
||||
if (THE_LOADER == null) {
|
||||
THE_LOADER = makeTheLoader(cha);
|
||||
try {
|
||||
THE_LOADER.init(scope.getModules(getTheReference()));
|
||||
} catch (java.io.IOException e) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
Assertions._assert(classLoaderReference.equals(getTheReference()));
|
||||
|
||||
return THE_LOADER;
|
||||
}
|
||||
|
||||
public IClassLoader getTheLoader() {
|
||||
return THE_LOADER;
|
||||
}
|
||||
|
||||
public abstract ClassLoaderReference getTheReference();
|
||||
|
||||
protected abstract IClassLoader makeTheLoader(ClassHierarchy cha);
|
||||
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.plugin;
|
||||
|
||||
import org.eclipse.core.runtime.Plugin;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
/**
|
||||
* The main plugin class to be used in the desktop.
|
||||
*/
|
||||
public class AstPlugin extends Plugin {
|
||||
|
||||
//The shared instance.
|
||||
private static AstPlugin plugin;
|
||||
|
||||
/**
|
||||
* The constructor.
|
||||
*/
|
||||
public AstPlugin() {
|
||||
plugin = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called upon plug-in activation
|
||||
*/
|
||||
public void start(BundleContext context) throws Exception {
|
||||
super.start(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when the plug-in is stopped
|
||||
*/
|
||||
public void stop(BundleContext context) throws Exception {
|
||||
super.stop(context);
|
||||
plugin = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the shared instance.
|
||||
*/
|
||||
public static AstPlugin getDefault() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.tree;
|
||||
|
||||
import org.eclipse.core.runtime.Plugin;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
/**
|
||||
* The main plugin class to be used in the desktop.
|
||||
*/
|
||||
public class AstPlugin extends Plugin {
|
||||
|
||||
//The shared instance.
|
||||
private static AstPlugin plugin;
|
||||
|
||||
/**
|
||||
* The constructor.
|
||||
*/
|
||||
public AstPlugin() {
|
||||
plugin = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called upon plug-in activation
|
||||
*/
|
||||
public void start(BundleContext context) throws Exception {
|
||||
super.start(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when the plug-in is stopped
|
||||
*/
|
||||
public void stop(BundleContext context) throws Exception {
|
||||
super.stop(context);
|
||||
plugin = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the shared instance.
|
||||
*/
|
||||
public static AstPlugin getDefault() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.tree;
|
||||
|
||||
/**
|
||||
* The main interface for creating CAPA Abstract Syntax Trees. This
|
||||
* interface provides essentially a factory for creating AST nodes in
|
||||
* a tree structure. There is no strong assumption about the meaning
|
||||
* of specific nodes; however, the `kind' argument to a makeNode call
|
||||
* should be a value from the constants in the CAstNode interface.
|
||||
* The other arguments to makeNode calls are child nodes. The
|
||||
* structure of the tree is a matter of agreement between providers and
|
||||
* consumers of specific trees.
|
||||
*
|
||||
* @author Julian Dolby (dolby@us.ibm.com)
|
||||
*
|
||||
*/
|
||||
public interface CAst {
|
||||
|
||||
/** Make a node of type kind with no children. */
|
||||
CAstNode makeNode(int kind);
|
||||
|
||||
/** Make a node of type kind with one child. */
|
||||
CAstNode makeNode(int kind, CAstNode c1);
|
||||
|
||||
/** Make a node of type kind with two children. */
|
||||
CAstNode makeNode(int kind, CAstNode c1, CAstNode c2);
|
||||
|
||||
/** Make a node of type kind with three children. */
|
||||
CAstNode makeNode(int kind, CAstNode c1, CAstNode c2, CAstNode c3);
|
||||
|
||||
/** Make a node of type kind with four children. */
|
||||
CAstNode makeNode(int kind, CAstNode c1, CAstNode c2, CAstNode c3, CAstNode c4);
|
||||
/** Make a node of type kind with five children. */
|
||||
CAstNode makeNode(int kind, CAstNode c1, CAstNode c2, CAstNode c3, CAstNode c4, CAstNode c5);
|
||||
|
||||
/** Make a node of type kind with six children. */
|
||||
CAstNode makeNode(int kind, CAstNode c1, CAstNode c2, CAstNode c3, CAstNode c4, CAstNode c5, CAstNode c6);
|
||||
|
||||
/** Make a node of type kind specifying an array of children. */
|
||||
CAstNode makeNode(int kind, CAstNode[] cs);
|
||||
|
||||
/** Make a node of type kind giving a first child and array of the rest. */
|
||||
CAstNode makeNode(int kind, CAstNode firstChild, CAstNode[] otherChildren);
|
||||
|
||||
/** Make a boolean constant node. */
|
||||
CAstNode makeConstant(boolean value);
|
||||
|
||||
/** Make a char constant node. */
|
||||
CAstNode makeConstant(char value);
|
||||
|
||||
/** Make a short integer constant node. */
|
||||
CAstNode makeConstant(short value);
|
||||
|
||||
/** Make an integer constant node. */
|
||||
CAstNode makeConstant(int value);
|
||||
|
||||
/** Make a long integer constant node. */
|
||||
CAstNode makeConstant(long value);
|
||||
|
||||
/** Make a double-precision floating point constant node. */
|
||||
CAstNode makeConstant(double value);
|
||||
|
||||
/** Make a single-precision floating point constant node. */
|
||||
CAstNode makeConstant(float value);
|
||||
|
||||
/** Make an arbitrary object constant node. */
|
||||
CAstNode makeConstant(Object value);
|
||||
|
||||
/** Make a new identifier, unqiue to this CAst instance. */
|
||||
String makeUnique();
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.tree;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
/**
|
||||
* The control flow information for the CAPA AST of a particular
|
||||
* entity. An ast may contain various nodes that pertain to control
|
||||
* flow---such as gotos, branches, exceptions and so on---and this map
|
||||
* denotes the target ast nodes of ast nodes that are control flow
|
||||
* instructions. The label is fairly arbitrary---it will depend on
|
||||
* the language, producers and consumers of the tree---but is
|
||||
* generally expected to be things like case labels, exception types,
|
||||
* conditional outcomes and so on.
|
||||
*
|
||||
* @author Julian Dolby (dolby@us.ibm.com)
|
||||
*
|
||||
*/
|
||||
public interface CAstControlFlowMap {
|
||||
|
||||
/**
|
||||
* A distinguished label that means this control flow is the
|
||||
* default target of a switch (or case) statement as found in many
|
||||
* procedural languages.
|
||||
*/
|
||||
public static final Object SWITCH_DEFAULT = new Object();
|
||||
|
||||
/**
|
||||
* A distinguished target that means this control flow is the target
|
||||
* of an uncaught exception.
|
||||
*/
|
||||
public static final CAstNode EXCEPTION_TO_EXIT = new CAstNode() {
|
||||
public int getKind() { return CAstNode.CONSTANT; }
|
||||
public Object getValue() { return this; }
|
||||
public CAstNode getChild(int n) { Assertions.UNREACHABLE(); return null; }
|
||||
public int getChildCount() { return 0;}
|
||||
public String toString() { return "EXCEPTION_TO_EXIT"; }
|
||||
public int hashCode() { return getKind()*toString().hashCode(); }
|
||||
public boolean equals(Object o) { return o == this; }
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the target ast node of the control-flow instruction
|
||||
* denoted by from with respect to the given label.
|
||||
*/
|
||||
CAstNode getTarget(CAstNode from, Object label);
|
||||
|
||||
/**
|
||||
* Return a collection of all labels for which the control-flow ast
|
||||
* node <code>from</code> has a target.
|
||||
*/
|
||||
Collection getTargetLabels(CAstNode from);
|
||||
|
||||
/**
|
||||
* Return a collection of control-flow ast nodes that have this one
|
||||
* as a possible target.
|
||||
*/
|
||||
Collection getSourceNodes(CAstNode to);
|
||||
|
||||
/**
|
||||
* Returns an iterator of all CAstNodes for which this map contains
|
||||
* control flow mapping information.
|
||||
*/
|
||||
Collection getMappedNodes();
|
||||
}
|
|
@ -0,0 +1,168 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.tree;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* The assumption is that abstract syntax trees pertain to particular
|
||||
* programming language constructs, such as classes, methods, programs
|
||||
* and the like. Thus, the expectation is that users of CAPA AST will
|
||||
* typically be communicating such entities, and this interface is
|
||||
* meant to give them a mechanism to do this.
|
||||
*
|
||||
* The set of kinds that are currently in this file is not meant to
|
||||
* be exhaustive, and should be extended as needed for any new
|
||||
* languages that come along.
|
||||
*
|
||||
* @author Julian Dolby (dolby@us.ibm.com)
|
||||
*
|
||||
*/
|
||||
public interface CAstEntity {
|
||||
|
||||
/** This entity is a function.
|
||||
* Children: in JavaScript, FUNCTION_ENTITY's; in Java, none.
|
||||
**/
|
||||
public static int FUNCTION_ENTITY = 1;
|
||||
|
||||
/** This entity is a program script for a scripting language.
|
||||
* Children: in JavaScript, FUNCTION_ENTITY's(?); doesn't occur in Java.
|
||||
**/
|
||||
public static int SCRIPT_ENTITY = 2;
|
||||
|
||||
/** This entity is a type in an object-oriented language.
|
||||
* Children: typically, immediately enclosed FIELD_ENTITY's,
|
||||
* FUNCTION_ENTITY's, and TYPE_ENTITY's.
|
||||
**/
|
||||
public static int TYPE_ENTITY = 3;
|
||||
|
||||
/** This entity is a field in an object-oriented language.
|
||||
* Children: usually, none
|
||||
**/
|
||||
public static int FIELD_ENTITY = 4;
|
||||
|
||||
/** This entity is a source file (i.e. a compilation unit).
|
||||
* Children: in JavaScript, nothing(doesn't occur?); in Java, TYPE_ENTITY's.
|
||||
**/
|
||||
public static int FILE_ENTITY = 5;
|
||||
|
||||
/** This entity represents a rule in a logic language.
|
||||
*/
|
||||
public static int RULE_ENTITY = 6;
|
||||
|
||||
/**
|
||||
* Languages that introduce new kinds of CAstEntity should use this
|
||||
* number as the base of integers chosen to denote the new entity
|
||||
* types.
|
||||
*/
|
||||
public static final int SUB_LANGUAGE_BASE = 100;
|
||||
|
||||
/**
|
||||
* What kind of entity is this? The answer should be one of the
|
||||
* constants in this file. This has no meaning to the CAPA AST
|
||||
* interfaces, but should be meaningful to a given producer and
|
||||
* consumer of an entity.
|
||||
*/
|
||||
int getKind();
|
||||
|
||||
/**
|
||||
* Some programming language constructs have names. This should be
|
||||
* it, if appropriate, and null otherwise.
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Some programming language constructs have signatures, which are like
|
||||
* names but usually have some detail to distinguish the construct from
|
||||
* others with the same name. Signatures often denote typing information
|
||||
* as well, but this is not required. This method should return a
|
||||
* signature if appropriate, and null otherwise.
|
||||
*/
|
||||
String getSignature();
|
||||
|
||||
/**
|
||||
* Some programming language constructs have named arguments. This
|
||||
* should be their names, if appropriate. Otherwise, please return
|
||||
* an array of size 0, since null can be a pain.
|
||||
*/
|
||||
String[] getArgumentNames();
|
||||
|
||||
/**
|
||||
* Some programming language constructs allow arguments to have default
|
||||
* values. This should be those defaults, one per named argument above.
|
||||
* Otherwise, please return an array of size 0, since null can be a pain.
|
||||
*/
|
||||
CAstNode[] getArgumentDefaults();
|
||||
|
||||
/**
|
||||
* Some programming language constructs have a specific number of
|
||||
* arguments. This should be that number, if appropriate, and 0
|
||||
* otherwise.
|
||||
*/
|
||||
int getArgumentCount();
|
||||
|
||||
/**
|
||||
* Some programming language constructs have a lexical structure.
|
||||
* This should be those constructs that are directly inside the current
|
||||
* one. The result of this method is a map from source construct to
|
||||
* the set of entities induced by that construct. Entities induced by
|
||||
* no particular construct are mapped by the null key.
|
||||
*/
|
||||
Map getAllScopedEntities();
|
||||
|
||||
/**
|
||||
* Some programming language constructs have a lexical structure.
|
||||
* This should be those constructs that are directly inside the current
|
||||
* one. The result of this method is the scoped entities induced by
|
||||
* the construct `construct' (i.e. a node of the AST returned by
|
||||
*
|
||||
* Enclosed entities not induced by a specific AST node are mapped
|
||||
* by the construct 'null'.
|
||||
*/
|
||||
Iterator getScopedEntities(CAstNode construct);
|
||||
|
||||
/**
|
||||
* The CAPA AST of this entity.
|
||||
*/
|
||||
CAstNode getAST();
|
||||
|
||||
/**
|
||||
* The control flow map for the CAPA AST of this entity.
|
||||
*/
|
||||
CAstControlFlowMap getControlFlow();
|
||||
|
||||
/**
|
||||
* The map of CAstNodes to source positions for the CAPA AST of this entity.
|
||||
*/
|
||||
CAstSourcePositionMap getSourceMap();
|
||||
|
||||
/**
|
||||
* The source position of this entity.
|
||||
*/
|
||||
CAstSourcePositionMap.Position getPosition();
|
||||
|
||||
/**
|
||||
* The map from CAstNodes to types. Valid for nodes that have an explicitly
|
||||
* declared type (e.g. local vars).
|
||||
*/
|
||||
CAstNodeTypeMap getNodeTypeMap();
|
||||
|
||||
/**
|
||||
* Returns an Iterator over the qualifiers of the given entity, if it has
|
||||
* any, e.g., "final", "private".
|
||||
*/
|
||||
Collection/*<CAstQualifier>*/ getQualifiers();
|
||||
|
||||
/**
|
||||
* The CAst type of this entity.
|
||||
*/
|
||||
CAstType getType();
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.tree;
|
||||
|
||||
public interface CAstMemberReference extends CAstReference {
|
||||
|
||||
public static final CAstMemberReference FUNCTION =
|
||||
new CAstMemberReference() {
|
||||
public String member() {
|
||||
return "the function body";
|
||||
}
|
||||
|
||||
public CAstType type() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Any::FUNCTION CALL";
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return toString().hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return o == this;
|
||||
}
|
||||
};
|
||||
|
||||
String member();
|
||||
|
||||
}
|
|
@ -0,0 +1,182 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.tree;
|
||||
|
||||
/**
|
||||
* This interface represents nodes of CAPA Abstract Syntax Trees. It
|
||||
* is a deliberately minimal interface, simply assuming that the nodes
|
||||
* form a tree and have some minimal state at each node. In
|
||||
* particular, a node has a kind---which should be one of the symbolic
|
||||
* constants in this file---and potentially has child nodes, a
|
||||
* constant values, or possibly both.
|
||||
*
|
||||
* Note that there is no support for mutating these trees. This is
|
||||
* deliberate, and should not be changed. We do not want to force all
|
||||
* clients of the capa ast to handle mutating programs. In
|
||||
* particular, the DOMO infrastructure has many forms of caching and
|
||||
* other operations that rely on the underlying program being
|
||||
* immutable. If you need to mutate these trees for some reason---and
|
||||
* think carefully if you really need to, since this is meant to be
|
||||
* essentially a wire format between components---make specialized
|
||||
* implementations that understand how to do that.
|
||||
*
|
||||
* Also note that this interface does not assume that you need some
|
||||
* great big class hierarchy to structure types of nodes in an ast.
|
||||
* Some people prefer such hierarchies as a matter of taste, but this
|
||||
* interface is designed to not inflict this design choice on others.
|
||||
*
|
||||
* Finally note that the set of node types in this file is not meant
|
||||
* to be exhaustive. As new languages are added, feel free to add new
|
||||
* nodes types as needed.
|
||||
*
|
||||
* @author Julian Dolby (dolby@us.ibm.com)
|
||||
* @author Robert M. Fuhrer (rfuhrer@watson.ibm.com)
|
||||
*
|
||||
*/
|
||||
public interface CAstNode {
|
||||
|
||||
// statement kinds
|
||||
/**
|
||||
* Represents a standard case statement. Children:
|
||||
* </ul>
|
||||
* <li>condition expression
|
||||
* <li>BLOCK_STMT containing all the cases
|
||||
* </ul>
|
||||
*/
|
||||
public static final int SWITCH = 1;
|
||||
|
||||
/**
|
||||
* Represents a standard while loop. Children:
|
||||
* <ul>
|
||||
* <li>expression denoting the loop condition
|
||||
* <li>statement denoting the loop body
|
||||
* </ul>
|
||||
*/
|
||||
public static final int LOOP = 2;
|
||||
|
||||
/**
|
||||
* Represents a block of sequential statements. Children:
|
||||
* <ul>
|
||||
* <li>statement #1
|
||||
* <li>statement #2
|
||||
* <li>...
|
||||
* </ul>
|
||||
*/
|
||||
public static final int BLOCK_STMT = 3;
|
||||
|
||||
/**
|
||||
* Represents a standard try/catch statement. Note that while some
|
||||
* languages choose to bundle together the notion of try/catch and
|
||||
* the notion of unwind-protect (aka 'finally'), the CAst does not.
|
||||
* There is a separate UNWIND node type. Children:
|
||||
* <ul>
|
||||
* <li>the code of the try block.
|
||||
* <li>the code of the catch block <li>...
|
||||
* </ul>
|
||||
*/
|
||||
public static final int TRY = 4;
|
||||
|
||||
/**
|
||||
* Represents an expression statement (e.g. "foo();"). Children:
|
||||
* <ul>
|
||||
* <li>the expression
|
||||
* </ul>
|
||||
*/
|
||||
public static final int EXPR_STMT = 5;
|
||||
public static final int DECL_STMT = 6;
|
||||
public static final int RETURN = 7;
|
||||
public static final int GOTO = 8;
|
||||
public static final int BREAK = 9;
|
||||
public static final int CONTINUE = 10;
|
||||
public static final int IF_STMT = 11;
|
||||
public static final int THROW = 12;
|
||||
public static final int FUNCTION_STMT = 13;
|
||||
public static final int ASSIGN = 14;
|
||||
public static final int ASSIGN_PRE_OP = 15;
|
||||
public static final int ASSIGN_POST_OP = 16;
|
||||
public static final int LABEL_STMT = 17;
|
||||
public static final int IFGOTO = 18;
|
||||
public static final int EMPTY = 19;
|
||||
public static final int RETURN_WITHOUT_BRANCH = 20;
|
||||
public static final int CATCH = 21;
|
||||
public static final int UNWIND = 22;
|
||||
public static final int MONITOR_ENTER = 23;
|
||||
public static final int MONITOR_EXIT = 24;
|
||||
public static final int ECHO = 25;
|
||||
|
||||
// expression kinds
|
||||
public static final int FUNCTION_EXPR = 100;
|
||||
public static final int EXPR_LIST = 101;
|
||||
public static final int CALL = 102;
|
||||
public static final int GET_CAUGHT_EXCEPTION = 103;
|
||||
public static final int BLOCK_EXPR = 104;
|
||||
public static final int BINARY_EXPR = 105;
|
||||
public static final int UNARY_EXPR = 106;
|
||||
public static final int IF_EXPR = 107;
|
||||
public static final int ANDOR_EXPR = 108; // TODO blow away?
|
||||
public static final int NEW = 109;
|
||||
public static final int OBJECT_LITERAL = 110;
|
||||
public static final int VAR = 111;
|
||||
public static final int OBJECT_REF = 112;
|
||||
public static final int CHOICE_EXPR = 113;
|
||||
public static final int CHOICE_CASE = 114;
|
||||
public static final int SUPER = 115;
|
||||
public static final int THIS = 116;
|
||||
public static final int ARRAY_LITERAL = 117;
|
||||
public static final int CAST = 118;
|
||||
public static final int INSTANCEOF = 119;
|
||||
public static final int ARRAY_REF = 120;
|
||||
public static final int ARRAY_LENGTH = 121;
|
||||
public static final int TYPE_OF = 122;
|
||||
public static final int EACH_ELEMENT_HAS_NEXT = 123;
|
||||
public static final int EACH_ELEMENT_GET = 124;
|
||||
public static final int LIST_EXPR = 125;
|
||||
public static final int EMPTY_LIST_EXPR = 126;
|
||||
public static final int TYPE_LITERAL_EXPR = 127;
|
||||
|
||||
// explicit lexical scopes
|
||||
public static final int LOCAL_SCOPE = 200;
|
||||
|
||||
// literal expression kinds
|
||||
public static final int CONSTANT = 300;
|
||||
public static final int OPERATOR = 301;
|
||||
|
||||
// special stuff
|
||||
public static final int PRIMITIVE = 400;
|
||||
public static final int ERROR = 401;
|
||||
public static final int VOID = 402;
|
||||
public static final int ASSERT = 403;
|
||||
|
||||
public static final int SUB_LANGUAGE_BASE = 1000;
|
||||
|
||||
/**
|
||||
* What kind of node is this? Should return some constant from this file.
|
||||
*/
|
||||
int getKind();
|
||||
|
||||
/**
|
||||
* Returns the constant value represented by this node, if
|
||||
* appropriate, and null otherwise.
|
||||
*/
|
||||
Object getValue();
|
||||
|
||||
/**
|
||||
* Return the nth child of this node. If there is no such child,
|
||||
* this method should throw a NoSuchElementException.
|
||||
*/
|
||||
CAstNode getChild(int n);
|
||||
|
||||
/**
|
||||
* How many children does this node have?
|
||||
*/
|
||||
int getChildCount();
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Aug 30, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.tree;
|
||||
|
||||
public interface CAstNodeTypeMap {
|
||||
CAstType getNodeType(CAstNode node);
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Sep 1, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.tree;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class CAstQualifier {
|
||||
public static final Set/* <CAstQualifier> */sQualifiers = new HashSet();
|
||||
|
||||
public static final CAstQualifier CONST = new CAstQualifier("const");
|
||||
public static final CAstQualifier STRICTFP = new CAstQualifier("strictfp");
|
||||
public static final CAstQualifier VOLATILE = new CAstQualifier("volatile");
|
||||
public static final CAstQualifier ABSTRACT = new CAstQualifier("abstract");
|
||||
public static final CAstQualifier INTERFACE = new CAstQualifier("interface");
|
||||
public static final CAstQualifier NATIVE = new CAstQualifier("native");
|
||||
public static final CAstQualifier TRANSIENT = new CAstQualifier("transient");
|
||||
public static final CAstQualifier FINAL = new CAstQualifier("final");
|
||||
public static final CAstQualifier STATIC = new CAstQualifier("static");
|
||||
public static final CAstQualifier PRIVATE = new CAstQualifier("private");
|
||||
public static final CAstQualifier PROTECTED = new CAstQualifier("protected");
|
||||
public static final CAstQualifier PUBLIC = new CAstQualifier("public");
|
||||
public static final CAstQualifier SYNCHRONIZED =
|
||||
new CAstQualifier("synchronized");
|
||||
|
||||
static {
|
||||
sQualifiers.add(PUBLIC);
|
||||
sQualifiers.add(PROTECTED);
|
||||
sQualifiers.add(PRIVATE);
|
||||
sQualifiers.add(STATIC);
|
||||
sQualifiers.add(FINAL);
|
||||
sQualifiers.add(SYNCHRONIZED);
|
||||
sQualifiers.add(TRANSIENT);
|
||||
sQualifiers.add(NATIVE);
|
||||
sQualifiers.add(INTERFACE);
|
||||
sQualifiers.add(ABSTRACT);
|
||||
sQualifiers.add(VOLATILE);
|
||||
sQualifiers.add(STRICTFP);
|
||||
sQualifiers.add(CONST);
|
||||
}
|
||||
|
||||
private static int sNextBitNum = 0;
|
||||
|
||||
private String fName;
|
||||
|
||||
private long fBit;
|
||||
|
||||
public CAstQualifier(String name) {
|
||||
super();
|
||||
fBit = 1L << sNextBitNum++;
|
||||
fName = name;
|
||||
sQualifiers.add(this);
|
||||
}
|
||||
|
||||
public long getBit() {
|
||||
return fBit;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return fName;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof CAstQualifier))
|
||||
return false;
|
||||
CAstQualifier other = (CAstQualifier) o;
|
||||
return other.fName.equals(fName) && (fBit == other.fBit);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int result = 37;
|
||||
result = result * 13 + fName.hashCode();
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.tree;
|
||||
|
||||
/**
|
||||
* This interface is used to denote various kinds of references in
|
||||
* CAst structures. It can be used to denote types for languages like
|
||||
* Java and PHP that have non-trivial mappings from names to actual
|
||||
* entities.
|
||||
*
|
||||
* @author Julian Dolby (dolby@us.ibm.com)
|
||||
*/
|
||||
public interface CAstReference {
|
||||
|
||||
CAstType type();
|
||||
|
||||
};
|
|
@ -0,0 +1,58 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.tree;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* The assumption is that a typical CAst is derived from some kind of
|
||||
* textual source file, for which it makes sense to record source
|
||||
* position in terms of line and column numbers. This interface
|
||||
* encapsulates a mapping from CAstNodes of the an ast to such source
|
||||
* positions.
|
||||
*
|
||||
* @author Julian Dolby (dolby@us.ibm.com)
|
||||
*/
|
||||
public interface CAstSourcePositionMap {
|
||||
|
||||
/**
|
||||
* This interface encapsulates the source position of an ast node
|
||||
* in its source file. Since different parsers record different
|
||||
* degrees of source position information, any client of these
|
||||
* Positions must be prepared to expect -1---symbolizing no
|
||||
* information---to be returned by some or all of its accessors.
|
||||
*
|
||||
* @author Julian Dolby (dolby@us.ibm.com)
|
||||
*/
|
||||
public interface Position extends Comparable {
|
||||
int getFirstLine();
|
||||
int getLastLine();
|
||||
int getFirstCol();
|
||||
int getLastCol();
|
||||
URL getURL();
|
||||
InputStream getInputStream() throws IOException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position of a given node in its source file, or
|
||||
* null if the position is not known or does not exist.
|
||||
*/
|
||||
Position getPosition(CAstNode n);
|
||||
|
||||
/**
|
||||
* Returns an iterator of all CAstNodes for which this map contains
|
||||
* source mapping information.
|
||||
*/
|
||||
Iterator getMappedNodes();
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Aug 30, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.tree;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public interface CAstType {
|
||||
/**
|
||||
* Returns the fully-qualified (e.g. bytecode-compliant for Java) type name.
|
||||
*/
|
||||
String getName();
|
||||
|
||||
Collection/*<CAstType>*/ getSupertypes();
|
||||
|
||||
public interface Primitive extends CAstType {
|
||||
// Need anything else? The name pretty much says it all...
|
||||
}
|
||||
|
||||
public interface Reference extends CAstType {
|
||||
}
|
||||
|
||||
public interface Class extends Reference {
|
||||
boolean isInterface();
|
||||
}
|
||||
|
||||
public interface Array extends Reference {
|
||||
int getNumDimensions();
|
||||
CAstType getElementType();
|
||||
}
|
||||
|
||||
public interface Function extends Reference {
|
||||
CAstType getReturnType();
|
||||
|
||||
List/*<CAstType>*/ getArgumentTypes();
|
||||
Collection/*<CAstType>*/ getExceptionTypes();
|
||||
|
||||
int getArgumentCount();
|
||||
}
|
||||
|
||||
public interface Method extends Function {
|
||||
CAstType getDeclaringType();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Aug 31, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.tree;
|
||||
|
||||
|
||||
public interface CAstTypeDictionary/*<ASTType>*/ {
|
||||
|
||||
CAstType getCAstTypeFor(Object/*ASTType*/ type);
|
||||
|
||||
CAstReference resolveReference(CAstReference ref);
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.tree;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Encapsulates a translator from source files to CAstEntities. This
|
||||
* interface is meant ease the creation of CAst consumers that can
|
||||
* take asts from multiple sources.
|
||||
*
|
||||
* @author Julian Dolby (dolby@us.ibm.com)
|
||||
*/
|
||||
public interface TranslatorToCAst {
|
||||
|
||||
CAstEntity translate(Reader file, String fileName) throws IOException;
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.tree.impl;
|
||||
|
||||
import com.ibm.wala.cast.tree.*;
|
||||
import com.ibm.wala.cast.tree.CAstSourcePositionMap.*;
|
||||
|
||||
public abstract class AbstractSourcePosition implements Position {
|
||||
|
||||
public boolean equals(Object o){
|
||||
if (o instanceof Position) {
|
||||
Position p = (Position)o;
|
||||
return getFirstLine() == p.getFirstLine() &&
|
||||
getLastLine() == p.getLastLine() &&
|
||||
getFirstCol() == p.getFirstCol() &&
|
||||
getLastCol() == p.getLastCol() &&
|
||||
( (getURL() != null)?
|
||||
getURL().equals(p.getURL()):
|
||||
p.getURL() == null);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return getFirstLine()*getLastLine()*getFirstCol()*getLastCol();
|
||||
}
|
||||
|
||||
public int compareTo(Object o) {
|
||||
if (o instanceof Position) {
|
||||
Position p = (Position)o;
|
||||
if (getFirstLine() != p.getFirstLine()) {
|
||||
return getFirstLine() - p.getFirstLine();
|
||||
} else if (getFirstCol() != p.getFirstCol()) {
|
||||
return getFirstCol() - p.getFirstCol();
|
||||
} else if (getLastLine() != p.getLastLine()) {
|
||||
return getLastLine() - p.getLastLine();
|
||||
} else {
|
||||
return getLastCol() - p.getLastCol();
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "["+getFirstLine()+":"+getFirstCol()+"] -> ["+getLastLine()+":"+getLastCol()+"]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.tree.impl;
|
||||
|
||||
import com.ibm.wala.cast.tree.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class CAstCloner {
|
||||
|
||||
private final CAst Ast;
|
||||
|
||||
public CAstCloner(CAst Ast) {
|
||||
this.Ast = Ast;
|
||||
}
|
||||
|
||||
public interface Clone {
|
||||
|
||||
CAstNode newRoot();
|
||||
|
||||
CAstControlFlowMap newCfg();
|
||||
|
||||
CAstSourcePositionMap newPos();
|
||||
|
||||
}
|
||||
|
||||
private CAstNode copyNodes(CAstNode root, Map nodeMap) {
|
||||
if (root instanceof CAstOperator) {
|
||||
nodeMap.put(root, root);
|
||||
return root;
|
||||
} else if (root.getValue() != null) {
|
||||
CAstNode copy = Ast.makeConstant( root.getValue() );
|
||||
nodeMap.put(root, copy);
|
||||
return copy;
|
||||
} else {
|
||||
CAstNode newChildren[] = new CAstNode[ root.getChildCount() ];
|
||||
|
||||
for(int i = 0; i < root.getChildCount(); i++) {
|
||||
newChildren[i] = copyNodes(root.getChild(i), nodeMap);
|
||||
}
|
||||
|
||||
CAstNode copy = Ast.makeNode(root.getKind(), newChildren);
|
||||
nodeMap.put(root, copy);
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
|
||||
private CAstControlFlowMap copyFlow(Map nodeMap, CAstControlFlowMap orig) {
|
||||
Collection oldSources = orig.getMappedNodes();
|
||||
CAstControlFlowRecorder newMap = new CAstControlFlowRecorder();
|
||||
for(Iterator NS = nodeMap.keySet().iterator(); NS.hasNext(); ) {
|
||||
CAstNode old = (CAstNode) NS.next();
|
||||
CAstNode newNode = (CAstNode) nodeMap.get(old);
|
||||
newMap.map(newNode, newNode);
|
||||
if (oldSources.contains(old)) {
|
||||
if (orig.getTarget(old, null) != null) {
|
||||
CAstNode oldTarget = orig.getTarget(old, null);
|
||||
if (nodeMap.containsKey(oldTarget)) {
|
||||
newMap.add(newNode, nodeMap.get(oldTarget), null);
|
||||
} else {
|
||||
newMap.add(newNode, oldTarget, null);
|
||||
}
|
||||
}
|
||||
|
||||
for(Iterator LS = orig.getTargetLabels(old).iterator(); LS.hasNext(); ) {
|
||||
Object label = LS.next();
|
||||
CAstNode oldTarget = orig.getTarget(old, label);
|
||||
if (nodeMap.containsKey(oldTarget)) {
|
||||
newMap.add(newNode, nodeMap.get(oldTarget), label);
|
||||
} else {
|
||||
newMap.add(newNode, oldTarget, label);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return newMap;
|
||||
}
|
||||
|
||||
private CAstSourcePositionMap
|
||||
copySource(Map nodeMap, CAstSourcePositionMap orig)
|
||||
{
|
||||
if (orig == null) {
|
||||
return null;
|
||||
} else {
|
||||
CAstSourcePositionRecorder newMap = new CAstSourcePositionRecorder();
|
||||
for(Iterator NS = nodeMap.keySet().iterator(); NS.hasNext(); ) {
|
||||
CAstNode old = (CAstNode) NS.next();
|
||||
CAstNode newNode = (CAstNode) nodeMap.get(old);
|
||||
|
||||
if (orig.getPosition(old) != null) {
|
||||
newMap.setPosition(newNode, orig.getPosition(old));
|
||||
}
|
||||
}
|
||||
|
||||
return newMap;
|
||||
}
|
||||
}
|
||||
|
||||
public Clone copy(CAstNode root,
|
||||
final CAstControlFlowMap cfg,
|
||||
final CAstSourcePositionMap pos)
|
||||
{
|
||||
final Map nodes = new HashMap();
|
||||
final CAstNode newRoot = copyNodes(root, nodes);
|
||||
return new Clone() {
|
||||
private CAstControlFlowMap theCfg = null;
|
||||
private CAstSourcePositionMap theSource = null;
|
||||
public CAstNode newRoot() { return newRoot; }
|
||||
public CAstControlFlowMap newCfg() {
|
||||
if (theCfg == null) theCfg = copyFlow(nodes, cfg);
|
||||
return theCfg;
|
||||
}
|
||||
public CAstSourcePositionMap newPos() {
|
||||
if (theSource == null) theSource = copySource(nodes, pos);
|
||||
return theSource;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.tree.impl;
|
||||
|
||||
import com.ibm.wala.cast.tree.*;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* An implementation of a CAstControlFlowMap that is designed to be
|
||||
* used by producers of CAPA asts. In addition to implementing the
|
||||
* control flow map, it additionally allows clients to record control
|
||||
* flow mappings in terms of some arbitrary type object that are then
|
||||
* mapped to CAstNodes by the client. These objects can be anything,
|
||||
* but one common use is that some type of parse tree is walked to
|
||||
* build a capa ast, with control flow being recorded in terms of
|
||||
* parse tree nodes and then ast nodes being mapped to parse tree
|
||||
* nodes.
|
||||
*
|
||||
* Note that, at present, support for mapping control flow on ast
|
||||
* nodes directly is clunky. It is necessary to establish that an ast
|
||||
* nodes maps to itself, i.e. call xx.map(node, node).
|
||||
*
|
||||
* @author Julian Dolby (dolby@us.ibm.com)
|
||||
*/
|
||||
public class CAstControlFlowRecorder implements CAstControlFlowMap {
|
||||
private final Map CAstToNode = new LinkedHashMap();
|
||||
private final Map nodeToCAst = new LinkedHashMap();
|
||||
private final Map table = new LinkedHashMap();
|
||||
private final Map labelMap = new LinkedHashMap();
|
||||
private final Map sourceMap = new LinkedHashMap();
|
||||
|
||||
private class Key {
|
||||
private final Object label;
|
||||
private final Object from;
|
||||
|
||||
Key(Object label, Object from) {
|
||||
this.from = from;
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
Key(Object label, CAstNode from) {
|
||||
this(label, CAstToNode.get(from));
|
||||
Assertions._assert(CAstToNode.containsKey(from));
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
if (label != null)
|
||||
return from.hashCode()*label.hashCode();
|
||||
else
|
||||
return from.hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return (o instanceof Key) &&
|
||||
from == ((Key)o).from &&
|
||||
((label==null)?
|
||||
((Key)o).label == null:
|
||||
label.equals( ((Key)o).label ));
|
||||
}
|
||||
}
|
||||
|
||||
public CAstControlFlowRecorder() {
|
||||
map(EXCEPTION_TO_EXIT, EXCEPTION_TO_EXIT);
|
||||
}
|
||||
|
||||
public CAstNode getTarget(CAstNode from, Object label) {
|
||||
Key key = new Key(label, from);
|
||||
if (table.containsKey(key))
|
||||
return (CAstNode)nodeToCAst.get( table.get(key) );
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public Collection getTargetLabels(CAstNode from) {
|
||||
if (labelMap.containsKey( CAstToNode.get(from) )) {
|
||||
return (Set) labelMap.get( CAstToNode.get(from) );
|
||||
} else {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
}
|
||||
|
||||
public Collection getSourceNodes(CAstNode to) {
|
||||
if (sourceMap.containsKey( CAstToNode.get(to) )) {
|
||||
return (Set) sourceMap.get( CAstToNode.get(to) );
|
||||
} else {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
}
|
||||
|
||||
public Collection getMappedNodes() {
|
||||
Set nodes = new LinkedHashSet();
|
||||
for(Iterator keys = table.keySet().iterator(); keys.hasNext(); ) {
|
||||
nodes.add( (CAstNode) nodeToCAst.get( ((Key)keys.next()).from ) );
|
||||
}
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a control-flow edge from the `from' node to the `to' node
|
||||
* with the (possibly null) label `label'. These nodes must be
|
||||
* mapped by the client to CAstNodes using the `map' call; this mapping
|
||||
* can happen before or after this add call.
|
||||
*/
|
||||
public void add(Object from, Object to, Object label) {
|
||||
table.put(new Key(label, from), to);
|
||||
|
||||
Set ls = (Set)labelMap.get(from);
|
||||
if (ls==null) labelMap.put(from, ls=new LinkedHashSet(2));
|
||||
ls.add( label );
|
||||
|
||||
Set ss = (Set)sourceMap.get(to);
|
||||
if (ss==null) sourceMap.put(to, ss=new LinkedHashSet(2));
|
||||
ss.add( from );
|
||||
}
|
||||
|
||||
/**
|
||||
* Establish a mapping between some object `node' and the ast node
|
||||
* `ast'. Objects used a endpoints in a control flow edge must be
|
||||
* mapped to ast nodes using this call.
|
||||
*/
|
||||
public void map(Object node, CAstNode ast) {
|
||||
nodeToCAst.put(node, ast);
|
||||
CAstToNode.put(ast, node);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,187 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.tree.impl;
|
||||
|
||||
import com.ibm.wala.cast.tree.*;
|
||||
import com.ibm.wala.cast.util.CAstPrinter;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* An implementation of CAst, i.e. a simple factory for creating capa
|
||||
* ast nodes. This class simply creates generic nodes with a kind
|
||||
* field, and either an array of children or a constant values. Note
|
||||
* that there is no easy way to mutate these trees; do not change
|
||||
* this (see CAstNode for the rationale for this rule).
|
||||
*
|
||||
* @author Julian Dolby (dolby@us.ibm.com)
|
||||
*
|
||||
*/
|
||||
public class CAstImpl implements CAst {
|
||||
private int nextID= 0;
|
||||
|
||||
public String makeUnique() {
|
||||
return "id" + (nextID++);
|
||||
}
|
||||
|
||||
protected static class CAstNodeImpl implements CAstNode {
|
||||
protected final CAstNode[] cs;
|
||||
protected final int kind;
|
||||
|
||||
protected CAstNodeImpl(int kind, CAstNode[] cs) {
|
||||
this.kind = kind;
|
||||
this.cs = cs;
|
||||
|
||||
if (Assertions.verifyAssertions)
|
||||
for(int i = 0; i < cs.length; i++)
|
||||
Assertions._assert(cs[i] != null,
|
||||
"argument " + i + " is null for node kind " + kind + " [" + CAstPrinter.entityKindAsString(kind) + "]");
|
||||
}
|
||||
|
||||
public int getKind() {
|
||||
return kind;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public CAstNode getChild(int n) {
|
||||
try {
|
||||
return cs[n];
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
}
|
||||
|
||||
public int getChildCount() {
|
||||
return cs.length;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return CAstPrinter.print(this);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int code = getKind() * (getChildCount()+13);
|
||||
for(int i = 0; i < getChildCount(); i++) {
|
||||
code *= getChild(i).getKind();
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
public CAstNode makeNode(final int kind, final CAstNode[] cs) {
|
||||
return new CAstNodeImpl(kind, cs);
|
||||
}
|
||||
|
||||
public CAstNode makeNode(int kind, CAstNode c1, CAstNode[] cs) {
|
||||
CAstNode[] children = new CAstNode[ cs.length + 1 ];
|
||||
children[0] = c1;
|
||||
System.arraycopy(cs, 0, children, 1, cs.length);
|
||||
return makeNode(kind, children);
|
||||
}
|
||||
|
||||
public CAstNode makeNode(int kind) {
|
||||
return makeNode(kind, new CAstNode[0]);
|
||||
}
|
||||
|
||||
public CAstNode makeNode(int kind, CAstNode c1) {
|
||||
return makeNode(kind, new CAstNode[]{c1});
|
||||
}
|
||||
|
||||
public CAstNode makeNode(int kind, CAstNode c1, CAstNode c2) {
|
||||
return makeNode(kind, new CAstNode[]{c1, c2});
|
||||
}
|
||||
|
||||
public CAstNode makeNode(int kind, CAstNode c1, CAstNode c2, CAstNode c3) {
|
||||
return makeNode(kind, new CAstNode[]{c1, c2, c3});
|
||||
}
|
||||
|
||||
public CAstNode makeNode(int kind, CAstNode c1, CAstNode c2, CAstNode c3, CAstNode c4) {
|
||||
return makeNode(kind, new CAstNode[]{c1, c2, c3, c4});
|
||||
}
|
||||
|
||||
public CAstNode makeNode(int kind, CAstNode c1, CAstNode c2, CAstNode c3, CAstNode c4, CAstNode c5) {
|
||||
return makeNode(kind, new CAstNode[]{c1, c2, c3, c4, c5});
|
||||
}
|
||||
|
||||
public CAstNode makeNode(int kind, CAstNode c1, CAstNode c2, CAstNode c3, CAstNode c4, CAstNode c5, CAstNode c6) {
|
||||
return makeNode(kind, new CAstNode[]{c1, c2, c3, c4, c5, c6});
|
||||
}
|
||||
|
||||
protected static class CAstValueImpl implements CAstNode {
|
||||
protected final Object value;
|
||||
|
||||
protected CAstValueImpl(Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getKind() {
|
||||
return CAstNode.CONSTANT;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public CAstNode getChild(int n) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
public int getChildCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "CAstValue: " + value;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return getKind() * toString().hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
public CAstNode makeConstant(final Object value) {
|
||||
return new CAstValueImpl(value);
|
||||
}
|
||||
|
||||
public CAstNode makeConstant(boolean value) {
|
||||
return makeConstant(value? Boolean.TRUE: Boolean.FALSE);
|
||||
}
|
||||
|
||||
public CAstNode makeConstant(char value) {
|
||||
return makeConstant( new Character(value) );
|
||||
}
|
||||
|
||||
public CAstNode makeConstant(short value) {
|
||||
return makeConstant( new Short(value) );
|
||||
}
|
||||
|
||||
public CAstNode makeConstant(int value) {
|
||||
return makeConstant( new Integer(value) );
|
||||
}
|
||||
|
||||
public CAstNode makeConstant(long value) {
|
||||
return makeConstant( new Long(value) );
|
||||
}
|
||||
|
||||
public CAstNode makeConstant(float value) {
|
||||
return makeConstant( new Float(value) );
|
||||
}
|
||||
|
||||
public CAstNode makeConstant(double value) {
|
||||
return makeConstant( new Double(value) );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Oct 10, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.tree.impl;
|
||||
|
||||
import com.ibm.wala.cast.tree.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class CAstNodeTypeMapRecorder
|
||||
extends HashMap
|
||||
implements CAstNodeTypeMap
|
||||
{
|
||||
private static final long serialVersionUID= 7812144102027916961L;
|
||||
|
||||
public CAstType getNodeType(CAstNode node) {
|
||||
return (CAstType) get(node);
|
||||
}
|
||||
|
||||
public void add(CAstNode node, CAstType type) {
|
||||
put(node, type);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.tree.impl;
|
||||
|
||||
import com.ibm.wala.cast.tree.*;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* Various operators that are built in to many languages, and hence
|
||||
* perhaps deserve special notice in capa ast interface. There is no
|
||||
* strong notion of what should be in here, so feel free to add other
|
||||
* common operators.
|
||||
*
|
||||
* @author Julian Dolby (dolby@us.ibm.com)
|
||||
*/
|
||||
public class CAstOperator implements CAstNode {
|
||||
private final String op;
|
||||
|
||||
private CAstOperator(String op) {
|
||||
this.op = op;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "OP:" + op;
|
||||
}
|
||||
|
||||
public int getKind() {
|
||||
return CAstNode.OPERATOR;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return op;
|
||||
}
|
||||
|
||||
public CAstNode getChild(int n) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
public int getChildCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public final static CAstOperator OP_ADD = new CAstOperator("+");
|
||||
public final static CAstOperator OP_CONCAT = new CAstOperator(".");
|
||||
public final static CAstOperator OP_DIV = new CAstOperator("/");
|
||||
public final static CAstOperator OP_LSH = new CAstOperator("<<");
|
||||
public final static CAstOperator OP_MOD = new CAstOperator("%");
|
||||
public final static CAstOperator OP_MUL = new CAstOperator("*");
|
||||
public final static CAstOperator OP_RSH = new CAstOperator(">>");
|
||||
public final static CAstOperator OP_URSH = new CAstOperator(">>>");
|
||||
public final static CAstOperator OP_SUB = new CAstOperator("-");
|
||||
public final static CAstOperator OP_EQ = new CAstOperator("==");
|
||||
public final static CAstOperator OP_GE = new CAstOperator(">=");
|
||||
public final static CAstOperator OP_GT = new CAstOperator(">");
|
||||
public final static CAstOperator OP_LE = new CAstOperator("<=");
|
||||
public final static CAstOperator OP_LT = new CAstOperator("<");
|
||||
public final static CAstOperator OP_NE = new CAstOperator("!=");
|
||||
public final static CAstOperator OP_NOT = new CAstOperator("!");
|
||||
public final static CAstOperator OP_BITNOT = new CAstOperator("~");
|
||||
public final static CAstOperator OP_BIT_AND = new CAstOperator("&");
|
||||
public final static CAstOperator OP_REL_AND = new CAstOperator("&&");
|
||||
public final static CAstOperator OP_BIT_OR = new CAstOperator("|");
|
||||
public final static CAstOperator OP_REL_OR = new CAstOperator("||");
|
||||
public final static CAstOperator OP_BIT_XOR = new CAstOperator("^");
|
||||
public final static CAstOperator OP_REL_XOR = new CAstOperator("^^");
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.tree.impl;
|
||||
|
||||
import com.ibm.wala.cast.tree.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
|
||||
public class CAstSourcePositionRecorder implements CAstSourcePositionMap {
|
||||
|
||||
private final HashMap positions = new HashMap();
|
||||
|
||||
public Position getPosition(CAstNode n) {
|
||||
return (Position) positions.get(n);
|
||||
}
|
||||
|
||||
public Iterator getMappedNodes() {
|
||||
return positions.keySet().iterator();
|
||||
}
|
||||
|
||||
public void setPosition(CAstNode n, Position p) {
|
||||
positions.put(n, p);
|
||||
}
|
||||
|
||||
public void setPosition(CAstNode n,
|
||||
final int fl,
|
||||
final int fc,
|
||||
final int ll,
|
||||
final int lc,
|
||||
final String url,
|
||||
final String file)
|
||||
throws MalformedURLException
|
||||
{
|
||||
setPosition(n, fl, fc, ll, lc, new URL(url), new URL(file));
|
||||
}
|
||||
|
||||
public void setPosition(CAstNode n,
|
||||
final int fl,
|
||||
final int fc,
|
||||
final int ll,
|
||||
final int lc,
|
||||
final URL url,
|
||||
final URL file)
|
||||
{
|
||||
setPosition(n,
|
||||
new AbstractSourcePosition() {
|
||||
public int getFirstLine() { return fl; }
|
||||
public int getLastLine() { return ll; }
|
||||
public int getFirstCol() { return fc; }
|
||||
public int getLastCol() { return lc; }
|
||||
public URL getURL() { return url; }
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return file.openConnection().getInputStream();
|
||||
}
|
||||
public String toString() {
|
||||
return "["+fl+":"+fc+"]->["+ll+":"+lc+"]";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setPosition(CAstNode n, int lineNumber, String url, String file)
|
||||
throws MalformedURLException
|
||||
{
|
||||
setPosition(n, lineNumber, new URL(url), new URL(file));
|
||||
}
|
||||
|
||||
public void setPosition(CAstNode n, int lineNumber, URL url, URL file) {
|
||||
setPosition(n, new LineNumberPosition(url, file, lineNumber));
|
||||
}
|
||||
|
||||
public void addAll(CAstSourcePositionMap other) {
|
||||
for(Iterator nodes = other.getMappedNodes(); nodes.hasNext(); ) {
|
||||
CAstNode node = (CAstNode) nodes.next();
|
||||
setPosition(node, other.getPosition(node));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Created on Sep 21, 2005
|
||||
*/
|
||||
package com.ibm.wala.cast.tree.impl;
|
||||
|
||||
import com.ibm.wala.cast.tree.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class CAstTypeDictionaryImpl implements CAstTypeDictionary {
|
||||
private final Map/*<ASTType,CAstType>*/ fMap= new HashMap();
|
||||
|
||||
public CAstType getCAstTypeFor(Object/*ASTType*/ astType) {
|
||||
return (CAstType) fMap.get(astType);
|
||||
}
|
||||
|
||||
public void map(Object/*ASTType*/ astType, CAstType castType) {
|
||||
fMap.put(astType, castType);
|
||||
}
|
||||
|
||||
public CAstReference resolveReference(CAstReference ref) {
|
||||
return ref;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.tree.impl;
|
||||
|
||||
import com.ibm.wala.cast.tree.*;
|
||||
|
||||
/**
|
||||
* An implementation of CAst, i.e. a simple factory for creating capa
|
||||
* ast nodes. This class simply creates generic nodes with a kind
|
||||
* field, and either an array of children. Note that there is no easy
|
||||
* way to mutate these trees; do not changes this (see CAstNode for
|
||||
* the rationale for this rule).
|
||||
*
|
||||
* @author Julian Dolby (dolby@us.ibm.com)
|
||||
*
|
||||
*/
|
||||
public class CAstValueImpl extends CAstImpl {
|
||||
|
||||
protected static class CAstNodeValueImpl extends CAstNodeImpl {
|
||||
|
||||
protected CAstNodeValueImpl(int kind, CAstNode cs[]) {
|
||||
super(kind, cs);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int value = 1237 * kind;
|
||||
for(int i = 0; i < cs.length; i++)
|
||||
value *= cs[i].hashCode();
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (! (o instanceof CAstNode)) return false;
|
||||
if (kind != ((CAstNode)o).getKind()) return false;
|
||||
if (((CAstNode)o).getChildCount() != cs.length) return false;
|
||||
for(int i = 0; i < cs.length; i++)
|
||||
if (! cs[i].equals(((CAstNode)o).getChild(i)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public CAstNode makeNode(final int kind, final CAstNode[] cs) {
|
||||
return new CAstNodeValueImpl(kind, cs);
|
||||
}
|
||||
|
||||
protected static class CAstValueValueImpl extends CAstValueImpl {
|
||||
|
||||
protected CAstValueValueImpl(Object value) {
|
||||
super(value);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return value.hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof CAstNode) {
|
||||
return value==null?
|
||||
((CAstNode)o).getValue()==null:
|
||||
value.equals(((CAstNode)o).getValue());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CAstNode makeConstant(final Object value) {
|
||||
return new CAstValueValueImpl(value);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.tree.impl;
|
||||
|
||||
import com.ibm.wala.cast.tree.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class DelegatingEntity implements CAstEntity {
|
||||
private final CAstEntity base;
|
||||
|
||||
public DelegatingEntity(CAstEntity base) {
|
||||
this.base = base;
|
||||
}
|
||||
|
||||
public int getKind() {
|
||||
return base.getKind();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return base.getName();
|
||||
}
|
||||
|
||||
public String getSignature() {
|
||||
return base.getSignature();
|
||||
}
|
||||
|
||||
public String[] getArgumentNames() {
|
||||
return base.getArgumentNames();
|
||||
}
|
||||
|
||||
public CAstNode[] getArgumentDefaults() {
|
||||
return base.getArgumentDefaults();
|
||||
}
|
||||
|
||||
public int getArgumentCount() {
|
||||
return base.getArgumentCount();
|
||||
}
|
||||
|
||||
public Map getAllScopedEntities() {
|
||||
return base.getAllScopedEntities();
|
||||
}
|
||||
|
||||
public Iterator getScopedEntities(CAstNode construct) {
|
||||
return base.getScopedEntities(construct);
|
||||
}
|
||||
|
||||
public CAstNode getAST() {
|
||||
return base.getAST();
|
||||
}
|
||||
|
||||
public CAstControlFlowMap getControlFlow() {
|
||||
return base.getControlFlow();
|
||||
}
|
||||
|
||||
public CAstSourcePositionMap getSourceMap() {
|
||||
return base.getSourceMap();
|
||||
}
|
||||
|
||||
public CAstSourcePositionMap.Position getPosition() {
|
||||
return base.getPosition();
|
||||
}
|
||||
|
||||
public CAstNodeTypeMap getNodeTypeMap() {
|
||||
return base.getNodeTypeMap();
|
||||
}
|
||||
|
||||
public Collection getQualifiers() {
|
||||
return base.getQualifiers();
|
||||
}
|
||||
|
||||
public CAstType getType() {
|
||||
return base.getType();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.tree.impl;
|
||||
|
||||
import com.ibm.wala.cast.tree.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
|
||||
public class LineNumberPosition extends AbstractSourcePosition {
|
||||
private final URL url;
|
||||
private final URL localFile;
|
||||
private final int lineNumber;
|
||||
|
||||
public LineNumberPosition(URL url, URL localFile, int lineNumber) {
|
||||
this.url = url;
|
||||
this.localFile = localFile;
|
||||
this.lineNumber = lineNumber;
|
||||
}
|
||||
|
||||
public int getFirstLine() { return lineNumber; }
|
||||
|
||||
public int getLastLine() { return lineNumber; }
|
||||
|
||||
public int getFirstCol() { return -1; }
|
||||
|
||||
public int getLastCol() { return -1; }
|
||||
|
||||
public URL getURL() { return url; }
|
||||
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return localFile.openConnection().getInputStream();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "[line:"+lineNumber+"]";
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue