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:
dolby-oss 2007-02-02 17:17:13 +00:00
parent 386cb9e3ad
commit 3d9390a397
108 changed files with 17251 additions and 0 deletions

View File

@ -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>

View File

@ -0,0 +1,2 @@
bin
domo-trace.txt*

View File

@ -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>

View File

@ -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>&lt;project&gt;/.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>

View File

@ -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

View File

@ -0,0 +1,4 @@
source.. = source/
output.. = bin/
bin.includes = META-INF/,\
.

View File

@ -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>

View File

@ -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.

View File

@ -0,0 +1,3 @@
Makefile.configuration
CAstWrapper.lib
CAstWrapper.exp

View File

@ -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*

View File

@ -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 =

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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 );
}

View File

@ -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()
}

View File

@ -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());
}
}

View File

@ -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());
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}
}

View File

@ -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 + "]";
}
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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));
}
}

View File

@ -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;
}
}

View File

@ -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() + "]";
}
}

View File

@ -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;
}
};
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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));
}
}
}

View File

@ -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);
}
}

View File

@ -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 );
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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);
}
}

View File

@ -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) {
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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);
}
}
};
}
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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();
}
*/
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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 ");
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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();
};

View File

@ -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();
}

View File

@ -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();
}
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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()+"]";
}
}

View File

@ -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;
}
};
}
}

View File

@ -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);
}
}

View File

@ -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) );
}
}

View File

@ -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);
}
}

View File

@ -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("^^");
}

View File

@ -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));
}
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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

Some files were not shown because too many files have changed in this diff Show More