attempt to introduce tags and trunk
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@490 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
commit
df97f42b7e
9
com.ibm.wala.core/.classpath
Normal file
9
com.ibm.wala.core/.classpath
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="dat"/>
|
||||
<classpathentry kind="src" path="lib"/>
|
||||
<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>
|
||||
28
com.ibm.wala.core/.project
Normal file
28
com.ibm.wala.core/.project
Normal file
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.ibm.wala.core</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>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
12
com.ibm.wala.core/.settings/org.eclipse.jdt.core.prefs
Normal file
12
com.ibm.wala.core/.settings/org.eclipse.jdt.core.prefs
Normal file
@ -0,0 +1,12 @@
|
||||
#Mon Oct 02 08:58:10 EDT 2006
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.5
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.5
|
||||
3
com.ibm.wala.core/.settings/org.eclipse.jdt.ui.prefs
Normal file
3
com.ibm.wala.core/.settings/org.eclipse.jdt.ui.prefs
Normal file
@ -0,0 +1,3 @@
|
||||
#Mon Oct 02 08:58:11 EDT 2006
|
||||
eclipse.preferences.version=1
|
||||
internal.default.compliance=default
|
||||
68
com.ibm.wala.core/META-INF/MANIFEST.MF
Normal file
68
com.ibm.wala.core/META-INF/MANIFEST.MF
Normal file
@ -0,0 +1,68 @@
|
||||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: WALA Core Plug-in
|
||||
Bundle-SymbolicName: com.ibm.wala.core
|
||||
Bundle-Version: 1.0.0
|
||||
Bundle-Activator: com.ibm.wala.core.plugin.CorePlugin
|
||||
Bundle-Vendor: IBM
|
||||
Bundle-Localization: plugin
|
||||
Require-Bundle: com.ibm.wala.emf;visibility:=reexport,
|
||||
com.ibm.wala.shrike;visibility:=reexport,
|
||||
org.eclipse.core.resources,
|
||||
org.eclipse.jface,
|
||||
org.eclipse.jdt.core
|
||||
Eclipse-LazyStart: true
|
||||
Export-Package: .,
|
||||
com.ibm.wala.analysis.pointers,
|
||||
com.ibm.wala.analysis.reflection,
|
||||
com.ibm.wala.analysis.stackMachine,
|
||||
com.ibm.wala.analysis.typeInference,
|
||||
com.ibm.wala.cfg,
|
||||
com.ibm.wala.cfg.cdg,
|
||||
com.ibm.wala.classLoader,
|
||||
com.ibm.wala.client,
|
||||
com.ibm.wala.client.impl,
|
||||
com.ibm.wala.core.plugin,
|
||||
com.ibm.wala.dataflow.IFDS,
|
||||
com.ibm.wala.dataflow.graph,
|
||||
com.ibm.wala.dataflow.ssa,
|
||||
com.ibm.wala.dynamic,
|
||||
com.ibm.wala.emf.wrappers,
|
||||
com.ibm.wala.escape,
|
||||
com.ibm.wala.fixedpoint.impl,
|
||||
com.ibm.wala.fixpoint,
|
||||
com.ibm.wala.ipa.callgraph,
|
||||
com.ibm.wala.ipa.callgraph.impl,
|
||||
com.ibm.wala.ipa.callgraph.propagation,
|
||||
com.ibm.wala.ipa.callgraph.propagation.cfa,
|
||||
com.ibm.wala.ipa.callgraph.propagation.rta,
|
||||
com.ibm.wala.ipa.cfg,
|
||||
com.ibm.wala.ipa.cha,
|
||||
com.ibm.wala.ipa.modref,
|
||||
com.ibm.wala.ipa.slicer,
|
||||
com.ibm.wala.ipa.summaries,
|
||||
com.ibm.wala.model,
|
||||
com.ibm.wala.model.java.lang,
|
||||
com.ibm.wala.properties,
|
||||
com.ibm.wala.ssa,
|
||||
com.ibm.wala.ssa.analysis,
|
||||
com.ibm.wala.types,
|
||||
com.ibm.wala.util,
|
||||
com.ibm.wala.util.bytecode,
|
||||
com.ibm.wala.util.collections,
|
||||
com.ibm.wala.util.config,
|
||||
com.ibm.wala.util.debug,
|
||||
com.ibm.wala.util.graph,
|
||||
com.ibm.wala.util.graph.impl,
|
||||
com.ibm.wala.util.graph.traverse,
|
||||
com.ibm.wala.util.heapTrace,
|
||||
com.ibm.wala.util.internationalization,
|
||||
com.ibm.wala.util.intset,
|
||||
com.ibm.wala.util.io,
|
||||
com.ibm.wala.util.logging,
|
||||
com.ibm.wala.util.math,
|
||||
com.ibm.wala.util.perf,
|
||||
com.ibm.wala.util.scope,
|
||||
com.ibm.wala.util.system,
|
||||
com.ibm.wala.util.warnings,
|
||||
com.ibm.wala.viz
|
||||
13
com.ibm.wala.core/build.properties
Normal file
13
com.ibm.wala.core/build.properties
Normal file
@ -0,0 +1,13 @@
|
||||
bin.includes = lib/primordial.jar.model,\
|
||||
plugin.properties,\
|
||||
dat/J2SEClassHierarchyExclusions.xml,\
|
||||
dat/SyntheticJ2SEModel.xml,\
|
||||
dat/benign.xml,\
|
||||
dat/natives.xml,\
|
||||
META-INF/,\
|
||||
.
|
||||
jars.compile.order = .
|
||||
output.. = bin/
|
||||
source.. = dat/,\
|
||||
src/,\
|
||||
lib/
|
||||
202
com.ibm.wala.core/build.xml
Normal file
202
com.ibm.wala.core/build.xml
Normal file
@ -0,0 +1,202 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="com.ibm.wala.core" default="build.jars" basedir=".">
|
||||
|
||||
<property name="basews" value="${ws}"/>
|
||||
<property name="baseos" value="${os}"/>
|
||||
<property name="basearch" value="${arch}"/>
|
||||
<property name="basenl" value="${nl}"/>
|
||||
|
||||
<!-- Compiler settings. -->
|
||||
<property name="javacFailOnError" value="true"/>
|
||||
<property name="javacDebugInfo" value="on"/>
|
||||
<property name="javacVerbose" value="false"/>
|
||||
<property name="logExtension" value=".log"/>
|
||||
<property name="compilerArg" value=""/>
|
||||
<property name="javacSource" value="1.5"/>
|
||||
<property name="javacTarget" value="1.5"/>
|
||||
<path id="path_bootclasspath">
|
||||
<fileset dir="${java.home}/lib">
|
||||
<include name="*.jar"/>
|
||||
</fileset>
|
||||
</path>
|
||||
<property name="bootclasspath" refid="path_bootclasspath"/>
|
||||
<property name="bundleJavacSource" value="${javacSource}"/>
|
||||
<property name="bundleJavacTarget" value="${javacTarget}"/>
|
||||
<property name="bundleBootClasspath" value="${bootclasspath}"/>
|
||||
|
||||
<target name="init" depends="properties">
|
||||
<condition property="pluginTemp" value="${buildTempFolder}/plugins">
|
||||
<isset property="buildTempFolder"/>
|
||||
</condition>
|
||||
<property name="pluginTemp" value="${basedir}"/>
|
||||
<condition property="build.result.folder" value="${pluginTemp}/com.ibm.wala.core">
|
||||
<isset property="buildTempFolder"/>
|
||||
</condition>
|
||||
<property name="build.result.folder" value="${basedir}"/>
|
||||
<property name="temp.folder" value="${basedir}/temp.folder"/>
|
||||
<property name="plugin.destination" value="${basedir}/output"/>
|
||||
<property name="eclipse.root" value="c:/eclipse"/>
|
||||
</target>
|
||||
|
||||
<target name="properties" if="eclipse.running">
|
||||
<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
|
||||
|
||||
</target>
|
||||
|
||||
<target name="build.update.jar" depends="init" description="Build the plug-in: com.ibm.wala.core for an update site.">
|
||||
<delete dir="${temp.folder}"/>
|
||||
<mkdir dir="${temp.folder}"/>
|
||||
<delete dir="${plugin.destination}"/>
|
||||
<mkdir dir="${plugin.destination}"/>
|
||||
<antcall target="build.jars"/>
|
||||
<antcall target="gather.bin.parts">
|
||||
<param name="destination.temp.folder" value="${temp.folder}/"/>
|
||||
</antcall>
|
||||
<copy todir="${temp.folder}/com.ibm.wala.core_1.0.0" failonerror="true" overwrite="false">
|
||||
<fileset dir="src/" includes="**/*.java" />
|
||||
</copy>
|
||||
<zip destfile="${plugin.destination}/com.ibm.wala.core_1.0.0.jar" basedir="${temp.folder}/com.ibm.wala.core_1.0.0" filesonly="false" whenempty="skip" update="false"/>
|
||||
<delete dir="${temp.folder}"/>
|
||||
</target>
|
||||
|
||||
<target name="@dot" depends="init" description="Create jar: com.ibm.wala.core @dot.">
|
||||
<delete dir="${temp.folder}/@dot.bin"/>
|
||||
<mkdir dir="${temp.folder}/@dot.bin"/>
|
||||
<path id="@dot.classpath">
|
||||
<pathelement path="../com.ibm.wala.emf/bin/"/>
|
||||
<pathelement path="../com.ibm.wala.emf/@dot"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.runtime_3.2.0.v20060603.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.osgi_3.2.0.v20060601.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.equinox.common_3.2.0.v20060603.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.jobs_3.2.0.v20060603.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603/runtime_registry_compatibility.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.equinox.registry_3.2.0.v20060601.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.apache.xerces_2.8.0.v200606131651/resolver.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.apache.xerces_2.8.0.v200606131651/xercesImpl.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.apache.xerces_2.8.0.v200606131651/xml-apis.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.equinox.preferences_3.2.0.v20060601.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603/@dot"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.contenttype_3.2.0.v20060603.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.runtime.compatibility.auth_3.2.0.v20060601.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.emf.ecore_2.2.0.v200606271057.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.emf.common_2.2.0.v200606271057.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.resources_3.2.0.v20060603.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.resources.compatibility_3.2.0.v20060603.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.resources.win32_3.2.0.v20060603.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.runtime.compatibility_3.1.100.v20060603.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.update.configurator_3.2.0.v20060605.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.ant.core_3.1.100.v20060531.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.variables_3.1.100.v20060605.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.expressions_3.2.0.v20060605-1400.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.filesystem_1.0.0.v20060603.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.filesystem.win32.x86_1.0.0.v20060603.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.emf.ecore.xmi_2.2.0.v200606271057.jar"/>
|
||||
<pathelement path="../com.ibm.wala.shrike/bin/"/>
|
||||
<pathelement path="../com.ibm.wala.shrike/@dot"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.jface_3.2.0.I20060605-1400.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.swt_3.2.0.v3232o.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.swt.win32.win32.x86_3.2.0.v3232m.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.commands_3.2.0.I20060605-1400.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.jdt.core_3.2.0.v_671.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.text_3.2.0.v20060605-1400.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/com.ibm.icu_3.4.4.1.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.team.core_3.2.0.I200606051140.jar"/>
|
||||
</path>
|
||||
<!-- compile the source code -->
|
||||
<javac destdir="${temp.folder}/@dot.bin" failonerror="${javacFailOnError}" verbose="${javacVerbose}" debug="${javacDebugInfo}" includeAntRuntime="no" bootclasspath="${bundleBootClasspath}" source="${bundleJavacSource}" target="${bundleJavacTarget}" >
|
||||
<compilerarg line="${compilerArg}" compiler="${build.compiler}"/>
|
||||
<classpath refid="@dot.classpath" />
|
||||
<src path="dat/" />
|
||||
<src path="src/" />
|
||||
<src path="lib/" />
|
||||
<compilerarg value="@${basedir}/javaCompiler...args" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
|
||||
<compilerarg line="-log '${temp.folder}/@dot.bin${logExtension}'" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
|
||||
</javac>
|
||||
<!-- Copy necessary resources -->
|
||||
<copy todir="${temp.folder}/@dot.bin" failonerror="true" overwrite="false">
|
||||
<fileset dir="dat/" excludes="**/*.java, **/package.htm*" />
|
||||
<fileset dir="src/" excludes="**/*.java, **/package.htm*" />
|
||||
<fileset dir="lib/" excludes="**/*.java, **/package.htm*" />
|
||||
</copy>
|
||||
<mkdir dir="${build.result.folder}"/>
|
||||
<copy todir="${build.result.folder}/@dot" failonerror="true" overwrite="false">
|
||||
<fileset dir="${temp.folder}/@dot.bin" />
|
||||
</copy>
|
||||
<delete dir="${temp.folder}/@dot.bin"/>
|
||||
</target>
|
||||
|
||||
<target name="src.zip" depends="init" unless="src.zip">
|
||||
<mkdir dir="${build.result.folder}"/>
|
||||
<zip destfile="${build.result.folder}/src.zip" filesonly="false" whenempty="skip" update="false">
|
||||
<fileset dir="dat/" includes="**/*.java" />
|
||||
<fileset dir="src/" includes="**/*.java" />
|
||||
<fileset dir="lib/" includes="**/*.java" />
|
||||
</zip>
|
||||
</target>
|
||||
|
||||
<target name="build.jars" depends="init" description="Build all the jars for the plug-in: com.ibm.wala.core.">
|
||||
<available property="@dot" file="${build.result.folder}/@dot"/>
|
||||
<antcall target="@dot"/>
|
||||
</target>
|
||||
|
||||
<target name="build.sources" depends="init">
|
||||
<available property="src.zip" file="${build.result.folder}/src.zip"/>
|
||||
<antcall target="src.zip"/>
|
||||
</target>
|
||||
|
||||
<target name="gather.bin.parts" depends="init" if="destination.temp.folder">
|
||||
<mkdir dir="${destination.temp.folder}/com.ibm.wala.core_1.0.0"/>
|
||||
<copy todir="${destination.temp.folder}/com.ibm.wala.core_1.0.0" failonerror="true" overwrite="false">
|
||||
<fileset dir="${build.result.folder}/@dot" includes="**" />
|
||||
</copy>
|
||||
<copy todir="${destination.temp.folder}/com.ibm.wala.core_1.0.0" failonerror="true" overwrite="false">
|
||||
<fileset dir="${basedir}" includes="lib/primordial.jar.model,plugin.properties,lib/extension.jar.model,dat/J2SEClassHierarchyExclusions.xml,dat/SyntheticJ2SEModel.xml,dat/benign.xml,dat/natives.xml,META-INF/" />
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="build.zips" depends="init">
|
||||
</target>
|
||||
|
||||
<target name="gather.sources" depends="init" if="destination.temp.folder">
|
||||
<mkdir dir="${destination.temp.folder}/com.ibm.wala.core_1.0.0"/>
|
||||
<copy file="${build.result.folder}/src.zip" todir="${destination.temp.folder}/com.ibm.wala.core_1.0.0" failonerror="false" overwrite="false"/>
|
||||
</target>
|
||||
|
||||
<target name="gather.logs" depends="init" if="destination.temp.folder">
|
||||
<mkdir dir="${destination.temp.folder}/com.ibm.wala.core_1.0.0"/>
|
||||
<copy file="${temp.folder}/@dot.bin${logExtension}" todir="${destination.temp.folder}/com.ibm.wala.core_1.0.0" failonerror="false" overwrite="false"/>
|
||||
</target>
|
||||
|
||||
<target name="clean" depends="init" description="Clean the plug-in: com.ibm.wala.core of all the zips, jars and logs created.">
|
||||
<delete dir="${build.result.folder}/@dot"/>
|
||||
<delete file="${build.result.folder}/src.zip"/>
|
||||
<delete file="${plugin.destination}/com.ibm.wala.core_1.0.0.jar"/>
|
||||
<delete file="${plugin.destination}/com.ibm.wala.core_1.0.0.zip"/>
|
||||
<delete dir="${temp.folder}"/>
|
||||
</target>
|
||||
|
||||
<target name="refresh" depends="init" if="eclipse.running" description="Refresh this folder.">
|
||||
<eclipse.convertPath fileSystemPath="C:/temp/walaWorkspace/com.ibm.wala.core" property="resourcePath"/>
|
||||
<eclipse.refreshLocal resource="${resourcePath}" depth="infinite"/>
|
||||
</target>
|
||||
|
||||
<target name="zip.plugin" depends="init" description="Create a zip containing all the elements for the plug-in: com.ibm.wala.core.">
|
||||
<delete dir="${temp.folder}"/>
|
||||
<mkdir dir="${temp.folder}"/>
|
||||
<antcall target="build.jars"/>
|
||||
<antcall target="build.sources"/>
|
||||
<antcall target="gather.bin.parts">
|
||||
<param name="destination.temp.folder" value="${temp.folder}/"/>
|
||||
</antcall>
|
||||
<antcall target="gather.sources">
|
||||
<param name="destination.temp.folder" value="${temp.folder}/"/>
|
||||
</antcall>
|
||||
<delete>
|
||||
<fileset dir="${temp.folder}" includes="**/*.bin${logExtension}" />
|
||||
</delete>
|
||||
<zip destfile="${plugin.destination}/com.ibm.wala.core_1.0.0.zip" basedir="${temp.folder}" filesonly="true" whenempty="skip" update="false"/>
|
||||
<delete dir="${temp.folder}"/>
|
||||
</target>
|
||||
|
||||
</project>
|
||||
9
com.ibm.wala.core/com.ibm.wala.core/.classpath
Normal file
9
com.ibm.wala.core/com.ibm.wala.core/.classpath
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="dat"/>
|
||||
<classpathentry kind="src" path="lib"/>
|
||||
<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>
|
||||
28
com.ibm.wala.core/com.ibm.wala.core/.project
Normal file
28
com.ibm.wala.core/com.ibm.wala.core/.project
Normal file
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.ibm.wala.core</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>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@ -0,0 +1,7 @@
|
||||
#Tue Nov 21 13:03:57 EST 2006
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
@ -0,0 +1,3 @@
|
||||
#Mon Oct 02 08:58:11 EDT 2006
|
||||
eclipse.preferences.version=1
|
||||
internal.default.compliance=default
|
||||
68
com.ibm.wala.core/com.ibm.wala.core/META-INF/MANIFEST.MF
Normal file
68
com.ibm.wala.core/com.ibm.wala.core/META-INF/MANIFEST.MF
Normal file
@ -0,0 +1,68 @@
|
||||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: WALA Core Plug-in
|
||||
Bundle-SymbolicName: com.ibm.wala.core
|
||||
Bundle-Version: 1.0.0
|
||||
Bundle-Activator: com.ibm.wala.core.plugin.CorePlugin
|
||||
Bundle-Vendor: IBM
|
||||
Bundle-Localization: plugin
|
||||
Require-Bundle: com.ibm.wala.emf;visibility:=reexport,
|
||||
com.ibm.wala.shrike;visibility:=reexport,
|
||||
org.eclipse.core.resources,
|
||||
org.eclipse.jface,
|
||||
org.eclipse.jdt.core
|
||||
Eclipse-LazyStart: true
|
||||
Export-Package: .,
|
||||
com.ibm.wala.analysis.pointers,
|
||||
com.ibm.wala.analysis.reflection,
|
||||
com.ibm.wala.analysis.stackMachine,
|
||||
com.ibm.wala.analysis.typeInference,
|
||||
com.ibm.wala.cfg,
|
||||
com.ibm.wala.cfg.cdg,
|
||||
com.ibm.wala.classLoader,
|
||||
com.ibm.wala.client,
|
||||
com.ibm.wala.client.impl,
|
||||
com.ibm.wala.core.plugin,
|
||||
com.ibm.wala.dataflow.IFDS,
|
||||
com.ibm.wala.dataflow.graph,
|
||||
com.ibm.wala.dataflow.ssa,
|
||||
com.ibm.wala.dynamic,
|
||||
com.ibm.wala.emf.wrappers,
|
||||
com.ibm.wala.escape,
|
||||
com.ibm.wala.fixedpoint.impl,
|
||||
com.ibm.wala.fixpoint,
|
||||
com.ibm.wala.ipa.callgraph,
|
||||
com.ibm.wala.ipa.callgraph.impl,
|
||||
com.ibm.wala.ipa.callgraph.propagation,
|
||||
com.ibm.wala.ipa.callgraph.propagation.cfa,
|
||||
com.ibm.wala.ipa.callgraph.propagation.rta,
|
||||
com.ibm.wala.ipa.cfg,
|
||||
com.ibm.wala.ipa.cha,
|
||||
com.ibm.wala.ipa.modref,
|
||||
com.ibm.wala.ipa.slicer,
|
||||
com.ibm.wala.ipa.summaries,
|
||||
com.ibm.wala.model,
|
||||
com.ibm.wala.model.java.lang,
|
||||
com.ibm.wala.properties,
|
||||
com.ibm.wala.ssa,
|
||||
com.ibm.wala.ssa.analysis,
|
||||
com.ibm.wala.types,
|
||||
com.ibm.wala.util,
|
||||
com.ibm.wala.util.bytecode,
|
||||
com.ibm.wala.util.collections,
|
||||
com.ibm.wala.util.config,
|
||||
com.ibm.wala.util.debug,
|
||||
com.ibm.wala.util.graph,
|
||||
com.ibm.wala.util.graph.impl,
|
||||
com.ibm.wala.util.graph.traverse,
|
||||
com.ibm.wala.util.heapTrace,
|
||||
com.ibm.wala.util.internationalization,
|
||||
com.ibm.wala.util.intset,
|
||||
com.ibm.wala.util.io,
|
||||
com.ibm.wala.util.logging,
|
||||
com.ibm.wala.util.math,
|
||||
com.ibm.wala.util.perf,
|
||||
com.ibm.wala.util.scope,
|
||||
com.ibm.wala.util.system,
|
||||
com.ibm.wala.util.warnings,
|
||||
com.ibm.wala.viz
|
||||
13
com.ibm.wala.core/com.ibm.wala.core/build.properties
Normal file
13
com.ibm.wala.core/com.ibm.wala.core/build.properties
Normal file
@ -0,0 +1,13 @@
|
||||
bin.includes = lib/primordial.jar.model,\
|
||||
plugin.properties,\
|
||||
dat/J2SEClassHierarchyExclusions.xml,\
|
||||
dat/SyntheticJ2SEModel.xml,\
|
||||
dat/benign.xml,\
|
||||
dat/natives.xml,\
|
||||
META-INF/,\
|
||||
.
|
||||
jars.compile.order = .
|
||||
output.. = bin/
|
||||
source.. = dat/,\
|
||||
src/,\
|
||||
lib/
|
||||
202
com.ibm.wala.core/com.ibm.wala.core/build.xml
Normal file
202
com.ibm.wala.core/com.ibm.wala.core/build.xml
Normal file
@ -0,0 +1,202 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="com.ibm.wala.core" default="build.jars" basedir=".">
|
||||
|
||||
<property name="basews" value="${ws}"/>
|
||||
<property name="baseos" value="${os}"/>
|
||||
<property name="basearch" value="${arch}"/>
|
||||
<property name="basenl" value="${nl}"/>
|
||||
|
||||
<!-- Compiler settings. -->
|
||||
<property name="javacFailOnError" value="true"/>
|
||||
<property name="javacDebugInfo" value="on"/>
|
||||
<property name="javacVerbose" value="false"/>
|
||||
<property name="logExtension" value=".log"/>
|
||||
<property name="compilerArg" value=""/>
|
||||
<property name="javacSource" value="1.5"/>
|
||||
<property name="javacTarget" value="1.5"/>
|
||||
<path id="path_bootclasspath">
|
||||
<fileset dir="${java.home}/lib">
|
||||
<include name="*.jar"/>
|
||||
</fileset>
|
||||
</path>
|
||||
<property name="bootclasspath" refid="path_bootclasspath"/>
|
||||
<property name="bundleJavacSource" value="${javacSource}"/>
|
||||
<property name="bundleJavacTarget" value="${javacTarget}"/>
|
||||
<property name="bundleBootClasspath" value="${bootclasspath}"/>
|
||||
|
||||
<target name="init" depends="properties">
|
||||
<condition property="pluginTemp" value="${buildTempFolder}/plugins">
|
||||
<isset property="buildTempFolder"/>
|
||||
</condition>
|
||||
<property name="pluginTemp" value="${basedir}"/>
|
||||
<condition property="build.result.folder" value="${pluginTemp}/com.ibm.wala.core">
|
||||
<isset property="buildTempFolder"/>
|
||||
</condition>
|
||||
<property name="build.result.folder" value="${basedir}"/>
|
||||
<property name="temp.folder" value="${basedir}/temp.folder"/>
|
||||
<property name="plugin.destination" value="${basedir}/output"/>
|
||||
<property name="eclipse.root" value="c:/eclipse"/>
|
||||
</target>
|
||||
|
||||
<target name="properties" if="eclipse.running">
|
||||
<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
|
||||
|
||||
</target>
|
||||
|
||||
<target name="build.update.jar" depends="init" description="Build the plug-in: com.ibm.wala.core for an update site.">
|
||||
<delete dir="${temp.folder}"/>
|
||||
<mkdir dir="${temp.folder}"/>
|
||||
<delete dir="${plugin.destination}"/>
|
||||
<mkdir dir="${plugin.destination}"/>
|
||||
<antcall target="build.jars"/>
|
||||
<antcall target="gather.bin.parts">
|
||||
<param name="destination.temp.folder" value="${temp.folder}/"/>
|
||||
</antcall>
|
||||
<copy todir="${temp.folder}/com.ibm.wala.core_1.0.0" failonerror="true" overwrite="false">
|
||||
<fileset dir="src/" includes="**/*.java" />
|
||||
</copy>
|
||||
<zip destfile="${plugin.destination}/com.ibm.wala.core_1.0.0.jar" basedir="${temp.folder}/com.ibm.wala.core_1.0.0" filesonly="false" whenempty="skip" update="false"/>
|
||||
<delete dir="${temp.folder}"/>
|
||||
</target>
|
||||
|
||||
<target name="@dot" depends="init" description="Create jar: com.ibm.wala.core @dot.">
|
||||
<delete dir="${temp.folder}/@dot.bin"/>
|
||||
<mkdir dir="${temp.folder}/@dot.bin"/>
|
||||
<path id="@dot.classpath">
|
||||
<pathelement path="../com.ibm.wala.emf/bin/"/>
|
||||
<pathelement path="../com.ibm.wala.emf/@dot"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.runtime_3.2.0.v20060603.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.osgi_3.2.0.v20060601.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.equinox.common_3.2.0.v20060603.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.jobs_3.2.0.v20060603.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603/runtime_registry_compatibility.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.equinox.registry_3.2.0.v20060601.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.apache.xerces_2.8.0.v200606131651/resolver.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.apache.xerces_2.8.0.v200606131651/xercesImpl.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.apache.xerces_2.8.0.v200606131651/xml-apis.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.equinox.preferences_3.2.0.v20060601.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603/@dot"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.contenttype_3.2.0.v20060603.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.runtime.compatibility.auth_3.2.0.v20060601.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.emf.ecore_2.2.0.v200606271057.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.emf.common_2.2.0.v200606271057.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.resources_3.2.0.v20060603.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.resources.compatibility_3.2.0.v20060603.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.resources.win32_3.2.0.v20060603.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.runtime.compatibility_3.1.100.v20060603.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.update.configurator_3.2.0.v20060605.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.ant.core_3.1.100.v20060531.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.variables_3.1.100.v20060605.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.expressions_3.2.0.v20060605-1400.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.filesystem_1.0.0.v20060603.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.filesystem.win32.x86_1.0.0.v20060603.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.emf.ecore.xmi_2.2.0.v200606271057.jar"/>
|
||||
<pathelement path="../com.ibm.wala.shrike/bin/"/>
|
||||
<pathelement path="../com.ibm.wala.shrike/@dot"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.jface_3.2.0.I20060605-1400.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.swt_3.2.0.v3232o.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.swt.win32.win32.x86_3.2.0.v3232m.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.core.commands_3.2.0.I20060605-1400.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.jdt.core_3.2.0.v_671.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.text_3.2.0.v20060605-1400.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/com.ibm.icu_3.4.4.1.jar"/>
|
||||
<pathelement path="${eclipse.root}/plugins/org.eclipse.team.core_3.2.0.I200606051140.jar"/>
|
||||
</path>
|
||||
<!-- compile the source code -->
|
||||
<javac destdir="${temp.folder}/@dot.bin" failonerror="${javacFailOnError}" verbose="${javacVerbose}" debug="${javacDebugInfo}" includeAntRuntime="no" bootclasspath="${bundleBootClasspath}" source="${bundleJavacSource}" target="${bundleJavacTarget}" >
|
||||
<compilerarg line="${compilerArg}" compiler="${build.compiler}"/>
|
||||
<classpath refid="@dot.classpath" />
|
||||
<src path="dat/" />
|
||||
<src path="src/" />
|
||||
<src path="lib/" />
|
||||
<compilerarg value="@${basedir}/javaCompiler...args" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
|
||||
<compilerarg line="-log '${temp.folder}/@dot.bin${logExtension}'" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/>
|
||||
</javac>
|
||||
<!-- Copy necessary resources -->
|
||||
<copy todir="${temp.folder}/@dot.bin" failonerror="true" overwrite="false">
|
||||
<fileset dir="dat/" excludes="**/*.java, **/package.htm*" />
|
||||
<fileset dir="src/" excludes="**/*.java, **/package.htm*" />
|
||||
<fileset dir="lib/" excludes="**/*.java, **/package.htm*" />
|
||||
</copy>
|
||||
<mkdir dir="${build.result.folder}"/>
|
||||
<copy todir="${build.result.folder}/@dot" failonerror="true" overwrite="false">
|
||||
<fileset dir="${temp.folder}/@dot.bin" />
|
||||
</copy>
|
||||
<delete dir="${temp.folder}/@dot.bin"/>
|
||||
</target>
|
||||
|
||||
<target name="src.zip" depends="init" unless="src.zip">
|
||||
<mkdir dir="${build.result.folder}"/>
|
||||
<zip destfile="${build.result.folder}/src.zip" filesonly="false" whenempty="skip" update="false">
|
||||
<fileset dir="dat/" includes="**/*.java" />
|
||||
<fileset dir="src/" includes="**/*.java" />
|
||||
<fileset dir="lib/" includes="**/*.java" />
|
||||
</zip>
|
||||
</target>
|
||||
|
||||
<target name="build.jars" depends="init" description="Build all the jars for the plug-in: com.ibm.wala.core.">
|
||||
<available property="@dot" file="${build.result.folder}/@dot"/>
|
||||
<antcall target="@dot"/>
|
||||
</target>
|
||||
|
||||
<target name="build.sources" depends="init">
|
||||
<available property="src.zip" file="${build.result.folder}/src.zip"/>
|
||||
<antcall target="src.zip"/>
|
||||
</target>
|
||||
|
||||
<target name="gather.bin.parts" depends="init" if="destination.temp.folder">
|
||||
<mkdir dir="${destination.temp.folder}/com.ibm.wala.core_1.0.0"/>
|
||||
<copy todir="${destination.temp.folder}/com.ibm.wala.core_1.0.0" failonerror="true" overwrite="false">
|
||||
<fileset dir="${build.result.folder}/@dot" includes="**" />
|
||||
</copy>
|
||||
<copy todir="${destination.temp.folder}/com.ibm.wala.core_1.0.0" failonerror="true" overwrite="false">
|
||||
<fileset dir="${basedir}" includes="lib/primordial.jar.model,plugin.properties,lib/extension.jar.model,dat/J2SEClassHierarchyExclusions.xml,dat/SyntheticJ2SEModel.xml,dat/benign.xml,dat/natives.xml,META-INF/" />
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="build.zips" depends="init">
|
||||
</target>
|
||||
|
||||
<target name="gather.sources" depends="init" if="destination.temp.folder">
|
||||
<mkdir dir="${destination.temp.folder}/com.ibm.wala.core_1.0.0"/>
|
||||
<copy file="${build.result.folder}/src.zip" todir="${destination.temp.folder}/com.ibm.wala.core_1.0.0" failonerror="false" overwrite="false"/>
|
||||
</target>
|
||||
|
||||
<target name="gather.logs" depends="init" if="destination.temp.folder">
|
||||
<mkdir dir="${destination.temp.folder}/com.ibm.wala.core_1.0.0"/>
|
||||
<copy file="${temp.folder}/@dot.bin${logExtension}" todir="${destination.temp.folder}/com.ibm.wala.core_1.0.0" failonerror="false" overwrite="false"/>
|
||||
</target>
|
||||
|
||||
<target name="clean" depends="init" description="Clean the plug-in: com.ibm.wala.core of all the zips, jars and logs created.">
|
||||
<delete dir="${build.result.folder}/@dot"/>
|
||||
<delete file="${build.result.folder}/src.zip"/>
|
||||
<delete file="${plugin.destination}/com.ibm.wala.core_1.0.0.jar"/>
|
||||
<delete file="${plugin.destination}/com.ibm.wala.core_1.0.0.zip"/>
|
||||
<delete dir="${temp.folder}"/>
|
||||
</target>
|
||||
|
||||
<target name="refresh" depends="init" if="eclipse.running" description="Refresh this folder.">
|
||||
<eclipse.convertPath fileSystemPath="C:/temp/walaWorkspace/com.ibm.wala.core" property="resourcePath"/>
|
||||
<eclipse.refreshLocal resource="${resourcePath}" depth="infinite"/>
|
||||
</target>
|
||||
|
||||
<target name="zip.plugin" depends="init" description="Create a zip containing all the elements for the plug-in: com.ibm.wala.core.">
|
||||
<delete dir="${temp.folder}"/>
|
||||
<mkdir dir="${temp.folder}"/>
|
||||
<antcall target="build.jars"/>
|
||||
<antcall target="build.sources"/>
|
||||
<antcall target="gather.bin.parts">
|
||||
<param name="destination.temp.folder" value="${temp.folder}/"/>
|
||||
</antcall>
|
||||
<antcall target="gather.sources">
|
||||
<param name="destination.temp.folder" value="${temp.folder}/"/>
|
||||
</antcall>
|
||||
<delete>
|
||||
<fileset dir="${temp.folder}" includes="**/*.bin${logExtension}" />
|
||||
</delete>
|
||||
<zip destfile="${plugin.destination}/com.ibm.wala.core_1.0.0.zip" basedir="${temp.folder}" filesonly="true" whenempty="skip" update="false"/>
|
||||
<delete dir="${temp.folder}"/>
|
||||
</target>
|
||||
|
||||
</project>
|
||||
1
com.ibm.wala.core/com.ibm.wala.core/dat/.cvsignore
Normal file
1
com.ibm.wala.core/com.ibm.wala.core/dat/.cvsignore
Normal file
@ -0,0 +1 @@
|
||||
wala.properties
|
||||
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="ASCII"?>
|
||||
<com.ibm.wala.common:EContainer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:com.ibm.wala.common="http:///com/ibm/wala/wala.ecore.common" xmlns:com.ibm.wala.regex="http:///com/ibm/wala/wala.ecore.regex">
|
||||
<contents xsi:type="com.ibm.wala.regex:EPattern" pattern="java\/awt\/.*"/>
|
||||
<contents xsi:type="com.ibm.wala.regex:EPattern" pattern="java\/lang\/Boolean"/>
|
||||
<contents xsi:type="com.ibm.wala.regex:EPattern" pattern="java\/lang\/Integer"/>
|
||||
<contents xsi:type="com.ibm.wala.regex:EPattern" pattern="java\/lang\/StringBuffer"/>
|
||||
<contents xsi:type="com.ibm.wala.regex:EPattern" pattern="java\/lang\/SecurityManager"/>
|
||||
<contents xsi:type="com.ibm.wala.regex:EPattern" pattern="java\/lang\/Float"/>
|
||||
<contents xsi:type="com.ibm.wala.regex:EPattern" pattern="java\/net\/.*"/>
|
||||
<contents xsi:type="com.ibm.wala.regex:EPattern" pattern="java\/util\/.*"/>
|
||||
<contents xsi:type="com.ibm.wala.regex:EPattern" pattern="javax\/.*"/>
|
||||
<contents xsi:type="com.ibm.wala.regex:EPattern" pattern="sun\/.*"/>
|
||||
</com.ibm.wala.common:EContainer>
|
||||
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<com.ibm.wala.java.scope:EJavaAnalysisScope xmlns:com.ibm.wala.java.scope="http:///com/ibm/wala/wala.ecore.java.scope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<loaders loaderName="Primordial">
|
||||
<modules xsi:type="com.ibm.wala.java.scope:EBuiltInModule" id="primordial_jar_model"/>
|
||||
</loaders>
|
||||
</com.ibm.wala.java.scope:EJavaAnalysisScope>
|
||||
@ -0,0 +1,15 @@
|
||||
########## General messages
|
||||
|
||||
########## Error messages
|
||||
|
||||
AbstractPropertyReader.invalid_property_value=Value for property ''{0}'' is invalid.
|
||||
AbstractPropertyReader.location_error=Path for file ''{0}'' do not exist and can''t be constructed.
|
||||
AbstractPropertyReader.no_string_value=Property ''{0}'' is not mapped to a string as expected.
|
||||
AbstractPropertyReader.incorrect_boolean_value=Boolean property ''{0}'' should not be mapped to a string.
|
||||
AbstractPropertyReader.incorrect_int_value=Integer property ''{0}'' should be mapped to an Integer object.
|
||||
AbstractPropertyReader.int_conversion_failed=Integer property ''{0}'' cannot convert ''{1}'' to an integer.
|
||||
|
||||
CancelCHAConstructionException.cancelation_message=ClassHierarchy construction has been cancelled by progress monitor.
|
||||
|
||||
PersistentPropertiesManager.property_file_unreadable=Unable to read property file named ''{0}''.
|
||||
PersistentPropertiesManager.reading_failure=Failed to load ''{0}''.
|
||||
1880
com.ibm.wala.core/com.ibm.wala.core/dat/benign.xml
Normal file
1880
com.ibm.wala.core/com.ibm.wala.core/dat/benign.xml
Normal file
File diff suppressed because it is too large
Load Diff
42
com.ibm.wala.core/com.ibm.wala.core/dat/codetemplates.xml
Normal file
42
com.ibm.wala.core/com.ibm.wala.core/dat/codetemplates.xml
Normal file
@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><templates><template autoinsert="true" context="gettercomment_context" deleted="false" description="Comment for getter method" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name="gettercomment">/**
|
||||
* @return the ${bare_field_name}
|
||||
*/</template><template autoinsert="true" context="settercomment_context" deleted="false" description="Comment for setter method" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.settercomment" name="settercomment">/**
|
||||
* @param ${param} the ${bare_field_name} to set
|
||||
*/</template><template autoinsert="true" context="constructorcomment_context" deleted="false" description="Comment for created constructors" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name="constructorcomment">/**
|
||||
* ${tags}
|
||||
*/</template><template autoinsert="true" context="filecomment_context" deleted="false" description="Comment for created Java files" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.filecomment" name="filecomment">/**
|
||||
*
|
||||
*/</template><template autoinsert="true" context="typecomment_context" deleted="false" description="Comment for created types" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.typecomment" name="typecomment">/**
|
||||
* @author ${user}
|
||||
*
|
||||
* ${tags}
|
||||
*/</template><template autoinsert="true" context="fieldcomment_context" deleted="false" description="Comment for fields" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name="fieldcomment">/**
|
||||
*
|
||||
*/</template><template autoinsert="true" context="methodcomment_context" deleted="false" description="Comment for non-overriding methods" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name="methodcomment">/**
|
||||
* ${tags}
|
||||
*/</template><template autoinsert="true" context="overridecomment_context" deleted="false" description="Comment for overriding methods" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name="overridecomment">/* (non-Javadoc)
|
||||
* ${see_to_overridden}
|
||||
*/</template><template autoinsert="true" context="delegatecomment_context" deleted="false" description="Comment for delegate methods" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name="delegatecomment">/**
|
||||
* ${tags}
|
||||
* ${see_to_target}
|
||||
*/</template><template autoinsert="false" context="newtype_context" deleted="false" description="Newly created files" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.newtype" name="newtype">/*******************************************************************************
|
||||
* Copyright (c) 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_declaration}
|
||||
|
||||
${typecomment}
|
||||
${type_declaration}</template><template autoinsert="true" context="classbody_context" deleted="false" description="Code in new class type bodies" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.classbody" name="classbody">
|
||||
</template><template autoinsert="true" context="interfacebody_context" deleted="false" description="Code in new interface type bodies" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name="interfacebody">
|
||||
</template><template autoinsert="true" context="enumbody_context" deleted="false" description="Code in new enum type bodies" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.enumbody" name="enumbody">
|
||||
</template><template autoinsert="true" context="annotationbody_context" deleted="false" description="Code in new annotation type bodies" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name="annotationbody">
|
||||
</template><template autoinsert="true" context="catchblock_context" deleted="false" description="Code in new catch blocks" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.catchblock" name="catchblock">// ${todo} Auto-generated catch block
|
||||
${exception_var}.printStackTrace();</template><template autoinsert="true" context="methodbody_context" deleted="false" description="Code in created method stubs" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.methodbody" name="methodbody">// ${todo} Auto-generated method stub
|
||||
${body_statement}</template><template autoinsert="true" context="constructorbody_context" deleted="false" description="Code in created constructor stubs" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name="constructorbody">${body_statement}
|
||||
// ${todo} Auto-generated constructor stub</template><template autoinsert="true" context="getterbody_context" deleted="false" description="Code in created getters" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.getterbody" name="getterbody">return ${field};</template><template autoinsert="true" context="setterbody_context" deleted="false" description="Code in created setters" enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.setterbody" name="setterbody">${field} = ${param};</template></templates>
|
||||
251
com.ibm.wala.core/com.ibm.wala.core/dat/formatter.xml
Normal file
251
com.ibm.wala.core/com.ibm.wala.core/dat/formatter.xml
Normal file
@ -0,0 +1,251 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<profiles version="10">
|
||||
<profile name="WALA" version="10">
|
||||
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="80"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="132"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="2"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
|
||||
</profile>
|
||||
</profiles>
|
||||
16
com.ibm.wala.core/com.ibm.wala.core/dat/log.properties
Normal file
16
com.ibm.wala.core/com.ibm.wala.core/dat/log.properties
Normal file
@ -0,0 +1,16 @@
|
||||
# Handlers installed for the root logger
|
||||
handlers= java.util.logging.ConsoleHandler java.util.logging.FileHandler
|
||||
|
||||
### Configure FileHandler
|
||||
# Logging file name in temporary directory of the machine.
|
||||
java.util.logging.FileHandler.pattern = %t/safeLogFile%g.log
|
||||
# Write 100 kbytes before rotating this file
|
||||
java.util.logging.FileHandler.limit = 100000
|
||||
# Number of rotating files to be used
|
||||
java.util.logging.FileHandler.count = 3
|
||||
# Formatter to be used with this FileHandler
|
||||
java.util.logging.FileHandler.formatter = com.ibm.wala.util.logging.SimplifiedFormatter
|
||||
|
||||
# Configure ConsoleHandler
|
||||
java.util.logging.ConsoleHandler.level = WARNING
|
||||
java.util.logging.ConsoleHandler.formatter = com.ibm.wala.util.logging.SimplifiedFormatter
|
||||
784
com.ibm.wala.core/com.ibm.wala.core/dat/natives.xml
Normal file
784
com.ibm.wala.core/com.ibm.wala.core/dat/natives.xml
Normal file
@ -0,0 +1,784 @@
|
||||
<?xml version="1.0" ?>
|
||||
<!-- native methods in the IBM Windows DK 1.3.1 -->
|
||||
<summary-spec>
|
||||
<classloader name="Primordial">
|
||||
|
||||
<package name="com/ibm/wala/model">
|
||||
<class name="SyntheticFactory">
|
||||
<method name="getObject"
|
||||
descriptor="()Ljava/lang/Object;" factory="true" static="true">
|
||||
<new def="x" class="Lcom/ibm/wala/Malleable" />
|
||||
<return value="x" />
|
||||
</method>
|
||||
</class>
|
||||
</package>
|
||||
|
||||
<package name="com/ibm/jvm">
|
||||
<class name="ExtendedSystem">
|
||||
<method name="isResettableJVM" descriptor="()Z"
|
||||
static="true">
|
||||
</method>
|
||||
<method name="setJVMUnresettableConditionally"
|
||||
descriptor="(ILjava/lang/String;)V" static="true">
|
||||
</method>
|
||||
<method name="resizeArray"
|
||||
descriptor="(ILjava/lang/Object;II)Ljava/lang/Object;"
|
||||
factory="true" static="true">
|
||||
<new def="x" class="Lcom/ibm/wala/Malleable" />
|
||||
<return value="x" />
|
||||
</method>
|
||||
</class>
|
||||
|
||||
</package>
|
||||
|
||||
<package name="java/io">
|
||||
<class name="FileDescriptor">
|
||||
<method name="sync" descriptor="()V"></method>
|
||||
</class>
|
||||
<class name="FileInputStream">
|
||||
<method name="available" descriptor="()I">
|
||||
<constant name="yes" type="int" value="1" />
|
||||
<constant name="no" type="int" value="0" />
|
||||
<return value="yes" />
|
||||
<return value="no" />
|
||||
<new def="x" class="Ljava/io/IOException" />
|
||||
<throw value="x" />
|
||||
</method>
|
||||
<method name="close" descriptor="()V">
|
||||
<new def="x" class="Ljava/io/IOException" />
|
||||
<throw value="x" />
|
||||
</method>
|
||||
<method name="open"
|
||||
descriptor="(Ljava/lang/String;)V">
|
||||
<new def="x" class="Ljava/io/IOException" />
|
||||
<throw value="x" />
|
||||
</method>
|
||||
<method name="read" descriptor="()I">
|
||||
<constant name="yes" type="int" value="1" />
|
||||
<constant name="no" type="int" value="0" />
|
||||
<return value="yes" />
|
||||
<return value="no" />
|
||||
<new def="x" class="Ljava/io/IOException" />
|
||||
<throw value="x" />
|
||||
</method>
|
||||
<method name="readBytes" descriptor="([BII)I">
|
||||
<constant name="yes" type="int" value="1" />
|
||||
<constant name="no" type="int" value="0" />
|
||||
<return value="yes" />
|
||||
<return value="no" />
|
||||
<new def="x" class="Ljava/io/IOException" />
|
||||
<throw value="x" />
|
||||
</method>
|
||||
<method name="readBytes"
|
||||
descriptor="([BIILjava/io/FileDescriptor;)I">
|
||||
<constant name="yes" type="int" value="1" />
|
||||
<constant name="no" type="int" value="0" />
|
||||
<return value="yes" />
|
||||
<return value="no" />
|
||||
<new def="x" class="Ljava/io/IOException" />
|
||||
<throw value="x" />
|
||||
</method>
|
||||
<method name="skip" descriptor="(J)J">
|
||||
<constant name="yes" type="int" value="1" />
|
||||
<constant name="no" type="int" value="0" />
|
||||
<return value="yes" />
|
||||
<return value="no" />
|
||||
<new def="x" class="Ljava/io/IOException" />
|
||||
<throw value="x" />
|
||||
</method>
|
||||
</class>
|
||||
<class name="FileOutputStream">
|
||||
<method name="close" descriptor="()V"></method>
|
||||
<method name="open"
|
||||
descriptor="(Ljava/lang/String;)V">
|
||||
</method>
|
||||
<method name="openAppend"
|
||||
descriptor="(Ljava/lang/String;)V">
|
||||
</method>
|
||||
<method name="write" descriptor="(I)V"></method>
|
||||
<method name="writeBytes" descriptor="([BII)V"></method>
|
||||
</class>
|
||||
<class name="ObjectOutputStream">
|
||||
<method name="doublesToBytes" descriptor="([DI[BII)V"
|
||||
static="true" />
|
||||
<method name="floatsToBytes" descriptor="([FI[BII)V"
|
||||
static="true" />
|
||||
</class>
|
||||
<class name="ObjectStreamClass">
|
||||
<method name="hasStaticInitializer"
|
||||
descriptor="(Ljava/lang/Class;)Z" static="true">
|
||||
</method>
|
||||
</class>
|
||||
<class name="RandomAccessFile">
|
||||
<method name="close" descriptor="()V"></method>
|
||||
<method name="getFilePointer" descriptor="()J"></method>
|
||||
<method name="length" descriptor="()J"></method>
|
||||
<method name="open"
|
||||
descriptor="(Ljava/lang/String;Z)V">
|
||||
</method>
|
||||
<method name="open"
|
||||
descriptor="(Ljava/lang/String;I)V">
|
||||
</method>
|
||||
<method name="read" descriptor="()I"></method>
|
||||
<method name="readBytes"
|
||||
descriptor="([BIILjava/io/FileDescriptor;)I">
|
||||
</method>
|
||||
<method name="seek" descriptor="(J)V"></method>
|
||||
<method name="write" descriptor="(I)V"></method>
|
||||
<method name="writeBytes"
|
||||
descriptor="([BIILjava/io/FileDescriptor;)V">
|
||||
</method>
|
||||
<method name="writeBytes" descriptor="([BII)V"></method>
|
||||
</class>
|
||||
</package>
|
||||
|
||||
<package name="java/lang">
|
||||
<class name="Class">
|
||||
<method name="forName"
|
||||
descriptor="(Ljava/lang/String;)Ljava/lang/Class;"
|
||||
static="true">
|
||||
<new def="x" class="Ljava/lang/Class" />
|
||||
<return value="x" />
|
||||
<new def="y"
|
||||
class="Ljava/lang/ClassNotFoundException" />
|
||||
<throw value="y" />
|
||||
<new def="z" class="Ljava/lang/ClassFormatError" />
|
||||
<throw value="z" />
|
||||
</method>
|
||||
<method name="forName0"
|
||||
descriptor="(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;"
|
||||
static="true">
|
||||
<new def="x" class="Ljava/lang/Class" />
|
||||
<return value="x" />
|
||||
<new def="y"
|
||||
class="Ljava/lang/ClassNotFoundException" />
|
||||
<throw value="y" />
|
||||
<new def="z" class="Ljava/lang/ClassFormatError" />
|
||||
<throw value="z" />
|
||||
</method>
|
||||
<method name="forName1"
|
||||
descriptor="(Ljava/lang/String;)Ljava/lang/Class;" static="true">
|
||||
<new def="x" class="Ljava/lang/Class" />
|
||||
<return value="x" />
|
||||
<new def="y"
|
||||
class="Ljava/lang/ClassNotFoundException" />
|
||||
<throw value="y" />
|
||||
<new def="z" class="Ljava/lang/ClassFormatError" />
|
||||
<throw value="z" />
|
||||
</method>
|
||||
<method name="getClassLoader0"
|
||||
descriptor="()Ljava/lang/ClassLoader;">
|
||||
<new def="x" class="Ljava/lang/ClassLoader" />
|
||||
<return value="x" />
|
||||
</method>
|
||||
<method name="getComponentType"
|
||||
descriptor="()Ljava/lang/Class;">
|
||||
<new def="x" class="Ljava/lang/Class" />
|
||||
<return value="x" />
|
||||
</method>
|
||||
<method name="getConstructor0"
|
||||
descriptor="([Ljava/lang/Class;I)Ljava/lang/reflect/Constructor;">
|
||||
<new def="x" class="Ljava/lang/reflect/Constructor" />
|
||||
<return value="x" />
|
||||
</method>
|
||||
<method name="getField0"
|
||||
descriptor="(Ljava/lang/String;I)Ljava/lang/reflect/Field;">
|
||||
<new def="x" class="Ljava/lang/reflect/Field" />
|
||||
<return value="x" />
|
||||
</method>
|
||||
<method name="getInterfaces"
|
||||
descriptor="()[Ljava/lang/Class;">
|
||||
<constant name="size" type="int" value="1" />
|
||||
<new def="x" class="[Ljava/lang/Class" size="size" />
|
||||
<new def="y" class="Ljava/lang/Class" />
|
||||
<aastore ref="x" value="y" index="0" />
|
||||
<return value="x" />
|
||||
</method>
|
||||
<method name="getMethod0"
|
||||
descriptor="(Ljava/lang/String;[Ljava/lang/Class;I)Ljava/lang/reflect/Method;">
|
||||
<new def="x" class="Ljava/lang/reflect/Method" />
|
||||
<return value="x" />
|
||||
</method>
|
||||
<method name="getMethods0"
|
||||
descriptor="(I)[Ljava/lang/reflect/Method;">
|
||||
<constant name="size" type="int" value="1" />
|
||||
<new def="x" class="[Ljava/lang/reflect/Method"
|
||||
size="size" />
|
||||
<new def="y" class="Ljava/lang/reflect/Method" />
|
||||
<aastore ref="x" value="y" index="0" />
|
||||
<return value="x" />
|
||||
</method>
|
||||
<method name="getModifiers" descriptor="()I"></method>
|
||||
<method name="getName"
|
||||
descriptor="()Ljava/lang/String;">
|
||||
<new def="x" class="Ljava/lang/String" />
|
||||
<return value="x" />
|
||||
</method>
|
||||
<method name="getPrimitiveClass"
|
||||
descriptor="(Ljava/lang/String;)Ljava/lang/Class;" static="true">
|
||||
<new def="x" class="Ljava/lang/Class" />
|
||||
<return value="x" />
|
||||
</method>
|
||||
<method name="getSigners"
|
||||
descriptor="()[Ljava/lang/Object;">
|
||||
<constant name="size" type="int" value="1" />
|
||||
<new def="x" class="[Ljava/lang/Object" size="size" />
|
||||
<new def="y" class="Ljava/lang/Class" />
|
||||
<aastore ref="x" value="y" index="0" />
|
||||
<return value="x" />
|
||||
</method>
|
||||
<method name="getSuperclass"
|
||||
descriptor="()Ljava/lang/Class;">
|
||||
<new def="x" class="Ljava/lang/Class" />
|
||||
<return value="x" />
|
||||
</method>
|
||||
<method name="getFields"
|
||||
descriptor="()[Ljava/lang/reflect/Field;">
|
||||
<constant name="size" type="int" value="1" />
|
||||
<new def="x" class="[Ljava/lang/reflect/Field" size="size"/>
|
||||
<new def="y" class="Ljava/lang/reflect/Field" />
|
||||
<aastore ref="x" value="y" index="0" />
|
||||
<return value="x" />
|
||||
</method>
|
||||
<method name="getConstructors"
|
||||
descriptor="()[Ljava/lang/reflect/Constructor;">
|
||||
<constant name="size" type="int" value="1" />
|
||||
<new def="x"
|
||||
class="[Ljava/lang/reflect/Constructor" size="size"/>
|
||||
<new def="y" class="Ljava/lang/reflect/Constructor" />
|
||||
<aastore ref="x" value="y" index="0" />
|
||||
<return value="x" />
|
||||
</method>
|
||||
<method name="isAssignableFrom"
|
||||
descriptor="(Ljava/lang/Class;)Z">
|
||||
</method>
|
||||
<method name="isArray" descriptor="()Z"></method>
|
||||
<method name="isInstance"
|
||||
descriptor="(Ljava/lang/Object;)Z">
|
||||
</method>
|
||||
<method name="isInterface" descriptor="()Z"></method>
|
||||
<method name="isPrimitive" descriptor="()Z"></method>
|
||||
<method name="newInstance"
|
||||
descriptor="()Ljava/lang/Object;" factory="true">
|
||||
<new def="x" class="Lcom/ibm/wala/Malleable" />
|
||||
<return value="x" />
|
||||
</method>
|
||||
</class>
|
||||
<class name="ClassLoader" allocatable="true">
|
||||
<method name="findBootstrapClass"
|
||||
descriptor="(Ljava/lang/String;)Ljava/lang/Class;">
|
||||
<new def="x" class="Ljava/lang/Class" />
|
||||
<return value="x" />
|
||||
</method>
|
||||
<method name="findLoadedClass"
|
||||
descriptor="(Ljava/lang/String;)Ljava/lang/Class;">
|
||||
<new def="x" class="Ljava/lang/Class" />
|
||||
<return value="x" />
|
||||
</method>
|
||||
<method name="getCallerClassLoader"
|
||||
descriptor="()Ljava/lang/ClassLoader;" static="true">
|
||||
<new def="x" class="Ljava/lang/ClassLoader" />
|
||||
<return value="x" />
|
||||
</method>
|
||||
</class>
|
||||
<class name="Double">
|
||||
<method name="doubleToLongBits" descriptor="(D)J"
|
||||
static="true">
|
||||
</method>
|
||||
<method name="longBitsToDouble" descriptor="(J)D"
|
||||
static="true">
|
||||
</method>
|
||||
</class>
|
||||
<class name="Float">
|
||||
<method name="floatToIntBits" descriptor="(F)I"
|
||||
static="true">
|
||||
</method>
|
||||
<method name="intBitsToFloat" descriptor="(I)F"
|
||||
static="true">
|
||||
</method>
|
||||
</class>
|
||||
<class name="Object">
|
||||
<method name="clone"
|
||||
descriptor="()Ljava/lang/Object;">
|
||||
<return value="null" />
|
||||
<!-- Note that propagation-style builders should intercept calls to clone, and this model is OK for RTA -->
|
||||
</method>
|
||||
<method name="getClass"
|
||||
descriptor="()Ljava/lang/Class;">
|
||||
<new def="x" class="Ljava/lang/Class" />
|
||||
<return value="x" />
|
||||
</method>
|
||||
<method name="hashCode" descriptor="()I"></method>
|
||||
<method name="notify" descriptor="()V"></method>
|
||||
<method name="notifyAll" descriptor="()V"></method>
|
||||
<method name="wait" descriptor="(J)V"></method>
|
||||
</class>
|
||||
<class name="Runtime">
|
||||
<method name="freeMemory" descriptor="()J"></method>
|
||||
<method name="gc" descriptor="()V"></method>
|
||||
<method name="totalMemory" descriptor="()J"></method>
|
||||
</class>
|
||||
<class name="SecurityManager">
|
||||
<method name="getClassContext"
|
||||
descriptor="()[Ljava/lang/Class;">
|
||||
<constant name="size" type="int" value="1" />
|
||||
<new def="x" class="[Ljava/lang/Class" size="size"/>
|
||||
<new def="y" class="Ljava/lang/Class" />
|
||||
<aastore ref="x" value="y" index="0" />
|
||||
<return value="x" />
|
||||
</method>
|
||||
</class>
|
||||
<class name="StrictMath">
|
||||
<method name="ceil" descriptor="(D)D" static="true"></method>
|
||||
<method name="exp" descriptor="(D)D" static="true"></method>
|
||||
<method name="floor" descriptor="(D)D" static="true"></method>
|
||||
<method name="pow" descriptor="(DD)D" static="true"></method>
|
||||
</class>
|
||||
<class name="String">
|
||||
<method name="intern"
|
||||
descriptor="()Ljava/lang/String;">
|
||||
<new def="x" class="Ljava/lang/String" />
|
||||
<return value="x" />
|
||||
<poison
|
||||
reason="questionable model of java/lang/String/intern()"
|
||||
level="mild" />
|
||||
</method>
|
||||
</class>
|
||||
<class name="System">
|
||||
<method name="arraycopy"
|
||||
descriptor="(Ljava/lang/Object;ILjava/lang/Object;II)V"
|
||||
static="true">
|
||||
<call type="static" name="arraycopy"
|
||||
class="Lcom/ibm/wala/model/java/lang/System"
|
||||
descriptor="(Ljava/lang/Object;Ljava/lang/Object;)V" arg0="arg0"
|
||||
arg1="arg2" />
|
||||
<return />
|
||||
</method>
|
||||
<method name="currentTimeMillis" descriptor="()J"
|
||||
static="true">
|
||||
</method>
|
||||
<method name="getCallerClass"
|
||||
descriptor="()Ljava/lang/Class;" static="true">
|
||||
<new def="x" class="Ljava/lang/Class" />
|
||||
<return value="x" />
|
||||
</method>
|
||||
<method name="identityHashCode"
|
||||
descriptor="(Ljava/lang/Object;)I" static="true">
|
||||
</method>
|
||||
<method name="initProperties"
|
||||
descriptor="(Ljava/util/Properties;)Ljava/util/Properties;"
|
||||
static="true">
|
||||
<new def="dummy1" class="Ljava/lang/Object" />
|
||||
<new def="dummy2" class="Ljava/lang/Object" />
|
||||
<call type="virtual" name="put"
|
||||
class="Ljava/util/Properties"
|
||||
descriptor="(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"
|
||||
arg0="arg0" arg1="dummy1" arg2="dummy2" def="ignore" />
|
||||
<new def="x" class="Ljava/util/Properties" />
|
||||
<return value="x" />
|
||||
</method>
|
||||
<method name="mapLibraryName"
|
||||
descriptor="(Ljava/lang/String;)Ljava/lang/String;"
|
||||
static="true">
|
||||
<return value="arg0" />
|
||||
</method>
|
||||
<method name="setErr0"
|
||||
descriptor="(Ljava/io/PrintStream;)V" static="true">
|
||||
</method>
|
||||
<method name="setIn0"
|
||||
descriptor="(Ljava/io/InputStream;)V" static="true">
|
||||
</method>
|
||||
<method name="setOut0"
|
||||
descriptor="(Ljava/io/PrintStream;)V" static="true">
|
||||
</method>
|
||||
</class>
|
||||
<class name="Thread">
|
||||
<method name="currentThread"
|
||||
descriptor="()Ljava/lang/Thread;" static="true">
|
||||
<new def="x" class="Ljava/lang/Thread" />
|
||||
<return value="x" />
|
||||
</method>
|
||||
<method name="interrupt0" descriptor="()V"></method>
|
||||
<method name="<init>" descriptor="()V">
|
||||
<putfield class="Ljava/lang/Thread" field="runnable"
|
||||
fieldType="Ljava/lang/Runnable" ref="arg0" value="arg0" />
|
||||
<putfield class="Ljava/lang/Thread" field="target"
|
||||
fieldType="Ljava/lang/Runnable" ref="arg0" value="arg0" />
|
||||
</method>
|
||||
<method name="<init>"
|
||||
descriptor="(Ljava/lang/Runnable;)V">
|
||||
<putfield class="Ljava/lang/Thread" field="runnable"
|
||||
fieldType="Ljava/lang/Runnable" ref="arg0" value="arg1" />
|
||||
<putfield class="Ljava/lang/Thread" field="target"
|
||||
fieldType="Ljava/lang/Runnable" ref="arg0" value="arg0" />
|
||||
</method>
|
||||
<method name="isAlive" descriptor="()Z"></method>
|
||||
<method name="resume0" descriptor="()V" />
|
||||
<method name="sleep" descriptor="(J)V" static="true">
|
||||
<new def="x"
|
||||
class="Ljava/lang/InterruptedException" />
|
||||
<throw value="x" />
|
||||
</method>
|
||||
<method name="start" descriptor="()V">
|
||||
<putfield class="Ljava/lang/Thread" field="runnable"
|
||||
fieldType="Ljava/lang/Runnable" ref="arg0" value="arg0" />
|
||||
<getfield class="Ljava/lang/Thread" field="runnable"
|
||||
fieldType="Ljava/lang/Runnable" def="x" ref="arg0" />
|
||||
<call type="interface" name="run"
|
||||
class="Ljava/lang/Runnable" descriptor="()V" arg0="x" />
|
||||
<putfield class="Ljava/lang/Thread" field="target"
|
||||
fieldType="Ljava/lang/Runnable" ref="arg0" value="arg0" />
|
||||
<getfield class="Ljava/lang/Thread" field="target"
|
||||
fieldType="Ljava/lang/Runnable" def="y" ref="arg0" />
|
||||
<call type="interface" name="run"
|
||||
class="Ljava/lang/Runnable" descriptor="()V" arg0="y" />
|
||||
</method>
|
||||
<method name="stop0" descriptor="()V" />
|
||||
<method name="yield" descriptor="()V" static="true" />
|
||||
</class>
|
||||
<class name="Throwable">
|
||||
<method name="fillInStackTrace"
|
||||
descriptor="()Ljava/lang/Throwable;">
|
||||
<return value="arg0" />
|
||||
</method>
|
||||
<method name="getStackTraceElement"
|
||||
descriptor="(I)Ljava/lang/StackTraceElement;">
|
||||
<new def="x" class="Ljava/lang/StackTraceElement" />
|
||||
<return value="x" />
|
||||
</method>
|
||||
<method name="printStackTrace0"
|
||||
descriptor="(Ljava/lang/Object;)V" />
|
||||
<method name="getStackTraceDepth" descriptor="()I" />
|
||||
|
||||
</class>
|
||||
</package>
|
||||
<package name="java/lang/reflect">
|
||||
<class name="Array">
|
||||
<method name="get"
|
||||
descriptor="(Ljava/lang/Object;I)Ljava/lang/Object;" static="true"
|
||||
factory="true">
|
||||
<new def="x" class="Lcom/ibm/wala/Malleable" />
|
||||
<return value="x" />
|
||||
<poison
|
||||
reason="bogus model of java/lang/reflect/Array/get"
|
||||
level="severe" />
|
||||
</method>
|
||||
<method name="getByte"
|
||||
descriptor="(Ljava/lang/Object;I)B" static="true">
|
||||
</method>
|
||||
<method name="getLength"
|
||||
descriptor="(Ljava/lang/Object;)I" static="true">
|
||||
</method>
|
||||
<method name="multiNewArray"
|
||||
descriptor="(Ljava/lang/Class;[I)Ljava/lang/Object;" static="true"
|
||||
factory="true">
|
||||
<new def="x" class="Lcom/ibm/wala/Malleable" />
|
||||
<return value="x" />
|
||||
</method>
|
||||
<method name="newArray"
|
||||
descriptor="(Ljava/lang/Class;I)Ljava/lang/Object;" static="true"
|
||||
factory="true">
|
||||
<new def="x" class="Lcom/ibm/wala/Malleable" />
|
||||
<return value="x" />
|
||||
</method>
|
||||
<method name="newInstance"
|
||||
descriptor="(Ljava/lang/Class;I)Ljava/lang/Object;" static="true"
|
||||
factory="true">
|
||||
<new def="x" class="Lcom/ibm/wala/Malleable" />
|
||||
<return value="x" />
|
||||
</method>
|
||||
<method name="set"
|
||||
descriptor="(Ljava/lang/Object;ILjava/lang/Object;)V"
|
||||
static="true">
|
||||
</method>
|
||||
<method name="setByte"
|
||||
descriptor="(Ljava/lang/Object;IB)V" static="true">
|
||||
</method>
|
||||
</class>
|
||||
<class name="Field">
|
||||
<method name="get"
|
||||
descriptor="(Ljava/lang/Object;)Ljava/lang/Object;"
|
||||
factory="true">
|
||||
<new def="x" class="Lcom/ibm/wala/Malleable" />
|
||||
<return value="x" />
|
||||
<poison
|
||||
reason="bogus model of java/lang/reflect/Field/get"
|
||||
level="severe" />
|
||||
</method>
|
||||
<method name="getBoolean"
|
||||
descriptor="(Ljava/lang/Object;)Z">
|
||||
</method>
|
||||
<method name="getByte"
|
||||
descriptor="(Ljava/lang/Object;)B">
|
||||
</method>
|
||||
<method name="getChar"
|
||||
descriptor="(Ljava/lang/Object;)C">
|
||||
</method>
|
||||
<method name="getDouble"
|
||||
descriptor="(Ljava/lang/Object;)D">
|
||||
</method>
|
||||
<method name="getFloat"
|
||||
descriptor="(Ljava/lang/Object;)F">
|
||||
</method>
|
||||
<method name="getInt"
|
||||
descriptor="(Ljava/lang/Object;)I">
|
||||
</method>
|
||||
<method name="getLong"
|
||||
descriptor="(Ljava/lang/Object;)J">
|
||||
</method>
|
||||
<method name="getShort"
|
||||
descriptor="(Ljava/lang/Object;)S">
|
||||
</method>
|
||||
<method name="set"
|
||||
descriptor="(Ljava/lang/Object;Ljava/lang/Object;)V">
|
||||
</method>
|
||||
<method name="setBoolean"
|
||||
descriptor="(Ljava/lang/Object;Z)V">
|
||||
</method>
|
||||
<method name="setByte"
|
||||
descriptor="(Ljava/lang/Object;B)V">
|
||||
</method>
|
||||
<method name="setChar"
|
||||
descriptor="(Ljava/lang/Object;C)V">
|
||||
</method>
|
||||
<method name="setDouble"
|
||||
descriptor="(Ljava/lang/Object;D)V">
|
||||
</method>
|
||||
<method name="setFloat"
|
||||
descriptor="(Ljava/lang/Object;F)V">
|
||||
</method>
|
||||
<method name="setInt"
|
||||
descriptor="(Ljava/lang/Object;I)V">
|
||||
</method>
|
||||
<method name="setLong"
|
||||
descriptor="(Ljava/lang/Object;J)V">
|
||||
</method>
|
||||
<method name="setShort"
|
||||
descriptor="(Ljava/lang/Object;S)V">
|
||||
</method>
|
||||
</class>
|
||||
</package>
|
||||
|
||||
<package name="java/net">
|
||||
<class name="PlainDatagramSocketImpl">
|
||||
<method name="bind"
|
||||
descriptor="(ILjava/net/InetAddress;)V">
|
||||
</method>
|
||||
</class>
|
||||
<class name="PlainSocketImpl">
|
||||
<method name="initProto" descriptor="()V" static="true" />
|
||||
<method name="socketAvailable" descriptor="()I" />
|
||||
<method name="socketBind"
|
||||
descriptor="(Ljava/net/InetAddress;I)V" />
|
||||
<method name="socketClose0" descriptor="(Z)V" />
|
||||
<method name="socketConnect"
|
||||
descriptor="(Ljava/net/InetAddress;II)V" />
|
||||
<method name="socketCreate" descriptor="(Z)V" />
|
||||
<method name="socketGetOption"
|
||||
descriptor="(ILjava/lang/Object;)I" />
|
||||
<method name="socketListen" descriptor="(I)V" />
|
||||
<method name="socketSetOption"
|
||||
descriptor="(IZLjava/lang/Object;)V" />
|
||||
</class>
|
||||
<class name="SocketInputStream">
|
||||
<method name="init" descriptor="()V" static="true" />
|
||||
<method name="socketRead0"
|
||||
descriptor="(Ljava/io/FileDescriptor;[BIII)I" />
|
||||
</class>
|
||||
<class name="SocketOutputStream">
|
||||
<method name="init" descriptor="()V" static="true" />
|
||||
<method name="socketWrite0"
|
||||
descriptor="(Ljava/io/FileDescriptor;[BII)V" />
|
||||
</class>
|
||||
</package>
|
||||
|
||||
<package name="java/security">
|
||||
<class name="AccessControlContext">
|
||||
<method name="getInheritedAccessControlContext"
|
||||
descriptor="()Ljava/security/AccessControlContext;">
|
||||
<new def="x" class="Ljava/lang/Object" />
|
||||
<return value="x" />
|
||||
<poison
|
||||
reason="questionable model of java/security/AccessControlContext/getInheritedAccessControlContext"
|
||||
level="moderate" />
|
||||
</method>
|
||||
</class>
|
||||
<class name="AccessController">
|
||||
<method name="doPrivileged"
|
||||
descriptor="(Ljava/security/PrivilegedAction;)Ljava/lang/Object;"
|
||||
static="true">
|
||||
<call type="interface" name="run"
|
||||
class="Ljava/security/PrivilegedAction"
|
||||
descriptor="()Ljava/lang/Object;" def="x" arg0="arg0" />
|
||||
<return value="x" />
|
||||
<new def="y"
|
||||
class="Ljava/security/PrivilegedActionException" />
|
||||
<throw value="y" />
|
||||
<poison
|
||||
reason="incorrect model of java/security/AccessController/doPrivileged"
|
||||
level="severe" />
|
||||
</method>
|
||||
<method name="doPrivileged"
|
||||
descriptor="(Ljava/security/PrivilegedExceptionAction;)Ljava/lang/Object;"
|
||||
static="true">
|
||||
<call type="interface" name="run"
|
||||
class="Ljava/security/PrivilegedExceptionAction"
|
||||
descriptor="()Ljava/lang/Object;" def="x" arg0="arg0" />
|
||||
<return value="x" />
|
||||
<new def="y"
|
||||
class="Ljava/security/PrivilegedActionException" />
|
||||
<throw value="y" />
|
||||
<poison
|
||||
reason="incorrect model of java/security/AccessController/doPrivileged"
|
||||
level="severe" />
|
||||
</method>
|
||||
<method name="doPrivileged"
|
||||
descriptor="(Ljava/security/PrivilegedAction;Ljava/security/AccessControlContext;)Ljava/lang/Object;"
|
||||
static="true">
|
||||
<call type="interface" name="run"
|
||||
class="Ljava/security/PrivilegedAction"
|
||||
descriptor="()Ljava/lang/Object;" def="x" arg0="arg0" />
|
||||
<return value="x" />
|
||||
<new def="y"
|
||||
class="Ljava/security/PrivilegedActionException" />
|
||||
<throw value="y" />
|
||||
<poison
|
||||
reason="incorrect model of java/security/AccessController/doPrivileged"
|
||||
level="severe" />
|
||||
</method>
|
||||
<method name="doPrivileged"
|
||||
descriptor="(Ljava/security/PrivilegedExceptionAction;Ljava/security/AccessControlContext;)Ljava/lang/Object;"
|
||||
static="true">
|
||||
<call type="interface" name="run"
|
||||
class="Ljava/security/PrivilegedExceptionAction"
|
||||
descriptor="()Ljava/lang/Object;" def="x" arg0="arg0" />
|
||||
<return value="x" />
|
||||
<new def="y"
|
||||
class="Ljava/security/PrivilegedActionException" />
|
||||
<throw value="y" />
|
||||
<poison
|
||||
reason="incorrect model of java/security/AccessController/doPrivileged"
|
||||
level="severe" />
|
||||
</method>
|
||||
<method name="getStackAccessControlContext"
|
||||
descriptor="()Ljava/security/AccessControlContext;"
|
||||
static="true">
|
||||
<new def="x"
|
||||
class="Ljava/security/AccessControlContext" />
|
||||
<return value="x" />
|
||||
<poison
|
||||
reason="questionable model of java/security/AccessController/getStackAccessControlContext"
|
||||
level="moderate" />
|
||||
</method>
|
||||
</class>
|
||||
</package>
|
||||
|
||||
<package name="java/util">
|
||||
<class name="TimeZone">
|
||||
<method name="getSystemTimeZoneID"
|
||||
descriptor="(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"
|
||||
static="true">
|
||||
<new def="x" class="Ljava/lang/String" />
|
||||
<return value="x" />
|
||||
</method>
|
||||
</class>
|
||||
</package>
|
||||
|
||||
<package name="java/util/logging">
|
||||
<class name="FileHandler">
|
||||
<method name="isSetUID" descriptor="()Z" static="true" />
|
||||
</class>
|
||||
</package>
|
||||
|
||||
<package name="java/util/prefs">
|
||||
<class name="FileSystemPreferences">
|
||||
<method name="chmod" descriptor="(Ljava/lang/String;I)I"
|
||||
static="true" />
|
||||
<method name="lockFile0"
|
||||
descriptor="(Ljava/lang/String;IZ)[I" static="true">
|
||||
<constant name="size" type="int" value="1" />
|
||||
<new def="x" class="[I" size="size"/>
|
||||
<return value="x" />
|
||||
</method>
|
||||
<method name="unlockFile0" descriptor="(I)I"
|
||||
static="true" />
|
||||
</class>
|
||||
</package>
|
||||
|
||||
<package name="sun/misc">
|
||||
<class name="AtomicLongCSImpl">
|
||||
<method name="attemptUpdate" descriptor="(JJ)Z" />
|
||||
</class>
|
||||
<class name="AtomicLong">
|
||||
<method name="VMSupportsCS8" descriptor="()Z"
|
||||
static="true" />
|
||||
</class>
|
||||
<class name="Signal">
|
||||
<method name="handle0" descriptor="(IJ)J" static="true" />
|
||||
<method name="findSignal"
|
||||
descriptor="(Ljava/lang/String;)I" static="true" />
|
||||
</class>
|
||||
<class name="Unsafe" allocatable="true">
|
||||
<method name="getUnsafe" descriptor="()Lsun/misc/Unsafe"
|
||||
static="true">
|
||||
<new def="x" class="Lsun/misc/Unsafe" />
|
||||
<return value="x" />
|
||||
</method>
|
||||
<method name="allocateMemory" descriptor="(J)J" />
|
||||
<method name="copyMemory" descriptor="(JJJ)V" />
|
||||
<method name="freeMemory" descriptor="(J)V" />
|
||||
<method name="objectFieldOffset"
|
||||
descriptor="(Ljava/lang/reflect/Field;)J" />
|
||||
<method name="getBoolean" descriptor="(J)Z" />
|
||||
<method name="getByte" descriptor="(J)B" />
|
||||
<method name="getChar" descriptor="(J)C" />
|
||||
<method name="getDouble" descriptor="(J)D" />
|
||||
<method name="getFloat" descriptor="(J)F" />
|
||||
<method name="getInt" descriptor="(J)I" />
|
||||
<method name="getLong" descriptor="(J)J" />
|
||||
<method name="getShort" descriptor="(J)S" />
|
||||
<method name="getBoolean"
|
||||
descriptor="(Ljava/lang/Object;J)Z" />
|
||||
<method name="getByte"
|
||||
descriptor="(Ljava/lang/Object;J)B" />
|
||||
<method name="getChar"
|
||||
descriptor="(Ljava/lang/Object;J)C" />
|
||||
<method name="getDouble"
|
||||
descriptor="(Ljava/lang/Object;J)D" />
|
||||
<method name="getFloat"
|
||||
descriptor="(Ljava/lang/Object;J)F" />
|
||||
<method name="getInt"
|
||||
descriptor="(Ljava/lang/Object;J)I" />
|
||||
<method name="getLong"
|
||||
descriptor="(Ljava/lang/Object;J)J" />
|
||||
<method name="getShort"
|
||||
descriptor="(Ljava/lang/Object;J)S" />
|
||||
<method name="putBoolean" descriptor="(JZ)V" />
|
||||
<method name="putByte" descriptor="(JB)V" />
|
||||
<method name="putChar" descriptor="(JC)V" />
|
||||
<method name="putDouble" descriptor="(JD)V" />
|
||||
<method name="putFloat" descriptor="(JF)V" />
|
||||
<method name="putInt" descriptor="(JI)V" />
|
||||
<method name="putLong" descriptor="(JJ)V" />
|
||||
<method name="putShort" descriptor="(JS)V" />
|
||||
<method name="registerNatives" descriptor="()V"
|
||||
static="true" />
|
||||
</class>
|
||||
</package>
|
||||
|
||||
<package name="sun/nio/ch">
|
||||
<class name="IOUtil">
|
||||
<method name="initIDs" descriptor="()V" static="true" />
|
||||
</class>
|
||||
<class name="FileDispatcher">
|
||||
<method name="init" descriptor="()V" static="true" />
|
||||
</class>
|
||||
<class name="FileChannelImpl">
|
||||
<method name="lock0"
|
||||
descriptor="(Ljava/io/FileDescriptor;ZJJZ)I" />
|
||||
<method name="initIDs" descriptor="()J" static="true" />
|
||||
</class>
|
||||
</package>
|
||||
|
||||
</classloader>
|
||||
</summary-spec>
|
||||
@ -0,0 +1,52 @@
|
||||
###############################################################################
|
||||
# WALA property file
|
||||
# This file defines the default settings for the core WALA Engine
|
||||
###############################################################################
|
||||
|
||||
################# Mandatory settings without default value ####################
|
||||
|
||||
#####
|
||||
# Identify the directory where Java Runtime libraries are located.
|
||||
# For instance, on a windows OS it's typically C:/Progra~1/Java/j2reYourVersion/lib
|
||||
#
|
||||
# N.B. This directory must contain a valid core.jar (or rt.jar for older VMs)
|
||||
# On IBM 1.4.x SDKs, this means you need to specify Java14x/jre/lib and not
|
||||
# Java14x/lib!
|
||||
#
|
||||
# Info: Location must be absolute.
|
||||
#####
|
||||
java_runtime_dir = Your location
|
||||
|
||||
################### Mandatory settings with default value ######################
|
||||
|
||||
##### Default output dir
|
||||
# Identify directory where all generated files without absolute path will be located.
|
||||
# Default value: results [Non absolute path are relative to WALA home location]
|
||||
# Info: Can be absolute or relative.
|
||||
#####
|
||||
#output_dir = Your location
|
||||
|
||||
############################ Optional settings ################################
|
||||
|
||||
#####
|
||||
# Identify the directory where J2EE standard libraries are located.
|
||||
# Required only if you ask to analyze J2EE code.
|
||||
# No default value.
|
||||
# Info: Location must be absolute.
|
||||
#####
|
||||
#j2ee_runtime_dir = Your location
|
||||
|
||||
#####
|
||||
# Identify the directory where Eclipse plugins are installed
|
||||
# Required only if you ask to analyze Eclipse plugins.
|
||||
# No default value.
|
||||
# Info: Location must be absolute.
|
||||
#####
|
||||
#eclipse_plugins_dir = Your location
|
||||
|
||||
##### Report file
|
||||
# Identify file name where to output WALA trace file.
|
||||
# Default value: wala_report.txt [Non absolute path are relative to 'output.dir' variable value]
|
||||
# Info: Can be absolute or relative.
|
||||
#####
|
||||
#WALA_report = Your file name
|
||||
27
com.ibm.wala.core/com.ibm.wala.core/javaCompiler...args
Normal file
27
com.ibm.wala.core/com.ibm.wala.core/javaCompiler...args
Normal file
@ -0,0 +1,27 @@
|
||||
#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime_3.2.0.v20060603.jar[~org/eclipse/core/internal/preferences/legacy/*;~org/eclipse/core/internal/runtime/*;+org/eclipse/core/runtime/*;?**/*]
|
||||
#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.osgi_3.2.0.v20060601.jar[+org/eclipse/osgi/event/*;+org/eclipse/osgi/framework/console/*;+org/eclipse/osgi/framework/eventmgr/*;+org/eclipse/osgi/framework/log/*;+org/eclipse/osgi/service/datalocation/*;+org/eclipse/osgi/service/debug/*;+org/eclipse/osgi/service/environment/*;+org/eclipse/osgi/service/localization/*;+org/eclipse/osgi/service/pluginconversion/*;+org/eclipse/osgi/service/resolver/*;+org/eclipse/osgi/service/runnable/*;+org/eclipse/osgi/service/urlconversion/*;+org/eclipse/osgi/storagemanager/*;+org/eclipse/osgi/util/*;+org/osgi/framework/*;+org/osgi/service/condpermadmin/*;+org/osgi/service/packageadmin/*;+org/osgi/service/permissionadmin/*;+org/osgi/service/startlevel/*;+org/osgi/service/url/*;+org/osgi/util/tracker/*;~org/eclipse/core/runtime/adaptor/*;~org/eclipse/core/runtime/internal/adaptor/*;~org/eclipse/core/runtime/internal/stats/*;~org/eclipse/osgi/baseadaptor/*;~org/eclipse/osgi/baseadaptor/bundlefile/*;~org/eclipse/osgi/baseadaptor/hooks/*;~org/eclipse/osgi/baseadaptor/loader/*;~org/eclipse/osgi/framework/adaptor/*;~org/eclipse/osgi/framework/debug/*;~org/eclipse/osgi/framework/internal/core/*;~org/eclipse/osgi/framework/internal/protocol/*;~org/eclipse/osgi/framework/internal/protocol/bundleentry/*;~org/eclipse/osgi/framework/internal/protocol/bundleresource/*;~org/eclipse/osgi/framework/internal/protocol/reference/*;~org/eclipse/osgi/framework/internal/reliablefile/*;~org/eclipse/osgi/framework/launcher/*;~org/eclipse/osgi/framework/util/*;~org/eclipse/osgi/internal/baseadaptor/*;~org/eclipse/osgi/internal/module/*;~org/eclipse/osgi/internal/profile/*;~org/eclipse/osgi/internal/resolver/*;~org/eclipse/osgi/internal/verifier/*;~org/eclipse/osgi/internal/provisional/verifier/*;?**/*]
|
||||
#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.equinox.common_3.2.0.v20060603.jar[~org/eclipse/core/internal/runtime/*;~org/eclipse/core/internal/boot/*;+org/eclipse/core/runtime/*;?**/*]
|
||||
#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.jobs_3.2.0.v20060603.jar[~org/eclipse/core/internal/jobs/*;+org/eclipse/core/runtime/jobs/*;?**/*]
|
||||
#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603/runtime_registry_compatibility.jar[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*]
|
||||
#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*]
|
||||
#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.equinox.registry_3.2.0.v20060601.jar[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*]
|
||||
#ADAPTER#ACCESS#eclipse/plugins/org.apache.xerces_2.8.0.v200606131651/resolver.jar[?**/*]
|
||||
#ADAPTER#ACCESS#eclipse/plugins/org.apache.xerces_2.8.0.v200606131651/xercesImpl.jar[?**/*]
|
||||
#ADAPTER#ACCESS#eclipse/plugins/org.apache.xerces_2.8.0.v200606131651/xml-apis.jar[?**/*]
|
||||
#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.equinox.preferences_3.2.0.v20060601.jar[~org/eclipse/core/internal/preferences/*;~org/eclipse/core/internal/preferences/exchange/*;+org/eclipse/core/runtime/preferences/*;+org/osgi/service/prefs/*;?**/*]
|
||||
#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603/@dot[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*]
|
||||
#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.contenttype_3.2.0.v20060603.jar[~org/eclipse/core/internal/content/*;+org/eclipse/core/runtime/content/*;?**/*]
|
||||
#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.auth_3.2.0.v20060601.jar[?**/*]
|
||||
#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.emf.ecore_2.2.0.v200606271057.jar[+org/eclipse/emf/ecore/*;+org/eclipse/emf/ecore/impl/*;+org/eclipse/emf/ecore/plugin/*;+org/eclipse/emf/ecore/resource/*;+org/eclipse/emf/ecore/resource/impl/*;+org/eclipse/emf/ecore/util/*;+org/eclipse/emf/ecore/xml/namespace/*;+org/eclipse/emf/ecore/xml/namespace/impl/*;+org/eclipse/emf/ecore/xml/namespace/util/*;+org/eclipse/emf/ecore/xml/type/*;+org/eclipse/emf/ecore/xml/type/impl/*;+org/eclipse/emf/ecore/xml/type/internal/*;+org/eclipse/emf/ecore/xml/type/util/*;?**/*]
|
||||
#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.emf.common_2.2.0.v200606271057.jar[+org/eclipse/emf/common/*;+org/eclipse/emf/common/archive/*;+org/eclipse/emf/common/command/*;+org/eclipse/emf/common/notify/*;+org/eclipse/emf/common/notify/impl/*;+org/eclipse/emf/common/util/*;?**/*]
|
||||
#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.resources_3.2.0.v20060603.jar[?**/*]
|
||||
#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.resources.compatibility_3.2.0.v20060603.jar[?**/*]
|
||||
#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.resources.win32_3.2.0.v20060603.jar[?**/*]
|
||||
#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility_3.1.100.v20060603.jar[?**/*]
|
||||
#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.update.configurator_3.2.0.v20060605.jar[?**/*]
|
||||
#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ant.core_3.1.100.v20060531.jar[?**/*]
|
||||
#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.variables_3.1.100.v20060605.jar[?**/*]
|
||||
#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.expressions_3.2.0.v20060605-1400.jar[?**/*]
|
||||
#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.filesystem_1.0.0.v20060603.jar[?**/*]
|
||||
#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.filesystem.win32.x86_1.0.0.v20060603.jar[?**/*]
|
||||
#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.emf.ecore.xmi_2.2.0.v200606271057.jar[+org/eclipse/emf/ecore/xmi/*;+org/eclipse/emf/ecore/xmi/impl/*;+org/eclipse/emf/ecore/xmi/util/*;?**/*]
|
||||
BIN
com.ibm.wala.core/com.ibm.wala.core/lib/primordial.jar.model
Normal file
BIN
com.ibm.wala.core/com.ibm.wala.core/lib/primordial.jar.model
Normal file
Binary file not shown.
6
com.ibm.wala.core/com.ibm.wala.core/plugin.properties
Normal file
6
com.ibm.wala.core/com.ibm.wala.core/plugin.properties
Normal file
@ -0,0 +1,6 @@
|
||||
PLUGINNAME=core WALA analysis engine
|
||||
VENDORNAME=IBMproviderName = www.example.org
|
||||
pluginName = PatternSet Model
|
||||
# ====================================================================
|
||||
providerName = www.example.org
|
||||
|
||||
@ -0,0 +1,561 @@
|
||||
/*******************************************************************************
|
||||
* 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.analysis.pointers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.ibm.wala.analysis.reflection.Malleable;
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IField;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.LocalPointerKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.CompoundIterator;
|
||||
import com.ibm.wala.util.IntFunction;
|
||||
import com.ibm.wala.util.IntMapIterator;
|
||||
import com.ibm.wala.util.collections.EmptyIterator;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.graph.AbstractNumberedGraph;
|
||||
import com.ibm.wala.util.graph.EdgeManager;
|
||||
import com.ibm.wala.util.graph.NodeManager;
|
||||
import com.ibm.wala.util.graph.NumberedGraph;
|
||||
import com.ibm.wala.util.graph.NumberedNodeManager;
|
||||
import com.ibm.wala.util.graph.impl.NumberedNodeIterator;
|
||||
import com.ibm.wala.util.intset.BasicNonNegativeIntRelation;
|
||||
import com.ibm.wala.util.intset.IBinaryNonNegativeIntRelation;
|
||||
import com.ibm.wala.util.intset.IntSet;
|
||||
import com.ibm.wala.util.intset.MutableMapping;
|
||||
import com.ibm.wala.util.intset.MutableSparseIntSet;
|
||||
import com.ibm.wala.util.intset.OrdinalSet;
|
||||
import com.ibm.wala.util.intset.OrdinalSetMapping;
|
||||
import com.ibm.wala.util.intset.SparseIntSet;
|
||||
|
||||
/**
|
||||
* @author sfink
|
||||
*/
|
||||
public class BasicHeapGraph extends HeapGraph {
|
||||
|
||||
private final static boolean VERBOSE = true;
|
||||
|
||||
private final static int VERBOSE_INTERVAL = 10000;
|
||||
|
||||
/**
|
||||
* Pointer analysis solution
|
||||
*/
|
||||
private final PointerAnalysis pointerAnalysis;
|
||||
|
||||
/**
|
||||
* The backing graph
|
||||
*/
|
||||
private final NumberedGraph<Object> G;
|
||||
|
||||
/**
|
||||
* governing call graph
|
||||
*/
|
||||
private final CallGraph callGraph;
|
||||
|
||||
/**
|
||||
* @param P
|
||||
* governing pointer analysis
|
||||
*/
|
||||
public BasicHeapGraph(final PointerAnalysis P, final CallGraph callGraph) {
|
||||
super(P.getHeapModel());
|
||||
this.pointerAnalysis = P;
|
||||
this.callGraph = callGraph;
|
||||
|
||||
final OrdinalSetMapping<PointerKey> pointerKeys = getPointerKeys(P);
|
||||
final NumberedNodeManager<Object> nodeMgr = new NumberedNodeManager<Object>() {
|
||||
public Iterator<Object> iterateNodes() {
|
||||
return new CompoundIterator<Object>(pointerKeys.iterator(), P.getInstanceKeyMapping().iterator());
|
||||
}
|
||||
|
||||
public int getNumberOfNodes() {
|
||||
return pointerKeys.getMappingSize() + P.getInstanceKeyMapping().getMappingSize();
|
||||
}
|
||||
|
||||
public void addNode(Object n) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
|
||||
public void removeNode(Object n) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
|
||||
public int getNumber(Object N) {
|
||||
if (N instanceof PointerKey) {
|
||||
return pointerKeys.getMappedIndex((PointerKey) N);
|
||||
} else {
|
||||
if (Assertions.verifyAssertions) {
|
||||
if (!(N instanceof InstanceKey)) {
|
||||
Assertions.UNREACHABLE(N.getClass().toString());
|
||||
}
|
||||
}
|
||||
int inumber = P.getInstanceKeyMapping().getMappedIndex((InstanceKey) N);
|
||||
return (inumber == -1) ? -1 : inumber + pointerKeys.getMappingSize();
|
||||
}
|
||||
}
|
||||
|
||||
public Object getNode(int number) {
|
||||
if (number >= pointerKeys.getMappingSize()) {
|
||||
return P.getInstanceKeyMapping().getMappedObject(number - pointerKeys.getMappingSize());
|
||||
} else {
|
||||
return pointerKeys.getMappedObject(number);
|
||||
}
|
||||
}
|
||||
|
||||
public int getMaxNumber() {
|
||||
return getNumberOfNodes() - 1;
|
||||
}
|
||||
|
||||
public boolean containsNode(Object n) {
|
||||
return getNumber(n) != -1;
|
||||
}
|
||||
|
||||
public Iterator<Object> iterateNodes(IntSet s) {
|
||||
return new NumberedNodeIterator<Object>(s, this);
|
||||
}
|
||||
};
|
||||
|
||||
final IBinaryNonNegativeIntRelation pred = computePredecessors(nodeMgr);
|
||||
final IntFunction<Object> toNode = new IntFunction<Object>() {
|
||||
public Object apply(int i) {
|
||||
return nodeMgr.getNode(i);
|
||||
}
|
||||
};
|
||||
|
||||
this.G = new AbstractNumberedGraph<Object>() {
|
||||
private final EdgeManager<Object> edgeMgr = new EdgeManager<Object>() {
|
||||
public Iterator<Object> getPredNodes(Object N) {
|
||||
int n = nodeMgr.getNumber(N);
|
||||
IntSet p = pred.getRelated(n);
|
||||
if (p == null) {
|
||||
return EmptyIterator.instance();
|
||||
} else {
|
||||
return new IntMapIterator<Object>(p.intIterator(), toNode);
|
||||
}
|
||||
}
|
||||
|
||||
public int getPredNodeCount(Object N) {
|
||||
int n = nodeMgr.getNumber(N);
|
||||
return pred.getRelatedCount(n);
|
||||
}
|
||||
|
||||
public Iterator<? extends Object> getSuccNodes(Object N) {
|
||||
int[] succ = computeSuccNodeNumbers(N, nodeMgr);
|
||||
if (succ == null) {
|
||||
return EmptyIterator.instance();
|
||||
}
|
||||
SparseIntSet s = new MutableSparseIntSet(succ);
|
||||
return new IntMapIterator<Object>(s.intIterator(), toNode);
|
||||
}
|
||||
|
||||
public int getSuccNodeCount(Object N) {
|
||||
int[] succ = computeSuccNodeNumbers(N, nodeMgr);
|
||||
return succ == null ? 0 : succ.length;
|
||||
}
|
||||
|
||||
public void addEdge(Object src, Object dst) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
|
||||
public void removeEdge(Object src, Object dst) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
|
||||
public void removeAllIncidentEdges(Object node) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
|
||||
public void removeIncomingEdges(Object node) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
|
||||
public void removeOutgoingEdges(Object node) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
|
||||
public boolean hasEdge(Object src, Object dst) {
|
||||
Assertions.UNREACHABLE();
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
protected NodeManager<Object> getNodeManager() {
|
||||
return nodeMgr;
|
||||
}
|
||||
|
||||
protected EdgeManager<Object> getEdgeManager() {
|
||||
return edgeMgr;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private OrdinalSetMapping<PointerKey> getPointerKeys(PointerAnalysis pointerAnalysis) {
|
||||
MutableMapping<PointerKey> result = new MutableMapping<PointerKey>();
|
||||
|
||||
for (Iterator it = pointerAnalysis.getPointerKeys().iterator(); it.hasNext();) {
|
||||
PointerKey p = (PointerKey) it.next();
|
||||
result.add(p);
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
private int[] computeSuccNodeNumbers(Object N, NumberedNodeManager<Object> nodeManager) {
|
||||
if (N instanceof PointerKey) {
|
||||
PointerKey P = (PointerKey) N;
|
||||
OrdinalSet S = pointerAnalysis.getPointsToSet(P);
|
||||
int[] result = new int[S.size()];
|
||||
int i = 0;
|
||||
for (Iterator it = S.iterator(); it.hasNext();) {
|
||||
result[i] = nodeManager.getNumber(it.next());
|
||||
i++;
|
||||
}
|
||||
return result;
|
||||
} else if (N instanceof InstanceKey) {
|
||||
InstanceKey I = (InstanceKey) N;
|
||||
TypeReference T = I.getConcreteType().getReference();
|
||||
|
||||
if (Assertions.verifyAssertions) {
|
||||
if (T == null) {
|
||||
Assertions._assert(T != null, "null concrete type from " + I.getClass());
|
||||
}
|
||||
}
|
||||
if (T.isArrayType()) {
|
||||
PointerKey p = getHeapModel().getPointerKeyForArrayContents(I);
|
||||
if (p == null || !nodeManager.containsNode(p)) {
|
||||
return null;
|
||||
} else {
|
||||
return new int[] { nodeManager.getNumber(p) };
|
||||
}
|
||||
} else if (!Malleable.isMalleable(T)) {
|
||||
IClass klass = getHeapModel().getClassHierarchy().lookupClass(T);
|
||||
if (Assertions.verifyAssertions) {
|
||||
if (klass == null) {
|
||||
Assertions._assert(klass != null, "null klass for type " + T);
|
||||
}
|
||||
}
|
||||
MutableSparseIntSet result = new MutableSparseIntSet();
|
||||
try {
|
||||
for (Iterator<IField> it = klass.getAllInstanceFields().iterator(); it.hasNext();) {
|
||||
IField f = it.next();
|
||||
if (!f.getFieldReference().getFieldType().isPrimitiveType()) {
|
||||
PointerKey p = getHeapModel().getPointerKeyForInstanceField(I, f);
|
||||
if (p != null && nodeManager.containsNode(p)) {
|
||||
result.add(nodeManager.getNumber(p));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ClassHierarchyException e) {
|
||||
// uh oh. skip it for now.
|
||||
}
|
||||
return result.toIntArray();
|
||||
} else {
|
||||
Assertions._assert(Malleable.isMalleable(T));
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
Assertions.UNREACHABLE("Unexpected type: " + N.getClass());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return R, y \in R(x,y) if the node y is a predecessor of node x
|
||||
*/
|
||||
private IBinaryNonNegativeIntRelation computePredecessors(NumberedNodeManager<Object> nodeManager) {
|
||||
BasicNonNegativeIntRelation R = new BasicNonNegativeIntRelation(new byte[] { BasicNonNegativeIntRelation.SIMPLE },
|
||||
BasicNonNegativeIntRelation.SIMPLE);
|
||||
|
||||
// we split the following loops to improve temporal locality,
|
||||
// particularly for locals
|
||||
computePredecessorsForNonLocals(nodeManager, R);
|
||||
computePredecessorsForLocals(nodeManager, R);
|
||||
|
||||
return R;
|
||||
}
|
||||
|
||||
private void computePredecessorsForNonLocals(NumberedNodeManager<Object> nodeManager, BasicNonNegativeIntRelation R) {
|
||||
// Note: we run this loop backwards on purpose, to avoid lots of resizing of
|
||||
// bitvectors
|
||||
// in the backing relation. i.e., we will add the biggest bits first.
|
||||
// pretty damn tricky.
|
||||
for (int i = nodeManager.getMaxNumber(); i >= 0; i--) {
|
||||
if (VERBOSE) {
|
||||
if (i % VERBOSE_INTERVAL == 0) {
|
||||
System.err.println("Building HeapGraph: " + i);
|
||||
}
|
||||
}
|
||||
Object n = nodeManager.getNode(i);
|
||||
if (!(n instanceof LocalPointerKey)) {
|
||||
int[] succ = computeSuccNodeNumbers(n, nodeManager);
|
||||
if (succ != null) {
|
||||
for (int z = 0; z < succ.length; z++) {
|
||||
int j = succ[z];
|
||||
R.add(j, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* traverse locals in order, first by node, then by value number: attempt to
|
||||
* improve locality
|
||||
*/
|
||||
private void computePredecessorsForLocals(NumberedNodeManager<Object> nodeManager, BasicNonNegativeIntRelation R) {
|
||||
|
||||
ArrayList<LocalPointerKey> list = new ArrayList<LocalPointerKey>();
|
||||
for (Iterator it = nodeManager.iterateNodes(); it.hasNext();) {
|
||||
Object n = it.next();
|
||||
if (n instanceof LocalPointerKey) {
|
||||
list.add((LocalPointerKey) n);
|
||||
}
|
||||
}
|
||||
Object[] arr = list.toArray();
|
||||
Arrays.sort(arr, new LocalPointerComparator());
|
||||
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
if (VERBOSE) {
|
||||
if (i % VERBOSE_INTERVAL == 0) {
|
||||
System.err.println("Building HeapGraph: " + i + " of " + arr.length);
|
||||
}
|
||||
}
|
||||
LocalPointerKey n = (LocalPointerKey) arr[i];
|
||||
int num = nodeManager.getNumber(n);
|
||||
int[] succ = computeSuccNodeNumbers(n, nodeManager);
|
||||
if (succ != null) {
|
||||
for (int z = 0; z < succ.length; z++) {
|
||||
int j = succ[z];
|
||||
R.add(j, num);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* sorts local pointers by node, then value number
|
||||
*/
|
||||
private final class LocalPointerComparator implements Comparator<Object> {
|
||||
public int compare(Object arg1, Object arg2) {
|
||||
LocalPointerKey o1 = (LocalPointerKey)arg1;
|
||||
LocalPointerKey o2 = (LocalPointerKey)arg2;
|
||||
if (o1.getNode().equals(o2.getNode())) {
|
||||
return o1.getValueNumber() - o2.getValueNumber();
|
||||
} else {
|
||||
return callGraph.getNumber(o1.getNode()) - callGraph.getNumber(o2.getNode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.util.graph.NumberedNodeManager#getNumber(com.ibm.wala.util.graph.Node)
|
||||
*/
|
||||
public int getNumber(Object N) {
|
||||
return G.getNumber(N);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.util.graph.NumberedNodeManager#getNode(int)
|
||||
*/
|
||||
public Object getNode(int number) {
|
||||
return G.getNode(number);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.util.graph.NumberedNodeManager#getMaxNumber()
|
||||
*/
|
||||
public int getMaxNumber() {
|
||||
return G.getMaxNumber();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.util.graph.NodeManager#iterateNodes()
|
||||
*/
|
||||
public Iterator<? extends Object> iterateNodes() {
|
||||
return G.iterateNodes();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.util.graph.NodeManager#getNumberOfNodes()
|
||||
*/
|
||||
public int getNumberOfNodes() {
|
||||
return G.getNumberOfNodes();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.util.graph.EdgeManager#getPredNodes(com.ibm.wala.util.graph.Node)
|
||||
*/
|
||||
public Iterator<? extends Object> getPredNodes(Object N) {
|
||||
return G.getPredNodes(N);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.util.graph.EdgeManager#getPredNodeCount(com.ibm.wala.util.graph.Node)
|
||||
*/
|
||||
public int getPredNodeCount(Object N) {
|
||||
return G.getPredNodeCount(N);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.util.graph.EdgeManager#getSuccNodes(com.ibm.wala.util.graph.Node)
|
||||
*/
|
||||
public Iterator<? extends Object> getSuccNodes(Object N) {
|
||||
return G.getSuccNodes(N);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.util.graph.EdgeManager#getSuccNodeCount(com.ibm.wala.util.graph.Node)
|
||||
*/
|
||||
public int getSuccNodeCount(Object N) {
|
||||
return G.getSuccNodeCount(N);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.util.graph.NodeManager#addNode(com.ibm.wala.util.graph.Node)
|
||||
*/
|
||||
public void addNode(Object n) {
|
||||
Assertions.UNREACHABLE();
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.util.graph.NodeManager#remove(com.ibm.wala.util.graph.Node)
|
||||
*/
|
||||
public void removeNode(Object n) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*/
|
||||
public void addEdge(Object from, Object to) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
|
||||
public void removeEdge(Object from, Object to) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*/
|
||||
public boolean hasEdge(Object from, Object to) {
|
||||
Assertions.UNREACHABLE();
|
||||
return false;
|
||||
}
|
||||
|
||||
public void removeAllIncidentEdges(Object node) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.util.graph.NodeManager#containsNode(com.ibm.wala.util.graph.Node)
|
||||
*/
|
||||
public boolean containsNode(Object N) {
|
||||
return G.containsNode(N);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuffer result = new StringBuffer();
|
||||
result.append("Nodes:\n");
|
||||
for (int i = 0; i < getMaxNumber(); i++) {
|
||||
Object node = getNode(i);
|
||||
if (node != null) {
|
||||
result.append(i).append(" ").append(node).append("\n");
|
||||
}
|
||||
}
|
||||
result.append("Edges:\n");
|
||||
for (int i = 0; i < getMaxNumber(); i++) {
|
||||
Object node = getNode(i);
|
||||
if (node != null) {
|
||||
result.append(i).append(" -> ");
|
||||
for (Iterator it = getSuccNodes(node); it.hasNext();) {
|
||||
Object s = it.next();
|
||||
result.append(getNumber(s)).append(" ");
|
||||
}
|
||||
result.append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*/
|
||||
public void removeIncomingEdges(Object node) {
|
||||
// TODO Auto-generated method stub
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*/
|
||||
public void removeOutgoingEdges(Object node) {
|
||||
// TODO Auto-generated method stub
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
|
||||
public IntSet getSuccNodeNumbers(Object node) {
|
||||
// TODO Auto-generated method stub
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
|
||||
public IntSet getPredNodeNumbers(Object node) {
|
||||
// TODO Auto-generated method stub
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,78 @@
|
||||
/*******************************************************************************
|
||||
* 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.analysis.pointers;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import com.ibm.wala.ipa.callgraph.propagation.HeapModel;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
import com.ibm.wala.util.collections.Filter;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.graph.NumberedGraph;
|
||||
import com.ibm.wala.util.graph.impl.NumberedNodeIterator;
|
||||
import com.ibm.wala.util.graph.traverse.DFS;
|
||||
import com.ibm.wala.util.intset.IntSet;
|
||||
|
||||
/**
|
||||
* A Graph view of a pointer analysis solution.
|
||||
*
|
||||
* Nodes in the Graph are PointerKeys and InstanceKeys.
|
||||
*
|
||||
* There is an edge from a PointerKey P to an InstanceKey I iff the PointerAnalysis
|
||||
* indicates that P may point to I.
|
||||
*
|
||||
* There is an edge from an InstanceKey I to a PointerKey P iff
|
||||
* - P represents a field of an object instance modelled by I, or
|
||||
* - P represents the array contents of array instance I.
|
||||
*
|
||||
* @author sfink
|
||||
*
|
||||
*/
|
||||
public abstract class HeapGraph implements NumberedGraph<Object> {
|
||||
|
||||
private final HeapModel hm;
|
||||
|
||||
protected HeapGraph(HeapModel hm) {
|
||||
this.hm = hm;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.ibm.wala.util.graph.NumberedNodeManager#iterateNodes(com.ibm.wala.util.intset.IntSet)
|
||||
*/
|
||||
public Iterator<Object> iterateNodes(IntSet s) {
|
||||
return new NumberedNodeIterator<Object>(s,this);
|
||||
}
|
||||
|
||||
public Collection<Object> getReachableInstances(Set<Object> roots) {
|
||||
Filter f = new Filter() {
|
||||
public boolean accepts(Object o) {
|
||||
return (o instanceof InstanceKey);
|
||||
}
|
||||
};
|
||||
return DFS.getReachableNodes(this, roots, f);
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see com.ibm.wala.util.graph.Graph#removeNode(com.ibm.wala.util.graph.Node)
|
||||
*/
|
||||
public void removeNodeAndEdges(Object N) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the heap model used in this pointer analysis.
|
||||
*/
|
||||
public HeapModel getHeapModel() {
|
||||
return hm;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
<HTML>
|
||||
<BODY>
|
||||
This package defines utilities to help navigate pointer analysis results.
|
||||
</BODY>
|
||||
</HTML>
|
||||
@ -0,0 +1,61 @@
|
||||
/*******************************************************************************
|
||||
* 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.analysis.reflection;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.ssa.IR;
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.ssa.SSAInvokeInstruction;
|
||||
import com.ibm.wala.ssa.SSAInstruction.Visitor;
|
||||
import com.ibm.wala.util.collections.HashMapFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* A mapping from CallSiteReference to SSA InvokeInstruction.
|
||||
*
|
||||
* @author sfink
|
||||
*/
|
||||
public class CallSiteMap {
|
||||
|
||||
/**
|
||||
* f: CallSiteReference -> InvokeInstruction
|
||||
*/
|
||||
private final Map<CallSiteReference, SSAInvokeInstruction> map = HashMapFactory.make();
|
||||
|
||||
/**
|
||||
* @param ir
|
||||
*/
|
||||
public CallSiteMap(final IR ir) {
|
||||
Visitor v = new Visitor() {
|
||||
public void visitInvoke(SSAInvokeInstruction instruction) {
|
||||
CallSiteReference site = instruction.getCallSite();
|
||||
map.put(site, instruction);
|
||||
}
|
||||
};
|
||||
SSAInstruction[] instructions = ir.getInstructions();
|
||||
for (int i = 0; i < instructions.length; i++) {
|
||||
if (instructions[i] != null) {
|
||||
instructions[i].visit(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param site
|
||||
* @return the InvokeInstruction corresponding to the call site.
|
||||
*/
|
||||
public SSAInvokeInstruction getInstructionForSite(CallSiteReference site) {
|
||||
SSAInvokeInstruction result = map.get(site);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -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.analysis.reflection;
|
||||
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.Context;
|
||||
import com.ibm.wala.ipa.callgraph.ContextItem;
|
||||
import com.ibm.wala.ipa.callgraph.ContextKey;
|
||||
|
||||
/**
|
||||
*
|
||||
* A context which is a <CGNode, CallSiteReference> pair
|
||||
*
|
||||
* @author sfink
|
||||
*/
|
||||
public class CallerSiteContext implements Context {
|
||||
private final CGNode caller;
|
||||
private final CallSiteReference site;
|
||||
|
||||
/**
|
||||
* @param caller
|
||||
* @param site
|
||||
*/
|
||||
public CallerSiteContext(CGNode caller, CallSiteReference site) {
|
||||
this.caller = caller;
|
||||
this.site = site;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.ibm.wala.ipa.callgraph.Context#get(com.ibm.wala.ipa.callgraph.ContextKey)
|
||||
*/
|
||||
public ContextItem get(ContextKey name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString() {
|
||||
return "[CallerSiteContext: " + caller + "," + site.getProgramCounter() + "]";
|
||||
}
|
||||
|
||||
public CGNode getCaller() {
|
||||
return caller;
|
||||
}
|
||||
|
||||
public CallSiteReference getSite() {
|
||||
return site;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
public boolean equals(Object arg0) {
|
||||
if (getClass().equals(arg0.getClass())) {
|
||||
CallerSiteContext other = (CallerSiteContext) arg0;
|
||||
return caller.equals(other.caller) && (site.equals(other.site));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
return site.hashCode() + 839 * caller.hashCode();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,362 @@
|
||||
/*******************************************************************************
|
||||
* 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.analysis.reflection;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.ibm.wala.cfg.ControlFlowGraph;
|
||||
import com.ibm.wala.cfg.InducedCFG;
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.classLoader.CodeScanner;
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IField;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.classLoader.NewSiteReference;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.Context;
|
||||
import com.ibm.wala.ipa.callgraph.ContextUtil;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.SSAContextInterpreter;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.ipa.summaries.SyntheticIR;
|
||||
import com.ibm.wala.shrikeBT.IInvokeInstruction;
|
||||
import com.ibm.wala.ssa.DefUse;
|
||||
import com.ibm.wala.ssa.IR;
|
||||
import com.ibm.wala.ssa.SSAArrayLengthInstruction;
|
||||
import com.ibm.wala.ssa.SSAGetInstruction;
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.ssa.SSAInvokeInstruction;
|
||||
import com.ibm.wala.ssa.SSANewInstruction;
|
||||
import com.ibm.wala.ssa.SSAOptions;
|
||||
import com.ibm.wala.ssa.SSAPutInstruction;
|
||||
import com.ibm.wala.ssa.SSAReturnInstruction;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.types.Descriptor;
|
||||
import com.ibm.wala.types.MethodReference;
|
||||
import com.ibm.wala.types.TypeName;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.Atom;
|
||||
import com.ibm.wala.util.collections.HashMapFactory;
|
||||
import com.ibm.wala.util.collections.NonNullSingletonIterator;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.warnings.WarningSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* A context interpreter for java.lang.Object.clone
|
||||
*
|
||||
* TODO: The current implementation does not model CloneNotSupportedExceptions
|
||||
*
|
||||
* @author sfink
|
||||
*/
|
||||
public class CloneInterpreter implements SSAContextInterpreter {
|
||||
|
||||
/**
|
||||
* Comment for <code>cloneAtom</code>
|
||||
*/
|
||||
public final static Atom cloneAtom = Atom.findOrCreateUnicodeAtom("clone");
|
||||
|
||||
private final static Descriptor cloneDesc = Descriptor.findOrCreateUTF8("()Ljava/lang/Object;");
|
||||
|
||||
/**
|
||||
* Comment for <code>CLONE</code>
|
||||
*/
|
||||
public final static MethodReference CLONE = MethodReference.findOrCreate(TypeReference.JavaLangObject, cloneAtom, cloneDesc);
|
||||
|
||||
private final static TypeReference SYNTHETIC_SYSTEM = TypeReference.findOrCreate(ClassLoaderReference.Primordial, TypeName
|
||||
.string2TypeName("Lcom/ibm/wala/model/java/lang/System"));
|
||||
|
||||
private final static Atom arraycopyAtom = Atom.findOrCreateUnicodeAtom("arraycopy");
|
||||
|
||||
private final static Descriptor arraycopyDesc = Descriptor.findOrCreateUTF8("(Ljava/lang/Object;Ljava/lang/Object;)V");
|
||||
|
||||
private final static MethodReference SYNTHETIC_ARRAYCOPY = MethodReference.findOrCreate(SYNTHETIC_SYSTEM, arraycopyAtom,
|
||||
arraycopyDesc);
|
||||
|
||||
/**
|
||||
* If the type is an array, the program counter of the synthesized call to
|
||||
* arraycopy. Doesn't really matter what it is.
|
||||
*/
|
||||
private final static int ARRAYCOPY_PC = 3;
|
||||
|
||||
private final static CallSiteReference ARRAYCOPY_SITE = CallSiteReference.make(ARRAYCOPY_PC, SYNTHETIC_ARRAYCOPY,
|
||||
IInvokeInstruction.Dispatch.STATIC);
|
||||
|
||||
private final static int NEW_PC = 0;
|
||||
|
||||
/**
|
||||
* Mapping from TypeReference -> IR TODO: Soft references?
|
||||
*/
|
||||
private Map<TypeReference, IR> IRCache = HashMapFactory.make();
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.ipa.callgraph.propagation.cfa.CFAContextInterpreter#getIR(com.ibm.wala.classLoader.IMethod,
|
||||
* com.ibm.detox.ipa.callgraph.Context,
|
||||
* com.ibm.wala.util.warnings.WarningSet)
|
||||
*/
|
||||
public IR getIR(CGNode node, WarningSet warnings) {
|
||||
if (Assertions.verifyAssertions) {
|
||||
Assertions._assert(understands(node));
|
||||
}
|
||||
IClass cls = ContextUtil.getConcreteClassFromContext(node.getContext());
|
||||
IR result = IRCache.get(cls.getReference());
|
||||
if (result == null) {
|
||||
result = makeIR(node.getMethod(), node.getContext(), cls, warnings);
|
||||
IRCache.put(cls.getReference(), result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.ipa.callgraph.propagation.cfa.CFAContextInterpreter#getNumberOfStatements(com.ibm.wala.classLoader.IMethod,
|
||||
* com.ibm.detox.ipa.callgraph.Context,
|
||||
* com.ibm.wala.util.warnings.WarningSet)
|
||||
*/
|
||||
public int getNumberOfStatements(CGNode node, WarningSet warnings) {
|
||||
if (Assertions.verifyAssertions) {
|
||||
Assertions._assert(understands(node));
|
||||
}
|
||||
return getIR(node, warnings).getInstructions().length;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.ipa.rta.RTAContextInterpreter#understands(com.ibm.wala.classLoader.IMethod,
|
||||
* com.ibm.detox.ipa.callgraph.Context)
|
||||
*/
|
||||
public boolean understands(CGNode node) {
|
||||
return (node.getMethod().getReference().equals(CLONE) && ContextUtil.getConcreteClassFromContext(node.getContext()) != null);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.ipa.rta.RTAContextInterpreter#getAllocatedTypes(com.ibm.wala.classLoader.IMethod,
|
||||
* com.ibm.detox.ipa.callgraph.Context,
|
||||
* com.ibm.wala.util.warnings.WarningSet)
|
||||
*/
|
||||
public Iterator<NewSiteReference> iterateNewSites(CGNode node, WarningSet warnings) {
|
||||
if (Assertions.verifyAssertions) {
|
||||
Assertions._assert(understands(node));
|
||||
}
|
||||
IClass cls = ContextUtil.getConcreteClassFromContext(node.getContext());
|
||||
return new NonNullSingletonIterator<NewSiteReference>(NewSiteReference.make(NEW_PC, cls.getReference()));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.ipa.rta.RTAContextInterpreter#getCallSites(com.ibm.wala.classLoader.IMethod,
|
||||
* com.ibm.detox.ipa.callgraph.Context,
|
||||
* com.ibm.wala.util.warnings.WarningSet)
|
||||
*/
|
||||
public Iterator<CallSiteReference> iterateCallSites(CGNode node, WarningSet warnings) {
|
||||
if (Assertions.verifyAssertions) {
|
||||
Assertions._assert(understands(node));
|
||||
}
|
||||
return new NonNullSingletonIterator<CallSiteReference>(ARRAYCOPY_SITE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an array of statements that encode the behavior of the clone method
|
||||
* for a given type.
|
||||
*/
|
||||
private SSAInstruction[] makeStatements(IClass klass) {
|
||||
if (Assertions.verifyAssertions) {
|
||||
Assertions._assert(klass != null);
|
||||
}
|
||||
|
||||
ArrayList<SSAInstruction> statements = new ArrayList<SSAInstruction>();
|
||||
// value number 1 is "this".
|
||||
int nextLocal = 2;
|
||||
|
||||
int retValue = nextLocal++;
|
||||
// value number of the result of the clone()
|
||||
NewSiteReference ref = NewSiteReference.make(NEW_PC, klass.getReference());
|
||||
SSANewInstruction N = null;
|
||||
if (klass.isArrayClass()) {
|
||||
int length = nextLocal++;
|
||||
statements.add(new SSAArrayLengthInstruction(length, 1));
|
||||
int[] sizes = new int[klass.getReference().getDimensionality()];
|
||||
Arrays.fill(sizes,length);
|
||||
N = new SSANewInstruction(retValue, ref, sizes);
|
||||
} else {
|
||||
N = new SSANewInstruction(retValue, ref);
|
||||
}
|
||||
statements.add(N);
|
||||
|
||||
int exceptionValue = nextLocal++;
|
||||
|
||||
if (klass.getReference().isArrayType()) {
|
||||
// generate a synthetic arraycopy from this (v.n. 1) to the clone
|
||||
int[] params = new int[2];
|
||||
params[0] = 1;
|
||||
params[1] = retValue;
|
||||
SSAInvokeInstruction S = new SSAInvokeInstruction(params, exceptionValue, ARRAYCOPY_SITE);
|
||||
statements.add(S);
|
||||
} else {
|
||||
// copy the fields over, one by one.
|
||||
// TODO:
|
||||
IClass k = klass;
|
||||
while (k != null) {
|
||||
for (Iterator<IField> it = klass.getDeclaredInstanceFields().iterator(); it.hasNext();) {
|
||||
IField f = it.next();
|
||||
int tempValue = nextLocal++;
|
||||
SSAGetInstruction G = new SSAGetInstruction(tempValue, 1, f.getFieldReference());
|
||||
statements.add(G);
|
||||
SSAPutInstruction P = new SSAPutInstruction(retValue, tempValue, f.getFieldReference());
|
||||
statements.add(P);
|
||||
}
|
||||
try {
|
||||
k = k.getSuperclass();
|
||||
} catch (ClassHierarchyException e) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SSAReturnInstruction R = new SSAReturnInstruction(retValue, false);
|
||||
statements.add(R);
|
||||
|
||||
SSAInstruction[] result = new SSAInstruction[statements.size()];
|
||||
Iterator<SSAInstruction> it = statements.iterator();
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
result[i] = it.next();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an IR that encodes the behavior of the clone method for a given
|
||||
* type.
|
||||
*/
|
||||
private IR makeIR(IMethod method, Context context, IClass klass, WarningSet warnings) {
|
||||
if (Assertions.verifyAssertions) {
|
||||
Assertions._assert(klass != null);
|
||||
}
|
||||
SSAInstruction instrs[] = makeStatements(klass);
|
||||
return new SyntheticIR(method, context, new InducedCFG(instrs, method, context), instrs, SSAOptions.defaultOptions(), null,
|
||||
warnings);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.ipa.callgraph.propagation.cfa.CFAContextInterpreter#recordFactoryType(com.ibm.wala.ipa.callgraph.CGNode,
|
||||
* com.ibm.wala.classLoader.IClass)
|
||||
*/
|
||||
public boolean recordFactoryType(CGNode node, IClass klass) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.ipa.callgraph.rta.RTAContextInterpreter#setWarnings(com.ibm.wala.util.warnings.WarningSet)
|
||||
*/
|
||||
public void setWarnings(WarningSet newWarnings) {
|
||||
// this object is not bound to a WarningSet
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.ipa.callgraph.propagation.xta.XTAContextInterpreter#iterateFieldsRead(com.ibm.wala.ipa.callgraph.CGNode,
|
||||
* com.ibm.wala.util.warnings.WarningSet)
|
||||
*/
|
||||
public Iterator iterateFieldsRead(CGNode node, WarningSet warnings) {
|
||||
SSAInstruction[] statements = getIR(node, warnings).getInstructions();
|
||||
return CodeScanner.getFieldsRead(statements).iterator();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.ipa.callgraph.propagation.xta.XTAContextInterpreter#iterateFieldsWritten(com.ibm.wala.ipa.callgraph.CGNode,
|
||||
* com.ibm.wala.util.warnings.WarningSet)
|
||||
*/
|
||||
public Iterator iterateFieldsWritten(CGNode node, WarningSet warnings) {
|
||||
SSAInstruction[] statements = getIR(node, warnings).getInstructions();
|
||||
return CodeScanner.getFieldsWritten(statements).iterator();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.ipa.callgraph.propagation.xta.XTAContextInterpreter#getCaughtExceptions(com.ibm.wala.ipa.callgraph.CGNode,
|
||||
* com.ibm.wala.util.warnings.WarningSet)
|
||||
*/
|
||||
public Set getCaughtExceptions(CGNode node, WarningSet warnings) {
|
||||
SSAInstruction[] statements = getIR(node, warnings).getInstructions();
|
||||
return CodeScanner.getCaughtExceptions(statements);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.ipa.callgraph.propagation.xta.XTAContextInterpreter#hasObjectArrayLoad(com.ibm.wala.ipa.callgraph.CGNode,
|
||||
* com.ibm.wala.util.warnings.WarningSet)
|
||||
*/
|
||||
public boolean hasObjectArrayLoad(CGNode node, WarningSet warnings) {
|
||||
SSAInstruction[] statements = getIR(node, warnings).getInstructions();
|
||||
return CodeScanner.hasObjectArrayLoad(statements);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.ipa.callgraph.propagation.xta.XTAContextInterpreter#hasObjectArrayStore(com.ibm.wala.ipa.callgraph.CGNode,
|
||||
* com.ibm.wala.util.warnings.WarningSet)
|
||||
*/
|
||||
public boolean hasObjectArrayStore(CGNode node, WarningSet warnings) {
|
||||
SSAInstruction[] statements = getIR(node, warnings).getInstructions();
|
||||
return CodeScanner.hasObjectArrayStore(statements);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.ipa.callgraph.propagation.xta.XTAContextInterpreter#iterateCastTypes(com.ibm.wala.ipa.callgraph.CGNode,
|
||||
* com.ibm.wala.util.warnings.WarningSet)
|
||||
*/
|
||||
public Iterator iterateCastTypes(CGNode node, WarningSet warnings) {
|
||||
SSAInstruction[] statements = getIR(node, warnings).getInstructions();
|
||||
return CodeScanner.iterateCastTypes(statements);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.ipa.cfg.CFGProvider#getCFG(com.ibm.wala.ipa.callgraph.CGNode)
|
||||
*/
|
||||
public ControlFlowGraph getCFG(CGNode N, WarningSet warnings) {
|
||||
return getIR(N, warnings).getControlFlowGraph();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.ipa.callgraph.propagation.SSAContextInterpreter#getDU(com.ibm.wala.ipa.callgraph.CGNode,
|
||||
* com.ibm.wala.util.warnings.WarningSet)
|
||||
*/
|
||||
public DefUse getDU(CGNode node, WarningSet warnings) {
|
||||
return new DefUse(getIR(node, warnings));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,809 @@
|
||||
/*******************************************************************************
|
||||
* 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.analysis.reflection;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.ibm.wala.analysis.typeInference.ConeType;
|
||||
import com.ibm.wala.analysis.typeInference.PointType;
|
||||
import com.ibm.wala.analysis.typeInference.SetType;
|
||||
import com.ibm.wala.analysis.typeInference.TypeAbstraction;
|
||||
import com.ibm.wala.cfg.ControlFlowGraph;
|
||||
import com.ibm.wala.cfg.InducedCFG;
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.classLoader.CodeScanner;
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.classLoader.NewSiteReference;
|
||||
import com.ibm.wala.classLoader.SyntheticMethod;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.Context;
|
||||
import com.ibm.wala.ipa.callgraph.ReflectionSpecification;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.SSAContextInterpreter;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.rta.RTAContextInterpreter;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.ipa.summaries.ReflectionSummary;
|
||||
import com.ibm.wala.ipa.summaries.SummarizedMethod;
|
||||
import com.ibm.wala.ipa.summaries.SyntheticIR;
|
||||
import com.ibm.wala.ipa.summaries.XMLReflectionReader;
|
||||
import com.ibm.wala.shrikeBT.IInvokeInstruction;
|
||||
import com.ibm.wala.shrikeCT.InvalidClassFileException;
|
||||
import com.ibm.wala.ssa.ConstantValue;
|
||||
import com.ibm.wala.ssa.DefUse;
|
||||
import com.ibm.wala.ssa.IR;
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.ssa.SSAInvokeInstruction;
|
||||
import com.ibm.wala.ssa.SSANewInstruction;
|
||||
import com.ibm.wala.ssa.SSAOptions;
|
||||
import com.ibm.wala.ssa.SSAReturnInstruction;
|
||||
import com.ibm.wala.types.MethodReference;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.collections.HashMapFactory;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.debug.Trace;
|
||||
import com.ibm.wala.util.warnings.Warning;
|
||||
import com.ibm.wala.util.warnings.WarningSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* Logic to interpret "factory" methods in context.
|
||||
*
|
||||
* @author sfink
|
||||
*/
|
||||
public class FactoryBypassInterpreter implements RTAContextInterpreter, SSAContextInterpreter {
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private final static int CONE_BOUND = 10;
|
||||
|
||||
private int indexLocal = 100;
|
||||
|
||||
private final Map<TypeReference, Integer> typeIndexMap = HashMapFactory.make();
|
||||
|
||||
/**
|
||||
* A Map from CallerSiteContext -> Set <TypeReference>represents the types a
|
||||
* factory method might create in a particular context
|
||||
*/
|
||||
private final Map<Context, Set<TypeReference>> map = HashMapFactory.make();
|
||||
|
||||
/**
|
||||
* A cache of synthetic method implementations, indexed by Context
|
||||
*/
|
||||
private final Map<Context, SpecializedFactoryMethod> syntheticMethodCache = HashMapFactory.make();
|
||||
|
||||
/**
|
||||
* Governing analysis options
|
||||
*/
|
||||
private final AnalysisOptions options;
|
||||
|
||||
/**
|
||||
* Governing class hierarchy
|
||||
*/
|
||||
private final ClassHierarchy cha;
|
||||
|
||||
/**
|
||||
* Keep track of analysis warnings
|
||||
*/
|
||||
private WarningSet warnings;
|
||||
|
||||
/**
|
||||
* User-defined reflection specification
|
||||
*/
|
||||
private final ReflectionSpecification userSpec;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param options
|
||||
* governing analysis options
|
||||
* @param cha
|
||||
* governing class hierarchy
|
||||
* @param userSpec
|
||||
* @param warnings
|
||||
* object to track analysis warnings
|
||||
*/
|
||||
public FactoryBypassInterpreter(AnalysisOptions options, ClassHierarchy cha, ReflectionSpecification userSpec, WarningSet warnings) {
|
||||
this.options = options;
|
||||
this.cha = cha;
|
||||
this.warnings = warnings;
|
||||
this.userSpec = userSpec;
|
||||
}
|
||||
|
||||
private int getLocalForType(TypeReference T) {
|
||||
Integer I = typeIndexMap.get(T);
|
||||
if (I == null) {
|
||||
typeIndexMap.put(T, I = new Integer(indexLocal += 2));
|
||||
}
|
||||
return I.intValue();
|
||||
}
|
||||
|
||||
private int getExceptionsForType(TypeReference T) {
|
||||
return getLocalForType(T) + 1;
|
||||
}
|
||||
|
||||
private int getCallSiteForType(TypeReference T) {
|
||||
return getLocalForType(T);
|
||||
}
|
||||
|
||||
private int getNewSiteForType(TypeReference T) {
|
||||
return getLocalForType(T) + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.ipa.callgraph.propagation.cfa.CFAContextInterpreter#getIR(com.ibm.wala.classLoader.IMethod,
|
||||
* com.ibm.wala.ipa.callgraph.Context,
|
||||
* com.ibm.wala.util.warnings.WarningSet)
|
||||
*/
|
||||
public IR getIR(CGNode node, WarningSet warnings) {
|
||||
SpecializedFactoryMethod m = findOrCreateSpecializedFactoryMethod(node);
|
||||
return options.getSSACache().findOrCreateIR(m, node.getContext(), cha, options.getSSAOptions(), warnings);
|
||||
}
|
||||
|
||||
private Set getTypesForContext(Context context) {
|
||||
// first try user spec
|
||||
XMLReflectionReader spec = (XMLReflectionReader) userSpec;
|
||||
if (spec != null && context instanceof CallerSiteContext) {
|
||||
CallerSiteContext site = (CallerSiteContext) context;
|
||||
MethodReference m = site.getCaller().getMethod().getReference();
|
||||
ReflectionSummary summary = spec.getSummary(m);
|
||||
if (summary != null) {
|
||||
Set types = summary.getTypesForProgramLocation(site.getSite().getProgramCounter());
|
||||
if (types != null) {
|
||||
return types;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Set types = map.get(context);
|
||||
return types;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.ipa.callgraph.propagation.cfa.CFAContextInterpreter#getNumberOfStatements(com.ibm.wala.classLoader.IMethod,
|
||||
* com.ibm.wala.ipa.callgraph.Context,
|
||||
* com.ibm.wala.util.warnings.WarningSet)
|
||||
*/
|
||||
public int getNumberOfStatements(CGNode node, WarningSet warnings) {
|
||||
SpecializedFactoryMethod m = findOrCreateSpecializedFactoryMethod(node);
|
||||
return m.allInstructions.size();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.ipa.callgraph.rta.RTAContextInterpreter#understands(com.ibm.wala.classLoader.IMethod,
|
||||
* com.ibm.wala.ipa.callgraph.Context)
|
||||
*/
|
||||
public boolean understands(CGNode node) {
|
||||
return getTypesForContext(node.getContext()) != null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.ipa.callgraph.rta.RTAContextInterpreter#getNewSites(com.ibm.wala.classLoader.IMethod,
|
||||
* com.ibm.wala.ipa.callgraph.Context,
|
||||
* com.ibm.wala.util.warnings.WarningSet)
|
||||
*/
|
||||
public Iterator<NewSiteReference> iterateNewSites(CGNode node, WarningSet warnings) {
|
||||
SpecializedFactoryMethod m = findOrCreateSpecializedFactoryMethod(node);
|
||||
HashSet<NewSiteReference> result = HashSetFactory.make(5);
|
||||
for (Iterator<SSAInstruction> it = m.getAllocationStatements().iterator(); it.hasNext();) {
|
||||
SSANewInstruction s = (SSANewInstruction) it.next();
|
||||
result.add(s.getNewSite());
|
||||
}
|
||||
return result.iterator();
|
||||
}
|
||||
|
||||
public Iterator<SSAInstruction> getInvokeStatements(CGNode node) {
|
||||
SpecializedFactoryMethod m = findOrCreateSpecializedFactoryMethod(node);
|
||||
return m.getInvokeStatements().iterator();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.ipa.rta.RTAContextInterpreter#getCallSites(com.ibm.wala.classLoader.IMethod,
|
||||
* com.ibm.detox.ipa.callgraph.Context,
|
||||
* com.ibm.wala.util.warnings.WarningSet)
|
||||
*/
|
||||
public Iterator<CallSiteReference> iterateCallSites(CGNode node, WarningSet warnings) {
|
||||
final Iterator<SSAInstruction> I = getInvokeStatements(node);
|
||||
return new Iterator<CallSiteReference>() {
|
||||
public boolean hasNext() {
|
||||
return I.hasNext();
|
||||
}
|
||||
|
||||
public CallSiteReference next() {
|
||||
SSAInvokeInstruction s = (SSAInvokeInstruction) I.next();
|
||||
return s.getCallSite();
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @author sfink
|
||||
*
|
||||
*/
|
||||
protected class SpecializedFactoryMethod extends SyntheticMethod {
|
||||
|
||||
/**
|
||||
* List of synthetic allocation statements we model for this specialized
|
||||
* instance
|
||||
*/
|
||||
private ArrayList<SSAInstruction> allocations = new ArrayList<SSAInstruction>();
|
||||
|
||||
/**
|
||||
* List of synthetic invoke instructions we model for this specialized
|
||||
* instance.
|
||||
*/
|
||||
private ArrayList<SSAInstruction> calls = new ArrayList<SSAInstruction>();
|
||||
|
||||
/**
|
||||
* List of all instructions
|
||||
*/
|
||||
private ArrayList<SSAInstruction> allInstructions = new ArrayList<SSAInstruction>();
|
||||
|
||||
/**
|
||||
* The method being modelled
|
||||
*/
|
||||
private final IMethod method;
|
||||
|
||||
/**
|
||||
* Context being modelled
|
||||
*/
|
||||
private final Context context;
|
||||
|
||||
/**
|
||||
* next free local value number;
|
||||
*/
|
||||
private int nextLocal;
|
||||
|
||||
/**
|
||||
* value number for integer constant 1
|
||||
*/
|
||||
private int valueNumberForConstantOne = -1;
|
||||
|
||||
private void initValueNumberForConstantOne() {
|
||||
if (valueNumberForConstantOne == -1) {
|
||||
valueNumberForConstantOne = nextLocal++;
|
||||
}
|
||||
}
|
||||
|
||||
private final HashSet<TypeReference> types = HashSetFactory.make(5);
|
||||
|
||||
private SpecializedFactoryMethod(final SummarizedMethod m, Context context, final Set S) {
|
||||
super(m, m.getDeclaringClass(), m.isStatic(), true);
|
||||
|
||||
this.context = context;
|
||||
if (DEBUG) {
|
||||
Trace.println("Create SpecializedFactoryMethod " + m + S);
|
||||
}
|
||||
|
||||
this.method = m;
|
||||
if (Assertions.verifyAssertions) {
|
||||
Assertions._assert(S != null);
|
||||
Assertions._assert(m.getDeclaringClass() != null, "null declaring class for " + m);
|
||||
}
|
||||
|
||||
// add original statements from the method summary
|
||||
nextLocal = addOriginalStatements(m);
|
||||
|
||||
for (Iterator it = S.iterator(); it.hasNext();) {
|
||||
TypeReference type = (TypeReference) it.next();
|
||||
TypeAbstraction T = typeRef2TypeAbstraction(type);
|
||||
addStatementsForTypeAbstraction(T);
|
||||
}
|
||||
}
|
||||
|
||||
private void addStatementsForTypeAbstraction(TypeAbstraction T) {
|
||||
|
||||
if (DEBUG) {
|
||||
Trace.println("adding " + T + " to " + method);
|
||||
}
|
||||
T = interceptType(T);
|
||||
if (T == null) {
|
||||
return;
|
||||
}
|
||||
if ((T instanceof PointType) || (T instanceof ConeType)) {
|
||||
TypeReference ref = T.getType().getReference();
|
||||
NewSiteReference site = NewSiteReference.make(0, ref);
|
||||
IClass klass = options.getClassTargetSelector().getAllocatedTarget(null, site);
|
||||
|
||||
if (DEBUG) {
|
||||
Trace.println("Selected allocated target: " + klass + " for " + T);
|
||||
}
|
||||
if (T instanceof PointType) {
|
||||
addStatementsForConcreteType(ref);
|
||||
} else if (T instanceof ConeType) {
|
||||
if (DEBUG) {
|
||||
Trace.println("Cone clause for " + T);
|
||||
}
|
||||
if (((ConeType) T).isInterface()) {
|
||||
Set implementors = cha.getImplementors(ref);
|
||||
if (DEBUG) {
|
||||
Trace.println("Implementors for " + T + " " + implementors);
|
||||
}
|
||||
if (implementors.isEmpty()) {
|
||||
if (DEBUG) {
|
||||
Trace.println("Found no implementors of type " + T);
|
||||
}
|
||||
warnings.add(NoSubtypesWarning.create(T));
|
||||
}
|
||||
if (implementors.size() > CONE_BOUND) {
|
||||
warnings.add(ManySubtypesWarning.create(T, implementors.size()));
|
||||
}
|
||||
|
||||
addStatementsForSetOfTypes(implementors.iterator());
|
||||
} else {
|
||||
Collection subclasses = cha.computeSubClasses(ref);
|
||||
if (DEBUG) {
|
||||
Trace.println("Subclasses for " + T + " " + subclasses);
|
||||
}
|
||||
if (subclasses.isEmpty()) {
|
||||
if (DEBUG) {
|
||||
Trace.println("Found no subclasses of type " + T);
|
||||
}
|
||||
warnings.add(NoSubtypesWarning.create(T));
|
||||
}
|
||||
if (subclasses.size() > CONE_BOUND) {
|
||||
warnings.add(ManySubtypesWarning.create(T, subclasses.size()));
|
||||
}
|
||||
addStatementsForSetOfTypes(subclasses.iterator());
|
||||
}
|
||||
} else {
|
||||
Assertions.UNREACHABLE("Unexpected type " + T.getClass());
|
||||
}
|
||||
} else if (T instanceof SetType) {
|
||||
addStatementsForSetOfTypes(((SetType) T).iteratePoints());
|
||||
} else {
|
||||
Assertions.UNREACHABLE("Unexpected type " + T.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
private TypeAbstraction interceptType(TypeAbstraction T) {
|
||||
TypeReference type = T.getType().getReference();
|
||||
if (type.equals(TypeReference.JavaIoSerializable)) {
|
||||
warnings.add(IgnoreSerializableWarning.create());
|
||||
return null;
|
||||
} else {
|
||||
return T;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up a method summary which allocates and returns an instance of
|
||||
* concrete type T.
|
||||
*
|
||||
* @param T
|
||||
*/
|
||||
private void addStatementsForConcreteType(final TypeReference T) {
|
||||
if (types.contains(T))
|
||||
return;
|
||||
types.add(T);
|
||||
if (DEBUG) {
|
||||
Trace.println("addStatementsForConcreteType: " + T);
|
||||
}
|
||||
NewSiteReference ref = NewSiteReference.make(getNewSiteForType(T), T);
|
||||
int alloc = getLocalForType(T);
|
||||
SSANewInstruction a = new SSANewInstruction(alloc, ref);
|
||||
if (DEBUG) {
|
||||
Trace.println("Added allocation: " + a);
|
||||
}
|
||||
|
||||
allocations.add(a);
|
||||
allInstructions.add(a);
|
||||
SSAReturnInstruction r = new SSAReturnInstruction(alloc, false);
|
||||
allInstructions.add(r);
|
||||
if (T.isArrayType()) {
|
||||
MethodReference init = MethodReference.findOrCreate(T, MethodReference.initAtom, MethodReference.defaultInitDesc);
|
||||
CallSiteReference site = CallSiteReference.make(getCallSiteForType(T), init, IInvokeInstruction.Dispatch.SPECIAL);
|
||||
int[] params = new int[1];
|
||||
params[0] = alloc;
|
||||
int exc = getExceptionsForType(T);
|
||||
SSAInvokeInstruction s = new SSAInvokeInstruction(params, exc, site);
|
||||
calls.add(s);
|
||||
allInstructions.add(s);
|
||||
}
|
||||
}
|
||||
|
||||
private int addOriginalStatements(SummarizedMethod m) {
|
||||
SSAInstruction[] original = m.getStatements(options.getSSAOptions(), warnings);
|
||||
// local value number 1 is "this", so the next free value number is 2
|
||||
int nextLocal = 2;
|
||||
for (int i = 0; i < original.length; i++) {
|
||||
SSAInstruction s = original[i];
|
||||
allInstructions.add(s);
|
||||
if (s instanceof SSAInvokeInstruction) {
|
||||
calls.add(s);
|
||||
}
|
||||
if (s instanceof SSANewInstruction) {
|
||||
allocations.add(s);
|
||||
}
|
||||
for (int j = 0; j < s.getNumberOfDefs(); j++) {
|
||||
int def = s.getDef(j);
|
||||
if (def >= nextLocal) {
|
||||
nextLocal = def + 1;
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < s.getNumberOfUses(); j++) {
|
||||
int use = s.getUse(j);
|
||||
if (use >= nextLocal) {
|
||||
nextLocal = use + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nextLocal;
|
||||
}
|
||||
|
||||
private void addStatementsForSetOfTypes(Iterator it) {
|
||||
|
||||
if (!it.hasNext()) { // Uh. No types. Hope the caller reported a warning.
|
||||
SSAReturnInstruction r = new SSAReturnInstruction(nextLocal, false);
|
||||
allInstructions.add(r);
|
||||
}
|
||||
|
||||
for (; it.hasNext();) {
|
||||
IClass klass = (IClass) it.next();
|
||||
TypeReference T = klass.getReference();
|
||||
if (klass.isAbstract() || types.contains(T)) {
|
||||
continue;
|
||||
}
|
||||
types.add(T);
|
||||
int i = getLocalForType(T);
|
||||
NewSiteReference ref = NewSiteReference.make(getNewSiteForType(T), T);
|
||||
SSANewInstruction a = null;
|
||||
if (T.isArrayType()) {
|
||||
int[] sizes = new int[T.getDimensionality()];
|
||||
initValueNumberForConstantOne();
|
||||
Arrays.fill(sizes, valueNumberForConstantOne);
|
||||
a = new SSANewInstruction(i, ref, sizes);
|
||||
|
||||
} else {
|
||||
a = new SSANewInstruction(i, ref);
|
||||
}
|
||||
allocations.add(a);
|
||||
allInstructions.add(a);
|
||||
SSAReturnInstruction r = new SSAReturnInstruction(i, false);
|
||||
allInstructions.add(r);
|
||||
MethodReference init = MethodReference.findOrCreate(T, MethodReference.initAtom, MethodReference.defaultInitDesc);
|
||||
CallSiteReference site = CallSiteReference.make(getCallSiteForType(T), init, IInvokeInstruction.Dispatch.SPECIAL);
|
||||
int[] params = new int[1];
|
||||
params[0] = i;
|
||||
SSAInvokeInstruction s = new SSAInvokeInstruction(params, getExceptionsForType(T), site);
|
||||
calls.add(s);
|
||||
allInstructions.add(s);
|
||||
}
|
||||
}
|
||||
|
||||
public List<SSAInstruction> getAllocationStatements() {
|
||||
return allocations;
|
||||
}
|
||||
|
||||
public List<SSAInstruction> getInvokeStatements() {
|
||||
return calls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Two specialized methods can be different, even if they represent the same
|
||||
* source method. So, revert to object identity for testing equality. TODO:
|
||||
* this is non-optimal; could try to re-use specialized methods that have
|
||||
* the same context.
|
||||
*
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
return this == obj;
|
||||
}
|
||||
|
||||
public int hashCode() { // TODO: change this to avoid non-determinism!
|
||||
return System.identityHashCode(this);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return super.toString();
|
||||
}
|
||||
|
||||
public SSAInstruction[] getStatements(WarningSet warnings) {
|
||||
SSAInstruction[] result = new SSAInstruction[allInstructions.size()];
|
||||
int i = 0;
|
||||
for (Iterator<SSAInstruction> it = allInstructions.iterator(); it.hasNext();) {
|
||||
result[i++] = it.next();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public IClass getDeclaringClass() {
|
||||
if (Assertions.verifyAssertions) {
|
||||
if (method.getDeclaringClass() == null) {
|
||||
Assertions._assert(method.getDeclaringClass() != null, "null declaring class for original method " + method);
|
||||
}
|
||||
}
|
||||
return method.getDeclaringClass();
|
||||
}
|
||||
|
||||
public int getNumberOfParameters() {
|
||||
return method.getNumberOfParameters();
|
||||
}
|
||||
|
||||
public TypeReference getParameterType(int i) {
|
||||
return method.getParameterType(i);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.classLoader.IMethod#getIR(com.ibm.wala.util.WarningSet)
|
||||
*/
|
||||
public IR makeIR(SSAOptions options, WarningSet warnings) {
|
||||
SSAInstruction[] instrs = getStatements(warnings);
|
||||
Map<Integer, ConstantValue> constants = null;
|
||||
if (valueNumberForConstantOne > -1) {
|
||||
constants = HashMapFactory.make(1);
|
||||
constants.put(new Integer(valueNumberForConstantOne), new ConstantValue(new Integer(1)));
|
||||
}
|
||||
|
||||
return new SyntheticIR(this, context, new InducedCFG(instrs, this, context), instrs, options, constants, warnings);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean recordType(Context context, TypeReference type) {
|
||||
Set<TypeReference> types = map.get(context);
|
||||
if (types == null) {
|
||||
types = HashSetFactory.make(2);
|
||||
map.put(context, types);
|
||||
}
|
||||
if (types.contains(type)) {
|
||||
return false;
|
||||
} else {
|
||||
types.add(type);
|
||||
// update any extant synthetic method
|
||||
SpecializedFactoryMethod m = syntheticMethodCache.get(context);
|
||||
if (m != null) {
|
||||
TypeAbstraction T = typeRef2TypeAbstraction(type);
|
||||
m.addStatementsForTypeAbstraction(T);
|
||||
options.getSSACache().invalidate(m, context);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param type
|
||||
* @return a TypeAbstraction object representing this type. We just use
|
||||
* ConeTypes by default, since we don't propagate information allowing
|
||||
* us to distinguish between points and cones yet.
|
||||
*/
|
||||
private TypeAbstraction typeRef2TypeAbstraction(TypeReference type) {
|
||||
IClass klass = cha.lookupClass(type);
|
||||
if (klass != null) {
|
||||
return new ConeType(klass, cha);
|
||||
// if (klass.isAbstract() || klass.isInterface()) {
|
||||
// return new ConeType(klass, cha);
|
||||
// } else {
|
||||
// return new PointType(klass, cha);
|
||||
// }
|
||||
}
|
||||
Assertions.UNREACHABLE(type.toString());
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.ipa.callgraph.propagation.rta.RTAContextInterpreter#recordFactoryType(com.ibm.wala.ipa.callgraph.CGNode,
|
||||
* com.ibm.wala.classLoader.IClass)
|
||||
*/
|
||||
public boolean recordFactoryType(CGNode node, IClass klass) {
|
||||
return recordType(node.getContext(), klass.getReference());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.ipa.callgraph.propagation.rta.RTAContextInterpreter#setWarnings(com.ibm.wala.util.warnings.WarningSet)
|
||||
*/
|
||||
public void setWarnings(WarningSet newWarnings) {
|
||||
this.warnings = newWarnings;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.ipa.callgraph.propagation.rta.RTAContextInterpreter#iterateFieldsRead(com.ibm.wala.ipa.callgraph.CGNode,
|
||||
* com.ibm.wala.util.warnings.WarningSet)
|
||||
*/
|
||||
public Iterator iterateFieldsRead(CGNode node, WarningSet warnings) {
|
||||
SpecializedFactoryMethod m = findOrCreateSpecializedFactoryMethod(node);
|
||||
try {
|
||||
return CodeScanner.iterateFieldsRead(m, warnings);
|
||||
} catch (InvalidClassFileException e) {
|
||||
e.printStackTrace();
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.ipa.callgraph.propagation.rta.RTAContextInterpreter#iterateFieldsWritten(com.ibm.wala.ipa.callgraph.CGNode,
|
||||
* com.ibm.wala.util.warnings.WarningSet)
|
||||
*/
|
||||
public Iterator iterateFieldsWritten(CGNode node, WarningSet warnings) {
|
||||
SpecializedFactoryMethod m = findOrCreateSpecializedFactoryMethod(node);
|
||||
try {
|
||||
return CodeScanner.iterateFieldsWritten(m, warnings);
|
||||
} catch (InvalidClassFileException e) {
|
||||
e.printStackTrace();
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private SpecializedFactoryMethod findOrCreateSpecializedFactoryMethod(CGNode node) {
|
||||
SpecializedFactoryMethod m = syntheticMethodCache.get(node.getContext());
|
||||
if (m == null) {
|
||||
Set types = getTypesForContext(node.getContext());
|
||||
m = new SpecializedFactoryMethod((SummarizedMethod) node.getMethod(), node.getContext(), types);
|
||||
syntheticMethodCache.put(node.getContext(), m);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
public Set getCaughtExceptions(CGNode node, WarningSet warnings) {
|
||||
SpecializedFactoryMethod m = findOrCreateSpecializedFactoryMethod(node);
|
||||
try {
|
||||
return CodeScanner.getCaughtExceptions(m, warnings);
|
||||
} catch (InvalidClassFileException e) {
|
||||
e.printStackTrace();
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasObjectArrayLoad(CGNode node, WarningSet warnings) {
|
||||
SpecializedFactoryMethod m = findOrCreateSpecializedFactoryMethod(node);
|
||||
try {
|
||||
return CodeScanner.hasObjectArrayLoad(m, warnings);
|
||||
} catch (InvalidClassFileException e) {
|
||||
e.printStackTrace();
|
||||
Assertions.UNREACHABLE();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasObjectArrayStore(CGNode node, WarningSet warnings) {
|
||||
SpecializedFactoryMethod m = findOrCreateSpecializedFactoryMethod(node);
|
||||
try {
|
||||
return CodeScanner.hasObjectArrayStore(m, warnings);
|
||||
} catch (InvalidClassFileException e) {
|
||||
e.printStackTrace();
|
||||
Assertions.UNREACHABLE();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public Iterator iterateCastTypes(CGNode node, WarningSet warnings) {
|
||||
SpecializedFactoryMethod m = findOrCreateSpecializedFactoryMethod(node);
|
||||
try {
|
||||
return CodeScanner.iterateCastTypes(m, warnings);
|
||||
} catch (InvalidClassFileException e) {
|
||||
e.printStackTrace();
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.ipa.cfg.CFGProvider#getCFG(com.ibm.wala.ipa.callgraph.CGNode)
|
||||
*/
|
||||
public ControlFlowGraph getCFG(CGNode N, WarningSet warnings) {
|
||||
return getIR(N, warnings).getControlFlowGraph();
|
||||
}
|
||||
|
||||
/**
|
||||
* @author sfink
|
||||
*
|
||||
* A waring when we expect excessive pollution from a factory method
|
||||
*/
|
||||
private static class ManySubtypesWarning extends Warning {
|
||||
|
||||
final int nImplementors;
|
||||
|
||||
final TypeAbstraction T;
|
||||
|
||||
ManySubtypesWarning(TypeAbstraction T, int nImplementors) {
|
||||
super(Warning.MODERATE);
|
||||
this.T = T;
|
||||
this.nImplementors = nImplementors;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return getClass().toString() + " : " + T + " " + nImplementors;
|
||||
}
|
||||
|
||||
public static ManySubtypesWarning create(TypeAbstraction T, int n) {
|
||||
return new ManySubtypesWarning(T, n);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author sfink
|
||||
*
|
||||
* A warning when we fail to find subtypes for a factory method
|
||||
*/
|
||||
private static class NoSubtypesWarning extends Warning {
|
||||
|
||||
final TypeAbstraction T;
|
||||
|
||||
NoSubtypesWarning(TypeAbstraction T) {
|
||||
super(Warning.SEVERE);
|
||||
this.T = T;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return getClass().toString() + " : " + T;
|
||||
}
|
||||
|
||||
public static NoSubtypesWarning create(TypeAbstraction T) {
|
||||
return new NoSubtypesWarning(T);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author sfink
|
||||
*
|
||||
* A waring when we find flow of a factory allocation to a cast to
|
||||
* serializable
|
||||
*/
|
||||
private static class IgnoreSerializableWarning extends Warning {
|
||||
|
||||
private static IgnoreSerializableWarning instance = new IgnoreSerializableWarning();
|
||||
|
||||
public String getMsg() {
|
||||
return getClass().toString();
|
||||
}
|
||||
|
||||
public static IgnoreSerializableWarning create() {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.ipa.callgraph.propagation.SSAContextInterpreter#getDU(com.ibm.wala.ipa.callgraph.CGNode,
|
||||
* com.ibm.wala.util.warnings.WarningSet)
|
||||
*/
|
||||
public DefUse getDU(CGNode node, WarningSet warnings) {
|
||||
SpecializedFactoryMethod m = findOrCreateSpecializedFactoryMethod(node);
|
||||
return options.getSSACache().findOrCreateDU(m, node.getContext(), cha, options.getSSAOptions(), warnings);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,139 @@
|
||||
/*******************************************************************************
|
||||
* 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.analysis.reflection;
|
||||
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.classLoader.SyntheticMethod;
|
||||
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.MethodTargetSelector;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.util.warnings.WarningSet;
|
||||
|
||||
/**
|
||||
* For synthetic methods marked as "Factories", we analyze in a context defined by the caller.
|
||||
*
|
||||
* @author sfink
|
||||
*/
|
||||
public class FactoryContextSelector implements ContextSelector {
|
||||
|
||||
|
||||
private final MethodTargetSelector methodTargetSelector;
|
||||
|
||||
private final ClassHierarchy cha;
|
||||
|
||||
/**
|
||||
* @param methodTargetSelector
|
||||
*/
|
||||
public FactoryContextSelector(ClassHierarchy cha, MethodTargetSelector methodTargetSelector) {
|
||||
this.cha = cha;
|
||||
this.methodTargetSelector = methodTargetSelector;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.ibm.wala.ipa.callgraph.ContextSelector#getCalleeTarget(com.ibm.wala.ipa.callgraph.CGNode, com.ibm.wala.classLoader.CallSiteReference, com.ibm.wala.classLoader.IMethod)
|
||||
*/
|
||||
public Context getCalleeTarget(CGNode caller, CallSiteReference site, IMethod callee, InstanceKey receiver) {
|
||||
if (callee.isSynthetic()) {
|
||||
SyntheticMethod s = (SyntheticMethod) callee;
|
||||
if (s.isFactoryMethod()) {
|
||||
return new CallerSiteContext(caller, site);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.ibm.wala.ipa.callgraph.ContextSelector#mayUnderstand(com.ibm.wala.ipa.callgraph.CGNode, com.ibm.wala.classLoader.CallSiteReference, com.ibm.wala.classLoader.IMethod, com.ibm.wala.ipa.callgraph.propagation.InstanceKey)
|
||||
*/
|
||||
public boolean mayUnderstand(CGNode caller, CallSiteReference site, IMethod targetMethod, InstanceKey instance) {
|
||||
if (targetMethod.isSynthetic()) {
|
||||
SyntheticMethod s = (SyntheticMethod) targetMethod;
|
||||
if (s.isFactoryMethod()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.ibm.wala.ipa.callgraph.ContextSelector#getBoundOnNumberOfTargets(com.ibm.wala.ipa.callgraph.CGNode, com.ibm.wala.classLoader.CallSiteReference, com.ibm.wala.classLoader.IMethod)
|
||||
*/
|
||||
public int getBoundOnNumberOfTargets(CGNode caller, CallSiteReference site, IMethod callee) {
|
||||
if (callee.isSynthetic()) {
|
||||
SyntheticMethod s = (SyntheticMethod) callee;
|
||||
if (s.isFactoryMethod()) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.ibm.wala.ipa.callgraph.rta.RTAContextInterpreter#setWarnings(com.ibm.wala.util.warnings.WarningSet)
|
||||
*/
|
||||
public void setWarnings(WarningSet newWarnings) {
|
||||
// this object is not bound to a WarningSet
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.ibm.wala.ipa.callgraph.ContextSelector#contextIsIrrelevant(com.ibm.wala.classLoader.CallSiteReference)
|
||||
*/
|
||||
public boolean contextIsIrrelevant(CGNode node, CallSiteReference site) {
|
||||
boolean result = methodTargetSelector.mightReturnSyntheticMethod(node,site);
|
||||
if (result) {
|
||||
IMethod callee = methodTargetSelector.getCalleeTarget(node, site, null);
|
||||
if (callee != null && callee.isSynthetic()) {
|
||||
SyntheticMethod s = (SyntheticMethod) callee;
|
||||
if (s.isFactoryMethod()) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.ibm.wala.ipa.callgraph.ContextSelector#contextIsIrrelevant(com.ibm.wala.types.MethodReference)
|
||||
*/
|
||||
public boolean allSitesDispatchIdentically(CGNode node, CallSiteReference site) {
|
||||
boolean result = methodTargetSelector.mightReturnSyntheticMethod(node,site);
|
||||
if (result) {
|
||||
IClass recv = cha.lookupClass(site.getDeclaredTarget().getDeclaringClass());
|
||||
if (recv == null) {
|
||||
return false;
|
||||
}
|
||||
IMethod callee = methodTargetSelector.getCalleeTarget(node, site, recv);
|
||||
if (callee != null && callee.isSynthetic()) {
|
||||
SyntheticMethod s = (SyntheticMethod) callee;
|
||||
if (s.isFactoryMethod()) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
/*******************************************************************************
|
||||
* 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.analysis.reflection;
|
||||
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
|
||||
/**
|
||||
*
|
||||
* An instance key which has an associated node
|
||||
*
|
||||
* @author sfink
|
||||
*/
|
||||
public interface InstanceKeyWithNode extends InstanceKey {
|
||||
|
||||
/**
|
||||
* @return the node which created this instance.
|
||||
*/
|
||||
CGNode getNode();
|
||||
}
|
||||
@ -0,0 +1,67 @@
|
||||
/*******************************************************************************
|
||||
* 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.analysis.reflection;
|
||||
|
||||
import com.ibm.wala.analysis.typeInference.TypeAbstraction;
|
||||
import com.ibm.wala.ipa.callgraph.Context;
|
||||
import com.ibm.wala.ipa.callgraph.ContextItem;
|
||||
import com.ibm.wala.ipa.callgraph.ContextKey;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
/**
|
||||
*
|
||||
* Implement a Context which corresponds to a given type abstraction.
|
||||
* Thus, this maps the name "TYPE" to a JavaTypeAbstraction.
|
||||
*
|
||||
* @author sfink
|
||||
*/
|
||||
public class JavaTypeContext implements Context {
|
||||
|
||||
private final TypeAbstraction type;
|
||||
|
||||
public JavaTypeContext(TypeAbstraction type) {
|
||||
if (Assertions.verifyAssertions) {
|
||||
Assertions._assert(type != null);
|
||||
}
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
|
||||
public ContextItem get(ContextKey name) {
|
||||
if (Assertions.verifyAssertions) {
|
||||
Assertions._assert(name == ContextKey.RECEIVER);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString() {
|
||||
return "JavaTypeContext<" + type + ">";
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return 6367 * type.hashCode();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (getClass().equals(obj.getClass())) {
|
||||
JavaTypeContext other = (JavaTypeContext)obj;
|
||||
return type.equals(other.type);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
/*******************************************************************************
|
||||
* 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.analysis.reflection;
|
||||
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.types.TypeName;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
|
||||
/**
|
||||
*
|
||||
* some utility support for dealing with "malleable" reflection allocations
|
||||
*
|
||||
* @author sfink
|
||||
*/
|
||||
public class Malleable {
|
||||
private final static TypeName MalleableName = TypeName.string2TypeName("Lcom/ibm/wala/Malleable");
|
||||
public final static TypeReference Malleable = TypeReference.findOrCreate(ClassLoaderReference.Primordial, MalleableName);
|
||||
public final static TypeReference ExtMalleable = TypeReference.findOrCreate(ClassLoaderReference.Extension, MalleableName);
|
||||
|
||||
public final static TypeReference MalleableCollection = TypeReference.findOrCreate(ClassLoaderReference.Primordial,
|
||||
"Lcom/ibm/wala/model/java/util/MalleableCollection");
|
||||
|
||||
|
||||
public static boolean isMalleable(TypeReference T) {
|
||||
return T.equals(Malleable) || T.equals(ExtMalleable);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
<HTML>
|
||||
<BODY>
|
||||
This package provides functions to deal with reflection.
|
||||
</BODY>
|
||||
</HTML>
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,6 @@
|
||||
<HTML>
|
||||
<BODY>
|
||||
This package provides a layer to perform abstract interpretation over
|
||||
the JVM stack machine.
|
||||
</BODY>
|
||||
</HTML>
|
||||
@ -0,0 +1,122 @@
|
||||
/*******************************************************************************
|
||||
* 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.analysis.typeInference;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
/**
|
||||
*
|
||||
* Absraction of a Java type. These are immutable.
|
||||
*
|
||||
* @author sfink
|
||||
*/
|
||||
public class ConeType extends TypeAbstraction {
|
||||
|
||||
private final IClass type;
|
||||
private final ClassHierarchy cha;
|
||||
|
||||
/**
|
||||
* default constructor
|
||||
*/
|
||||
public ConeType(IClass type, ClassHierarchy cha) {
|
||||
if (Assertions.verifyAssertions) {
|
||||
Assertions._assert(type != null);
|
||||
Assertions._assert(type.getReference().isReferenceType());
|
||||
}
|
||||
this.type = type;
|
||||
this.cha = cha;
|
||||
}
|
||||
|
||||
public TypeAbstraction meet(TypeAbstraction rhs) {
|
||||
if (rhs == TOP) {
|
||||
return this;
|
||||
} else if (rhs instanceof ConeType) {
|
||||
ConeType other = (ConeType) rhs;
|
||||
if (type.equals(other.type)) {
|
||||
return this;
|
||||
} else if (type.isArrayClass() || other.type.isArrayClass()) {
|
||||
// give up on arrays. We don't care anyway.
|
||||
return new ConeType(cha.getRootClass(), cha);
|
||||
} else {
|
||||
return new ConeType(cha.getLeastCommonSuperclass(this.type, other.type), cha);
|
||||
}
|
||||
} else if (rhs instanceof PointType) {
|
||||
return rhs.meet(this);
|
||||
} else if (rhs instanceof PrimitiveType) {
|
||||
return TOP;
|
||||
} else {
|
||||
Assertions.UNREACHABLE("unexpected type " + rhs.getClass());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString() {
|
||||
return "cone:" + type.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getType.
|
||||
* @return TypeReference
|
||||
*/
|
||||
public IClass getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#equals(Object)
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof ConeType))
|
||||
return false;
|
||||
ConeType other = (ConeType) obj;
|
||||
if (other == TOP)
|
||||
return false;
|
||||
if (Assertions.verifyAssertions) {
|
||||
if (!cha.equals(other.cha)) {
|
||||
Assertions._assert(cha.equals(other.cha), "different chas " + this +" " + other);
|
||||
}
|
||||
}
|
||||
return type.equals(other.type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
return 39 * type.hashCode();
|
||||
}
|
||||
|
||||
public boolean isArrayType() {
|
||||
return getType().isArrayClass();
|
||||
}
|
||||
|
||||
public boolean isInterface() {
|
||||
return getType().isInterface();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an Iteration of IClass that implement this interface
|
||||
*/
|
||||
public Iterator iterateImplementors() {
|
||||
return cha.getImplementors(getType().getReference()).iterator();
|
||||
}
|
||||
|
||||
public ClassHierarchy getClassHierarchy() {
|
||||
return cha;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,125 @@
|
||||
/*******************************************************************************
|
||||
* 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.analysis.typeInference;
|
||||
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
/**
|
||||
*
|
||||
* Abstraction of a Java type. These are immutable.
|
||||
* @author sfink
|
||||
*/
|
||||
public class PointType extends TypeAbstraction {
|
||||
|
||||
private final IClass type;
|
||||
private final ClassHierarchy cha;
|
||||
|
||||
/**
|
||||
* Private constructor ... only for internal use.
|
||||
*/
|
||||
public PointType(IClass type, ClassHierarchy cha) {
|
||||
this.type = type;
|
||||
if (Assertions.verifyAssertions) {
|
||||
Assertions._assert(type != null);
|
||||
Assertions._assert(type.getReference().isReferenceType());
|
||||
}
|
||||
this.cha = cha;
|
||||
}
|
||||
|
||||
public TypeAbstraction meet(TypeAbstraction rhs) {
|
||||
if (rhs == TOP) {
|
||||
return this;
|
||||
} else {
|
||||
if (rhs instanceof PointType) {
|
||||
PointType other = (PointType) rhs;
|
||||
if (type.equals(other.type)) {
|
||||
return this;
|
||||
} else if (type.isArrayClass() || other.type.isArrayClass()) {
|
||||
// give up on arrays. We don't care anyway.
|
||||
return new ConeType(cha.getRootClass(), cha);
|
||||
} else {
|
||||
return new ConeType(cha.getLeastCommonSuperclass(this.type, other.type), cha);
|
||||
}
|
||||
} else if (rhs instanceof ConeType) {
|
||||
ConeType other = (ConeType) rhs;
|
||||
TypeReference T = other.getType().getReference();
|
||||
if (type.isArrayClass() || T.isArrayType()) {
|
||||
// give up on arrays. We don't care anyway.
|
||||
return new ConeType(cha.getRootClass(), cha);
|
||||
}
|
||||
IClass typeKlass = type;
|
||||
if (cha.isSubclassOf(typeKlass, other.getType())) {
|
||||
return other;
|
||||
} else if (other.isInterface()) {
|
||||
if (cha.implementsInterface(typeKlass, T)) {
|
||||
return other;
|
||||
}
|
||||
}
|
||||
// if we get here, we need to do cha-based superclass and return a cone.
|
||||
// TODO: avoid the allocation
|
||||
return other.meet(new ConeType(other.getType(), cha));
|
||||
} else {
|
||||
Assertions.UNREACHABLE("Unexpected type: " + rhs.getClass());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString() {
|
||||
return "point: " + type.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getType.
|
||||
*
|
||||
* @return TypeReference
|
||||
*/
|
||||
public IClass getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#equals(Object)
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof PointType)) {
|
||||
return false;
|
||||
}
|
||||
PointType other = (PointType) obj;
|
||||
if (Assertions.verifyAssertions) {
|
||||
if (!cha.equals(other.cha)) {
|
||||
Assertions._assert(cha.equals(other.cha), "different chas " + this + " " + other);
|
||||
}
|
||||
}
|
||||
return type.equals(other.type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
return 37 * type.hashCode();
|
||||
}
|
||||
|
||||
public boolean isArrayType() {
|
||||
return getType().isArrayClass();
|
||||
}
|
||||
|
||||
public IClass getIClass() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
@ -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.analysis.typeInference;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.collections.HashMapFactory;
|
||||
|
||||
public class PrimitiveType extends TypeAbstraction {
|
||||
|
||||
private static Map<TypeReference, PrimitiveType> refernceToType = new HashMap<TypeReference, PrimitiveType>();
|
||||
|
||||
public static final PrimitiveType BOOLEAN = makePrimitive(TypeReference.Boolean);
|
||||
|
||||
public static final PrimitiveType CHAR = makePrimitive(TypeReference.Char);
|
||||
|
||||
public static final PrimitiveType BYTE = makePrimitive(TypeReference.Byte);
|
||||
|
||||
public static final PrimitiveType SHORT = makePrimitive(TypeReference.Short);
|
||||
|
||||
public static final PrimitiveType INT = makePrimitive(TypeReference.Int);
|
||||
|
||||
public static final PrimitiveType LONG = makePrimitive(TypeReference.Long);
|
||||
|
||||
public static final PrimitiveType FLOAT = makePrimitive(TypeReference.Float);
|
||||
|
||||
public static final PrimitiveType DOUBLE = makePrimitive(TypeReference.Double);
|
||||
|
||||
private static HashMap<String, String> primitiveNameMap;
|
||||
static {
|
||||
primitiveNameMap = HashMapFactory.make(9);
|
||||
primitiveNameMap.put("I", "int");
|
||||
primitiveNameMap.put("J", "long");
|
||||
primitiveNameMap.put("S", "short");
|
||||
primitiveNameMap.put("B", "byte");
|
||||
primitiveNameMap.put("C", "char");
|
||||
primitiveNameMap.put("D", "double");
|
||||
primitiveNameMap.put("F", "float");
|
||||
primitiveNameMap.put("Z", "boolean");
|
||||
primitiveNameMap.put("V", "void");
|
||||
}
|
||||
|
||||
private final TypeReference reference;
|
||||
|
||||
private PrimitiveType(TypeReference reference) {
|
||||
this.reference = reference;
|
||||
}
|
||||
|
||||
public TypeAbstraction meet(TypeAbstraction rhs) {
|
||||
if (rhs == TOP) {
|
||||
return this;
|
||||
} else if (rhs == this) {
|
||||
return this;
|
||||
} else if (this == BOOLEAN) {
|
||||
return rhs;
|
||||
} else if (rhs == BOOLEAN) {
|
||||
return this;
|
||||
}
|
||||
return TOP;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return reference.hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object other) {
|
||||
return this == other;
|
||||
}
|
||||
|
||||
public IClass getType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static PrimitiveType getPrimitive(TypeReference reference) {
|
||||
return refernceToType.get(reference);
|
||||
}
|
||||
|
||||
private static PrimitiveType makePrimitive(TypeReference reference) {
|
||||
PrimitiveType newType = new PrimitiveType(reference);
|
||||
refernceToType.put(reference, newType);
|
||||
return newType;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
String result = primitiveNameMap.get(reference.getName().toString());
|
||||
return (result != null) ? result : "PrimitiveType";
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,113 @@
|
||||
/*******************************************************************************
|
||||
* 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.analysis.typeInference;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.classLoader.CodeScanner;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.shrikeCT.InvalidClassFileException;
|
||||
import com.ibm.wala.ssa.IR;
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.ssa.SSAInvokeInstruction;
|
||||
import com.ibm.wala.util.collections.HashMapFactory;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.warnings.WarningSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* Holds results of type inference for call site receivers.
|
||||
*
|
||||
* @author sfink
|
||||
*/
|
||||
public class ReceiverTypeInference {
|
||||
|
||||
private TypeInference ti;
|
||||
|
||||
/**
|
||||
* Mapping from call site reference to InvokeInstruction. TODO: this kind of
|
||||
* sucks. Redesign?
|
||||
*/
|
||||
private HashMap<CallSiteReference, SSAInvokeInstruction> invokeMap;
|
||||
|
||||
/**
|
||||
* An object to track analysis warnings
|
||||
*/
|
||||
private WarningSet warnings;
|
||||
|
||||
public ReceiverTypeInference(TypeInference ti, WarningSet warnings) {
|
||||
this.ti = ti;
|
||||
this.warnings = warnings;
|
||||
|
||||
try {
|
||||
setupInvokeMap();
|
||||
} catch (InvalidClassFileException e) {
|
||||
e.printStackTrace();
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method setupInvokeMap. TODO: redesign stuff so that all this is not
|
||||
* necessary. TODO: has that time come .. is this unnecesary yet?
|
||||
*
|
||||
* @throws InvalidClassFileException
|
||||
*/
|
||||
private void setupInvokeMap() throws InvalidClassFileException {
|
||||
|
||||
invokeMap = HashMapFactory.make(5);
|
||||
IR ir = ti.getIR();
|
||||
IMethod method = ir.getMethod();
|
||||
// set up mapping from Integer (program counter) -> CallSiteReference
|
||||
HashMap<Integer, CallSiteReference> intMap = HashMapFactory.make(5);
|
||||
for (Iterator it = CodeScanner.iterateCallSites(method, warnings); it.hasNext();) {
|
||||
CallSiteReference site = (CallSiteReference) it.next();
|
||||
int pc = site.getProgramCounter();
|
||||
intMap.put(new Integer(pc), site);
|
||||
}
|
||||
// now set up mapping from CallSiteReference -> InvokeInstruction
|
||||
SSAInstruction[] instructions = ir.getInstructions();
|
||||
for (int i = 0; i < instructions.length; i++) {
|
||||
SSAInstruction s = instructions[i];
|
||||
if (s instanceof SSAInvokeInstruction) {
|
||||
SSAInvokeInstruction call = (SSAInvokeInstruction) s;
|
||||
int pc = call.getProgramCounter();
|
||||
CallSiteReference site = intMap.get(new Integer(pc));
|
||||
invokeMap.put(site, call);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public TypeAbstraction getReceiverType(CallSiteReference site) {
|
||||
SSAInvokeInstruction instruction = getInvokeInstruction(site);
|
||||
if (instruction == null) {
|
||||
return null;
|
||||
}
|
||||
int def = instruction.getReceiver();
|
||||
if (def == -1) {
|
||||
return null;
|
||||
} else {
|
||||
return ti.getType(def);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getInvokeInstruction.
|
||||
*
|
||||
* @param site
|
||||
* @return InvokeInstruction
|
||||
*/
|
||||
private SSAInvokeInstruction getInvokeInstruction(CallSiteReference site) {
|
||||
return invokeMap.get(site);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,78 @@
|
||||
/*******************************************************************************
|
||||
* 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.analysis.typeInference;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.ssa.IR;
|
||||
import com.ibm.wala.ssa.SSAOptions;
|
||||
import com.ibm.wala.util.CacheReference;
|
||||
import com.ibm.wala.util.collections.HashMapFactory;
|
||||
import com.ibm.wala.util.warnings.WarningSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* A soft cache of results of type inference
|
||||
*
|
||||
* @author sfink
|
||||
*/
|
||||
public class ReceiverTypeInferenceCache {
|
||||
|
||||
private final WarningSet warnings;
|
||||
|
||||
private final ClassHierarchy cha;
|
||||
|
||||
private final AnalysisOptions options;
|
||||
|
||||
public ReceiverTypeInferenceCache(ClassHierarchy cha, AnalysisOptions options, WarningSet warnings) {
|
||||
this.warnings = warnings;
|
||||
this.options = options;
|
||||
this.cha = cha;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A cache of TypeInference results; a mapping from CGNode ->
|
||||
* ReceiverTypeInference
|
||||
*/
|
||||
private final Map<CGNode, Object> typeInferenceMap = HashMapFactory.make();
|
||||
|
||||
/**
|
||||
* @param n
|
||||
* node
|
||||
* @return null if unable to perform type inference
|
||||
*/
|
||||
public ReceiverTypeInference findOrCreate(CGNode n) {
|
||||
Object ref = typeInferenceMap.get(n);
|
||||
ReceiverTypeInference result = (ReceiverTypeInference) CacheReference.get(ref);
|
||||
try {
|
||||
if (result == null) {
|
||||
SSAOptions options = SSAOptions.defaultOptions();
|
||||
options.setUsePiNodes(true);
|
||||
IR ir = this.options.getSSACache().findOrCreateIR(n.getMethod(), n.getContext(), cha, options, warnings);
|
||||
TypeInference T = new TypeInference(ir, cha);
|
||||
T.solve();
|
||||
|
||||
result = new ReceiverTypeInference(T, warnings);
|
||||
ref = CacheReference.make(result);
|
||||
typeInferenceMap.put(n, ref);
|
||||
}
|
||||
return result;
|
||||
} catch (ClassCastException e) {
|
||||
// this might happen if it's not a ShrikeCTMethodWrapper
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,95 @@
|
||||
/*******************************************************************************
|
||||
* 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.analysis.typeInference;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Abstraction of a set of PointTypes. These are immutable.
|
||||
* TODO: fix for efficiency if needed.
|
||||
*
|
||||
* @author sfink
|
||||
*
|
||||
*/
|
||||
public class SetType extends TypeAbstraction {
|
||||
|
||||
private final HashSet<TypeReference> types;
|
||||
private final int hashCode;
|
||||
|
||||
public SetType(PointType[] points) {
|
||||
if (Assertions.verifyAssertions) {
|
||||
Assertions._assert(points != null);
|
||||
Assertions._assert(points.length > 0);
|
||||
}
|
||||
types = HashSetFactory.make(points.length);
|
||||
int h = 0;
|
||||
for (int i = 0; i< points.length; i++) {
|
||||
TypeReference T = points[i].getType().getReference();
|
||||
h ^= T.hashCode();
|
||||
types.add(T);
|
||||
}
|
||||
hashCode = h;
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.ibm.wala.analysis.typeInference.TypeAbstraction#meet(com.ibm.wala.analysis.typeInference.TypeAbstraction)
|
||||
*/
|
||||
public TypeAbstraction meet(TypeAbstraction rhs) {
|
||||
// TODO Auto-generated method stub
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.ibm.wala.analysis.typeInference.TypeAbstraction#equals(java.lang.Object)
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
// TODO: make SetTypes of size 1 equal PointTypes.
|
||||
// need a factory facade for this.
|
||||
|
||||
// TODO: canonicalize?? How to improve this?
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
if (obj instanceof SetType) {
|
||||
if (hashCode() != obj.hashCode()) {
|
||||
return false;
|
||||
} else {
|
||||
SetType other = (SetType)obj;
|
||||
return (types.equals(other.types));
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.ibm.wala.analysis.typeInference.TypeAbstraction#hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Iterator of the TypeReferences which compose this Set.
|
||||
*/
|
||||
public Iterator iteratePoints() {
|
||||
return types.iterator();
|
||||
}
|
||||
}
|
||||
@ -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.analysis.typeInference;
|
||||
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.ipa.callgraph.ContextItem;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
/**
|
||||
*
|
||||
* Absraction of a Java type. These are immutable.
|
||||
*
|
||||
* @author sfink
|
||||
*/
|
||||
public abstract class TypeAbstraction implements ContextItem {
|
||||
|
||||
/**
|
||||
* Canonical element representing TOP for a dataflow lattice
|
||||
*/
|
||||
public final static TypeAbstraction TOP = new TypeAbstraction() {
|
||||
public TypeAbstraction meet(TypeAbstraction rhs) {
|
||||
return rhs;
|
||||
}
|
||||
public String toString() {
|
||||
return "JavaTypeAbstraction.TOP";
|
||||
}
|
||||
public int hashCode() {
|
||||
return 17;
|
||||
}
|
||||
public boolean equals(Object other) {
|
||||
return this == other;
|
||||
}
|
||||
public IClass getType() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
public abstract TypeAbstraction meet(TypeAbstraction rhs);
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#equals(Object)
|
||||
*/
|
||||
public abstract boolean equals(Object obj);
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
public abstract int hashCode();
|
||||
|
||||
/**
|
||||
* This is here for convenience; it makes sense for Point and Cone Dispatch.
|
||||
* TODO: probably should get rid of it.
|
||||
*/
|
||||
public IClass getType() {
|
||||
Assertions.UNREACHABLE("getType not implemented for " + getClass());
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,766 @@
|
||||
/*******************************************************************************
|
||||
* 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.analysis.typeInference;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.dataflow.ssa.SSAInference;
|
||||
import com.ibm.wala.fixedpoint.impl.AbstractOperator;
|
||||
import com.ibm.wala.fixedpoint.impl.AbstractVariable;
|
||||
import com.ibm.wala.fixedpoint.impl.NullaryOperator;
|
||||
import com.ibm.wala.fixpoint.FixedPointConstants;
|
||||
import com.ibm.wala.fixpoint.IVariable;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.ssa.IR;
|
||||
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
|
||||
import com.ibm.wala.ssa.SSAArrayLengthInstruction;
|
||||
import com.ibm.wala.ssa.SSAArrayLoadInstruction;
|
||||
import com.ibm.wala.ssa.SSABinaryOpInstruction;
|
||||
import com.ibm.wala.ssa.SSACheckCastInstruction;
|
||||
import com.ibm.wala.ssa.SSAConversionInstruction;
|
||||
import com.ibm.wala.ssa.SSAGetCaughtExceptionInstruction;
|
||||
import com.ibm.wala.ssa.SSAGetInstruction;
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.ssa.SSAInvokeInstruction;
|
||||
import com.ibm.wala.ssa.SSANewInstruction;
|
||||
import com.ibm.wala.ssa.SSAPhiInstruction;
|
||||
import com.ibm.wala.ssa.SSAPiInstruction;
|
||||
import com.ibm.wala.ssa.SSAUnaryOpInstruction;
|
||||
import com.ibm.wala.ssa.SymbolTable;
|
||||
import com.ibm.wala.ssa.SSACFG.ExceptionHandlerBasicBlock;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
/**
|
||||
*
|
||||
* This class performs intraprocedural type propagation on an SSA IR.
|
||||
*
|
||||
* @author sfink
|
||||
*/
|
||||
public class TypeInference extends SSAInference implements FixedPointConstants {
|
||||
|
||||
/**
|
||||
* The governing SSA form
|
||||
*/
|
||||
protected IR ir;
|
||||
|
||||
/**
|
||||
* The governing class hierarchy
|
||||
*/
|
||||
protected ClassHierarchy cha;
|
||||
|
||||
/**
|
||||
* A singleton instance of the phi operator.
|
||||
*/
|
||||
private final static AbstractOperator phiOp = new PhiOperator();
|
||||
|
||||
private final static AbstractOperator primitivePropagateOp = new PrimitivePropagateOperator();
|
||||
|
||||
/**
|
||||
* A cone type for java.lang.Object
|
||||
*/
|
||||
protected final TypeAbstraction BOTTOM;
|
||||
|
||||
/**
|
||||
* A singleton instance of the pi operator.
|
||||
*/
|
||||
private final static PiOperator piOp = new PiOperator();
|
||||
|
||||
/**
|
||||
* should type inference track primitive types?
|
||||
*/
|
||||
protected final boolean doPrimitives;
|
||||
|
||||
public TypeInference(IR ir, ClassHierarchy cha, boolean doPrimitives) {
|
||||
this.cha = cha;
|
||||
this.ir = ir;
|
||||
this.doPrimitives = doPrimitives;
|
||||
this.BOTTOM = new ConeType(cha.getRootClass(), cha);
|
||||
initialize();
|
||||
}
|
||||
|
||||
public TypeInference(IR ir, ClassHierarchy cha) {
|
||||
this(ir, cha, false);
|
||||
}
|
||||
|
||||
protected void initialize() {
|
||||
init(ir, this.new TypeVarFactory(), this.new TypeOperatorFactory());
|
||||
}
|
||||
|
||||
protected void initializeVariables() {
|
||||
int[] parameterValueNumbers = ir.getParameterValueNumbers();
|
||||
for (int i = 0; i < parameterValueNumbers.length; i++) {
|
||||
TypeVariable v = (TypeVariable) getVariable(parameterValueNumbers[i]);
|
||||
TypeReference t = ir.getParameterType(i);
|
||||
|
||||
if (t.isReferenceType()) {
|
||||
IClass klass = cha.lookupClass(t);
|
||||
if (klass != null) {
|
||||
v.setType(new ConeType(klass, cha));
|
||||
} else {
|
||||
v.setType(ConeType.TOP);
|
||||
// v.setType(BOTTOM);
|
||||
}
|
||||
} else if (doPrimitives) {
|
||||
v.setType(PrimitiveType.getPrimitive(t));
|
||||
}
|
||||
}
|
||||
|
||||
SymbolTable st = ir.getSymbolTable();
|
||||
if (st != null) {
|
||||
for(int i = 0; i < st.getMaxValueNumber(); i++ ) {
|
||||
if (st.isConstant(i)) {
|
||||
TypeVariable v = (TypeVariable) getVariable(i);
|
||||
v.setType(getConstantType(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Iterator it = ir.iterateNormalInstructions(); it.hasNext();) {
|
||||
SSAInstruction s = (SSAInstruction) it.next();
|
||||
if (s instanceof SSAAbstractInvokeInstruction) {
|
||||
SSAAbstractInvokeInstruction call = (SSAAbstractInvokeInstruction) s;
|
||||
TypeVariable v = (TypeVariable) getVariable(call.getException());
|
||||
Collection defaultExceptions = call.getExceptionTypes();
|
||||
if (Assertions.verifyAssertions) {
|
||||
Assertions._assert(defaultExceptions.size() == 1);
|
||||
}
|
||||
// t should be NullPointerException
|
||||
TypeReference t = (TypeReference) defaultExceptions.iterator().next();
|
||||
IClass klass = cha.lookupClass(t);
|
||||
if (Assertions.verifyAssertions) {
|
||||
Assertions._assert(klass != null);
|
||||
}
|
||||
v.setType(new PointType(klass, cha));
|
||||
|
||||
IMethod m = cha.resolveMethod(call.getDeclaredTarget());
|
||||
if (m != null) {
|
||||
TypeReference[] x = m.getDeclaredExceptions();
|
||||
if (x != null) {
|
||||
for (int i = 0; i < x.length; i++) {
|
||||
TypeReference tx = x[i];
|
||||
IClass tc = cha.lookupClass(tx);
|
||||
if (tc != null) {
|
||||
v.setType(v.getType().meet(new ConeType(tc, cha)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void initializeWorkList() {
|
||||
addAllStatementsToWorkList();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @author sfink
|
||||
*
|
||||
* An operator which initializes a type to a declared type.
|
||||
*/
|
||||
protected final class DeclaredTypeOperator extends NullaryOperator {
|
||||
private final TypeAbstraction type;
|
||||
|
||||
public DeclaredTypeOperator(TypeAbstraction type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note that we need evalute this operator at most once
|
||||
*/
|
||||
public byte evaluate(IVariable lhs) {
|
||||
TypeVariable t = (TypeVariable) lhs;
|
||||
if (t.type.equals(type)) {
|
||||
return NOT_CHANGED_AND_FIXED;
|
||||
} else {
|
||||
t.setType(type);
|
||||
return CHANGED_AND_FIXED;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString() {
|
||||
return "delared type := " + type;
|
||||
}
|
||||
|
||||
public boolean isNullary() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.dataflow.Operator#hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
return 9931 * type.hashCode();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.dataflow.Operator#equals(java.lang.Object)
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof DeclaredTypeOperator) {
|
||||
DeclaredTypeOperator d = (DeclaredTypeOperator) o;
|
||||
return type.equals(d.type);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author sfink
|
||||
*
|
||||
*/
|
||||
private static final class PhiOperator extends AbstractOperator {
|
||||
|
||||
private PhiOperator() {
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: work on efficiency shortcuts for this.
|
||||
*/
|
||||
public byte evaluate(IVariable lhs, IVariable[] rhs) {
|
||||
TypeVariable L = (TypeVariable) lhs;
|
||||
TypeAbstraction lhsType = L.getType();
|
||||
TypeAbstraction meet = TypeAbstraction.TOP;
|
||||
for (int i = 0; i < rhs.length; i++) {
|
||||
if (rhs[i] != null) {
|
||||
TypeVariable r = (TypeVariable) rhs[i];
|
||||
meet = meet.meet(r.getType());
|
||||
}
|
||||
}
|
||||
if (lhsType.equals(meet)) {
|
||||
return NOT_CHANGED;
|
||||
} else {
|
||||
L.setType(meet);
|
||||
return CHANGED;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString() {
|
||||
return "phi meet";
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.dataflow.Operator#hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
return 9929;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.dataflow.Operator#equals(java.lang.Object)
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
return (o instanceof PhiOperator);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author sfink
|
||||
*
|
||||
*/
|
||||
private static final class PiOperator extends AbstractOperator {
|
||||
|
||||
private PiOperator() {
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: work on efficiency shortcuts for this.
|
||||
*/
|
||||
public byte evaluate(IVariable lhsOperand, IVariable[] rhsOperands) {
|
||||
TypeVariable lhs = (TypeVariable) lhsOperand;
|
||||
TypeAbstraction lhsType = lhs.getType();
|
||||
|
||||
TypeVariable rhs = (TypeVariable) rhsOperands[0];
|
||||
TypeAbstraction rhsType = rhs.getType();
|
||||
|
||||
if (lhsType.equals(rhsType)) {
|
||||
return NOT_CHANGED;
|
||||
} else {
|
||||
lhs.setType(rhsType);
|
||||
return CHANGED;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString() {
|
||||
return "pi";
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.dataflow.Operator#hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
return 9929 * 13;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.dataflow.Operator#equals(java.lang.Object)
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
return (o instanceof PiOperator);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author sfink
|
||||
*
|
||||
*/
|
||||
private static final class PrimitivePropagateOperator extends AbstractOperator {
|
||||
|
||||
private PrimitivePropagateOperator() {
|
||||
}
|
||||
|
||||
public byte evaluate(IVariable lhs, IVariable[] rhs) {
|
||||
TypeVariable L = (TypeVariable) lhs;
|
||||
TypeAbstraction lhsType = L.getType();
|
||||
TypeAbstraction meet = TypeAbstraction.TOP;
|
||||
for (int i = 0; i < rhs.length; i++) {
|
||||
if (rhs[i] != null) {
|
||||
TypeVariable r = (TypeVariable) rhs[i];
|
||||
meet = meet.meet(r.getType());
|
||||
}
|
||||
}
|
||||
if (lhsType.equals(meet)) {
|
||||
return NOT_CHANGED;
|
||||
} else {
|
||||
L.setType(meet);
|
||||
return CHANGED;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString() {
|
||||
return "propagate";
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.dataflow.Operator#hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
return 99292;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.dataflow.Operator#equals(java.lang.Object)
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
return (o instanceof PrimitivePropagateOperator);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This operator will extract the element type from an arrayref in an array
|
||||
* access instruction
|
||||
*
|
||||
* TODO: why isn't this a nullary operator?
|
||||
*/
|
||||
private final class GetElementType extends AbstractOperator {
|
||||
private final SSAArrayLoadInstruction load;
|
||||
|
||||
GetElementType(SSAArrayLoadInstruction load) {
|
||||
this.load = load;
|
||||
}
|
||||
|
||||
public byte evaluate(IVariable lhs, IVariable[] rhs) {
|
||||
TypeVariable t = (TypeVariable) lhs;
|
||||
TypeAbstraction arrayType = getType(load.getArrayRef());
|
||||
if (arrayType.equals(TypeAbstraction.TOP)) {
|
||||
return NOT_CHANGED;
|
||||
}
|
||||
TypeReference elementType = null;
|
||||
|
||||
if (arrayType instanceof PointType) {
|
||||
elementType = ((PointType) arrayType).getType().getReference().getArrayElementType();
|
||||
} else if (arrayType instanceof ConeType) {
|
||||
elementType = ((ConeType) arrayType).getType().getReference().getArrayElementType();
|
||||
} else {
|
||||
Assertions.UNREACHABLE("Unexpected type " + arrayType.getClass());
|
||||
}
|
||||
if (elementType.isPrimitiveType()) {
|
||||
if (doPrimitives && t.getType() == TypeAbstraction.TOP) {
|
||||
t.setType(PrimitiveType.getPrimitive(elementType));
|
||||
return CHANGED;
|
||||
}
|
||||
return NOT_CHANGED;
|
||||
}
|
||||
|
||||
if (t.getType() != TypeAbstraction.TOP) {
|
||||
TypeReference tType = null;
|
||||
if (t.getType() instanceof PointType) {
|
||||
tType = ((PointType) t.getType()).getType().getReference();
|
||||
} else if (t.getType() instanceof ConeType) {
|
||||
tType = ((ConeType) t.getType()).getType().getReference();
|
||||
} else {
|
||||
Assertions.UNREACHABLE("Unexpected type " + t.getType().getClass());
|
||||
}
|
||||
if (tType.equals(elementType)) {
|
||||
return NOT_CHANGED;
|
||||
} else {
|
||||
IClass klass = cha.lookupClass(elementType);
|
||||
if (Assertions.verifyAssertions) {
|
||||
Assertions._assert(klass != null);
|
||||
}
|
||||
t.setType(new ConeType(klass, cha));
|
||||
return CHANGED;
|
||||
}
|
||||
} else {
|
||||
IClass klass = cha.lookupClass(elementType);
|
||||
// if (Assertions.verifyAssertions) {
|
||||
// Assertions._assert(klass != null);
|
||||
// }
|
||||
if (klass != null) {
|
||||
t.setType(new ConeType(klass, cha));
|
||||
} else {
|
||||
t.setType(ConeType.TOP);
|
||||
}
|
||||
|
||||
return CHANGED;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString() {
|
||||
return "getElementType " + load;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.dataflow.Operator#hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
return 9923 * load.hashCode();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.dataflow.Operator#equals(java.lang.Object)
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof GetElementType) {
|
||||
GetElementType other = (GetElementType) o;
|
||||
return load.equals(other.load);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected class TypeOperatorFactory extends SSAInstruction.Visitor implements OperatorFactory {
|
||||
|
||||
protected AbstractOperator result = null;
|
||||
|
||||
public AbstractOperator get(SSAInstruction instruction) {
|
||||
instruction.visit(this);
|
||||
AbstractOperator temp = result;
|
||||
result = null;
|
||||
return temp;
|
||||
}
|
||||
|
||||
public void visitArrayLoad(SSAArrayLoadInstruction instruction) {
|
||||
result = new GetElementType(instruction);
|
||||
}
|
||||
|
||||
public void visitArrayLength(SSAArrayLengthInstruction instruction) {
|
||||
if (!doPrimitives) {
|
||||
result = null;
|
||||
} else {
|
||||
result = new DeclaredTypeOperator(PrimitiveType.INT);
|
||||
}
|
||||
}
|
||||
|
||||
public void visitGet(SSAGetInstruction instruction) {
|
||||
TypeReference type = instruction.getDeclaredFieldType();
|
||||
|
||||
if (doPrimitives && type.isPrimitiveType()) {
|
||||
result = new DeclaredTypeOperator(PrimitiveType.getPrimitive(type));
|
||||
} else {
|
||||
IClass klass = cha.lookupClass(type);
|
||||
if (klass == null) {
|
||||
// get from a field of a type that cannot be loaded.
|
||||
// be pessimistic
|
||||
result = new DeclaredTypeOperator(BOTTOM);
|
||||
} else {
|
||||
result = new DeclaredTypeOperator(new ConeType(klass, cha));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void visitInvoke(SSAInvokeInstruction instruction) {
|
||||
TypeReference type = instruction.getDeclaredResultType();
|
||||
if (type.isReferenceType()) {
|
||||
IClass klass = cha.lookupClass(type);
|
||||
if (klass == null) {
|
||||
// a type that cannot be loaded.
|
||||
// be pessimistic
|
||||
result = new DeclaredTypeOperator(BOTTOM);
|
||||
} else {
|
||||
result = new DeclaredTypeOperator(new ConeType(klass, cha));
|
||||
}
|
||||
} else if (doPrimitives && type.isPrimitiveType()) {
|
||||
result = new DeclaredTypeOperator(PrimitiveType.getPrimitive(type));
|
||||
} else {
|
||||
result = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void visitNew(SSANewInstruction instruction) {
|
||||
TypeReference type = instruction.getConcreteType();
|
||||
IClass klass = cha.lookupClass(type);
|
||||
if (klass == null) {
|
||||
// a type that cannot be loaded.
|
||||
// be pessimistic
|
||||
result = new DeclaredTypeOperator(BOTTOM);
|
||||
} else {
|
||||
result = new DeclaredTypeOperator(new PointType(klass, cha));
|
||||
}
|
||||
}
|
||||
|
||||
public void visitCheckCast(SSACheckCastInstruction instruction) {
|
||||
TypeReference type = instruction.getDeclaredResultType();
|
||||
IClass klass = cha.lookupClass(type);
|
||||
if (klass == null) {
|
||||
// a type that cannot be loaded.
|
||||
// be pessimistic
|
||||
result = new DeclaredTypeOperator(BOTTOM);
|
||||
} else {
|
||||
result = new DeclaredTypeOperator(new ConeType(klass, cha));
|
||||
}
|
||||
}
|
||||
|
||||
public void visitConversion(SSAConversionInstruction instruction) {
|
||||
if (doPrimitives) {
|
||||
result = new DeclaredTypeOperator(PrimitiveType.getPrimitive(instruction.getToType()));
|
||||
}
|
||||
}
|
||||
|
||||
public void visitBinaryOp(SSABinaryOpInstruction instruction) {
|
||||
if (doPrimitives) {
|
||||
result = primitivePropagateOp;
|
||||
}
|
||||
}
|
||||
|
||||
public void visitUnaryOp(SSAUnaryOpInstruction instruction) {
|
||||
if (doPrimitives) {
|
||||
result = primitivePropagateOp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void visitGetCaughtException(SSAGetCaughtExceptionInstruction instruction) {
|
||||
TypeAbstraction type = meetDeclaredExceptionTypes(instruction, cha);
|
||||
result = new DeclaredTypeOperator(type);
|
||||
}
|
||||
|
||||
public void visitPhi(SSAPhiInstruction instruction) {
|
||||
result = phiOp;
|
||||
}
|
||||
|
||||
public void visitPi(SSAPiInstruction instruction) {
|
||||
result = piOp;
|
||||
}
|
||||
|
||||
private TypeAbstraction meetDeclaredExceptionTypes(SSAGetCaughtExceptionInstruction s, ClassHierarchy cha) {
|
||||
ExceptionHandlerBasicBlock bb = (ExceptionHandlerBasicBlock) ir.getControlFlowGraph().getNode(s.getBasicBlockNumber());
|
||||
Iterator it = bb.getCaughtExceptionTypes();
|
||||
TypeReference t = (TypeReference) it.next();
|
||||
IClass klass = cha.lookupClass(t);
|
||||
TypeAbstraction result = null;
|
||||
if (klass == null) {
|
||||
// a type that cannot be loaded.
|
||||
// be pessimistic
|
||||
result = BOTTOM;
|
||||
} else {
|
||||
result = new ConeType(klass, cha);
|
||||
}
|
||||
while (it.hasNext()) {
|
||||
t = (TypeReference) it.next();
|
||||
IClass tClass = cha.lookupClass(t);
|
||||
if (tClass == null) {
|
||||
result = BOTTOM;
|
||||
} else {
|
||||
result = result.meet(new ConeType(tClass, cha));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A type variable in the dataflow system.
|
||||
*/
|
||||
protected static class TypeVariable extends AbstractVariable {
|
||||
|
||||
private TypeAbstraction type;
|
||||
|
||||
private final int hash;
|
||||
|
||||
public TypeVariable(TypeAbstraction type, int hashCode) {
|
||||
this.type = type;
|
||||
this.hash = hashCode;
|
||||
}
|
||||
|
||||
public void copyState(IVariable v) {
|
||||
TypeVariable other = (TypeVariable) v;
|
||||
this.type = other.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type.
|
||||
*
|
||||
* @return TypeAbstraction
|
||||
*/
|
||||
public TypeAbstraction getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type.
|
||||
*
|
||||
* @param type
|
||||
* The type to set
|
||||
*/
|
||||
public void setType(TypeAbstraction type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString() {
|
||||
return type.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.dataflow.AbstractVariable#hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
return hash;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class TypeVarFactory implements VariableFactory {
|
||||
|
||||
public IVariable makeVariable(int valueNumber) {
|
||||
SymbolTable st = ir.getSymbolTable();
|
||||
if (doPrimitives) {
|
||||
if (st.isConstant(valueNumber)) {
|
||||
if (st.isBooleanConstant(valueNumber)) {
|
||||
return new TypeVariable(PrimitiveType.BOOLEAN, 797 * valueNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
// if (st.isStringConstant(valueNumber)) {
|
||||
// IClass klass = cha.lookupClass(TypeReference.JavaLangString);
|
||||
// TypeAbstraction stringTypeAbs = new PointType(klass,cha);
|
||||
// return new TypeVariable(stringTypeAbs, 797 * valueNumber);
|
||||
// }
|
||||
return new TypeVariable(TypeAbstraction.TOP, 797 * valueNumber);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ir.
|
||||
*
|
||||
* @return IR
|
||||
*/
|
||||
public IR getIR() {
|
||||
return ir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getType.
|
||||
*
|
||||
* @param valueNumber
|
||||
* @return JavaTypeAbstraction
|
||||
*/
|
||||
public TypeAbstraction getType(int valueNumber) {
|
||||
if (Assertions.verifyAssertions) {
|
||||
if (getVariable(valueNumber) == null) {
|
||||
Assertions._assert(getVariable(valueNumber) != null, "null variable for value number " + valueNumber);
|
||||
}
|
||||
}
|
||||
return ((TypeVariable) getVariable(valueNumber)).getType();
|
||||
}
|
||||
|
||||
public TypeAbstraction getConstantType(int valueNumber) {
|
||||
if (ir.getSymbolTable().isStringConstant(valueNumber)) {
|
||||
return new PointType(cha.lookupClass(TypeReference.JavaLangString), cha);
|
||||
} else {
|
||||
return getConstantPrimitiveType(valueNumber);
|
||||
}
|
||||
}
|
||||
|
||||
public TypeAbstraction getConstantPrimitiveType(int valueNumber) {
|
||||
SymbolTable st = ir.getSymbolTable();
|
||||
if (!st.isConstant(valueNumber)) {
|
||||
return TypeAbstraction.TOP;
|
||||
}
|
||||
if (st.isIntegerConstant(valueNumber)) {
|
||||
return PrimitiveType.INT;
|
||||
} else if (st.isFloatConstant(valueNumber)) {
|
||||
return PrimitiveType.FLOAT;
|
||||
} else if (st.isDoubleConstant(valueNumber)) {
|
||||
return PrimitiveType.DOUBLE;
|
||||
}
|
||||
return TypeAbstraction.TOP;
|
||||
}
|
||||
|
||||
public boolean isUndefined(int valueNumber) {
|
||||
// TODO: Julian, you seem to be using BOTTOM in the European style.
|
||||
// Steve's code assumes American style (god forbid), so what you're getting
|
||||
// here
|
||||
// is not undefined, but java.lang.Object [NR/EY]
|
||||
if (getVariable(valueNumber) == null)
|
||||
return true;
|
||||
TypeAbstraction ta = ((TypeVariable) getVariable(valueNumber)).getType();
|
||||
return ta == BOTTOM || ta.getType() == null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
<HTML>
|
||||
<BODY>
|
||||
This package provides intraprocedural type inference over the SSA form.
|
||||
</BODY>
|
||||
</HTML>
|
||||
@ -0,0 +1,656 @@
|
||||
/*******************************************************************************
|
||||
* 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.cfg;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.shrikeBT.Constants;
|
||||
import com.ibm.wala.util.CompoundIterator;
|
||||
import com.ibm.wala.util.IteratorPlusOne;
|
||||
import com.ibm.wala.util.IteratorPlusTwo;
|
||||
import com.ibm.wala.util.collections.EmptyIterator;
|
||||
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.collections.NonNullSingletonIterator;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.graph.impl.DelegatingNumberedNodeManager;
|
||||
import com.ibm.wala.util.graph.impl.NumberedNodeIterator;
|
||||
import com.ibm.wala.util.graph.impl.SparseNumberedEdgeManager;
|
||||
import com.ibm.wala.util.intset.BasicNonNegativeIntRelation;
|
||||
import com.ibm.wala.util.intset.BitVector;
|
||||
import com.ibm.wala.util.intset.FixedSizeBitVector;
|
||||
import com.ibm.wala.util.intset.IntSet;
|
||||
import com.ibm.wala.util.intset.MutableSparseIntSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* A graph of basic blocks.
|
||||
*
|
||||
* @author sfink
|
||||
*/
|
||||
public abstract class AbstractCFG implements ControlFlowGraph, Constants {
|
||||
|
||||
/**
|
||||
* The method this AbstractCFG represents
|
||||
*/
|
||||
private final IMethod method;
|
||||
|
||||
/**
|
||||
* An object to track nodes in this cfg
|
||||
*/
|
||||
private DelegatingNumberedNodeManager<IBasicBlock> nodeManager = new DelegatingNumberedNodeManager<IBasicBlock>();
|
||||
|
||||
/**
|
||||
* An object to track most normal edges in this cfg
|
||||
*/
|
||||
private SparseNumberedEdgeManager<IBasicBlock> normalEdgeManager = new SparseNumberedEdgeManager<IBasicBlock>(nodeManager, 2,
|
||||
BasicNonNegativeIntRelation.SIMPLE);
|
||||
|
||||
/**
|
||||
* An object to track not-to-exit exceptional edges in this cfg
|
||||
*/
|
||||
private SparseNumberedEdgeManager<IBasicBlock> exceptionalEdgeManager = new SparseNumberedEdgeManager<IBasicBlock>(nodeManager,
|
||||
0, BasicNonNegativeIntRelation.SIMPLE);
|
||||
|
||||
/**
|
||||
* Which basic blocks have a normal edge to exit()?
|
||||
*/
|
||||
private FixedSizeBitVector normalToExit;
|
||||
|
||||
/**
|
||||
* Which basic blocks have an exceptional edge to exit()?
|
||||
*/
|
||||
private FixedSizeBitVector exceptionalToExit;
|
||||
|
||||
/**
|
||||
* Which basic blocks have a fall-through?
|
||||
*/
|
||||
private FixedSizeBitVector fallThru;
|
||||
|
||||
/**
|
||||
* Which basic blocks are catch blocks?
|
||||
*/
|
||||
private BitVector catchBlocks;
|
||||
|
||||
/**
|
||||
* Cache here for efficiency
|
||||
*/
|
||||
private IBasicBlock exit;
|
||||
|
||||
/**
|
||||
* @param method
|
||||
*/
|
||||
protected AbstractCFG(IMethod method) {
|
||||
this.method = method;
|
||||
this.catchBlocks = new BitVector(10);
|
||||
}
|
||||
|
||||
/**
|
||||
* subclasses must call this before calling addEdge, but after creating the
|
||||
* nodes
|
||||
*/
|
||||
protected void init() {
|
||||
normalToExit = new FixedSizeBitVector(getMaxNumber() + 1);
|
||||
exceptionalToExit = new FixedSizeBitVector(getMaxNumber() + 1);
|
||||
fallThru = new FixedSizeBitVector(getMaxNumber() + 1);
|
||||
exit = (IBasicBlock) getNode(getMaxNumber());
|
||||
}
|
||||
|
||||
public abstract boolean equals(Object o);
|
||||
|
||||
public abstract int hashCode();
|
||||
|
||||
/**
|
||||
* Return the entry basic block for the CFG.
|
||||
*
|
||||
* @return the entry basic block for the CFG.
|
||||
*/
|
||||
public IBasicBlock entry() {
|
||||
return (IBasicBlock) getNode(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the exit basic block for the CFG.
|
||||
*
|
||||
* @return the exit basic block for the CFG.
|
||||
*/
|
||||
public IBasicBlock exit() {
|
||||
return exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*/
|
||||
public int getPredNodeCount(IBasicBlock N) {
|
||||
if (N.equals(exit())) {
|
||||
// TODO: cache if necessary
|
||||
FixedSizeBitVector x = FixedSizeBitVector.or(normalToExit, exceptionalToExit);
|
||||
return x.populationCount();
|
||||
} else {
|
||||
boolean normalIn = getNumberOfNormalIn(N) > 0;
|
||||
boolean exceptionalIn = getNumberOfExceptionalIn(N) > 0;
|
||||
if (normalIn) {
|
||||
if (exceptionalIn) {
|
||||
return new Iterator2Collection<IBasicBlock>(getPredNodes(N)).size();
|
||||
} else {
|
||||
return getNumberOfNormalIn(N);
|
||||
}
|
||||
} else {
|
||||
return getNumberOfExceptionalIn(N);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getNumberOfNormalIn(IBasicBlock N) {
|
||||
if (Assertions.verifyAssertions) {
|
||||
Assertions._assert(!N.equals(exit()));
|
||||
}
|
||||
int number = getNumber(N);
|
||||
int xtra = 0;
|
||||
if (number > 0) {
|
||||
if (fallThru.get(number - 1)) {
|
||||
xtra++;
|
||||
}
|
||||
}
|
||||
return normalEdgeManager.getPredNodeCount(N) + xtra;
|
||||
}
|
||||
|
||||
public int getNumberOfExceptionalIn(IBasicBlock N) {
|
||||
if (Assertions.verifyAssertions) {
|
||||
Assertions._assert(!N.equals(exit()));
|
||||
}
|
||||
return exceptionalEdgeManager.getPredNodeCount(N);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param number
|
||||
* number of a basic block in this cfg
|
||||
*/
|
||||
boolean hasAnyNormalOut(int number) {
|
||||
return (fallThru.get(number) || normalEdgeManager.getSuccNodeCount(number) > 0 || normalToExit.get(number));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param number
|
||||
* number of a basic block in this cfg
|
||||
*/
|
||||
private int getNumberOfNormalOut(int number) {
|
||||
int xtra = 0;
|
||||
if (fallThru.get(number)) {
|
||||
xtra++;
|
||||
}
|
||||
if (normalToExit.get(number)) {
|
||||
xtra++;
|
||||
}
|
||||
return normalEdgeManager.getSuccNodeCount(number) + xtra;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param number
|
||||
* number of a basic block in this cfg
|
||||
*/
|
||||
public int getNumberOfExceptionalOut(int number) {
|
||||
int xtra = 0;
|
||||
if (exceptionalToExit.get(number)) {
|
||||
xtra++;
|
||||
}
|
||||
return exceptionalEdgeManager.getSuccNodeCount(number) + xtra;
|
||||
}
|
||||
|
||||
public int getNumberOfNormalOut(IBasicBlock N) {
|
||||
return getNumberOfNormalOut(getNumber(N));
|
||||
}
|
||||
|
||||
public int getNumberOfExceptionalOut(IBasicBlock N) {
|
||||
return getNumberOfExceptionalOut(getNumber(N));
|
||||
}
|
||||
|
||||
public Iterator<IBasicBlock> getPredNodes(IBasicBlock N) {
|
||||
if (N.equals(exit())) {
|
||||
return new FilterIterator<IBasicBlock>(iterateNodes(), new Filter() {
|
||||
public boolean accepts(Object o) {
|
||||
int i = getNumber((IBasicBlock) o);
|
||||
return normalToExit.get(i) || exceptionalToExit.get(i);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
int number = getNumber(N);
|
||||
boolean normalIn = getNumberOfNormalIn(N) > 0;
|
||||
boolean exceptionalIn = getNumberOfExceptionalIn(N) > 0;
|
||||
if (normalIn) {
|
||||
if (exceptionalIn) {
|
||||
HashSet<IBasicBlock> result = new HashSet<IBasicBlock>(getNumberOfNormalIn(N) + getNumberOfExceptionalIn(N));
|
||||
result.addAll(new Iterator2Collection<IBasicBlock>(normalEdgeManager.getPredNodes(N)));
|
||||
result.addAll(new Iterator2Collection<IBasicBlock>(exceptionalEdgeManager.getPredNodes(N)));
|
||||
if (fallThru.get(number - 1)) {
|
||||
result.add(getNode(number - 1));
|
||||
}
|
||||
return result.iterator();
|
||||
} else {
|
||||
if (number > 0 && fallThru.get(number - 1)) {
|
||||
return new IteratorPlusOne<IBasicBlock>(normalEdgeManager.getPredNodes(N), getNode(number - 1));
|
||||
} else {
|
||||
return normalEdgeManager.getPredNodes(N);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// !normalIn
|
||||
if (exceptionalIn) {
|
||||
return exceptionalEdgeManager.getPredNodes(N);
|
||||
} else {
|
||||
return EmptyIterator.instance();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getSuccNodeCount(IBasicBlock N) {
|
||||
if (N.equals(exit())) {
|
||||
return 0;
|
||||
}
|
||||
int nNormal = getNumberOfNormalOut(N);
|
||||
int nExc = getNumberOfExceptionalOut(N);
|
||||
if (nNormal > 0) {
|
||||
if (nExc > 0) {
|
||||
if (nExc == 1) {
|
||||
int number = getNumber(N);
|
||||
if (exceptionalToExit.get(number)) {
|
||||
if (normalToExit.get(number)) {
|
||||
return nNormal + nExc - 1;
|
||||
} else {
|
||||
return nNormal + nExc;
|
||||
}
|
||||
} else {
|
||||
return slowCountSuccNodes(N);
|
||||
}
|
||||
} else {
|
||||
return slowCountSuccNodes(N);
|
||||
}
|
||||
} else {
|
||||
return nNormal;
|
||||
}
|
||||
} else {
|
||||
// nNormal == 0
|
||||
return nExc;
|
||||
}
|
||||
}
|
||||
|
||||
private int slowCountSuccNodes(IBasicBlock N) {
|
||||
return new Iterator2Collection<IBasicBlock>(getSuccNodes(N)).size();
|
||||
}
|
||||
|
||||
public Iterator<IBasicBlock> getSuccNodes(IBasicBlock N) {
|
||||
int number = getNumber(N);
|
||||
if (normalToExit.get(number) && exceptionalToExit.get(number)) {
|
||||
return new CompoundIterator<IBasicBlock>(iterateNormalSuccessorsWithoutExit(number), iterateExceptionalSuccessors(number));
|
||||
} else {
|
||||
return new CompoundIterator<IBasicBlock>(iterateNormalSuccessors(number), iterateExceptionalSuccessors(number));
|
||||
}
|
||||
}
|
||||
|
||||
private Iterator<IBasicBlock> iterateExceptionalSuccessors(int number) {
|
||||
if (exceptionalEdgeManager.hasAnySuccessor(number)) {
|
||||
if (exceptionalToExit.get(number)) {
|
||||
return new IteratorPlusOne<IBasicBlock>(exceptionalEdgeManager.getSuccNodes(number), exit());
|
||||
} else {
|
||||
return exceptionalEdgeManager.getSuccNodes(number);
|
||||
}
|
||||
} else {
|
||||
if (exceptionalToExit.get(number)) {
|
||||
return new NonNullSingletonIterator<IBasicBlock>(exit());
|
||||
} else {
|
||||
return EmptyIterator.instance();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Iterator<IBasicBlock> iterateExceptionalPredecessors(IBasicBlock N) {
|
||||
if (N.equals(exit())) {
|
||||
return new FilterIterator<IBasicBlock>(iterateNodes(), new Filter() {
|
||||
public boolean accepts(Object o) {
|
||||
int i = getNumber((IBasicBlock) o);
|
||||
return exceptionalToExit.get(i);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return exceptionalEdgeManager.getPredNodes(N);
|
||||
}
|
||||
}
|
||||
|
||||
Iterator<IBasicBlock> iterateNormalPredecessors(IBasicBlock N) {
|
||||
if (N.equals(exit())) {
|
||||
return new FilterIterator<IBasicBlock>(iterateNodes(), new Filter() {
|
||||
public boolean accepts(Object o) {
|
||||
int i = getNumber((IBasicBlock) o);
|
||||
return normalToExit.get(i);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
int number = getNumber(N);
|
||||
if (number > 0 && fallThru.get(number - 1)) {
|
||||
return new IteratorPlusOne<IBasicBlock>(normalEdgeManager.getPredNodes(N), getNode(number - 1));
|
||||
} else {
|
||||
return normalEdgeManager.getPredNodes(N);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Iterator<IBasicBlock> iterateNormalSuccessors(int number) {
|
||||
if (fallThru.get(number)) {
|
||||
if (normalToExit.get(number)) {
|
||||
return new IteratorPlusTwo<IBasicBlock>(normalEdgeManager.getSuccNodes(number), getNode(number + 1), exit());
|
||||
} else {
|
||||
return new IteratorPlusOne<IBasicBlock>(normalEdgeManager.getSuccNodes(number), getNode(number + 1));
|
||||
}
|
||||
} else {
|
||||
if (normalToExit.get(number)) {
|
||||
return new IteratorPlusOne<IBasicBlock>(normalEdgeManager.getSuccNodes(number), exit());
|
||||
} else {
|
||||
return normalEdgeManager.getSuccNodes(number);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Iterator<IBasicBlock> iterateNormalSuccessorsWithoutExit(int number) {
|
||||
if (fallThru.get(number)) {
|
||||
return new IteratorPlusOne<IBasicBlock>(normalEdgeManager.getSuccNodes(number), getNode(number + 1));
|
||||
} else {
|
||||
return normalEdgeManager.getSuccNodes(number);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param n
|
||||
*/
|
||||
public void addNode(IBasicBlock n) {
|
||||
nodeManager.addNode(n);
|
||||
}
|
||||
|
||||
public int getMaxNumber() {
|
||||
return nodeManager.getMaxNumber();
|
||||
}
|
||||
|
||||
public IBasicBlock getNode(int number) {
|
||||
return nodeManager.getNode(number);
|
||||
}
|
||||
|
||||
public int getNumber(IBasicBlock N) {
|
||||
return nodeManager.getNumber(N);
|
||||
}
|
||||
|
||||
public int getNumberOfNodes() {
|
||||
return nodeManager.getNumberOfNodes();
|
||||
}
|
||||
|
||||
public Iterator<IBasicBlock> iterateNodes() {
|
||||
return nodeManager.iterateNodes();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param src
|
||||
* @param dst
|
||||
*/
|
||||
public void addEdge(IBasicBlock src, IBasicBlock dst) {
|
||||
Assertions.UNREACHABLE("Don't call me .. use addNormalEdge or addExceptionalEdge");
|
||||
}
|
||||
|
||||
public void removeEdge(IBasicBlock src, IBasicBlock dst) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*/
|
||||
public boolean hasEdge(IBasicBlock src, IBasicBlock dst) {
|
||||
int x = getNumber(src);
|
||||
if (dst.equals(exit())) {
|
||||
return normalToExit.get(x) || exceptionalToExit.get(x);
|
||||
} else if (getNumber(dst) == (x + 1) && fallThru.get(x)) {
|
||||
return true;
|
||||
}
|
||||
return normalEdgeManager.hasEdge(src, dst) || exceptionalEdgeManager.hasEdge(src, dst);
|
||||
}
|
||||
|
||||
public boolean hasExceptionalEdge(IBasicBlock src, IBasicBlock dst) {
|
||||
int x = getNumber(src);
|
||||
if (dst.equals(exit())) {
|
||||
return exceptionalToExit.get(x);
|
||||
}
|
||||
return exceptionalEdgeManager.hasEdge(src, dst);
|
||||
}
|
||||
|
||||
public boolean hasNormalEdge(IBasicBlock src, IBasicBlock dst) {
|
||||
int x = getNumber(src);
|
||||
if (dst.equals(exit())) {
|
||||
return normalToExit.get(x);
|
||||
} else if (getNumber(dst) == (x + 1) && fallThru.get(x)) {
|
||||
return true;
|
||||
}
|
||||
return normalEdgeManager.hasEdge(src, dst);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param src
|
||||
* @param dst
|
||||
*/
|
||||
public void addNormalEdge(IBasicBlock src, IBasicBlock dst) {
|
||||
if (dst.equals(exit())) {
|
||||
normalToExit.set(getNumber(src));
|
||||
} else if (getNumber(dst) == (getNumber(src) + 1)) {
|
||||
fallThru.set(getNumber(src));
|
||||
} else {
|
||||
normalEdgeManager.addEdge(src, dst);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param src
|
||||
* @param dst
|
||||
*/
|
||||
public void addExceptionalEdge(IBasicBlock src, IBasicBlock dst) {
|
||||
if (dst.equals(exit())) {
|
||||
exceptionalToExit.set(getNumber(src));
|
||||
} else {
|
||||
exceptionalEdgeManager.addEdge(src, dst);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.util.graph.Graph#removeNode(com.ibm.wala.util.graph.Node)
|
||||
*/
|
||||
public void removeNodeAndEdges(IBasicBlock N) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.util.graph.NodeManager#remove(com.ibm.wala.util.graph.Node)
|
||||
*/
|
||||
public void removeNode(IBasicBlock n) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.util.graph.NodeManager#containsNode(com.ibm.wala.util.graph.Node)
|
||||
*/
|
||||
public boolean containsNode(IBasicBlock N) {
|
||||
return nodeManager.containsNode(N);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuffer s = new StringBuffer("");
|
||||
for (Iterator it = iterateNodes(); it.hasNext();) {
|
||||
IBasicBlock bb = (IBasicBlock) it.next();
|
||||
s.append("BB").append(getNumber(bb)).append("\n");
|
||||
|
||||
Iterator<IBasicBlock> succNodes = getSuccNodes(bb);
|
||||
while (succNodes.hasNext()) {
|
||||
s.append(" -> BB").append(getNumber(succNodes.next())).append("\n");
|
||||
}
|
||||
}
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* record that basic block i is a catch block
|
||||
*
|
||||
* @param i
|
||||
*/
|
||||
protected void setCatchBlock(int i) {
|
||||
catchBlocks.set(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param i
|
||||
* @return true iff block i is a catch block
|
||||
*/
|
||||
public boolean isCatchBlock(int i) {
|
||||
return catchBlocks.get(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the catchBlocks.
|
||||
*
|
||||
* @return BitVector
|
||||
*/
|
||||
public BitVector getCatchBlocks() {
|
||||
return catchBlocks;
|
||||
}
|
||||
|
||||
public IMethod getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.util.graph.EdgeManager#removeEdges(java.lang.Object)
|
||||
*/
|
||||
public void removeAllIncidentEdges(IBasicBlock node) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.cfg.ControlFlowGraph#getExceptionalSuccessors(com.ibm.wala.cfg.IBasicBlock)
|
||||
*/
|
||||
public Collection<IBasicBlock> getExceptionalSuccessors(IBasicBlock b) {
|
||||
return new Iterator2Collection<IBasicBlock>(iterateExceptionalSuccessors(b.getNumber()));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.cfg.ControlFlowGraph#getNormalSuccessors(com.ibm.wala.cfg.IBasicBlock)
|
||||
*/
|
||||
public Collection<IBasicBlock> getNormalSuccessors(IBasicBlock b) {
|
||||
return new Iterator2Collection<IBasicBlock>(iterateNormalSuccessors(b.getNumber()));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.util.graph.NumberedNodeManager#iterateNodes(com.ibm.wala.util.intset.IntSet)
|
||||
*/
|
||||
public Iterator<IBasicBlock> iterateNodes(IntSet s) {
|
||||
return new NumberedNodeIterator<IBasicBlock>(s, this);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*/
|
||||
public void removeIncomingEdges(IBasicBlock node) {
|
||||
// TODO Auto-generated method stub
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*/
|
||||
public void removeOutgoingEdges(IBasicBlock node) {
|
||||
// TODO Auto-generated method stub
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
|
||||
public FixedSizeBitVector getExceptionalToExit() {
|
||||
return exceptionalToExit;
|
||||
}
|
||||
|
||||
public FixedSizeBitVector getNormalToExit() {
|
||||
return normalToExit;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.cfg.ControlFlowGraph#getExceptionalPredecessors(com.ibm.wala.cfg.IBasicBlock)
|
||||
*/
|
||||
public Collection<IBasicBlock> getExceptionalPredecessors(IBasicBlock b) {
|
||||
return new Iterator2Collection<IBasicBlock>(iterateExceptionalPredecessors(b));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.ibm.wala.cfg.ControlFlowGraph#getNormalPredecessors(com.ibm.wala.cfg.IBasicBlock)
|
||||
*/
|
||||
public Collection<IBasicBlock> getNormalPredecessors(IBasicBlock b) {
|
||||
return new Iterator2Collection<IBasicBlock>(iterateNormalPredecessors(b));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*/
|
||||
public IntSet getPredNodeNumbers(IBasicBlock node) {
|
||||
// TODO Auto-generated method stub
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: optimize this. (non-Javadoc)
|
||||
*
|
||||
*/
|
||||
public IntSet getSuccNodeNumbers(IBasicBlock node) {
|
||||
int number = getNumber(node);
|
||||
IntSet s = normalEdgeManager.getSuccNodeNumbers(node);
|
||||
MutableSparseIntSet result = s == null ? new MutableSparseIntSet() : new MutableSparseIntSet(s);
|
||||
s = exceptionalEdgeManager.getSuccNodeNumbers(node);
|
||||
if (s != null) {
|
||||
result.addAll(s);
|
||||
}
|
||||
if (normalToExit.get(number) || exceptionalToExit.get(number)) {
|
||||
result.add(exit.getNumber());
|
||||
}
|
||||
if (fallThru.get(number)) {
|
||||
result.add(number + 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,131 @@
|
||||
/*******************************************************************************
|
||||
* 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.cfg;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.ipa.callgraph.Context;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.ssa.IRFactory;
|
||||
import com.ibm.wala.util.CacheReference;
|
||||
import com.ibm.wala.util.collections.Pair;
|
||||
import com.ibm.wala.util.warnings.WarningSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* A mapping from IMethod -> SoftReference -> ShrikeCFG
|
||||
*
|
||||
* This doesn't work very well ... GCs don't do such a great job with
|
||||
* SoftReferences ... revamp it.
|
||||
*
|
||||
*
|
||||
* @author sfink
|
||||
*/
|
||||
public class CFGCache {
|
||||
|
||||
/**
|
||||
* Help out the garbage collector: periodically "reset" this cache
|
||||
*/
|
||||
final private static int RESET_INTERVAL = 10000;
|
||||
|
||||
/**
|
||||
* A mapping from ShrikeCTMethodWrapper -> SoftReference -> IR
|
||||
*/
|
||||
private HashMap<Object, Object> dictionary = new HashMap<Object, Object>();
|
||||
|
||||
/**
|
||||
* Count accesses between resets.
|
||||
*/
|
||||
private int resetCount = 0;
|
||||
|
||||
/**
|
||||
* The factory that actually creates new IR objects
|
||||
*/
|
||||
private final IRFactory factory;
|
||||
|
||||
public CFGCache(IRFactory factory) {
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param m
|
||||
* a "normal" (bytecode-based) method
|
||||
* @param warnings
|
||||
* an option to track analysis warnings
|
||||
* @return an IR for m, built according to the specified options. null if m is
|
||||
* abstract or native.
|
||||
*/
|
||||
public synchronized ControlFlowGraph findOrCreate(IMethod m, Context C, ClassHierarchy cha, WarningSet warnings) {
|
||||
|
||||
if (m.isAbstract() || m.isNative()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
processResetLogic(m);
|
||||
|
||||
Pair<IMethod,Context> p = new Pair<IMethod,Context>(m, C);
|
||||
Object ref = dictionary.get(p);
|
||||
if (ref == null || CacheReference.get(ref) == null) {
|
||||
ControlFlowGraph cfg = factory.makeCFG(m, C, cha, warnings);
|
||||
ref = CacheReference.make(cfg);
|
||||
dictionary.put(p, ref);
|
||||
return cfg;
|
||||
} else {
|
||||
ControlFlowGraph cfg = (ControlFlowGraph) CacheReference.get(ref);
|
||||
return (cfg == null) ? findOrCreate(m, C, cha, warnings) : cfg;
|
||||
}
|
||||
}
|
||||
|
||||
private void processResetLogic(IMethod m) {
|
||||
resetCount++;
|
||||
if (resetCount == RESET_INTERVAL) {
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The existence of this is unfortunate.
|
||||
*/
|
||||
public void wipe() {
|
||||
dictionary = new HashMap<Object, Object>();
|
||||
}
|
||||
|
||||
/**
|
||||
* clear out null refs
|
||||
*/
|
||||
private void reset() {
|
||||
resetCount = 0;
|
||||
Map<Object, Object> oldDictionary = dictionary;
|
||||
dictionary = new HashMap<Object, Object>();
|
||||
|
||||
for (Iterator it = oldDictionary.entrySet().iterator(); it.hasNext();) {
|
||||
Map.Entry e = (Map.Entry) it.next();
|
||||
Object key = e.getKey();
|
||||
Object val = e.getValue();
|
||||
if (CacheReference.get(val) != null) {
|
||||
dictionary.put(key, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate cached information relating to a method
|
||||
*
|
||||
* @param method
|
||||
*/
|
||||
public void invalidate(IMethod method, Context C) {
|
||||
dictionary.remove(new Pair<IMethod,Context>(method, C));
|
||||
|
||||
}
|
||||
}
|
||||
@ -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.cfg;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.ssa.IR;
|
||||
import com.ibm.wala.ssa.SSACFG;
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.ssa.SSAInvokeInstruction;
|
||||
import com.ibm.wala.ssa.SSAReturnInstruction;
|
||||
import com.ibm.wala.ssa.SSAThrowInstruction;
|
||||
import com.ibm.wala.ssa.SSACFG.ExceptionHandlerBasicBlock;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.Exceptions;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.graph.Graph;
|
||||
import com.ibm.wala.util.graph.impl.SlowSparseNumberedGraph;
|
||||
import com.ibm.wala.util.warnings.WalaException;
|
||||
import com.ibm.wala.util.warnings.WarningSet;
|
||||
|
||||
/**
|
||||
* Utility class to remove edges to exit() from a CFG
|
||||
*
|
||||
* @author Stephen Fink
|
||||
*/
|
||||
public class CFGSanitizer {
|
||||
|
||||
/*
|
||||
*/
|
||||
public static Graph<IBasicBlock> sanitize(IR ir, ClassHierarchy cha) throws WalaException {
|
||||
|
||||
Assertions._assert(ir != null, "IR is null");
|
||||
|
||||
ControlFlowGraph cfg = ir.getControlFlowGraph();
|
||||
Graph<IBasicBlock> G = new SlowSparseNumberedGraph<IBasicBlock>();
|
||||
// add all nodes to the graph
|
||||
for (Iterator<? extends IBasicBlock> it = cfg.iterateNodes(); it.hasNext();) {
|
||||
G.addNode(it.next());
|
||||
}
|
||||
|
||||
// add all edges to the graph, except those that go to exit
|
||||
for (Iterator it = cfg.iterateNodes(); it.hasNext();) {
|
||||
IBasicBlock b = (IBasicBlock) it.next();
|
||||
for (Iterator it2 = cfg.getSuccNodes(b); it2.hasNext();) {
|
||||
IBasicBlock b2 = (IBasicBlock) it2.next();
|
||||
|
||||
if (!b2.isExitBlock()) {
|
||||
G.addEdge(b, b2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now add edges to exit, ignoring undeclared exceptions
|
||||
IBasicBlock exit = cfg.exit();
|
||||
|
||||
for (Iterator it = cfg.getPredNodes(exit); it.hasNext();) {
|
||||
// for each predecessor of exit ...
|
||||
IBasicBlock b = (IBasicBlock) it.next();
|
||||
|
||||
SSAInstruction s = ir.getInstructions()[b.getLastInstructionIndex()];
|
||||
if (s == null) {
|
||||
// TODO: this shouldn't happen?
|
||||
continue;
|
||||
}
|
||||
if (s instanceof SSAReturnInstruction || s instanceof SSAThrowInstruction) {
|
||||
// return or athrow: add edge to exit
|
||||
G.addEdge(b, exit);
|
||||
} else {
|
||||
// compute types of exceptions the pei may throw
|
||||
TypeReference[] exceptions = computeExceptions(cha, s);
|
||||
// remove any exceptions that are caught by catch blocks
|
||||
for (Iterator it2 = cfg.getSuccNodes(b); it2.hasNext();) {
|
||||
IBasicBlock c = (IBasicBlock) it2.next();
|
||||
|
||||
if (c.isCatchBlock()) {
|
||||
SSACFG.ExceptionHandlerBasicBlock cb = (ExceptionHandlerBasicBlock) c;
|
||||
|
||||
for (Iterator it3 = cb.getCaughtExceptionTypes(); it3.hasNext();) {
|
||||
TypeReference ex = (TypeReference) it3.next();
|
||||
IClass exClass = cha.lookupClass(ex);
|
||||
if (exClass == null) {
|
||||
throw new WalaException("failed to find " + ex);
|
||||
}
|
||||
for (int i = 0; i < exceptions.length; i++) {
|
||||
if (exceptions[i] != null) {
|
||||
IClass exi = cha.lookupClass(exceptions[i]);
|
||||
if (exi == null) {
|
||||
throw new WalaException("failed to find " + exceptions[i]);
|
||||
}
|
||||
if (cha.isSubclassOf(exi, exClass)) {
|
||||
exceptions[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// check the remaining uncaught exceptions
|
||||
TypeReference[] declared = ir.getMethod().getDeclaredExceptions();
|
||||
if (declared != null && exceptions != null) {
|
||||
for (int i = 0; i < exceptions.length; i++) {
|
||||
boolean isDeclared = false;
|
||||
if (exceptions[i] != null) {
|
||||
IClass exi = cha.lookupClass(exceptions[i]);
|
||||
if (exi == null) {
|
||||
throw new WalaException("failed to find " + exceptions[i]);
|
||||
}
|
||||
for (int j = 0; j < declared.length; j++) {
|
||||
IClass dc = cha.lookupClass(declared[j]);
|
||||
if (dc == null) {
|
||||
throw new WalaException("failed to find " + declared[j]);
|
||||
}
|
||||
if (cha.isSubclassOf(exi, dc)) {
|
||||
isDeclared = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isDeclared) {
|
||||
// found a declared exceptional edge
|
||||
G.addEdge(b, exit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return G;
|
||||
}
|
||||
|
||||
private static TypeReference[] computeExceptions(ClassHierarchy cha, SSAInstruction s) {
|
||||
Collection c = null;
|
||||
if (s instanceof SSAInvokeInstruction) {
|
||||
SSAInvokeInstruction call = (SSAInvokeInstruction) s;
|
||||
c = Exceptions.inferInvokeExceptions(call.getDeclaredTarget(), cha, new WarningSet());
|
||||
} else {
|
||||
c = s.getExceptionTypes();
|
||||
}
|
||||
if (c == null) {
|
||||
return null;
|
||||
} else {
|
||||
TypeReference[] exceptions = new TypeReference[c.size()];
|
||||
Iterator it = c.iterator();
|
||||
for (int i = 0; i < exceptions.length; i++) {
|
||||
exceptions[i] = (TypeReference) it.next();
|
||||
}
|
||||
return exceptions;
|
||||
}
|
||||
}
|
||||
|
||||
} // CFGSanitizerImpl
|
||||
@ -0,0 +1,102 @@
|
||||
/*******************************************************************************
|
||||
* 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.cfg;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.shrikeBT.IInstruction;
|
||||
import com.ibm.wala.util.graph.NumberedGraph;
|
||||
import com.ibm.wala.util.intset.BitVector;
|
||||
|
||||
/**
|
||||
* An interface that is common to the Shrike and SSA CFG implementations.
|
||||
*
|
||||
* @author cahoon
|
||||
* @author sfink
|
||||
*/
|
||||
public interface ControlFlowGraph extends NumberedGraph<IBasicBlock> {
|
||||
|
||||
/**
|
||||
* Return the entry basic block in the CFG
|
||||
*/
|
||||
public IBasicBlock entry();
|
||||
|
||||
/**
|
||||
* @return the synthetic exit block for the cfg
|
||||
*/
|
||||
public IBasicBlock exit();
|
||||
|
||||
/**
|
||||
* @return the indices of the catch blocks, as a bit vector
|
||||
*/
|
||||
public BitVector getCatchBlocks();
|
||||
|
||||
/**
|
||||
* @param index
|
||||
* an instruction index
|
||||
* @return the basic block which contains this instruction.
|
||||
*/
|
||||
public IBasicBlock getBlockForInstruction(int index);
|
||||
|
||||
/**
|
||||
* @return the instructions of this CFG, as an array.
|
||||
*/
|
||||
IInstruction[] getInstructions();
|
||||
|
||||
/**
|
||||
* @param index
|
||||
* an instruction index
|
||||
* @return the program counter (bytecode index) corresponding to that
|
||||
* instruction
|
||||
*/
|
||||
public int getProgramCounter(int index);
|
||||
|
||||
/**
|
||||
* @return the Method this CFG represents
|
||||
*/
|
||||
public IMethod getMethod();
|
||||
|
||||
/**
|
||||
* The order of blocks returned should be arbitrary but deterministic.
|
||||
*
|
||||
* @param b
|
||||
* @return the basic blocks which may be reached from b via exceptional
|
||||
* control flow
|
||||
*/
|
||||
public Collection<IBasicBlock> getExceptionalSuccessors(IBasicBlock b);
|
||||
|
||||
/**
|
||||
* The order of blocks returned should be arbitrary but deterministic.
|
||||
* @param b
|
||||
* @return the basic blocks which may be reached from b via normal control
|
||||
* flow
|
||||
*/
|
||||
public Collection<IBasicBlock> getNormalSuccessors(IBasicBlock b);
|
||||
|
||||
/**
|
||||
* The order of blocks returned should be arbitrary but deterministic.
|
||||
*
|
||||
* @param b
|
||||
* @return the basic blocks from which b may be reached via exceptional
|
||||
* control flow
|
||||
*/
|
||||
public Collection<IBasicBlock> getExceptionalPredecessors(IBasicBlock b);
|
||||
|
||||
/**
|
||||
* The order of blocks returned should be arbitrary but deterministic.
|
||||
*
|
||||
* @param b
|
||||
* @return the basic blocks from which b may be reached via normal
|
||||
* control flow
|
||||
*/
|
||||
public Collection<IBasicBlock> getNormalPredecessors(IBasicBlock b);
|
||||
}
|
||||
@ -0,0 +1,83 @@
|
||||
/*******************************************************************************
|
||||
* 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.cfg;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.shrikeBT.IInstruction;
|
||||
import com.ibm.wala.util.graph.INodeWithNumber;
|
||||
|
||||
/**
|
||||
* An interface for a basic block in a control flow graph.
|
||||
* @author cahoon
|
||||
* @author Stephen Fink
|
||||
*/
|
||||
public interface IBasicBlock extends INodeWithNumber {
|
||||
|
||||
/**
|
||||
* Get the index of the first instruction in the basic block. The value
|
||||
* is an index into the instruction array that contains all the instructions
|
||||
* for the method.
|
||||
*
|
||||
* If the result is < 0, the block has no instructions
|
||||
*
|
||||
* @return the instruction index for the first instruction in the basic block.
|
||||
*/
|
||||
public int getFirstInstructionIndex();
|
||||
|
||||
/**
|
||||
* Get the index of the last instruction in the basic block. The value
|
||||
* is an index into the instruction array that contains all the instructions
|
||||
* for the method.
|
||||
*
|
||||
* If the result is < 0, the block has no instructions
|
||||
*
|
||||
* @return the instruction index for the last instruction in the basic block
|
||||
*/
|
||||
public int getLastInstructionIndex();
|
||||
|
||||
/**
|
||||
* @return an Iterator of all instructions in this basic block
|
||||
*/
|
||||
public Iterator<? extends IInstruction> iterateAllInstructions();
|
||||
|
||||
/**
|
||||
* Return true if the basic block represents a catch block.
|
||||
* @return true if the basic block represents a catch block.
|
||||
*/
|
||||
public boolean isCatchBlock();
|
||||
|
||||
/**
|
||||
* Return true if the basic block represents the unique exit block.
|
||||
* @return true if the basic block represents the unique exit block.
|
||||
*/
|
||||
public boolean isExitBlock();
|
||||
|
||||
/**
|
||||
* Return true if the basic block represents the unique entry block.
|
||||
* @return true if the basic block represents the unique entry block.
|
||||
*/
|
||||
public boolean isEntryBlock();
|
||||
|
||||
/**
|
||||
* @return governing method for this block
|
||||
*/
|
||||
public IMethod getMethod();
|
||||
|
||||
/**
|
||||
* Each basic block should have a unique number in its cfg
|
||||
* @return the basic block's number
|
||||
*/
|
||||
public int getNumber();
|
||||
|
||||
}
|
||||
@ -0,0 +1,524 @@
|
||||
/*******************************************************************************
|
||||
* 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.cfg;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.ipa.callgraph.Context;
|
||||
import com.ibm.wala.shrikeBT.IInstruction;
|
||||
import com.ibm.wala.ssa.SSAArrayLengthInstruction;
|
||||
import com.ibm.wala.ssa.SSAArrayLoadInstruction;
|
||||
import com.ibm.wala.ssa.SSAArrayStoreInstruction;
|
||||
import com.ibm.wala.ssa.SSACheckCastInstruction;
|
||||
import com.ibm.wala.ssa.SSAConditionalBranchInstruction;
|
||||
import com.ibm.wala.ssa.SSAGetInstruction;
|
||||
import com.ibm.wala.ssa.SSAGotoInstruction;
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.ssa.SSAInvokeInstruction;
|
||||
import com.ibm.wala.ssa.SSAMonitorInstruction;
|
||||
import com.ibm.wala.ssa.SSANewInstruction;
|
||||
import com.ibm.wala.ssa.SSAPutInstruction;
|
||||
import com.ibm.wala.ssa.SSAReturnInstruction;
|
||||
import com.ibm.wala.ssa.SSASwitchInstruction;
|
||||
import com.ibm.wala.ssa.SSAThrowInstruction;
|
||||
import com.ibm.wala.util.collections.ArrayIterator;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.debug.Trace;
|
||||
import com.ibm.wala.util.graph.GraphIntegrity;
|
||||
import com.ibm.wala.util.graph.GraphIntegrity.UnsoundGraphException;
|
||||
import com.ibm.wala.util.graph.impl.NodeWithNumber;
|
||||
|
||||
/**
|
||||
* A ControlFlowGraph computed from a set of SSA instructions
|
||||
*
|
||||
* This is a funny CFG ... we assume that there are always fallthru edges, even
|
||||
* from throws and returns.
|
||||
*/
|
||||
public class InducedCFG extends AbstractCFG {
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
/**
|
||||
* A partial map from Instruction -> BasicBlock
|
||||
*/
|
||||
private final BasicBlock[] i2block;
|
||||
|
||||
private final Context context;
|
||||
|
||||
private final IInstruction[] instructions;
|
||||
|
||||
/**
|
||||
* TODO: we do not yet support induced CFGS with exception handlers.
|
||||
*
|
||||
* @param instructions
|
||||
*/
|
||||
public InducedCFG(SSAInstruction[] instructions, IMethod method, Context context) {
|
||||
super(method);
|
||||
this.context = context;
|
||||
this.instructions = instructions;
|
||||
if (DEBUG) {
|
||||
Trace.println("compute InducedCFG: " + method);
|
||||
}
|
||||
i2block = new BasicBlock[instructions.length];
|
||||
if (instructions.length == 0) {
|
||||
makeEmptyBlocks();
|
||||
} else {
|
||||
makeBasicBlocks();
|
||||
}
|
||||
init();
|
||||
computeEdges();
|
||||
|
||||
if (DEBUG) {
|
||||
try {
|
||||
GraphIntegrity.check(this);
|
||||
} catch (UnsoundGraphException e) {
|
||||
e.printStackTrace();
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return context.hashCode() ^ getMethod().hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return (o instanceof InducedCFG) &&
|
||||
getMethod().equals(((InducedCFG)o).getMethod()) &&
|
||||
context.equals(((InducedCFG)o).context);
|
||||
}
|
||||
|
||||
public IInstruction[] getInstructions() {
|
||||
return instructions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute outgoing edges in the control flow graph.
|
||||
*/
|
||||
private void computeEdges() {
|
||||
for (Iterator it = iterateNodes(); it.hasNext();) {
|
||||
BasicBlock b = (BasicBlock) it.next();
|
||||
if (b.equals(exit()))
|
||||
continue;
|
||||
b.computeOutgoingEdges();
|
||||