diff --git a/.classpath b/.classpath index ea29fcf2197..4ed3d90cc47 100644 --- a/.classpath +++ b/.classpath @@ -58,7 +58,7 @@ - + diff --git a/.watchmanconfig b/.watchmanconfig index 3e6cbca658a..46b52c84e73 100644 --- a/.watchmanconfig +++ b/.watchmanconfig @@ -16,6 +16,6 @@ "test/com/facebook/buck/test/cache/testdata", "test/com/facebook/buck/test/labels/testdata", "test/com/facebook/buck/test/result/groups/testdata", - "third-party/java/dx-from-kitkat" + "third-party/java/dx" ] } diff --git a/buck.iml b/buck.iml index 8638394aa08..2683fce6232 100644 --- a/buck.iml +++ b/buck.iml @@ -10,7 +10,7 @@ - + @@ -48,4 +48,4 @@ - \ No newline at end of file + diff --git a/build.xml b/build.xml index 8c218be0de2..bd7786cfc49 100644 --- a/build.xml +++ b/build.xml @@ -30,7 +30,7 @@ - + diff --git a/programs/BUCK b/programs/BUCK index 46b09e24f1b..b619b1e8311 100644 --- a/programs/BUCK +++ b/programs/BUCK @@ -41,7 +41,7 @@ BUCK_CORE_RESOURCES = { 'bootstrapper_jar': '//src/com/facebook/buck/cli/bootstrapper:bootstrapper', 'buck_package_info': ':gen_buck_package_info', 'buck_server': '//src/com/facebook/buck/cli:main-fixed', - 'dx': '//third-party/java/dx-from-kitkat:etc_dx', + 'dx': '//third-party/java/dx:etc_dx', 'jacoco_agent_jar': '//third-party/java/jacoco:agent', 'logging_config_file': '//config:logging.properties', 'native_exopackage_fake_path': '//assets/android:native-exopackage-fakes.apk', diff --git a/programs/buck_repo.py b/programs/buck_repo.py index 7af757c42da..35d97578573 100644 --- a/programs/buck_repo.py +++ b/programs/buck_repo.py @@ -64,7 +64,7 @@ "android_agent_path": "assets/android/agent.apk", "buck_client": "build/ng", "buck_server": "bin/buck", - "dx": "third-party/java/dx-from-kitkat/etc/dx", + "dx": "third-party/java/dx/etc/dx", "jacoco_agent_jar": "third-party/java/jacoco/jacocoagent.jar", "logging_config_file": "config/logging.properties", "native_exopackage_fake_path": "assets/android/native-exopackage-fakes.apk", diff --git a/src/com/facebook/buck/android/BUCK b/src/com/facebook/buck/android/BUCK index d4c0434ec18..da62b003c32 100644 --- a/src/com/facebook/buck/android/BUCK +++ b/src/com/facebook/buck/android/BUCK @@ -248,7 +248,7 @@ java_immutables_library( '//src/com/facebook/buck/zip:stream', '//third-party/java/aosp:aosp', '//third-party/java/asm:asm', - '//third-party/java/dx-from-kitkat:dx', + '//third-party/java/dx:dx', '//third-party/java/guava:guava', '//third-party/java/jackson:jackson-core', '//third-party/java/jackson:jackson-databind', diff --git a/third-party/java/dx-do_not_use/BUCK b/third-party/java/dx-do_not_use/BUCK deleted file mode 100644 index e718b7b31dd..00000000000 --- a/third-party/java/dx-do_not_use/BUCK +++ /dev/null @@ -1,16 +0,0 @@ -java_library( - name = 'dx-do_not_use', - srcs = glob(['src/**/*.java']), - deps = [ - '//third-party/java/guava:guava', - ], - visibility = ['PUBLIC'], -) - -export_file( - name = 'etc_dx', - src = 'etc/dx', - visibility = [ - 'PUBLIC', - ], -) diff --git a/third-party/java/dx-from-kitkat/.classpath b/third-party/java/dx-from-kitkat/.classpath deleted file mode 100644 index 5b6d9c718c2..00000000000 --- a/third-party/java/dx-from-kitkat/.classpath +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/third-party/java/dx-from-kitkat/.project b/third-party/java/dx-from-kitkat/.project deleted file mode 100644 index bcae232c97d..00000000000 --- a/third-party/java/dx-from-kitkat/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - dx - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/third-party/java/dx-from-kitkat/Android.mk b/third-party/java/dx-from-kitkat/Android.mk deleted file mode 100644 index 37568d7bd08..00000000000 --- a/third-party/java/dx-from-kitkat/Android.mk +++ /dev/null @@ -1,152 +0,0 @@ -# Copyright 2006 The Android Open Source Project -# -LOCAL_PATH := $(call my-dir) - -# We use copy-file-to-new-target so that the installed -# script files' timestamps are at least as new as the -# .jar files they wrap. - -# This tool is prebuilt if we're doing an app-only build. -ifeq ($(TARGET_BUILD_APPS),) - -# the dx script -# ============================================================ -include $(CLEAR_VARS) -LOCAL_IS_HOST_MODULE := true -LOCAL_MODULE_CLASS := EXECUTABLES -LOCAL_MODULE_TAGS := optional -LOCAL_MODULE := dx - -include $(BUILD_SYSTEM)/base_rules.mk - -$(LOCAL_BUILT_MODULE): $(HOST_OUT_JAVA_LIBRARIES)/dx$(COMMON_JAVA_PACKAGE_SUFFIX) -$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/etc/dx | $(ACP) - @echo "Copy: $(PRIVATE_MODULE) ($@)" - $(copy-file-to-new-target) - $(hide) chmod 755 $@ - -INTERNAL_DALVIK_MODULES += $(LOCAL_INSTALLED_MODULE) - -# the mainDexClasses rules -# ============================================================ -include $(CLEAR_VARS) -LOCAL_IS_HOST_MODULE := true -LOCAL_MODULE_CLASS := EXECUTABLES -LOCAL_MODULE_TAGS := optional -LOCAL_MODULE := mainDexClasses.rules - -include $(BUILD_SYSTEM)/base_rules.mk - -$(LOCAL_BUILT_MODULE): $(HOST_OUT_JAVA_LIBRARIES)/dx$(COMMON_JAVA_PACKAGE_SUFFIX) -$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/etc/mainDexClasses.rules | $(ACP) - @echo "Copy: $(PRIVATE_MODULE) ($@)" - $(copy-file-to-new-target) - -INTERNAL_DALVIK_MODULES += $(LOCAL_INSTALLED_MODULE) - -installed_mainDexClasses.rules := $(LOCAL_INSTALLED_MODULE) - -# the shrinkedAndroid jar is a library used by the mainDexClasses script -# ============================================================ -include $(CLEAR_VARS) -LOCAL_IS_HOST_MODULE := true -LOCAL_MODULE_CLASS := JAVA_LIBRARIES -LOCAL_MODULE_TAGS := optional -LOCAL_MODULE := shrinkedAndroid -LOCAL_BUILT_MODULE_STEM := shrinkedAndroid.jar -LOCAL_MODULE_SUFFIX := $(COMMON_JAVA_PACKAGE_SUFFIX) - -include $(BUILD_SYSTEM)/base_rules.mk - -$(LOCAL_BUILT_MODULE): PRIVATE_PROGUARD_FLAGS:= \ - -include $(addprefix $(LOCAL_PATH)/, shrinkedAndroid.proguard.flags) -$(LOCAL_BUILT_MODULE): $(call java-lib-files,android_stubs_current) | $(PROGUARD) - @echo Proguard: $@ - $(hide) $(PROGUARD) -injars "$<(**/*.class)" -outjars $@ $(PRIVATE_PROGUARD_FLAGS) - -INTERNAL_DALVIK_MODULES += $(LOCAL_INSTALLED_MODULE) - -installed_shrinkedAndroid := $(LOCAL_INSTALLED_MODULE) - -# the mainDexClasses script -# ============================================================ -include $(CLEAR_VARS) -LOCAL_IS_HOST_MODULE := true -LOCAL_MODULE_CLASS := EXECUTABLES -LOCAL_MODULE_TAGS := optional -LOCAL_MODULE := mainDexClasses - -include $(BUILD_SYSTEM)/base_rules.mk - -$(LOCAL_BUILT_MODULE): $(HOST_OUT_JAVA_LIBRARIES)/dx$(COMMON_JAVA_PACKAGE_SUFFIX) -$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/etc/mainDexClasses | $(ACP) - @echo "Copy: $(PRIVATE_MODULE) ($@)" - $(copy-file-to-new-target) - $(hide) chmod 755 $@ - -$(LOCAL_INSTALLED_MODULE): | $(installed_shrinkedAndroid) $(installed_mainDexClasses.rules) -INTERNAL_DALVIK_MODULES += $(LOCAL_INSTALLED_MODULE) - -endif # TARGET_BUILD_APPS - -# the dexmerger script -# ============================================================ -include $(CLEAR_VARS) -LOCAL_IS_HOST_MODULE := true -LOCAL_MODULE_CLASS := EXECUTABLES -LOCAL_MODULE_TAGS := optional -LOCAL_MODULE := dexmerger - -include $(BUILD_SYSTEM)/base_rules.mk - -$(LOCAL_BUILT_MODULE): $(HOST_OUT_JAVA_LIBRARIES)/dx$(COMMON_JAVA_PACKAGE_SUFFIX) -$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/etc/dexmerger | $(ACP) - @echo "Copy: $(PRIVATE_MODULE) ($@)" - $(copy-file-to-new-target) - $(hide) chmod 755 $@ - -INTERNAL_DALVIK_MODULES += $(LOCAL_INSTALLED_MODULE) - -# the jasmin script -# ============================================================ -include $(CLEAR_VARS) -LOCAL_IS_HOST_MODULE := true -LOCAL_MODULE_CLASS := EXECUTABLES -LOCAL_MODULE_TAGS := optional -LOCAL_MODULE := jasmin - -include $(BUILD_SYSTEM)/base_rules.mk - -$(LOCAL_BUILT_MODULE): $(HOST_OUT_JAVA_LIBRARIES)/jasmin.jar -$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/etc/jasmin | $(ACP) - @echo "Copy: $(PRIVATE_MODULE) ($@)" - $(copy-file-to-new-target) - $(hide) chmod 755 $@ - -INTERNAL_DALVIK_MODULES += $(LOCAL_INSTALLED_MODULE) - -# the jasmin lib -# ============================================================ -include $(CLEAR_VARS) -LOCAL_IS_HOST_MODULE := true -LOCAL_MODULE_CLASS := JAVA_LIBRARIES -LOCAL_MODULE_TAGS := optional -LOCAL_MODULE := jasmin.jar - -include $(BUILD_SYSTEM)/base_rules.mk - -$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/etc/jasmin.jar | $(ACP) - @echo "Copy: $(PRIVATE_MODULE) ($@)" - $(copy-file-to-target) - $(hide) chmod 644 $@ - -INTERNAL_DALVIK_MODULES += $(LOCAL_INSTALLED_MODULE) - -# the other stuff -# ============================================================ -subdirs := $(addprefix $(LOCAL_PATH)/,$(addsuffix /Android.mk, \ - junit-tests \ - src \ - )) - -include $(subdirs) diff --git a/third-party/java/dx-from-kitkat/NOTICE b/third-party/java/dx-from-kitkat/NOTICE deleted file mode 100644 index c5b1efa7aac..00000000000 --- a/third-party/java/dx-from-kitkat/NOTICE +++ /dev/null @@ -1,190 +0,0 @@ - - Copyright (c) 2005-2008, The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - diff --git a/third-party/java/dx-from-kitkat/README.txt b/third-party/java/dx-from-kitkat/README.txt deleted file mode 100644 index 6a20c826e28..00000000000 --- a/third-party/java/dx-from-kitkat/README.txt +++ /dev/null @@ -1,3 +0,0 @@ -Home of Dalvik eXchange, the thing that takes in class files and -reformulates them for consumption in the VM. It also does a few other -things; use "dx --help" to see a modicum of self-documentation. diff --git a/third-party/java/dx-from-kitkat/etc/dexmerger b/third-party/java/dx-from-kitkat/etc/dexmerger deleted file mode 100644 index 58fd9ab9d72..00000000000 --- a/third-party/java/dx-from-kitkat/etc/dexmerger +++ /dev/null @@ -1,89 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2012 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Set up prog to be the path of this script, including following symlinks, -# and set up progdir to be the fully-qualified pathname of its directory. -prog="$0" -while [ -h "${prog}" ]; do - newProg=`/bin/ls -ld "${prog}"` - newProg=`expr "${newProg}" : ".* -> \(.*\)$"` - if expr "x${newProg}" : 'x/' >/dev/null; then - prog="${newProg}" - else - progdir=`dirname "${prog}"` - prog="${progdir}/${newProg}" - fi -done -oldwd=`pwd` -progdir=`dirname "${prog}"` -cd "${progdir}" -progdir=`pwd` -prog="${progdir}"/`basename "${prog}"` -cd "${oldwd}" - -jarfile=dx.jar -libdir="$progdir" - -if [ ! -r "$libdir/$jarfile" ]; then - # set dx.jar location for the SDK case - libdir=`dirname "$progdir"`/platform-tools/lib -fi - - -if [ ! -r "$libdir/$jarfile" ]; then - # set dx.jar location for the Android tree case - libdir=`dirname "$progdir"`/framework -fi - -if [ ! -r "$libdir/$jarfile" ]; then - echo `basename "$prog"`": can't find $jarfile" - exit 1 -fi - -# By default, give dexmerger a max heap size of 1 gig. This can be overridden -# by using a "-J" option (see below). -defaultMx="-Xmx1024M" - -# The following will extract any initial parameters of the form -# "-J" from the command line and pass them to the Java -# invocation (instead of to dexmerger). This makes it possible for you to add -# a command-line parameter such as "-JXmx256M" in your scripts, for -# example. "java" (with no args) and "java -X" give a summary of -# available options. - -javaOpts="" - -while expr "x$1" : 'x-J' >/dev/null; do - opt=`expr "x$1" : 'x-J\(.*\)'` - javaOpts="${javaOpts} -${opt}" - if expr "x${opt}" : "xXmx[0-9]" >/dev/null; then - defaultMx="no" - fi - shift -done - -if [ "${defaultMx}" != "no" ]; then - javaOpts="${javaOpts} ${defaultMx}" -fi - -if [ "$OSTYPE" = "cygwin" ]; then - # For Cygwin, convert the jarfile path into native Windows style. - jarpath=`cygpath -w "$libdir/$jarfile"` -else - jarpath="$libdir/$jarfile" -fi - -exec java $javaOpts -cp "$jarpath" com.android.dx.merge.DexMerger "$@" diff --git a/third-party/java/dx-from-kitkat/etc/dx b/third-party/java/dx-from-kitkat/etc/dx deleted file mode 100755 index 43ffca824ef..00000000000 --- a/third-party/java/dx-from-kitkat/etc/dx +++ /dev/null @@ -1,89 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2007 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Set up prog to be the path of this script, including following symlinks, -# and set up progdir to be the fully-qualified pathname of its directory. -prog="$0" -while [ -h "${prog}" ]; do - newProg=`/bin/ls -ld "${prog}"` - newProg=`expr "${newProg}" : ".* -> \(.*\)$"` - if expr "x${newProg}" : 'x/' >/dev/null; then - prog="${newProg}" - else - progdir=`dirname "${prog}"` - prog="${progdir}/${newProg}" - fi -done -oldwd=`pwd` -progdir=`dirname "${prog}"` -cd "${progdir}" -progdir=`pwd` -prog="${progdir}"/`basename "${prog}"` -cd "${oldwd}" - -jarfile=dx.jar -libdir="${progdir}/../../../../build/" - -if [ ! -r "$libdir/$jarfile" ]; then - # set dx.jar location for the SDK case - libdir="$libdir/lib" -fi - - -if [ ! -r "$libdir/$jarfile" ]; then - # set dx.jar location for the Android tree case - libdir=`dirname "$progdir"`/framework -fi - -if [ ! -r "$libdir/$jarfile" ]; then - echo `basename "$prog"`": can't find $jarfile" - exit 1 -fi - -# By default, give dx a max heap size of 1 gig. This can be overridden -# by using a "-J" option (see below). -defaultMx="-Xmx1024M" - -# The following will extract any initial parameters of the form -# "-J" from the command line and pass them to the Java -# invocation (instead of to dx). This makes it possible for you to add -# a command-line parameter such as "-JXmx256M" in your scripts, for -# example. "java" (with no args) and "java -X" give a summary of -# available options. - -javaOpts="" - -while expr "x$1" : 'x-J' >/dev/null; do - opt=`expr "x$1" : 'x-J\(.*\)'` - javaOpts="${javaOpts} -${opt}" - if expr "x${opt}" : "xXmx[0-9]" >/dev/null; then - defaultMx="no" - fi - shift -done - -if [ "${defaultMx}" != "no" ]; then - javaOpts="${javaOpts} ${defaultMx}" -fi - -if [ "$OSTYPE" = "cygwin" ]; then - # For Cygwin, convert the jarfile path into native Windows style. - jarpath=`cygpath -w "$libdir/$jarfile"` -else - jarpath="$libdir/$jarfile" -fi - -exec java $javaOpts -jar "$jarpath" "$@" diff --git a/third-party/java/dx-from-kitkat/etc/dx.bat b/third-party/java/dx-from-kitkat/etc/dx.bat deleted file mode 100755 index e2d678b8395..00000000000 --- a/third-party/java/dx-from-kitkat/etc/dx.bat +++ /dev/null @@ -1,88 +0,0 @@ -@echo off -REM Copyright (C) 2007 The Android Open Source Project -REM -REM Licensed under the Apache License, Version 2.0 (the "License"); -REM you may not use this file except in compliance with the License. -REM You may obtain a copy of the License at -REM -REM http://www.apache.org/licenses/LICENSE-2.0 -REM -REM Unless required by applicable law or agreed to in writing, software -REM distributed under the License is distributed on an "AS IS" BASIS, -REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -REM See the License for the specific language governing permissions and -REM limitations under the License. - -REM don't modify the caller's environment -setlocal - -REM Locate dx.jar in the directory where dx.bat was found and start it. - -REM Set up prog to be the path of this script, including following symlinks, -REM and set up progdir to be the fully-qualified pathname of its directory. -set prog=%~f0 - -rem Check we have a valid Java.exe in the path. -set java_exe= -if exist "%~dp0..\tools\lib\find_java.bat" call "%~dp0..\tools\lib\find_java.bat" -if exist "%~dp0..\..\tools\lib\find_java.bat" call "%~dp0..\..\tools\lib\find_java.bat" -if not defined java_exe goto :EOF - -set jarfile=dx.jar -set "frameworkdir=%~dp0" -rem frameworkdir must not end with a dir sep. -set "frameworkdir=%frameworkdir:~0,-1%" - -if exist "%frameworkdir%\%jarfile%" goto JarFileOk - set "frameworkdir=%~dp0lib" - -if exist "%frameworkdir%\%jarfile%" goto JarFileOk - set "frameworkdir=%~dp0..\framework" - -:JarFileOk - -set "jarpath=%frameworkdir%\%jarfile%" - -set javaOpts= -set args= - -REM By default, give dx a max heap size of 1 gig and a stack size of 1meg. -rem This can be overridden by using "-JXmx..." and "-JXss..." options below. -set defaultXmx=-Xmx1024M -set defaultXss=-Xss1m - -REM Capture all arguments that are not -J options. -REM Note that when reading the input arguments with %1, the cmd.exe -REM automagically converts --name=value arguments into 2 arguments "--name" -REM followed by "value". Dx has been changed to know how to deal with that. -set params= - -:firstArg -if [%1]==[] goto endArgs -set a=%~1 - - if [%defaultXmx%]==[] goto notXmx - if %a:~0,5% NEQ -JXmx goto notXmx - set defaultXmx= - :notXmx - - if [%defaultXss%]==[] goto notXss - if %a:~0,5% NEQ -JXss goto notXss - set defaultXss= - :notXss - - if %a:~0,2% NEQ -J goto notJ - set javaOpts=%javaOpts% -%a:~2% - shift /1 - goto firstArg - - :notJ - set params=%params% %1 - shift /1 - goto firstArg - -:endArgs - -set javaOpts=%javaOpts% %defaultXmx% %defaultXss% -call "%java_exe%" %javaOpts% -Djava.ext.dirs="%frameworkdir%" -jar "%jarpath%" %params% - diff --git a/third-party/java/dx-from-kitkat/etc/jasmin b/third-party/java/dx-from-kitkat/etc/jasmin deleted file mode 100755 index b514553efb7..00000000000 --- a/third-party/java/dx-from-kitkat/etc/jasmin +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2007 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Set up prog to be the path of this script, including following symlinks, -# and set up progdir to be the fully-qualified pathname of its directory. -prog="$0" -while [ -h "${prog}" ]; do - newProg=`/bin/ls -ld "${prog}"` - newProg=`expr "${newProg}" : ".* -> \(.*\)$"` - if expr "x${newProg}" : 'x/' >/dev/null; then - prog="${newProg}" - else - progdir=`dirname "${prog}"` - prog="${progdir}/${newProg}" - fi -done -oldwd=`pwd` -progdir=`dirname "${prog}"` -cd "${progdir}" -progdir=`pwd` -prog="${progdir}"/`basename "${prog}"` -cd "${oldwd}" - -libdir=`dirname $progdir`/etc - -exec java -jar $libdir/jasmin.jar "$@" diff --git a/third-party/java/dx-from-kitkat/etc/jasmin.jar b/third-party/java/dx-from-kitkat/etc/jasmin.jar deleted file mode 100644 index 87db0d0346a..00000000000 Binary files a/third-party/java/dx-from-kitkat/etc/jasmin.jar and /dev/null differ diff --git a/third-party/java/dx-from-kitkat/etc/mainDexClasses b/third-party/java/dx-from-kitkat/etc/mainDexClasses deleted file mode 100644 index 034d47eaa88..00000000000 --- a/third-party/java/dx-from-kitkat/etc/mainDexClasses +++ /dev/null @@ -1,158 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2013 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -function makeTempJar () -{ - local tempDir=/tmp - if [ ! -e "${tempDir}" ]; then - tempDir=. - fi - local tempfile="${tempDir}/mainDexClasses-$$.tmp.jar" - if [ -e "${tempfile}" ]; then - echo "Failed to create temporary file" >2 - exit 6 - fi - echo "${tempfile}" -} - -function cleanTmp () -{ - if [ -e "${tmpOut}" ] ; then - rm "${tmpOut}" - fi -} - - -# Set up prog to be the path of this script, including following symlinks, -# and set up progdir to be the fully-qualified pathname of its directory. -prog="$0" - -while [ -h "${prog}" ]; do - newProg=`/bin/ls -ld "${prog}"` - newProg=`expr "${newProg}" : ".* -> \(.*\)$"` - if expr "x${newProg}" : 'x/' >/dev/null; then - prog="${newProg}" - else - progdir=`dirname "${prog}"` - prog="${progdir}/${newProg}" - fi -done -oldwd=`pwd` -progdir=`dirname "${prog}"` -cd "${progdir}" -progdir=`pwd` -prog="${progdir}"/`basename "${prog}"` -cd "${oldwd}" - -baserules="${progdir}"/mainDexClasses.rules -if [ ! -r ${baserules} ]; then - echo `basename "$prog"`": can't find mainDexClasses.rules" 1>&2 - exit 1 -fi - -jarfile=dx.jar -libdir="$progdir" - -if [ ! -r "$libdir/$jarfile" ]; then - # set dx.jar location for the SDK case - libdir="$libdir/lib" -fi - - -if [ ! -r "$libdir/$jarfile" ]; then - # set dx.jar location for the Android tree case - libdir=`dirname "$progdir"`/framework -fi - -if [ ! -r "$libdir/$jarfile" ]; then - echo `basename "$prog"`": can't find $jarfile" 1>&2 - exit 1 -fi - -proguardExec="proguard.sh" -proguard=${PROGUARD_HOME}/bin/${proguardExec} - -if [ ! -r "${proguard}" ]; then - # set proguard location for the SDK case - proguardBaseDir=`dirname "$progdir"` - # "${progdir}"/../.. - proguardBaseDir=`dirname "$proguardBaseDir"` - proguard="${proguardBaseDir}"/tools/proguard/bin/${proguardExec} -fi - -if [ ! -r "${proguard}" ]; then - # set proguard location for the Android tree case - proguardBaseDir=`dirname "$proguardBaseDir"` - # "${progdir}"/../../../.. - proguardBaseDir=`dirname "$proguardBaseDir"` - proguard="${proguardBaseDir}"/external/proguard/bin/${proguardExec} -fi - -if [ ! -r "${proguard}" ]; then - proguard="`which proguard`" -fi - -if [ -z "${proguard}" -o ! -r "${proguard}" ]; then - proguard="`which ${proguardExec}`" -fi - -if [ -z "${proguard}" -o ! -r "${proguard}" ]; then - echo `basename "$prog"`": can't find ${proguardExec}" 1>&2 - exit 1 -fi - -shrinkedAndroidJar="${SHRINKED_ANDROID_JAR}" -if [ -z "${shrinkedAndroidJar}" ]; then - shrinkedAndroidJar=shrinkedAndroid.jar -fi - -if [ ! -r "${shrinkedAndroidJar}" ]; then - shrinkedAndroidJar=${libdir}/${shrinkedAndroidJar} -fi - -if [ ! -r "${shrinkedAndroidJar}" ]; then - echo `basename "$prog"`": can't find shrinkedAndroid.jar" 1>&2 - exit 1 -fi - -if [ "$OSTYPE" = "cygwin" ]; then - # For Cygwin, convert the jarfile path into native Windows style. - jarpath=`cygpath -w "$libdir/$jarfile"` - proguard=`cygpath -w "${proguard}"` - shrinkedAndroidJar=`cygpath -w "${shrinkedAndroidJar}"` -else - jarpath="$libdir/$jarfile" -fi - -if expr "x$1" : 'x--output' >/dev/null; then - exec 1>$2 - shift 2 -fi - -if [ $# -ne 1 ]; then - echo "Usage : $0 [--output ] " 1>&2 - exit 2 -fi - -tmpOut=`makeTempJar` - -trap cleanTmp 0 - -${proguard} -injars ${@} -dontwarn -forceprocessing -outjars ${tmpOut} \ - -libraryjars "${shrinkedAndroidJar}" -dontoptimize -dontobfuscate -dontpreverify \ - -include "${baserules}" 1>/dev/null || exit 10 - -java -cp "$jarpath" com.android.multidex.ClassReferenceListBuilder "${tmpOut}" ${@} || exit 11 diff --git a/third-party/java/dx-from-kitkat/etc/mainDexClasses.bat b/third-party/java/dx-from-kitkat/etc/mainDexClasses.bat deleted file mode 100755 index 5ba2eaf1946..00000000000 --- a/third-party/java/dx-from-kitkat/etc/mainDexClasses.bat +++ /dev/null @@ -1,110 +0,0 @@ -@echo off -REM Copyright (C) 2013 The Android Open Source Project -REM -REM Licensed under the Apache License, Version 2.0 (the "License"); -REM you may not use this file except in compliance with the License. -REM You may obtain a copy of the License at -REM -REM http://www.apache.org/licenses/LICENSE-2.0 -REM -REM Unless required by applicable law or agreed to in writing, software -REM distributed under the License is distributed on an "AS IS" BASIS, -REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -REM See the License for the specific language governing permissions and -REM limitations under the License. - -REM don't modify the caller's environment -setlocal - -rem Check we have a valid Java.exe in the path. -set java_exe= -if exist "%~dp0..\tools\lib\find_java.bat" call "%~dp0..\tools\lib\find_java.bat" -if exist "%~dp0..\..\tools\lib\find_java.bat" call "%~dp0..\..\tools\lib\find_java.bat" -if not defined java_exe goto :EOF - -set baserules="%~dp0\mainDexClasses.rules" - -REM Locate dx.jar in the directory where dx.bat was found. -set jarfile=dx.jar -set "frameworkdir=%~dp0" -rem frameworkdir must not end with a dir sep. -set "frameworkdir=%frameworkdir:~0,-1%" -if exist "%frameworkdir%\%jarfile%" goto JarFileOk - set "frameworkdir=%~dp0lib" - -if exist "%frameworkdir%\%jarfile%" goto JarFileOk - set "frameworkdir=%~dp0..\framework" -:JarFileOk - -set "jarpath=%frameworkdir%\%jarfile%" - -set "shrinkedAndroidJar=%SHRINKED_ANDROID_JAR% -if exist "%shrinkedAndroidJar%" goto shrinkedAndroidOk - set "shrinkedAndroidJar=shrinkedAndroid.jar" - -if exist "%shrinkedAndroidJar%" goto shrinkedAndroidOk - set "shrinkedAndroidJar=%frameworkdir%\%shrinkedAndroidJar%" - -:shrinkedAndroidOk -set "proguardExec=proguard.bat" -set "proguard=%PROGUARD_HOME%\bin\%proguardExec%" - -if exist "%proguard%" goto proguardOk -REM set proguard location for the SDK case - set "PROGUARD_HOME=%~dp0\..\..\tools\proguard" - set "proguard=%PROGUARD_HOME%\bin\%proguardExec%" - -if exist "%proguard%" goto proguardOk -REM set proguard location for the Android tree case - set "PROGUARD_HOME=%~dp0\..\..\..\..\external\proguard" - set "proguard=%PROGUARD_HOME%\bin\%proguardExec%" - -:proguardOk -REM Capture all arguments. -REM Note that when reading the input arguments with %1, the cmd.exe -REM automagically converts --name=value arguments into 2 arguments "--name" -REM followed by "value". Dx has been changed to know how to deal with that. -set params= - -set output= - -:firstArg -if [%1]==[] goto endArgs - - if %1 NEQ --output goto notOut - set "output=%2" - shift - shift - goto firstArg - -:notOut - if defined params goto usage - set params=%1 - shift - goto firstArg - -:endArgs -if defined params ( goto makeTmpJar ) else ( goto usage ) - -:makeTmpJar -set "tmpJar=%TMP%\mainDexClasses-%RANDOM%.tmp.jar" -if exist "%tmpJar%" goto makeTmpJar -echo "" > "%tmpJar%" -set "exitStatus=0" - - -call "%proguard%" -injars %params% -dontwarn -forceprocessing -outjars "%tmpJar%" -libraryjars "%shrinkedAndroidJar%" -dontoptimize -dontobfuscate -dontpreverify -include "%baserules%" 1>nul - -if DEFINED output goto redirect -call "%java_exe%" -Djava.ext.dirs="%frameworkdir%" com.android.multidex.ClassReferenceListBuilder "%tmpJar%" "%params%" -goto afterClassReferenceListBuilder -:redirect -call "%java_exe%" -Djava.ext.dirs="%frameworkdir%" com.android.multidex.ClassReferenceListBuilder "%tmpJar%" "%params%" 1>"%output%" -:afterClassReferenceListBuilder - -del %tmpJar% -exit /b - -:usage -echo "Usage : %0 [--output ] " -exit /b 1 diff --git a/third-party/java/dx-from-kitkat/etc/mainDexClasses.rules b/third-party/java/dx-from-kitkat/etc/mainDexClasses.rules deleted file mode 100644 index f1bbbf868aa..00000000000 --- a/third-party/java/dx-from-kitkat/etc/mainDexClasses.rules +++ /dev/null @@ -1,24 +0,0 @@ - -keep public class * extends android.app.Instrumentation { - (); - } - -keep public class * extends android.app.Application { - (); - } - -keep public class * extends android.app.Activity { - (); - } - -keep public class * extends android.app.Service { - (); - } - -keep public class * extends android.content.ContentProvider { - (); - } - -keep public class * extends android.content.BroadcastReceiver { - (); - } - -keep public class * extends android.app.backup.BackupAgent { - (); - } - -keep class android.support.multidex.** { - *; - } \ No newline at end of file diff --git a/third-party/java/dx-from-kitkat/etc/manifest.txt b/third-party/java/dx-from-kitkat/etc/manifest.txt deleted file mode 100644 index 46bbe63a18b..00000000000 --- a/third-party/java/dx-from-kitkat/etc/manifest.txt +++ /dev/null @@ -1 +0,0 @@ -Main-Class: com.android.dx.command.Main diff --git a/third-party/java/dx-from-kitkat/junit-tests/Android.mk b/third-party/java/dx-from-kitkat/junit-tests/Android.mk deleted file mode 100644 index f999c92a8a0..00000000000 --- a/third-party/java/dx-from-kitkat/junit-tests/Android.mk +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright 2011 The Android Open Source Project - -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) -LOCAL_SRC_FILES := $(call all-subdir-java-files) -LOCAL_JAVA_LIBRARIES := dx junit -LOCAL_MODULE_TAGS := tests -LOCAL_MODULE:= dx-tests -include $(BUILD_HOST_JAVA_LIBRARY) diff --git a/third-party/java/dx-from-kitkat/junit-tests/com/android/dx/util/BitIntSetTest.java b/third-party/java/dx-from-kitkat/junit-tests/com/android/dx/util/BitIntSetTest.java deleted file mode 100644 index d46d14fe31c..00000000000 --- a/third-party/java/dx-from-kitkat/junit-tests/com/android/dx/util/BitIntSetTest.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.util; - -import java.util.NoSuchElementException; -import junit.framework.TestCase; - -public final class BitIntSetTest extends TestCase { - public void test_basic() { - BitIntSet set = new BitIntSet(32); - - assertEquals(0, set.elements()); - - set.add(0); - set.add(1); - set.add(31); - - assertTrue(set.has(0)); - assertTrue(set.has(1)); - assertTrue(set.has(31)); - - assertEquals(3, set.elements()); - - assertFalse(set.has(2)); - assertFalse(set.has(7)); - assertFalse(set.has(30)); - } - - public void test_iterator() { - BitIntSet set = new BitIntSet(32); - - set.add(0); - set.add(0); - set.add(1); - set.add(1); - set.add(31); - set.add(31); - - IntIterator iter = set.iterator(); - - assertTrue(iter.hasNext()); - assertEquals(iter.next(), 0); - assertTrue(iter.hasNext()); - assertEquals(iter.next(), 1); - assertTrue(iter.hasNext()); - assertEquals(iter.next(), 31); - - assertFalse(iter.hasNext()); - - try { - iter.next(); - fail(); - } catch (NoSuchElementException ex) { - // exception excepted - } - } - - public void test_remove() { - BitIntSet set = new BitIntSet(32); - - set.add(0); - set.add(1); - set.add(31); - - assertTrue(set.has(0)); - assertTrue(set.has(1)); - assertTrue(set.has(31)); - - assertFalse(set.has(2)); - assertFalse(set.has(7)); - assertFalse(set.has(30)); - - set.remove(0); - - assertFalse(set.has(0)); - - assertTrue(set.has(1)); - assertTrue(set.has(31)); - } - - /** - * Tests the auto-expansion of the set - */ - public void test_expand() { - BitIntSet set = new BitIntSet(32); - int[] values = {0, 1, 31, 32, 128}; - - for (int i = 0; i < values.length; i++) { - set.add(values[i]); - } - - IntIterator iter = set.iterator(); - - for (int i = 0; i < values.length; i++) { - assertTrue(iter.hasNext()); - assertEquals(values[i], iter.next()); - } - assertFalse(iter.hasNext()); - } - - public void test_merge() { - BitIntSet setA = new BitIntSet(32); - int[] valuesA = {0, 1, 31}; - - for (int i = 0; i < valuesA.length; i++) { - setA.add(valuesA[i]); - } - - BitIntSet setB = new BitIntSet(32); - int[] valuesB = {0, 5, 6, 8, 31}; - - for (int i = 0; i < valuesB.length; i++) { - setB.add(valuesB[i]); - } - - setA.merge(setB); - - for (int i = 0; i < valuesA.length; i++) { - assertTrue(setA.has(valuesA[i])); - } - - for (int i = 0; i < valuesB.length; i++) { - assertTrue(setA.has(valuesB[i])); - } - } - - public void test_mergeWithListIntSet() { - BitIntSet setA = new BitIntSet(32); - int[] valuesA = {0, 1, 31}; - - for (int i = 0; i < valuesA.length; i++) { - setA.add(valuesA[i]); - } - - ListIntSet setB = new ListIntSet(); - int[] valuesB = {0, 5, 6, 8, 31}; - - for (int i = 0; i < valuesB.length; i++) { - setB.add(valuesB[i]); - } - - setA.merge(setB); - - for (int i = 0; i < valuesA.length; i++) { - assertTrue(setA.has(valuesA[i])); - } - - for (int i = 0; i < valuesB.length; i++) { - assertTrue(setA.has(valuesB[i])); - } - } - - public void test_mergeAndExpand() { - BitIntSet setA = new BitIntSet(32); - int[] valuesA = {0, 1, 31}; - - for (int i = 0; i < valuesA.length; i++) { - setA.add(valuesA[i]); - } - - BitIntSet setB = new BitIntSet(32); - int[] valuesB = {0, 5, 6, 32, 127}; - - for (int i = 0; i < valuesB.length; i++) { - setB.add(valuesB[i]); - } - - setA.merge(setB); - - for (int i = 0; i < valuesA.length; i++) { - assertTrue(setA.has(valuesA[i])); - } - - for (int i = 0; i < valuesB.length; i++) { - assertTrue(setA.has(valuesB[i])); - } - } - - public void test_toString() { - BitIntSet set = new BitIntSet(32); - - assertEquals(set.toString(), "{}"); - - set.add(1); - - assertEquals(set.toString(), "{1}"); - - set.add(2); - - assertEquals(set.toString(), "{1, 2}"); - } -} diff --git a/third-party/java/dx-from-kitkat/junit-tests/com/android/dx/util/BitsTest.java b/third-party/java/dx-from-kitkat/junit-tests/com/android/dx/util/BitsTest.java deleted file mode 100644 index e4275132fbb..00000000000 --- a/third-party/java/dx-from-kitkat/junit-tests/com/android/dx/util/BitsTest.java +++ /dev/null @@ -1,345 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.util; - -import junit.framework.TestCase; - -public final class BitsTest extends TestCase { - public void test_makeBitSet() { - assertEquals(label(0), 0, Bits.makeBitSet(0).length); - - for (int i = 1; i <= 32; i++) { - assertEquals(label(i), 1, Bits.makeBitSet(i).length); - } - - for (int i = 33; i <= 64; i++) { - assertEquals(label(i), 2, Bits.makeBitSet(i).length); - } - - for (int i = 65; i < 4000; i += 101) { - int expect = i >> 5; - if ((expect * 32) < i) { - expect++; - } - assertEquals(label(i), expect, Bits.makeBitSet(i).length); - } - } - - public void test_getMax() { - for (int i = 0; i < 4000; i += 59) { - int expect = i >> 5; - if ((expect * 32) < i) { - expect++; - } - assertEquals(label(i), expect * 32, - Bits.getMax(new int[expect])); - } - } - - public void test1_get() { - int[] bits = Bits.makeBitSet(100); - - for (int i = 0; i < 100; i++) { - assertFalse(label(i), Bits.get(bits, i)); - } - } - - public void test2_get() { - int[] bits = Bits.makeBitSet(100); - for (int i = 0; i < bits.length; i++) { - bits[i] = -1; - } - - for (int i = 0; i < 100; i++) { - assertTrue(label(i), Bits.get(bits, i)); - } - } - - public void test3_get() { - int[] bits = Bits.makeBitSet(100); - - for (int i = 0; i < 100; i++) { - Bits.set(bits, i, (i % 5) == 0); - } - - for (int i = 0; i < 100; i++) { - boolean expect = (i % 5) == 0; - assertTrue(label(i), Bits.get(bits, i) == expect); - } - } - - public void test1_set1() { - int[] bits = Bits.makeBitSet(50); - bits[1] = -1; - - Bits.set(bits, 0, true); - Bits.set(bits, 3, true); - Bits.set(bits, 6, true); - Bits.set(bits, 3, false); - Bits.set(bits, 35, false); - Bits.set(bits, 38, false); - Bits.set(bits, 42, false); - Bits.set(bits, 38, true); - - assertEquals(label(1), 0x41, bits[0]); - assertEquals(label(2), 0xfffffbf7, bits[1]); - } - - public void test2_set1() { - int[] bits = Bits.makeBitSet(100); - - for (int i = 0; i < 100; i++) { - if ((i % 3) == 0) { - Bits.set(bits, i, true); - } - } - - for (int i = 0; i < 100; i++) { - if ((i % 5) == 0) { - Bits.set(bits, i, false); - } - } - - for (int i = 0; i < 100; i++) { - if ((i % 7) == 0) { - Bits.set(bits, i, true); - } - } - - for (int i = 0; i < 100; i++) { - boolean expect = ((i % 7) == 0) || - (((i % 3) == 0) && ((i % 5) != 0)); - assertTrue(label(i), Bits.get(bits, i) == expect); - } - } - - public void test_set2() { - int[] bits = Bits.makeBitSet(100); - - for (int i = 0; i < 100; i++) { - if ((i % 11) == 0) { - Bits.set(bits, i); - } - } - - for (int i = 0; i < 100; i++) { - boolean expect = (i % 11) == 0; - assertTrue(label(i), Bits.get(bits, i) == expect); - } - } - - public void test_clear() { - int[] bits = Bits.makeBitSet(100); - for (int i = 0; i < bits.length; i++) { - bits[i] = -1; - } - - for (int i = 0; i < 100; i++) { - if ((i % 5) == 0) { - Bits.clear(bits, i); - } - } - - for (int i = 0; i < 100; i++) { - boolean expect = (i % 5) != 0; - assertTrue(label(i), Bits.get(bits, i) == expect); - } - } - - public void test1_isEmpty() { - for (int i = 0; i < 10; i++) { - assertTrue(label(i), Bits.isEmpty(new int[i])); - } - } - - public void test2_isEmpty() { - for (int i = 1; i < 1000; i += 11) { - int[] bits = Bits.makeBitSet(i); - for (int j = i % 11; j >= 0; j--) { - int x = i - 1 - (j * 13); - if (x >= 0) { - Bits.set(bits, x); - } - } - assertFalse(label(i), Bits.isEmpty(bits)); - } - } - - public void test1_bitCount() { - for (int i = 0; i < 10; i++) { - assertEquals(label(i), 0, Bits.bitCount(new int[i])); - } - } - - public void test2_bitCount() { - for (int i = 1; i < 1000; i += 13) { - int[] bits = Bits.makeBitSet(i); - int count = 0; - for (int j = 0; j < i; j += 20) { - Bits.set(bits, j); - count++; - } - for (int j = 7; j < i; j += 11) { - if (!Bits.get(bits, j)) { - Bits.set(bits, j); - count++; - } - } - for (int j = 3; j < i; j += 17) { - if (!Bits.get(bits, j)) { - Bits.set(bits, j); - count++; - } - } - assertEquals(label(i), count, Bits.bitCount(bits)); - } - } - - public void test1_anyInRange() { - int[] bits = new int[100]; - - for (int i = 0; i < 100; i += 11) { - assertFalse(label(i), Bits.anyInRange(bits, 0, i)); - } - } - - public void test2_anyInRange() { - int[] bits = new int[100]; - - for (int i = 0; i < 100; i += 11) { - assertFalse(label(i), Bits.anyInRange(bits, i, 100)); - } - } - - public void test3_anyInRange() { - int[] bits = new int[100]; - - for (int i = 0; i < 50; i += 7) { - assertFalse(label(i), Bits.anyInRange(bits, i, 100 - i)); - } - } - - public void test4_anyInRange() { - int[] bits = new int[100]; - for (int i = 0; i < bits.length; i++) { - bits[i] = -1; - } - - for (int i = 1; i < 100; i += 11) { - assertTrue(label(i), Bits.anyInRange(bits, 0, i)); - } - } - - public void test5_anyInRange() { - int[] bits = new int[100]; - for (int i = 0; i < bits.length; i++) { - bits[i] = -1; - } - - for (int i = 1; i < 100; i += 11) { - assertTrue(label(i), Bits.anyInRange(bits, i, 100)); - } - } - - public void test6_anyInRange() { - int[] bits = new int[100]; - for (int i = 0; i < bits.length; i++) { - bits[i] = -1; - } - - for (int i = 0; i < 50; i += 7) { - assertTrue(label(i), Bits.anyInRange(bits, i, 100 - i)); - } - } - - public void test1_findFirst1() { - int[] bits = new int[100]; - - for (int i = 0; i < 100; i++) { - assertEquals(label(i), -1, Bits.findFirst(bits, i)); - } - } - - public void test2_findFirst1() { - int[] bits = new int[100]; - for (int i = 0; i < bits.length; i++) { - bits[i] = -1; - } - - for (int i = 0; i < 100; i++) { - assertEquals(label(i), i, Bits.findFirst(bits, i)); - } - } - - public void test3_findFirst1() { - int[] bits = new int[100]; - - for (int i = 25; i < 80; i++) { - for (int j = 0; j < bits.length; j++) { - bits[j] = 0; - } - - Bits.set(bits, i - 5); - Bits.set(bits, i + 5); - Bits.set(bits, i + 10); - Bits.set(bits, i + 20); - assertEquals(label(i), i + 5, Bits.findFirst(bits, i)); - } - } - - public void test1_findFirst2() { - for (int i = 0; i < 32; i++) { - assertEquals(label(i), -1, Bits.findFirst(0, i)); - } - } - - public void test2_findFirst2() { - for (int i = 0; i < 32; i++) { - assertEquals(label(i), i, Bits.findFirst(-1, i)); - } - } - - public void test3_findFirst2() { - for (int i = 0; i < 32; i++) { - assertEquals(label(i), -1, Bits.findFirst((1 << i) >>> 1, i)); - } - } - - public void test4_findFirst2() { - for (int i = 0; i < 32; i++) { - assertEquals(label(i), i, Bits.findFirst(1 << i, i)); - } - } - - public void test5_findFirst2() { - for (int i = 0; i < 31; i++) { - assertEquals(label(i), i + 1, Bits.findFirst(1 << (i + 1), i)); - } - } - - public void test6_findFirst2() { - for (int i = 0; i < 32; i++) { - int value = (1 << i); - value |= (value >>> 1); - assertEquals(label(i), i, Bits.findFirst(value, i)); - } - } - - private static String label(int n) { - return "(" + n + ")"; - } -} diff --git a/third-party/java/dx-from-kitkat/junit-tests/com/android/dx/util/IntListTest.java b/third-party/java/dx-from-kitkat/junit-tests/com/android/dx/util/IntListTest.java deleted file mode 100644 index 7a53a67ba2b..00000000000 --- a/third-party/java/dx-from-kitkat/junit-tests/com/android/dx/util/IntListTest.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.util; - -import junit.framework.TestCase; - -public final class IntListTest extends TestCase { - public void test_contains() { - for (int sz = 0; sz < 100; sz++) { - IntList list = new IntList(sz); - for (int i = 0; i < sz; i++) { - list.add(i * 2); - } - for (int i = (sz * 2) - 1; i >= 0; i--) { - boolean contains = list.contains(i); - if ((i & 1) == 0) { - assertTrue(label(sz, i), contains); - } else { - assertFalse(label(sz, i), contains); - } - } - assertFalse(label(sz, -1), list.contains(-1)); - assertFalse(label(sz, sz * 2), list.contains(sz * 2)); - } - } - - public void test_addSorted() { - IntList list = new IntList(2); - - list.add(9); - list.add(12); - - assertTrue(list.contains(9)); - assertTrue(list.contains(12)); - } - - public void test_addUnsorted() { - IntList list = new IntList(2); - - list.add(12); - list.add(9); - - assertTrue(list.contains(12)); - assertTrue(list.contains(9)); - } - - private static String label(int n, int m) { - return "(" + n + "/" + m + ")"; - } -} diff --git a/third-party/java/dx-from-kitkat/junit-tests/com/android/dx/util/ListIntSetTest.java b/third-party/java/dx-from-kitkat/junit-tests/com/android/dx/util/ListIntSetTest.java deleted file mode 100644 index 868e630a1f2..00000000000 --- a/third-party/java/dx-from-kitkat/junit-tests/com/android/dx/util/ListIntSetTest.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.util; - -import java.util.NoSuchElementException; -import junit.framework.TestCase; - -public final class ListIntSetTest extends TestCase { - public void test_basic() { - ListIntSet set = new ListIntSet(); - - assertEquals(0, set.elements()); - - set.add(31); - set.add(0); - set.add(1); - - assertTrue(set.has(0)); - assertTrue(set.has(1)); - assertTrue(set.has(31)); - - assertEquals(3, set.elements()); - - assertFalse(set.has(2)); - assertFalse(set.has(7)); - assertFalse(set.has(30)); - } - - public void test_iterator() { - ListIntSet set = new ListIntSet(); - - set.add(0); - set.add(0); - set.add(1); - set.add(1); - set.add(31); - set.add(31); - - IntIterator iter = set.iterator(); - - assertTrue(iter.hasNext()); - assertEquals(iter.next(), 0); - assertTrue(iter.hasNext()); - assertEquals(iter.next(), 1); - assertTrue(iter.hasNext()); - assertEquals(iter.next(), 31); - - assertFalse(iter.hasNext()); - - try { - iter.next(); - fail(); - } catch (NoSuchElementException ex) { - // exception excepted - } - } - - public void test_empty() { - ListIntSet set = new ListIntSet(); - - IntIterator iter = set.iterator(); - - assertFalse(iter.hasNext()); - } - - public void test_remove() { - ListIntSet set = new ListIntSet(); - - set.add(0); - set.add(1); - set.add(31); - - assertTrue(set.has(0)); - assertTrue(set.has(1)); - assertTrue(set.has(31)); - - assertFalse(set.has(2)); - assertFalse(set.has(7)); - assertFalse(set.has(30)); - - set.remove(0); - - assertFalse(set.has(0)); - - assertTrue(set.has(1)); - assertTrue(set.has(31)); - } - - public void test_mergeA() { - ListIntSet setA = new ListIntSet(); - int[] valuesA = {0, 1, 31}; - - for (int i = 0; i < valuesA.length; i++) { - setA.add(valuesA[i]); - } - - ListIntSet setB = new ListIntSet(); - int[] valuesB = {0, 5, 6, 32, 127, 128}; - - for (int i = 0; i < valuesB.length; i++) { - setB.add(valuesB[i]); - } - - setA.merge(setB); - - for (int i = 0; i < valuesA.length; i++) { - assertTrue(setA.has(valuesA[i])); - } - - for (int i = 0; i < valuesB.length; i++) { - assertTrue(setA.has(valuesB[i])); - } - - } - - public void test_mergeB() { - ListIntSet setA = new ListIntSet(); - int[] valuesA = {0, 1, 31, 129, 130}; - - for (int i = 0; i < valuesA.length; i++) { - setA.add(valuesA[i]); - } - - ListIntSet setB = new ListIntSet(); - int[] valuesB = {0, 5, 6, 32, 127,128}; - - for (int i = 0; i < valuesB.length; i++) { - setB.add(valuesB[i]); - } - - setA.merge(setB); - - for (int i = 0; i < valuesA.length; i++) { - assertTrue(setA.has(valuesA[i])); - } - - for (int i = 0; i < valuesB.length; i++) { - assertTrue(setA.has(valuesB[i])); - } - - } - - public void test_mergeWithBitIntSet() { - ListIntSet setA = new ListIntSet(); - int[] valuesA = {0, 1, 31, 129, 130}; - - for (int i = 0; i < valuesA.length; i++) { - setA.add(valuesA[i]); - } - - BitIntSet setB = new BitIntSet(129); - int[] valuesB = {0, 5, 6, 32, 127,128}; - - for (int i = 0; i < valuesB.length; i++) { - setB.add(valuesB[i]); - } - - setA.merge(setB); - - for (int i = 0; i < valuesA.length; i++) { - assertTrue(setA.has(valuesA[i])); - } - - for (int i = 0; i < valuesB.length; i++) { - assertTrue(setA.has(valuesB[i])); - } - - } - - public void test_toString() { - ListIntSet set = new ListIntSet(); - - assertEquals(set.toString(), "{}"); - - set.add(1); - - assertEquals(set.toString(), "{1}"); - - set.add(2); - - assertEquals(set.toString(), "{1, 2}"); - } - -} diff --git a/third-party/java/dx-from-kitkat/shrinkedAndroid.proguard.flags b/third-party/java/dx-from-kitkat/shrinkedAndroid.proguard.flags deleted file mode 100644 index 65c8689f15c..00000000000 --- a/third-party/java/dx-from-kitkat/shrinkedAndroid.proguard.flags +++ /dev/null @@ -1,21 +0,0 @@ --dontwarn --forceprocessing --dontoptimize --dontobfuscate --dontpreverify --keep public class * extends android.app.Instrumentation { -} --keep public class * extends android.app.Application { -} --keep public class * extends android.app.Activity { -} --keep public class * extends android.app.Service { -} --keep public class * extends android.content.ContentProvider { -} --keep public class * extends android.content.BroadcastReceiver { -} --keep public class * extends android.app.backup.BackupAgent { -} --keep class android.support.multidex.installer.** { -} diff --git a/third-party/java/dx-from-kitkat/src/Android.mk b/third-party/java/dx-from-kitkat/src/Android.mk deleted file mode 100644 index 678397f78e8..00000000000 --- a/third-party/java/dx-from-kitkat/src/Android.mk +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2006 The Android Open Source Project -# -LOCAL_PATH := $(call my-dir) - -# This tool is prebuilt if we're doing an app-only build. -ifeq ($(TARGET_BUILD_APPS),) - -# dx java library -# ============================================================ -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := $(call all-subdir-java-files) -LOCAL_SRC_FILES += $(call all-java-files-under,../../../libcore/dex/src/main/java) -LOCAL_JAR_MANIFEST := ../etc/manifest.txt -LOCAL_MODULE_TAGS := optional -LOCAL_MODULE:= dx - -include $(BUILD_HOST_JAVA_LIBRARY) - -INTERNAL_DALVIK_MODULES += $(LOCAL_INSTALLED_MODULE) - -endif # TARGET_BUILD_APPS - -# the documentation -# ============================================================ -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := $(call all-subdir-java-files) $(call all-subdir-html-files) -LOCAL_MODULE_TAGS := optional -LOCAL_MODULE:= dx -LOCAL_DROIDDOC_OPTIONS := -hidden -LOCAL_MODULE_CLASS := JAVA_LIBRARIES -LOCAL_IS_HOST_MODULE := true - -include $(BUILD_DROIDDOC) diff --git a/third-party/java/dx-from-kitkat/src/com/android/dex/Annotation.java b/third-party/java/dx-from-kitkat/src/com/android/dex/Annotation.java deleted file mode 100644 index e5ef9783b7c..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dex/Annotation.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dex; - -import static com.android.dex.EncodedValueReader.ENCODED_ANNOTATION; - -/** - * An annotation. - */ -public final class Annotation implements Comparable { - private final Dex dex; - private final byte visibility; - private final EncodedValue encodedAnnotation; - - public Annotation(Dex dex, byte visibility, EncodedValue encodedAnnotation) { - this.dex = dex; - this.visibility = visibility; - this.encodedAnnotation = encodedAnnotation; - } - - public byte getVisibility() { - return visibility; - } - - public EncodedValueReader getReader() { - return new EncodedValueReader(encodedAnnotation, ENCODED_ANNOTATION); - } - - public int getTypeIndex() { - EncodedValueReader reader = getReader(); - reader.readAnnotation(); - return reader.getAnnotationType(); - } - - public void writeTo(Dex.Section out) { - out.writeByte(visibility); - encodedAnnotation.writeTo(out); - } - - @Override public int compareTo(Annotation other) { - return encodedAnnotation.compareTo(other.encodedAnnotation); - } - - @Override public String toString() { - return dex == null - ? visibility + " " + getTypeIndex() - : visibility + " " + dex.typeNames().get(getTypeIndex()); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dex/ClassData.java b/third-party/java/dx-from-kitkat/src/com/android/dex/ClassData.java deleted file mode 100644 index 840756c5b71..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dex/ClassData.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dex; - -public final class ClassData { - private final Field[] staticFields; - private final Field[] instanceFields; - private final Method[] directMethods; - private final Method[] virtualMethods; - - public ClassData(Field[] staticFields, Field[] instanceFields, - Method[] directMethods, Method[] virtualMethods) { - this.staticFields = staticFields; - this.instanceFields = instanceFields; - this.directMethods = directMethods; - this.virtualMethods = virtualMethods; - } - - public Field[] getStaticFields() { - return staticFields; - } - - public Field[] getInstanceFields() { - return instanceFields; - } - - public Method[] getDirectMethods() { - return directMethods; - } - - public Method[] getVirtualMethods() { - return virtualMethods; - } - - public Field[] allFields() { - Field[] result = new Field[staticFields.length + instanceFields.length]; - System.arraycopy(staticFields, 0, result, 0, staticFields.length); - System.arraycopy(instanceFields, 0, result, staticFields.length, instanceFields.length); - return result; - } - - public Method[] allMethods() { - Method[] result = new Method[directMethods.length + virtualMethods.length]; - System.arraycopy(directMethods, 0, result, 0, directMethods.length); - System.arraycopy(virtualMethods, 0, result, directMethods.length, virtualMethods.length); - return result; - } - - public static class Field { - private final int fieldIndex; - private final int accessFlags; - - public Field(int fieldIndex, int accessFlags) { - this.fieldIndex = fieldIndex; - this.accessFlags = accessFlags; - } - - public int getFieldIndex() { - return fieldIndex; - } - - public int getAccessFlags() { - return accessFlags; - } - } - - public static class Method { - private final int methodIndex; - private final int accessFlags; - private final int codeOffset; - - public Method(int methodIndex, int accessFlags, int codeOffset) { - this.methodIndex = methodIndex; - this.accessFlags = accessFlags; - this.codeOffset = codeOffset; - } - - public int getMethodIndex() { - return methodIndex; - } - - public int getAccessFlags() { - return accessFlags; - } - - public int getCodeOffset() { - return codeOffset; - } - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dex/ClassDef.java b/third-party/java/dx-from-kitkat/src/com/android/dex/ClassDef.java deleted file mode 100644 index b3225ec0e3b..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dex/ClassDef.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dex; - -/** - * A type definition. - */ -public final class ClassDef { - public static final int NO_INDEX = -1; - private final Dex buffer; - private final int offset; - private final int typeIndex; - private final int accessFlags; - private final int supertypeIndex; - private final int interfacesOffset; - private final int sourceFileIndex; - private final int annotationsOffset; - private final int classDataOffset; - private final int staticValuesOffset; - - public ClassDef(Dex buffer, int offset, int typeIndex, int accessFlags, - int supertypeIndex, int interfacesOffset, int sourceFileIndex, - int annotationsOffset, int classDataOffset, int staticValuesOffset) { - this.buffer = buffer; - this.offset = offset; - this.typeIndex = typeIndex; - this.accessFlags = accessFlags; - this.supertypeIndex = supertypeIndex; - this.interfacesOffset = interfacesOffset; - this.sourceFileIndex = sourceFileIndex; - this.annotationsOffset = annotationsOffset; - this.classDataOffset = classDataOffset; - this.staticValuesOffset = staticValuesOffset; - } - - public int getOffset() { - return offset; - } - - public int getTypeIndex() { - return typeIndex; - } - - public int getSupertypeIndex() { - return supertypeIndex; - } - - public int getInterfacesOffset() { - return interfacesOffset; - } - - public short[] getInterfaces() { - return buffer.readTypeList(interfacesOffset).getTypes(); - } - - public int getAccessFlags() { - return accessFlags; - } - - public int getSourceFileIndex() { - return sourceFileIndex; - } - - public int getAnnotationsOffset() { - return annotationsOffset; - } - - public int getClassDataOffset() { - return classDataOffset; - } - - public int getStaticValuesOffset() { - return staticValuesOffset; - } - - @Override public String toString() { - if (buffer == null) { - return typeIndex + " " + supertypeIndex; - } - - StringBuilder result = new StringBuilder(); - result.append(buffer.typeNames().get(typeIndex)); - if (supertypeIndex != NO_INDEX) { - result.append(" extends ").append(buffer.typeNames().get(supertypeIndex)); - } - return result.toString(); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dex/Code.java b/third-party/java/dx-from-kitkat/src/com/android/dex/Code.java deleted file mode 100644 index 9258af795f4..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dex/Code.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dex; - -public final class Code { - private final int registersSize; - private final int insSize; - private final int outsSize; - private final int debugInfoOffset; - private final short[] instructions; - private final Try[] tries; - private final CatchHandler[] catchHandlers; - - public Code(int registersSize, int insSize, int outsSize, int debugInfoOffset, - short[] instructions, Try[] tries, CatchHandler[] catchHandlers) { - this.registersSize = registersSize; - this.insSize = insSize; - this.outsSize = outsSize; - this.debugInfoOffset = debugInfoOffset; - this.instructions = instructions; - this.tries = tries; - this.catchHandlers = catchHandlers; - } - - public int getRegistersSize() { - return registersSize; - } - - public int getInsSize() { - return insSize; - } - - public int getOutsSize() { - return outsSize; - } - - public int getDebugInfoOffset() { - return debugInfoOffset; - } - - public short[] getInstructions() { - return instructions; - } - - public Try[] getTries() { - return tries; - } - - public CatchHandler[] getCatchHandlers() { - return catchHandlers; - } - - public static class Try { - final int startAddress; - final int instructionCount; - final int catchHandlerIndex; - - Try(int startAddress, int instructionCount, int catchHandlerIndex) { - this.startAddress = startAddress; - this.instructionCount = instructionCount; - this.catchHandlerIndex = catchHandlerIndex; - } - - public int getStartAddress() { - return startAddress; - } - - public int getInstructionCount() { - return instructionCount; - } - - /** - * Returns this try's catch handler index. Note that - * this is distinct from the its catch handler offset. - */ - public int getCatchHandlerIndex() { - return catchHandlerIndex; - } - } - - public static class CatchHandler { - final int[] typeIndexes; - final int[] addresses; - final int catchAllAddress; - final int offset; - - public CatchHandler(int[] typeIndexes, int[] addresses, int catchAllAddress, int offset) { - this.typeIndexes = typeIndexes; - this.addresses = addresses; - this.catchAllAddress = catchAllAddress; - this.offset = offset; - } - - public int[] getTypeIndexes() { - return typeIndexes; - } - - public int[] getAddresses() { - return addresses; - } - - public int getCatchAllAddress() { - return catchAllAddress; - } - - public int getOffset() { - return offset; - } - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dex/Dex.java b/third-party/java/dx-from-kitkat/src/com/android/dex/Dex.java deleted file mode 100644 index b1afd50ba6a..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dex/Dex.java +++ /dev/null @@ -1,983 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dex; - -import com.android.dex.Code.CatchHandler; -import com.android.dex.Code.Try; -import com.android.dex.util.ByteInput; -import com.android.dex.util.ByteOutput; -import com.android.dex.util.FileUtils; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.UTFDataFormatException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.AbstractList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.RandomAccess; -import java.util.zip.Adler32; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - -/** - * The bytes of a dex file in memory for reading and writing. All int offsets - * are unsigned. - */ -public final class Dex { - private static final int CHECKSUM_OFFSET = 8; - private static final int CHECKSUM_SIZE = 4; - private static final int SIGNATURE_OFFSET = CHECKSUM_OFFSET + CHECKSUM_SIZE; - private static final int SIGNATURE_SIZE = 20; - // Provided as a convenience to avoid a memory allocation to benefit Dalvik. - // Note: libcore.util.EmptyArray cannot be accessed when this code isn't run on Dalvik. - static final short[] EMPTY_SHORT_ARRAY = new short[0]; - - private ByteBuffer data; - private final TableOfContents tableOfContents = new TableOfContents(); - private int nextSectionStart = 0; - private final StringTable strings = new StringTable(); - private final TypeIndexToDescriptorIndexTable typeIds = new TypeIndexToDescriptorIndexTable(); - private final TypeIndexToDescriptorTable typeNames = new TypeIndexToDescriptorTable(); - private final ProtoIdTable protoIds = new ProtoIdTable(); - private final FieldIdTable fieldIds = new FieldIdTable(); - private final MethodIdTable methodIds = new MethodIdTable(); - - /** - * Creates a new dex that reads from {@code data}. It is an error to modify - * {@code data} after using it to create a dex buffer. - */ - public Dex(byte[] data) throws IOException { - this(ByteBuffer.wrap(data)); - } - - private Dex(ByteBuffer data) throws IOException { - this.data = data; - this.data.order(ByteOrder.LITTLE_ENDIAN); - this.tableOfContents.readFrom(this); - } - - /** - * Creates a new empty dex of the specified size. - */ - public Dex(int byteCount) throws IOException { - this.data = ByteBuffer.wrap(new byte[byteCount]); - this.data.order(ByteOrder.LITTLE_ENDIAN); - } - - /** - * Creates a new dex buffer of the dex in {@code in}, and closes {@code in}. - */ - public Dex(InputStream in) throws IOException { - loadFrom(in); - } - - /** - * Creates a new dex buffer from the dex file {@code file}. - */ - public Dex(File file) throws IOException { - if (FileUtils.hasArchiveSuffix(file.getName())) { - try (ZipFile zipFile = new ZipFile(file)) { - ZipEntry entry = zipFile.getEntry(DexFormat.DEX_IN_JAR_NAME); - if (entry != null) { - loadFrom(zipFile.getInputStream(entry)); - } else { - throw new DexException("Expected " + DexFormat.DEX_IN_JAR_NAME + " in " + file); - } - } - } else if (file.getName().endsWith(".dex")) { - loadFrom(new FileInputStream(file)); - } else { - throw new DexException("unknown output extension: " + file); - } - } - - /** - * Creates a new dex from the contents of {@code bytes}. This API supports - * both {@code .dex} and {@code .odex} input. Calling this constructor - * transfers ownership of {@code bytes} to the returned Dex: it is an error - * to access the buffer after calling this method. - */ - public static Dex create(ByteBuffer data) throws IOException { - data.order(ByteOrder.LITTLE_ENDIAN); - - // if it's an .odex file, set position and limit to the .dex section - if (data.get(0) == 'd' - && data.get(1) == 'e' - && data.get(2) == 'y' - && data.get(3) == '\n') { - data.position(8); - int offset = data.getInt(); - int length = data.getInt(); - data.position(offset); - data.limit(offset + length); - data = data.slice(); - } - - return new Dex(data); - } - - private void loadFrom(InputStream in) throws IOException { - ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); - byte[] buffer = new byte[8192]; - - int count; - while ((count = in.read(buffer)) != -1) { - bytesOut.write(buffer, 0, count); - } - in.close(); - - this.data = ByteBuffer.wrap(bytesOut.toByteArray()); - this.data.order(ByteOrder.LITTLE_ENDIAN); - this.tableOfContents.readFrom(this); - } - - private static void checkBounds(int index, int length) { - if (index < 0 || index >= length) { - throw new IndexOutOfBoundsException("index:" + index + ", length=" + length); - } - } - - public void writeTo(OutputStream out) throws IOException { - byte[] buffer = new byte[8192]; - ByteBuffer data = this.data.duplicate(); // positioned ByteBuffers aren't thread safe - data.clear(); - while (data.hasRemaining()) { - int count = Math.min(buffer.length, data.remaining()); - data.get(buffer, 0, count); - out.write(buffer, 0, count); - } - } - - public void writeTo(File dexOut) throws IOException { - OutputStream out = new FileOutputStream(dexOut); - writeTo(out); - out.close(); - } - - public TableOfContents getTableOfContents() { - return tableOfContents; - } - - public Section open(int position) { - if (position < 0 || position >= data.capacity()) { - throw new IllegalArgumentException("position=" + position - + " length=" + data.capacity()); - } - ByteBuffer sectionData = data.duplicate(); - sectionData.order(ByteOrder.LITTLE_ENDIAN); // necessary? - sectionData.position(position); - sectionData.limit(data.capacity()); - return new Section("section", sectionData); - } - - public Section appendSection(int maxByteCount, String name) { - if ((maxByteCount & 3) != 0) { - throw new IllegalStateException("Not four byte aligned!"); - } - int limit = nextSectionStart + maxByteCount; - ByteBuffer sectionData = data.duplicate(); - sectionData.order(ByteOrder.LITTLE_ENDIAN); // necessary? - sectionData.position(nextSectionStart); - sectionData.limit(limit); - Section result = new Section(name, sectionData); - nextSectionStart = limit; - return result; - } - - public int getLength() { - return data.capacity(); - } - - public int getNextSectionStart() { - return nextSectionStart; - } - - /** - * Returns a copy of the the bytes of this dex. - */ - public byte[] getBytes() { - ByteBuffer data = this.data.duplicate(); // positioned ByteBuffers aren't thread safe - byte[] result = new byte[data.capacity()]; - data.position(0); - data.get(result); - return result; - } - - public List strings() { - return strings; - } - - public List typeIds() { - return typeIds; - } - - public List typeNames() { - return typeNames; - } - - public List protoIds() { - return protoIds; - } - - public List fieldIds() { - return fieldIds; - } - - public List methodIds() { - return methodIds; - } - - public Iterable classDefs() { - return new ClassDefIterable(); - } - - public TypeList readTypeList(int offset) { - if (offset == 0) { - return TypeList.EMPTY; - } - return open(offset).readTypeList(); - } - - public ClassData readClassData(ClassDef classDef) { - int offset = classDef.getClassDataOffset(); - if (offset == 0) { - throw new IllegalArgumentException("offset == 0"); - } - return open(offset).readClassData(); - } - - public Code readCode(ClassData.Method method) { - int offset = method.getCodeOffset(); - if (offset == 0) { - throw new IllegalArgumentException("offset == 0"); - } - return open(offset).readCode(); - } - - /** - * Returns the signature of all but the first 32 bytes of this dex. The - * first 32 bytes of dex files are not specified to be included in the - * signature. - */ - public byte[] computeSignature() throws IOException { - MessageDigest digest; - try { - digest = MessageDigest.getInstance("SHA-1"); - } catch (NoSuchAlgorithmException e) { - throw new AssertionError(); - } - byte[] buffer = new byte[8192]; - ByteBuffer data = this.data.duplicate(); // positioned ByteBuffers aren't thread safe - data.limit(data.capacity()); - data.position(SIGNATURE_OFFSET + SIGNATURE_SIZE); - while (data.hasRemaining()) { - int count = Math.min(buffer.length, data.remaining()); - data.get(buffer, 0, count); - digest.update(buffer, 0, count); - } - return digest.digest(); - } - - /** - * Returns the checksum of all but the first 12 bytes of {@code dex}. - */ - public int computeChecksum() throws IOException { - Adler32 adler32 = new Adler32(); - byte[] buffer = new byte[8192]; - ByteBuffer data = this.data.duplicate(); // positioned ByteBuffers aren't thread safe - data.limit(data.capacity()); - data.position(CHECKSUM_OFFSET + CHECKSUM_SIZE); - while (data.hasRemaining()) { - int count = Math.min(buffer.length, data.remaining()); - data.get(buffer, 0, count); - adler32.update(buffer, 0, count); - } - return (int) adler32.getValue(); - } - - /** - * Generates the signature and checksum of the dex file {@code out} and - * writes them to the file. - */ - public void writeHashes() throws IOException { - open(SIGNATURE_OFFSET).write(computeSignature()); - open(CHECKSUM_OFFSET).writeInt(computeChecksum()); - } - - /** - * Look up a field id name index from a field index. Cheaper than: - * {@code fieldIds().get(fieldDexIndex).getNameIndex();} - */ - public int nameIndexFromFieldIndex(int fieldIndex) { - checkBounds(fieldIndex, tableOfContents.fieldIds.size); - int position = tableOfContents.fieldIds.off + (SizeOf.MEMBER_ID_ITEM * fieldIndex); - position += SizeOf.USHORT; // declaringClassIndex - position += SizeOf.USHORT; // typeIndex - return data.getInt(position); // nameIndex - } - - public int findStringIndex(String s) { - return Collections.binarySearch(strings, s); - } - - public int findTypeIndex(String descriptor) { - return Collections.binarySearch(typeNames, descriptor); - } - - public int findFieldIndex(FieldId fieldId) { - return Collections.binarySearch(fieldIds, fieldId); - } - - public int findMethodIndex(MethodId methodId) { - return Collections.binarySearch(methodIds, methodId); - } - - public int findClassDefIndexFromTypeIndex(int typeIndex) { - checkBounds(typeIndex, tableOfContents.typeIds.size); - if (!tableOfContents.classDefs.exists()) { - return -1; - } - for (int i = 0; i < tableOfContents.classDefs.size; i++) { - if (typeIndexFromClassDefIndex(i) == typeIndex) { - return i; - } - } - return -1; - } - - /** - * Look up a field id type index from a field index. Cheaper than: - * {@code fieldIds().get(fieldDexIndex).getTypeIndex();} - */ - public int typeIndexFromFieldIndex(int fieldIndex) { - checkBounds(fieldIndex, tableOfContents.fieldIds.size); - int position = tableOfContents.fieldIds.off + (SizeOf.MEMBER_ID_ITEM * fieldIndex); - position += SizeOf.USHORT; // declaringClassIndex - return data.getShort(position) & 0xFFFF; // typeIndex - } - - /** - * Look up a method id declaring class index from a method index. Cheaper than: - * {@code methodIds().get(methodIndex).getDeclaringClassIndex();} - */ - public int declaringClassIndexFromMethodIndex(int methodIndex) { - checkBounds(methodIndex, tableOfContents.methodIds.size); - int position = tableOfContents.methodIds.off + (SizeOf.MEMBER_ID_ITEM * methodIndex); - return data.getShort(position) & 0xFFFF; // declaringClassIndex - } - - /** - * Look up a method id name index from a method index. Cheaper than: - * {@code methodIds().get(methodIndex).getNameIndex();} - */ - public int nameIndexFromMethodIndex(int methodIndex) { - checkBounds(methodIndex, tableOfContents.methodIds.size); - int position = tableOfContents.methodIds.off + (SizeOf.MEMBER_ID_ITEM * methodIndex); - position += SizeOf.USHORT; // declaringClassIndex - position += SizeOf.USHORT; // protoIndex - return data.getInt(position); // nameIndex - } - - /** - * Look up a parameter type ids from a method index. Cheaper than: - * {@code readTypeList(protoIds.get(methodIds().get(methodDexIndex).getProtoIndex()).getParametersOffset()).getTypes();} - */ - public short[] parameterTypeIndicesFromMethodIndex(int methodIndex) { - checkBounds(methodIndex, tableOfContents.methodIds.size); - int position = tableOfContents.methodIds.off + (SizeOf.MEMBER_ID_ITEM * methodIndex); - position += SizeOf.USHORT; // declaringClassIndex - int protoIndex = data.getShort(position) & 0xFFFF; - checkBounds(protoIndex, tableOfContents.protoIds.size); - position = tableOfContents.protoIds.off + (SizeOf.PROTO_ID_ITEM * protoIndex); - position += SizeOf.UINT; // shortyIndex - position += SizeOf.UINT; // returnTypeIndex - int parametersOffset = data.getInt(position); - if (parametersOffset == 0) { - return EMPTY_SHORT_ARRAY; - } - position = parametersOffset; - int size = data.getInt(position); - if (size <= 0) { - throw new AssertionError("Unexpected parameter type list size: " + size); - } - position += SizeOf.UINT; - short[] types = new short[size]; - for (int i = 0; i < size; i++) { - types[i] = data.getShort(position); - position += SizeOf.USHORT; - } - return types; - } - - /** - * Look up a method id return type index from a method index. Cheaper than: - * {@code protoIds().get(methodIds().get(methodDexIndex).getProtoIndex()).getReturnTypeIndex();} - */ - public int returnTypeIndexFromMethodIndex(int methodIndex) { - checkBounds(methodIndex, tableOfContents.methodIds.size); - int position = tableOfContents.methodIds.off + (SizeOf.MEMBER_ID_ITEM * methodIndex); - position += SizeOf.USHORT; // declaringClassIndex - int protoIndex = data.getShort(position) & 0xFFFF; - checkBounds(protoIndex, tableOfContents.protoIds.size); - position = tableOfContents.protoIds.off + (SizeOf.PROTO_ID_ITEM * protoIndex); - position += SizeOf.UINT; // shortyIndex - return data.getInt(position); // returnTypeIndex - } - - /** - * Look up a descriptor index from a type index. Cheaper than: - * {@code open(tableOfContents.typeIds.off + (index * SizeOf.TYPE_ID_ITEM)).readInt();} - */ - public int descriptorIndexFromTypeIndex(int typeIndex) { - checkBounds(typeIndex, tableOfContents.typeIds.size); - int position = tableOfContents.typeIds.off + (SizeOf.TYPE_ID_ITEM * typeIndex); - return data.getInt(position); - } - - /** - * Look up a type index index from a class def index. - */ - public int typeIndexFromClassDefIndex(int classDefIndex) { - checkBounds(classDefIndex, tableOfContents.classDefs.size); - int position = tableOfContents.classDefs.off + (SizeOf.CLASS_DEF_ITEM * classDefIndex); - return data.getInt(position); - } - - /** - * Look up a type index index from a class def index. - */ - public int annotationDirectoryOffsetFromClassDefIndex(int classDefIndex) { - checkBounds(classDefIndex, tableOfContents.classDefs.size); - int position = tableOfContents.classDefs.off + (SizeOf.CLASS_DEF_ITEM * classDefIndex); - position += SizeOf.UINT; // type - position += SizeOf.UINT; // accessFlags - position += SizeOf.UINT; // superType - position += SizeOf.UINT; // interfacesOffset - position += SizeOf.UINT; // sourceFileIndex - return data.getInt(position); - } - - /** - * Look up interface types indices from a return type index from a method index. Cheaper than: - * {@code ...getClassDef(classDefIndex).getInterfaces();} - */ - public short[] interfaceTypeIndicesFromClassDefIndex(int classDefIndex) { - checkBounds(classDefIndex, tableOfContents.classDefs.size); - int position = tableOfContents.classDefs.off + (SizeOf.CLASS_DEF_ITEM * classDefIndex); - position += SizeOf.UINT; // type - position += SizeOf.UINT; // accessFlags - position += SizeOf.UINT; // superType - int interfacesOffset = data.getInt(position); - if (interfacesOffset == 0) { - return EMPTY_SHORT_ARRAY; - } - position = interfacesOffset; - int size = data.getInt(position); - if (size <= 0) { - throw new AssertionError("Unexpected interfaces list size: " + size); - } - position += SizeOf.UINT; - short[] types = new short[size]; - for (int i = 0; i < size; i++) { - types[i] = data.getShort(position); - position += SizeOf.USHORT; - } - return types; - } - - public final class Section implements ByteInput, ByteOutput { - private final String name; - private final ByteBuffer data; - private final int initialPosition; - - private Section(String name, ByteBuffer data) { - this.name = name; - this.data = data; - this.initialPosition = data.position(); - } - - public int getPosition() { - return data.position(); - } - - public int readInt() { - return data.getInt(); - } - - public short readShort() { - return data.getShort(); - } - - public int readUnsignedShort() { - return readShort() & 0xffff; - } - - public byte readByte() { - return data.get(); - } - - public byte[] readByteArray(int length) { - byte[] result = new byte[length]; - data.get(result); - return result; - } - - public short[] readShortArray(int length) { - if (length == 0) { - return EMPTY_SHORT_ARRAY; - } - short[] result = new short[length]; - for (int i = 0; i < length; i++) { - result[i] = readShort(); - } - return result; - } - - public int readUleb128() { - return Leb128.readUnsignedLeb128(this); - } - - public int readUleb128p1() { - return Leb128.readUnsignedLeb128(this) - 1; - } - - public int readSleb128() { - return Leb128.readSignedLeb128(this); - } - - public void writeUleb128p1(int i) { - writeUleb128(i + 1); - } - - public TypeList readTypeList() { - int size = readInt(); - short[] types = readShortArray(size); - alignToFourBytes(); - return new TypeList(Dex.this, types); - } - - public String readString() { - int offset = readInt(); - int savedPosition = data.position(); - int savedLimit = data.limit(); - data.position(offset); - data.limit(data.capacity()); - try { - int expectedLength = readUleb128(); - String result = Mutf8.decode(this, new char[expectedLength]); - if (result.length() != expectedLength) { - throw new DexException("Declared length " + expectedLength - + " doesn't match decoded length of " + result.length()); - } - return result; - } catch (UTFDataFormatException e) { - throw new DexException(e); - } finally { - data.position(savedPosition); - data.limit(savedLimit); - } - } - - public FieldId readFieldId() { - int declaringClassIndex = readUnsignedShort(); - int typeIndex = readUnsignedShort(); - int nameIndex = readInt(); - return new FieldId(Dex.this, declaringClassIndex, typeIndex, nameIndex); - } - - public MethodId readMethodId() { - int declaringClassIndex = readUnsignedShort(); - int protoIndex = readUnsignedShort(); - int nameIndex = readInt(); - return new MethodId(Dex.this, declaringClassIndex, protoIndex, nameIndex); - } - - public ProtoId readProtoId() { - int shortyIndex = readInt(); - int returnTypeIndex = readInt(); - int parametersOffset = readInt(); - return new ProtoId(Dex.this, shortyIndex, returnTypeIndex, parametersOffset); - } - - public ClassDef readClassDef() { - int offset = getPosition(); - int type = readInt(); - int accessFlags = readInt(); - int supertype = readInt(); - int interfacesOffset = readInt(); - int sourceFileIndex = readInt(); - int annotationsOffset = readInt(); - int classDataOffset = readInt(); - int staticValuesOffset = readInt(); - return new ClassDef(Dex.this, offset, type, accessFlags, supertype, - interfacesOffset, sourceFileIndex, annotationsOffset, classDataOffset, - staticValuesOffset); - } - - private Code readCode() { - int registersSize = readUnsignedShort(); - int insSize = readUnsignedShort(); - int outsSize = readUnsignedShort(); - int triesSize = readUnsignedShort(); - int debugInfoOffset = readInt(); - int instructionsSize = readInt(); - short[] instructions = readShortArray(instructionsSize); - Try[] tries; - CatchHandler[] catchHandlers; - if (triesSize > 0) { - if (instructions.length % 2 == 1) { - readShort(); // padding - } - - /* - * We can't read the tries until we've read the catch handlers. - * Unfortunately they're in the opposite order in the dex file - * so we need to read them out-of-order. - */ - Section triesSection = open(data.position()); - skip(triesSize * SizeOf.TRY_ITEM); - catchHandlers = readCatchHandlers(); - tries = triesSection.readTries(triesSize, catchHandlers); - } else { - tries = new Try[0]; - catchHandlers = new CatchHandler[0]; - } - return new Code(registersSize, insSize, outsSize, debugInfoOffset, instructions, - tries, catchHandlers); - } - - private CatchHandler[] readCatchHandlers() { - int baseOffset = data.position(); - int catchHandlersSize = readUleb128(); - CatchHandler[] result = new CatchHandler[catchHandlersSize]; - for (int i = 0; i < catchHandlersSize; i++) { - int offset = data.position() - baseOffset; - result[i] = readCatchHandler(offset); - } - return result; - } - - private Try[] readTries(int triesSize, CatchHandler[] catchHandlers) { - Try[] result = new Try[triesSize]; - for (int i = 0; i < triesSize; i++) { - int startAddress = readInt(); - int instructionCount = readUnsignedShort(); - int handlerOffset = readUnsignedShort(); - int catchHandlerIndex = findCatchHandlerIndex(catchHandlers, handlerOffset); - result[i] = new Try(startAddress, instructionCount, catchHandlerIndex); - } - return result; - } - - private int findCatchHandlerIndex(CatchHandler[] catchHandlers, int offset) { - for (int i = 0; i < catchHandlers.length; i++) { - CatchHandler catchHandler = catchHandlers[i]; - if (catchHandler.getOffset() == offset) { - return i; - } - } - throw new IllegalArgumentException(); - } - - private CatchHandler readCatchHandler(int offset) { - int size = readSleb128(); - int handlersCount = Math.abs(size); - int[] typeIndexes = new int[handlersCount]; - int[] addresses = new int[handlersCount]; - for (int i = 0; i < handlersCount; i++) { - typeIndexes[i] = readUleb128(); - addresses[i] = readUleb128(); - } - int catchAllAddress = size <= 0 ? readUleb128() : -1; - return new CatchHandler(typeIndexes, addresses, catchAllAddress, offset); - } - - private ClassData readClassData() { - int staticFieldsSize = readUleb128(); - int instanceFieldsSize = readUleb128(); - int directMethodsSize = readUleb128(); - int virtualMethodsSize = readUleb128(); - ClassData.Field[] staticFields = readFields(staticFieldsSize); - ClassData.Field[] instanceFields = readFields(instanceFieldsSize); - ClassData.Method[] directMethods = readMethods(directMethodsSize); - ClassData.Method[] virtualMethods = readMethods(virtualMethodsSize); - return new ClassData(staticFields, instanceFields, directMethods, virtualMethods); - } - - private ClassData.Field[] readFields(int count) { - ClassData.Field[] result = new ClassData.Field[count]; - int fieldIndex = 0; - for (int i = 0; i < count; i++) { - fieldIndex += readUleb128(); // field index diff - int accessFlags = readUleb128(); - result[i] = new ClassData.Field(fieldIndex, accessFlags); - } - return result; - } - - private ClassData.Method[] readMethods(int count) { - ClassData.Method[] result = new ClassData.Method[count]; - int methodIndex = 0; - for (int i = 0; i < count; i++) { - methodIndex += readUleb128(); // method index diff - int accessFlags = readUleb128(); - int codeOff = readUleb128(); - result[i] = new ClassData.Method(methodIndex, accessFlags, codeOff); - } - return result; - } - - /** - * Returns a byte array containing the bytes from {@code start} to this - * section's current position. - */ - private byte[] getBytesFrom(int start) { - int end = data.position(); - byte[] result = new byte[end - start]; - data.position(start); - data.get(result); - return result; - } - - public Annotation readAnnotation() { - byte visibility = readByte(); - int start = data.position(); - new EncodedValueReader(this, EncodedValueReader.ENCODED_ANNOTATION).skipValue(); - return new Annotation(Dex.this, visibility, new EncodedValue(getBytesFrom(start))); - } - - public EncodedValue readEncodedArray() { - int start = data.position(); - new EncodedValueReader(this, EncodedValueReader.ENCODED_ARRAY).skipValue(); - return new EncodedValue(getBytesFrom(start)); - } - - public void skip(int count) { - if (count < 0) { - throw new IllegalArgumentException(); - } - data.position(data.position() + count); - } - - /** - * Skips bytes until the position is aligned to a multiple of 4. - */ - public void alignToFourBytes() { - data.position((data.position() + 3) & ~3); - } - - /** - * Writes 0x00 until the position is aligned to a multiple of 4. - */ - public void alignToFourBytesWithZeroFill() { - while ((data.position() & 3) != 0) { - data.put((byte) 0); - } - } - - public void assertFourByteAligned() { - if ((data.position() & 3) != 0) { - throw new IllegalStateException("Not four byte aligned!"); - } - } - - public void write(byte[] bytes) { - this.data.put(bytes); - } - - public void writeByte(int b) { - data.put((byte) b); - } - - public void writeShort(short i) { - data.putShort(i); - } - - public void writeUnsignedShort(int i) { - short s = (short) i; - if (i != (s & 0xffff)) { - throw new IllegalArgumentException("Expected an unsigned short: " + i); - } - writeShort(s); - } - - public void write(short[] shorts) { - for (short s : shorts) { - writeShort(s); - } - } - - public void writeInt(int i) { - data.putInt(i); - } - - public void writeUleb128(int i) { - try { - Leb128.writeUnsignedLeb128(this, i); - } catch (ArrayIndexOutOfBoundsException e) { - throw new DexException("Section limit " + data.limit() + " exceeded by " + name); - } - } - - public void writeSleb128(int i) { - try { - Leb128.writeSignedLeb128(this, i); - } catch (ArrayIndexOutOfBoundsException e) { - throw new DexException("Section limit " + data.limit() + " exceeded by " + name); - } - } - - public void writeStringData(String value) { - try { - int length = value.length(); - writeUleb128(length); - write(Mutf8.encode(value)); - writeByte(0); - } catch (UTFDataFormatException e) { - throw new AssertionError(); - } - } - - public void writeTypeList(TypeList typeList) { - short[] types = typeList.getTypes(); - writeInt(types.length); - for (short type : types) { - writeShort(type); - } - alignToFourBytesWithZeroFill(); - } - - /** - * Returns the number of bytes remaining in this section. - */ - public int remaining() { - return data.remaining(); - } - - /** - * Returns the number of bytes used by this section. - */ - public int used () { - return data.position() - initialPosition; - } - } - - private final class StringTable extends AbstractList implements RandomAccess { - @Override public String get(int index) { - checkBounds(index, tableOfContents.stringIds.size); - return open(tableOfContents.stringIds.off + (index * SizeOf.STRING_ID_ITEM)) - .readString(); - } - @Override public int size() { - return tableOfContents.stringIds.size; - } - }; - - private final class TypeIndexToDescriptorIndexTable extends AbstractList - implements RandomAccess { - @Override public Integer get(int index) { - return descriptorIndexFromTypeIndex(index); - } - @Override public int size() { - return tableOfContents.typeIds.size; - } - }; - - private final class TypeIndexToDescriptorTable extends AbstractList - implements RandomAccess { - @Override public String get(int index) { - return strings.get(descriptorIndexFromTypeIndex(index)); - } - @Override public int size() { - return tableOfContents.typeIds.size; - } - }; - - private final class ProtoIdTable extends AbstractList implements RandomAccess { - @Override public ProtoId get(int index) { - checkBounds(index, tableOfContents.protoIds.size); - return open(tableOfContents.protoIds.off + (SizeOf.PROTO_ID_ITEM * index)) - .readProtoId(); - } - @Override public int size() { - return tableOfContents.protoIds.size; - } - }; - - private final class FieldIdTable extends AbstractList implements RandomAccess { - @Override public FieldId get(int index) { - checkBounds(index, tableOfContents.fieldIds.size); - return open(tableOfContents.fieldIds.off + (SizeOf.MEMBER_ID_ITEM * index)) - .readFieldId(); - } - @Override public int size() { - return tableOfContents.fieldIds.size; - } - }; - - private final class MethodIdTable extends AbstractList implements RandomAccess { - @Override public MethodId get(int index) { - checkBounds(index, tableOfContents.methodIds.size); - return open(tableOfContents.methodIds.off + (SizeOf.MEMBER_ID_ITEM * index)) - .readMethodId(); - } - @Override public int size() { - return tableOfContents.methodIds.size; - } - }; - - private final class ClassDefIterator implements Iterator { - private final Dex.Section in = open(tableOfContents.classDefs.off); - private int count = 0; - - @Override - public boolean hasNext() { - return count < tableOfContents.classDefs.size; - } - @Override - public ClassDef next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - count++; - return in.readClassDef(); - } - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - - private final class ClassDefIterable implements Iterable { - public Iterator iterator() { - return !tableOfContents.classDefs.exists() - ? Collections.emptySet().iterator() - : new ClassDefIterator(); - } - }; -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dex/DexException.java b/third-party/java/dx-from-kitkat/src/com/android/dex/DexException.java deleted file mode 100644 index a30a46f7882..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dex/DexException.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dex; - -import com.android.dex.util.ExceptionWithContext; - -/** - * Thrown when there's a format problem reading, writing, or generally - * processing a dex file. - */ -public final class DexException extends ExceptionWithContext { - public DexException(String message) { - super(message); - } - - public DexException(Throwable cause) { - super(cause); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dex/DexFormat.java b/third-party/java/dx-from-kitkat/src/com/android/dex/DexFormat.java deleted file mode 100644 index 9319bc22ee1..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dex/DexFormat.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dex; - -/** - * Constants that show up in and are otherwise related to {@code .dex} - * files, and helper methods for same. - */ -public final class DexFormat { - private DexFormat() {} - - /** - * API level to target in order to produce the most modern file - * format - */ - public static final int API_CURRENT = 14; - - /** API level to target in order to suppress extended opcode usage */ - public static final int API_NO_EXTENDED_OPCODES = 13; - - /** - * file name of the primary {@code .dex} file inside an - * application or library {@code .jar} file - */ - public static final String DEX_IN_JAR_NAME = "classes.dex"; - - /** common prefix for all dex file "magic numbers" */ - public static final String MAGIC_PREFIX = "dex\n"; - - /** common suffix for all dex file "magic numbers" */ - public static final String MAGIC_SUFFIX = "\0"; - - /** dex file version number for the current format variant */ - public static final String VERSION_CURRENT = "036"; - - /** dex file version number for API level 13 and earlier */ - public static final String VERSION_FOR_API_13 = "035"; - - /** - * value used to indicate endianness of file contents - */ - public static final int ENDIAN_TAG = 0x12345678; - - /** - * Maximum addressable field or method index. - * The largest addressable member is 0xffff, in the "instruction formats" spec as field@CCCC or - * meth@CCCC. - */ - public static final int MAX_MEMBER_IDX = 0xFFFF; - - /** - * Maximum addressable type index. - * The largest addressable type is 0xffff, in the "instruction formats" spec as type@CCCC. - */ - public static final int MAX_TYPE_IDX = 0xFFFF; - - /** - * Returns the API level corresponding to the given magic number, - * or {@code -1} if the given array is not a well-formed dex file - * magic number. - */ - public static int magicToApi(byte[] magic) { - if (magic.length != 8) { - return -1; - } - - if ((magic[0] != 'd') || (magic[1] != 'e') || (magic[2] != 'x') || (magic[3] != '\n') || - (magic[7] != '\0')) { - return -1; - } - - String version = "" + ((char) magic[4]) + ((char) magic[5]) +((char) magic[6]); - - if (version.equals(VERSION_CURRENT)) { - return API_CURRENT; - } else if (version.equals(VERSION_FOR_API_13)) { - return 13; - } - - return -1; - } - - /** - * Returns the magic number corresponding to the given target API level. - */ - public static String apiToMagic(int targetApiLevel) { - String version; - - if (targetApiLevel >= API_CURRENT) { - version = VERSION_CURRENT; - } else { - version = VERSION_FOR_API_13; - } - - return MAGIC_PREFIX + version + MAGIC_SUFFIX; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dex/EncodedValue.java b/third-party/java/dx-from-kitkat/src/com/android/dex/EncodedValue.java deleted file mode 100644 index 8d0c3adcf6b..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dex/EncodedValue.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dex; - -import com.android.dex.util.ByteArrayByteInput; -import com.android.dex.util.ByteInput; - -/** - * An encoded value or array. - */ -public final class EncodedValue implements Comparable { - private final byte[] data; - - public EncodedValue(byte[] data) { - this.data = data; - } - - public ByteInput asByteInput() { - return new ByteArrayByteInput(data); - } - - public byte[] getBytes() { - return data; - } - - public void writeTo(Dex.Section out) { - out.write(data); - } - - @Override public int compareTo(EncodedValue other) { - int size = Math.min(data.length, other.data.length); - for (int i = 0; i < size; i++) { - if (data[i] != other.data[i]) { - return (data[i] & 0xff) - (other.data[i] & 0xff); - } - } - return data.length - other.data.length; - } - - @Override public String toString() { - return Integer.toHexString(data[0] & 0xff) + "...(" + data.length + ")"; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dex/EncodedValueCodec.java b/third-party/java/dx-from-kitkat/src/com/android/dex/EncodedValueCodec.java deleted file mode 100644 index 7fc1724348a..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dex/EncodedValueCodec.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dex; - -import com.android.dex.util.ByteInput; -import com.android.dex.util.ByteOutput; - -/** - * Read and write {@code encoded_value} primitives. - */ -public final class EncodedValueCodec { - private EncodedValueCodec() { - } - - /** - * Writes a signed integral to {@code out}. - */ - public static void writeSignedIntegralValue(ByteOutput out, int type, long value) { - /* - * Figure out how many bits are needed to represent the value, - * including a sign bit: The bit count is subtracted from 65 - * and not 64 to account for the sign bit. The xor operation - * has the effect of leaving non-negative values alone and - * unary complementing negative values (so that a leading zero - * count always returns a useful number for our present - * purpose). - */ - int requiredBits = 65 - Long.numberOfLeadingZeros(value ^ (value >> 63)); - - // Round up the requiredBits to a number of bytes. - int requiredBytes = (requiredBits + 0x07) >> 3; - - /* - * Write the header byte, which includes the type and - * requiredBytes - 1. - */ - out.writeByte(type | ((requiredBytes - 1) << 5)); - - // Write the value, per se. - while (requiredBytes > 0) { - out.writeByte((byte) value); - value >>= 8; - requiredBytes--; - } - } - - /** - * Writes an unsigned integral to {@code out}. - */ - public static void writeUnsignedIntegralValue(ByteOutput out, int type, long value) { - // Figure out how many bits are needed to represent the value. - int requiredBits = 64 - Long.numberOfLeadingZeros(value); - if (requiredBits == 0) { - requiredBits = 1; - } - - // Round up the requiredBits to a number of bytes. - int requiredBytes = (requiredBits + 0x07) >> 3; - - /* - * Write the header byte, which includes the type and - * requiredBytes - 1. - */ - out.writeByte(type | ((requiredBytes - 1) << 5)); - - // Write the value, per se. - while (requiredBytes > 0) { - out.writeByte((byte) value); - value >>= 8; - requiredBytes--; - } - } - - /** - * Writes a right-zero-extended value to {@code out}. - */ - public static void writeRightZeroExtendedValue(ByteOutput out, int type, long value) { - // Figure out how many bits are needed to represent the value. - int requiredBits = 64 - Long.numberOfTrailingZeros(value); - if (requiredBits == 0) { - requiredBits = 1; - } - - // Round up the requiredBits to a number of bytes. - int requiredBytes = (requiredBits + 0x07) >> 3; - - // Scootch the first bits to be written down to the low-order bits. - value >>= 64 - (requiredBytes * 8); - - /* - * Write the header byte, which includes the type and - * requiredBytes - 1. - */ - out.writeByte(type | ((requiredBytes - 1) << 5)); - - // Write the value, per se. - while (requiredBytes > 0) { - out.writeByte((byte) value); - value >>= 8; - requiredBytes--; - } - } - - /** - * Read a signed integer. - * - * @param zwidth byte count minus one - */ - public static int readSignedInt(ByteInput in, int zwidth) { - int result = 0; - for (int i = zwidth; i >= 0; i--) { - result = (result >>> 8) | ((in.readByte() & 0xff) << 24); - } - result >>= (3 - zwidth) * 8; - return result; - } - - /** - * Read an unsigned integer. - * - * @param zwidth byte count minus one - * @param fillOnRight true to zero fill on the right; false on the left - */ - public static int readUnsignedInt(ByteInput in, int zwidth, boolean fillOnRight) { - int result = 0; - if (!fillOnRight) { - for (int i = zwidth; i >= 0; i--) { - result = (result >>> 8) | ((in.readByte() & 0xff) << 24); - } - result >>>= (3 - zwidth) * 8; - } else { - for (int i = zwidth; i >= 0; i--) { - result = (result >>> 8) | ((in.readByte() & 0xff) << 24); - } - } - return result; - } - - /** - * Read a signed long. - * - * @param zwidth byte count minus one - */ - public static long readSignedLong(ByteInput in, int zwidth) { - long result = 0; - for (int i = zwidth; i >= 0; i--) { - result = (result >>> 8) | ((in.readByte() & 0xffL) << 56); - } - result >>= (7 - zwidth) * 8; - return result; - } - - /** - * Read an unsigned long. - * - * @param zwidth byte count minus one - * @param fillOnRight true to zero fill on the right; false on the left - */ - public static long readUnsignedLong(ByteInput in, int zwidth, boolean fillOnRight) { - long result = 0; - if (!fillOnRight) { - for (int i = zwidth; i >= 0; i--) { - result = (result >>> 8) | ((in.readByte() & 0xffL) << 56); - } - result >>>= (7 - zwidth) * 8; - } else { - for (int i = zwidth; i >= 0; i--) { - result = (result >>> 8) | ((in.readByte() & 0xffL) << 56); - } - } - return result; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dex/EncodedValueReader.java b/third-party/java/dx-from-kitkat/src/com/android/dex/EncodedValueReader.java deleted file mode 100644 index 6f60538a2f7..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dex/EncodedValueReader.java +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dex; - -import com.android.dex.util.ByteInput; - -/** - * Pull parser for encoded values. - */ -public final class EncodedValueReader { - public static final int ENCODED_BYTE = 0x00; - public static final int ENCODED_SHORT = 0x02; - public static final int ENCODED_CHAR = 0x03; - public static final int ENCODED_INT = 0x04; - public static final int ENCODED_LONG = 0x06; - public static final int ENCODED_FLOAT = 0x10; - public static final int ENCODED_DOUBLE = 0x11; - public static final int ENCODED_STRING = 0x17; - public static final int ENCODED_TYPE = 0x18; - public static final int ENCODED_FIELD = 0x19; - public static final int ENCODED_ENUM = 0x1b; - public static final int ENCODED_METHOD = 0x1a; - public static final int ENCODED_ARRAY = 0x1c; - public static final int ENCODED_ANNOTATION = 0x1d; - public static final int ENCODED_NULL = 0x1e; - public static final int ENCODED_BOOLEAN = 0x1f; - - /** placeholder type if the type is not yet known */ - private static final int MUST_READ = -1; - - protected final ByteInput in; - private int type = MUST_READ; - private int annotationType; - private int arg; - - public EncodedValueReader(ByteInput in) { - this.in = in; - } - - public EncodedValueReader(EncodedValue in) { - this(in.asByteInput()); - } - - /** - * Creates a new encoded value reader whose only value is the specified - * known type. This is useful for encoded values without a type prefix, - * such as class_def_item's encoded_array or annotation_item's - * encoded_annotation. - */ - public EncodedValueReader(ByteInput in, int knownType) { - this.in = in; - this.type = knownType; - } - - public EncodedValueReader(EncodedValue in, int knownType) { - this(in.asByteInput(), knownType); - } - - /** - * Returns the type of the next value to read. - */ - public int peek() { - if (type == MUST_READ) { - int argAndType = in.readByte() & 0xff; - type = argAndType & 0x1f; - arg = (argAndType & 0xe0) >> 5; - } - return type; - } - - /** - * Begins reading the elements of an array, returning the array's size. The - * caller must follow up by calling a read method for each element in the - * array. For example, this reads a byte array:
   {@code
-     *   int arraySize = readArray();
-     *   for (int i = 0, i < arraySize; i++) {
-     *     readByte();
-     *   }
-     * }
- */ - public int readArray() { - checkType(ENCODED_ARRAY); - type = MUST_READ; - return Leb128.readUnsignedLeb128(in); - } - - /** - * Begins reading the fields of an annotation, returning the number of - * fields. The caller must follow up by making alternating calls to {@link - * #readAnnotationName()} and another read method. For example, this reads - * an annotation whose fields are all bytes:
   {@code
-     *   int fieldCount = readAnnotation();
-     *   int annotationType = getAnnotationType();
-     *   for (int i = 0; i < fieldCount; i++) {
-     *       readAnnotationName();
-     *       readByte();
-     *   }
-     * }
- */ - public int readAnnotation() { - checkType(ENCODED_ANNOTATION); - type = MUST_READ; - annotationType = Leb128.readUnsignedLeb128(in); - return Leb128.readUnsignedLeb128(in); - } - - /** - * Returns the type of the annotation just returned by {@link - * #readAnnotation()}. This method's value is undefined unless the most - * recent call was to {@link #readAnnotation()}. - */ - public int getAnnotationType() { - return annotationType; - } - - public int readAnnotationName() { - return Leb128.readUnsignedLeb128(in); - } - - public byte readByte() { - checkType(ENCODED_BYTE); - type = MUST_READ; - return (byte) EncodedValueCodec.readSignedInt(in, arg); - } - - public short readShort() { - checkType(ENCODED_SHORT); - type = MUST_READ; - return (short) EncodedValueCodec.readSignedInt(in, arg); - } - - public char readChar() { - checkType(ENCODED_CHAR); - type = MUST_READ; - return (char) EncodedValueCodec.readUnsignedInt(in, arg, false); - } - - public int readInt() { - checkType(ENCODED_INT); - type = MUST_READ; - return EncodedValueCodec.readSignedInt(in, arg); - } - - public long readLong() { - checkType(ENCODED_LONG); - type = MUST_READ; - return EncodedValueCodec.readSignedLong(in, arg); - } - - public float readFloat() { - checkType(ENCODED_FLOAT); - type = MUST_READ; - return Float.intBitsToFloat(EncodedValueCodec.readUnsignedInt(in, arg, true)); - } - - public double readDouble() { - checkType(ENCODED_DOUBLE); - type = MUST_READ; - return Double.longBitsToDouble(EncodedValueCodec.readUnsignedLong(in, arg, true)); - } - - public int readString() { - checkType(ENCODED_STRING); - type = MUST_READ; - return EncodedValueCodec.readUnsignedInt(in, arg, false); - } - - public int readType() { - checkType(ENCODED_TYPE); - type = MUST_READ; - return EncodedValueCodec.readUnsignedInt(in, arg, false); - } - - public int readField() { - checkType(ENCODED_FIELD); - type = MUST_READ; - return EncodedValueCodec.readUnsignedInt(in, arg, false); - } - - public int readEnum() { - checkType(ENCODED_ENUM); - type = MUST_READ; - return EncodedValueCodec.readUnsignedInt(in, arg, false); - } - - public int readMethod() { - checkType(ENCODED_METHOD); - type = MUST_READ; - return EncodedValueCodec.readUnsignedInt(in, arg, false); - } - - public void readNull() { - checkType(ENCODED_NULL); - type = MUST_READ; - } - - public boolean readBoolean() { - checkType(ENCODED_BOOLEAN); - type = MUST_READ; - return arg != 0; - } - - /** - * Skips a single value, including its nested values if it is an array or - * annotation. - */ - public void skipValue() { - switch (peek()) { - case ENCODED_BYTE: - readByte(); - break; - case ENCODED_SHORT: - readShort(); - break; - case ENCODED_CHAR: - readChar(); - break; - case ENCODED_INT: - readInt(); - break; - case ENCODED_LONG: - readLong(); - break; - case ENCODED_FLOAT: - readFloat(); - break; - case ENCODED_DOUBLE: - readDouble(); - break; - case ENCODED_STRING: - readString(); - break; - case ENCODED_TYPE: - readType(); - break; - case ENCODED_FIELD: - readField(); - break; - case ENCODED_ENUM: - readEnum(); - break; - case ENCODED_METHOD: - readMethod(); - break; - case ENCODED_ARRAY: - for (int i = 0, size = readArray(); i < size; i++) { - skipValue(); - } - break; - case ENCODED_ANNOTATION: - for (int i = 0, size = readAnnotation(); i < size; i++) { - readAnnotationName(); - skipValue(); - } - break; - case ENCODED_NULL: - readNull(); - break; - case ENCODED_BOOLEAN: - readBoolean(); - break; - default: - throw new DexException("Unexpected type: " + Integer.toHexString(type)); - } - } - - private void checkType(int expected) { - if (peek() != expected) { - throw new IllegalStateException( - String.format("Expected %x but was %x", expected, peek())); - } - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dex/FieldId.java b/third-party/java/dx-from-kitkat/src/com/android/dex/FieldId.java deleted file mode 100644 index 2f41708c826..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dex/FieldId.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dex; - -import com.android.dex.util.Unsigned; - -public final class FieldId implements Comparable { - private final Dex dex; - private final int declaringClassIndex; - private final int typeIndex; - private final int nameIndex; - - public FieldId(Dex dex, int declaringClassIndex, int typeIndex, int nameIndex) { - this.dex = dex; - this.declaringClassIndex = declaringClassIndex; - this.typeIndex = typeIndex; - this.nameIndex = nameIndex; - } - - public int getDeclaringClassIndex() { - return declaringClassIndex; - } - - public int getTypeIndex() { - return typeIndex; - } - - public int getNameIndex() { - return nameIndex; - } - - public int compareTo(FieldId other) { - if (declaringClassIndex != other.declaringClassIndex) { - return Unsigned.compare(declaringClassIndex, other.declaringClassIndex); - } - if (nameIndex != other.nameIndex) { - return Unsigned.compare(nameIndex, other.nameIndex); - } - return Unsigned.compare(typeIndex, other.typeIndex); // should always be 0 - } - - public void writeTo(Dex.Section out) { - out.writeUnsignedShort(declaringClassIndex); - out.writeUnsignedShort(typeIndex); - out.writeInt(nameIndex); - } - - @Override public String toString() { - if (dex == null) { - return declaringClassIndex + " " + typeIndex + " " + nameIndex; - } - return dex.typeNames().get(typeIndex) + "." + dex.strings().get(nameIndex); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dex/Leb128.java b/third-party/java/dx-from-kitkat/src/com/android/dex/Leb128.java deleted file mode 100644 index 1a82e383e9f..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dex/Leb128.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dex; - -import com.android.dex.util.ByteInput; -import com.android.dex.util.ByteOutput; - -/** - * Reads and writes DWARFv3 LEB 128 signed and unsigned integers. See DWARF v3 - * section 7.6. - */ -public final class Leb128 { - private Leb128() { - } - - /** - * Gets the number of bytes in the unsigned LEB128 encoding of the - * given value. - * - * @param value the value in question - * @return its write size, in bytes - */ - public static int unsignedLeb128Size(int value) { - // TODO: This could be much cleverer. - - int remaining = value >> 7; - int count = 0; - - while (remaining != 0) { - remaining >>= 7; - count++; - } - - return count + 1; - } - - /** - * Gets the number of bytes in the signed LEB128 encoding of the - * given value. - * - * @param value the value in question - * @return its write size, in bytes - */ - public static int signedLeb128Size(int value) { - // TODO: This could be much cleverer. - - int remaining = value >> 7; - int count = 0; - boolean hasMore = true; - int end = ((value & Integer.MIN_VALUE) == 0) ? 0 : -1; - - while (hasMore) { - hasMore = (remaining != end) - || ((remaining & 1) != ((value >> 6) & 1)); - - value = remaining; - remaining >>= 7; - count++; - } - - return count; - } - - /** - * Reads an signed integer from {@code in}. - */ - public static int readSignedLeb128(ByteInput in) { - int result = 0; - int cur; - int count = 0; - int signBits = -1; - - do { - cur = in.readByte() & 0xff; - result |= (cur & 0x7f) << (count * 7); - signBits <<= 7; - count++; - } while (((cur & 0x80) == 0x80) && count < 5); - - if ((cur & 0x80) == 0x80) { - throw new DexException("invalid LEB128 sequence"); - } - - // Sign extend if appropriate - if (((signBits >> 1) & result) != 0 ) { - result |= signBits; - } - - return result; - } - - /** - * Reads an unsigned integer from {@code in}. - */ - public static int readUnsignedLeb128(ByteInput in) { - int result = 0; - int cur; - int count = 0; - - do { - cur = in.readByte() & 0xff; - result |= (cur & 0x7f) << (count * 7); - count++; - } while (((cur & 0x80) == 0x80) && count < 5); - - if ((cur & 0x80) == 0x80) { - throw new DexException("invalid LEB128 sequence"); - } - - return result; - } - - /** - * Writes {@code value} as an unsigned integer to {@code out}, starting at - * {@code offset}. Returns the number of bytes written. - */ - public static void writeUnsignedLeb128(ByteOutput out, int value) { - int remaining = value >>> 7; - - while (remaining != 0) { - out.writeByte((byte) ((value & 0x7f) | 0x80)); - value = remaining; - remaining >>>= 7; - } - - out.writeByte((byte) (value & 0x7f)); - } - - /** - * Writes {@code value} as a signed integer to {@code out}, starting at - * {@code offset}. Returns the number of bytes written. - */ - public static void writeSignedLeb128(ByteOutput out, int value) { - int remaining = value >> 7; - boolean hasMore = true; - int end = ((value & Integer.MIN_VALUE) == 0) ? 0 : -1; - - while (hasMore) { - hasMore = (remaining != end) - || ((remaining & 1) != ((value >> 6) & 1)); - - out.writeByte((byte) ((value & 0x7f) | (hasMore ? 0x80 : 0))); - value = remaining; - remaining >>= 7; - } - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dex/MethodId.java b/third-party/java/dx-from-kitkat/src/com/android/dex/MethodId.java deleted file mode 100644 index e518740265c..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dex/MethodId.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dex; - -import com.android.dex.util.Unsigned; - -public final class MethodId implements Comparable { - private final Dex dex; - private final int declaringClassIndex; - private final int protoIndex; - private final int nameIndex; - - public MethodId(Dex dex, int declaringClassIndex, int protoIndex, int nameIndex) { - this.dex = dex; - this.declaringClassIndex = declaringClassIndex; - this.protoIndex = protoIndex; - this.nameIndex = nameIndex; - } - - public int getDeclaringClassIndex() { - return declaringClassIndex; - } - - public int getProtoIndex() { - return protoIndex; - } - - public int getNameIndex() { - return nameIndex; - } - - public int compareTo(MethodId other) { - if (declaringClassIndex != other.declaringClassIndex) { - return Unsigned.compare(declaringClassIndex, other.declaringClassIndex); - } - if (nameIndex != other.nameIndex) { - return Unsigned.compare(nameIndex, other.nameIndex); - } - return Unsigned.compare(protoIndex, other.protoIndex); - } - - public void writeTo(Dex.Section out) { - out.writeUnsignedShort(declaringClassIndex); - out.writeUnsignedShort(protoIndex); - out.writeInt(nameIndex); - } - - @Override public String toString() { - if (dex == null) { - return declaringClassIndex + " " + protoIndex + " " + nameIndex; - } - return dex.typeNames().get(declaringClassIndex) - + "." + dex.strings().get(nameIndex) - + dex.readTypeList(dex.protoIds().get(protoIndex).getParametersOffset()); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dex/Mutf8.java b/third-party/java/dx-from-kitkat/src/com/android/dex/Mutf8.java deleted file mode 100644 index c64da331b3b..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dex/Mutf8.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dex; - -import com.android.dex.util.ByteInput; -import java.io.UTFDataFormatException; - -/** - * Modified UTF-8 as described in the dex file format spec. - * - *

Derived from libcore's MUTF-8 encoder at java.nio.charset.ModifiedUtf8. - */ -public final class Mutf8 { - private Mutf8() {} - - /** - * Decodes bytes from {@code in} into {@code out} until a delimiter 0x00 is - * encountered. Returns a new string containing the decoded characters. - */ - public static String decode(ByteInput in, char[] out) throws UTFDataFormatException { - int s = 0; - while (true) { - char a = (char) (in.readByte() & 0xff); - if (a == 0) { - return new String(out, 0, s); - } - out[s] = a; - if (a < '\u0080') { - s++; - } else if ((a & 0xe0) == 0xc0) { - int b = in.readByte() & 0xff; - if ((b & 0xC0) != 0x80) { - throw new UTFDataFormatException("bad second byte"); - } - out[s++] = (char) (((a & 0x1F) << 6) | (b & 0x3F)); - } else if ((a & 0xf0) == 0xe0) { - int b = in.readByte() & 0xff; - int c = in.readByte() & 0xff; - if (((b & 0xC0) != 0x80) || ((c & 0xC0) != 0x80)) { - throw new UTFDataFormatException("bad second or third byte"); - } - out[s++] = (char) (((a & 0x0F) << 12) | ((b & 0x3F) << 6) | (c & 0x3F)); - } else { - throw new UTFDataFormatException("bad byte"); - } - } - } - - /** - * Returns the number of bytes the modified UTF8 representation of 's' would take. - */ - private static long countBytes(String s, boolean shortLength) throws UTFDataFormatException { - long result = 0; - final int length = s.length(); - for (int i = 0; i < length; ++i) { - char ch = s.charAt(i); - if (ch != 0 && ch <= 127) { // U+0000 uses two bytes. - ++result; - } else if (ch <= 2047) { - result += 2; - } else { - result += 3; - } - if (shortLength && result > 65535) { - throw new UTFDataFormatException("String more than 65535 UTF bytes long"); - } - } - return result; - } - - /** - * Encodes the modified UTF-8 bytes corresponding to {@code s} into {@code - * dst}, starting at {@code offset}. - */ - public static void encode(byte[] dst, int offset, String s) { - final int length = s.length(); - for (int i = 0; i < length; i++) { - char ch = s.charAt(i); - if (ch != 0 && ch <= 127) { // U+0000 uses two bytes. - dst[offset++] = (byte) ch; - } else if (ch <= 2047) { - dst[offset++] = (byte) (0xc0 | (0x1f & (ch >> 6))); - dst[offset++] = (byte) (0x80 | (0x3f & ch)); - } else { - dst[offset++] = (byte) (0xe0 | (0x0f & (ch >> 12))); - dst[offset++] = (byte) (0x80 | (0x3f & (ch >> 6))); - dst[offset++] = (byte) (0x80 | (0x3f & ch)); - } - } - } - - /** - * Returns an array containing the modified UTF-8 form of {@code s}. - */ - public static byte[] encode(String s) throws UTFDataFormatException { - int utfCount = (int) countBytes(s, true); - byte[] result = new byte[utfCount]; - encode(result, 0, s); - return result; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dex/ProtoId.java b/third-party/java/dx-from-kitkat/src/com/android/dex/ProtoId.java deleted file mode 100644 index 9d9f484f24f..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dex/ProtoId.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dex; - -import com.android.dex.util.Unsigned; - -public final class ProtoId implements Comparable { - private final Dex dex; - private final int shortyIndex; - private final int returnTypeIndex; - private final int parametersOffset; - - public ProtoId(Dex dex, int shortyIndex, int returnTypeIndex, int parametersOffset) { - this.dex = dex; - this.shortyIndex = shortyIndex; - this.returnTypeIndex = returnTypeIndex; - this.parametersOffset = parametersOffset; - } - - public int compareTo(ProtoId other) { - if (returnTypeIndex != other.returnTypeIndex) { - return Unsigned.compare(returnTypeIndex, other.returnTypeIndex); - } - return Unsigned.compare(parametersOffset, other.parametersOffset); - } - - public int getShortyIndex() { - return shortyIndex; - } - - public int getReturnTypeIndex() { - return returnTypeIndex; - } - - public int getParametersOffset() { - return parametersOffset; - } - - public void writeTo(Dex.Section out) { - out.writeInt(shortyIndex); - out.writeInt(returnTypeIndex); - out.writeInt(parametersOffset); - } - - @Override public String toString() { - if (dex == null) { - return shortyIndex + " " + returnTypeIndex + " " + parametersOffset; - } - - return dex.strings().get(shortyIndex) - + ": " + dex.typeNames().get(returnTypeIndex) - + " " + dex.readTypeList(parametersOffset); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dex/SizeOf.java b/third-party/java/dx-from-kitkat/src/com/android/dex/SizeOf.java deleted file mode 100644 index 65fab565b34..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dex/SizeOf.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dex; - -public final class SizeOf { - private SizeOf() {} - - public static final int UBYTE = 1; - public static final int USHORT = 2; - public static final int UINT = 4; - - public static final int SIGNATURE = UBYTE * 20; - - /** - * magic ubyte[8] - * checksum uint - * signature ubyte[20] - * file_size uint - * header_size uint - * endian_tag uint - * link_size uint - * link_off uint - * map_off uint - * string_ids_size uint - * string_ids_off uint - * type_ids_size uint - * type_ids_off uint - * proto_ids_size uint - * proto_ids_off uint - * field_ids_size uint - * field_ids_off uint - * method_ids_size uint - * method_ids_off uint - * class_defs_size uint - * class_defs_off uint - * data_size uint - * data_off uint - */ - public static final int HEADER_ITEM = (8 * UBYTE) + UINT + SIGNATURE + (20 * UINT); // 0x70 - - /** - * string_data_off uint - */ - public static final int STRING_ID_ITEM = UINT; - - /** - * descriptor_idx uint - */ - public static final int TYPE_ID_ITEM = UINT; - - /** - * type_idx ushort - */ - public static final int TYPE_ITEM = USHORT; - - /** - * shorty_idx uint - * return_type_idx uint - * return_type_idx uint - */ - public static final int PROTO_ID_ITEM = UINT + UINT + UINT; - - /** - * class_idx ushort - * type_idx/proto_idx ushort - * name_idx uint - */ - public static final int MEMBER_ID_ITEM = USHORT + USHORT + UINT; - - /** - * class_idx uint - * access_flags uint - * superclass_idx uint - * interfaces_off uint - * source_file_idx uint - * annotations_off uint - * class_data_off uint - * static_values_off uint - */ - public static final int CLASS_DEF_ITEM = 8 * UINT; - - /** - * type ushort - * unused ushort - * size uint - * offset uint - */ - public static final int MAP_ITEM = USHORT + USHORT + UINT + UINT; - - /** - * start_addr uint - * insn_count ushort - * handler_off ushort - */ - public static final int TRY_ITEM = UINT + USHORT + USHORT; -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dex/TableOfContents.java b/third-party/java/dx-from-kitkat/src/com/android/dex/TableOfContents.java deleted file mode 100644 index d1b87ac8fc4..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dex/TableOfContents.java +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dex; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.util.Arrays; - -/** - * The file header and map. - */ -public final class TableOfContents { - - /* - * TODO: factor out ID constants. - */ - - public final Section header = new Section(0x0000); - public final Section stringIds = new Section(0x0001); - public final Section typeIds = new Section(0x0002); - public final Section protoIds = new Section(0x0003); - public final Section fieldIds = new Section(0x0004); - public final Section methodIds = new Section(0x0005); - public final Section classDefs = new Section(0x0006); - public final Section mapList = new Section(0x1000); - public final Section typeLists = new Section(0x1001); - public final Section annotationSetRefLists = new Section(0x1002); - public final Section annotationSets = new Section(0x1003); - public final Section classDatas = new Section(0x2000); - public final Section codes = new Section(0x2001); - public final Section stringDatas = new Section(0x2002); - public final Section debugInfos = new Section(0x2003); - public final Section annotations = new Section(0x2004); - public final Section encodedArrays = new Section(0x2005); - public final Section annotationsDirectories = new Section(0x2006); - public final Section[] sections = { - header, stringIds, typeIds, protoIds, fieldIds, methodIds, classDefs, mapList, - typeLists, annotationSetRefLists, annotationSets, classDatas, codes, stringDatas, - debugInfos, annotations, encodedArrays, annotationsDirectories - }; - - public int checksum; - public byte[] signature; - public int fileSize; - public int linkSize; - public int linkOff; - public int dataSize; - public int dataOff; - - public TableOfContents() { - signature = new byte[20]; - } - - public void readFrom(Dex dex) throws IOException { - readHeader(dex.open(0)); - readMap(dex.open(mapList.off)); - computeSizesFromOffsets(); - } - - private void readHeader(Dex.Section headerIn) throws UnsupportedEncodingException { - byte[] magic = headerIn.readByteArray(8); - int apiTarget = DexFormat.magicToApi(magic); - - if (apiTarget != DexFormat.API_NO_EXTENDED_OPCODES) { - throw new DexException("Unexpected magic: " + Arrays.toString(magic)); - } - - checksum = headerIn.readInt(); - signature = headerIn.readByteArray(20); - fileSize = headerIn.readInt(); - int headerSize = headerIn.readInt(); - if (headerSize != SizeOf.HEADER_ITEM) { - throw new DexException("Unexpected header: 0x" + Integer.toHexString(headerSize)); - } - int endianTag = headerIn.readInt(); - if (endianTag != DexFormat.ENDIAN_TAG) { - throw new DexException("Unexpected endian tag: 0x" + Integer.toHexString(endianTag)); - } - linkSize = headerIn.readInt(); - linkOff = headerIn.readInt(); - mapList.off = headerIn.readInt(); - if (mapList.off == 0) { - throw new DexException("Cannot merge dex files that do not contain a map"); - } - stringIds.size = headerIn.readInt(); - stringIds.off = headerIn.readInt(); - typeIds.size = headerIn.readInt(); - typeIds.off = headerIn.readInt(); - protoIds.size = headerIn.readInt(); - protoIds.off = headerIn.readInt(); - fieldIds.size = headerIn.readInt(); - fieldIds.off = headerIn.readInt(); - methodIds.size = headerIn.readInt(); - methodIds.off = headerIn.readInt(); - classDefs.size = headerIn.readInt(); - classDefs.off = headerIn.readInt(); - dataSize = headerIn.readInt(); - dataOff = headerIn.readInt(); - } - - private void readMap(Dex.Section in) throws IOException { - int mapSize = in.readInt(); - Section previous = null; - for (int i = 0; i < mapSize; i++) { - short type = in.readShort(); - in.readShort(); // unused - Section section = getSection(type); - int size = in.readInt(); - int offset = in.readInt(); - - if ((section.size != 0 && section.size != size) - || (section.off != -1 && section.off != offset)) { - throw new DexException("Unexpected map value for 0x" + Integer.toHexString(type)); - } - - section.size = size; - section.off = offset; - - if (previous != null && previous.off > section.off) { - throw new DexException("Map is unsorted at " + previous + ", " + section); - } - - previous = section; - } - Arrays.sort(sections); - } - - public void computeSizesFromOffsets() { - int end = dataOff + dataSize; - for (int i = sections.length - 1; i >= 0; i--) { - Section section = sections[i]; - if (section.off == -1) { - continue; - } - if (section.off > end) { - throw new DexException("Map is unsorted at " + section); - } - section.byteCount = end - section.off; - end = section.off; - } - } - - private Section getSection(short type) { - for (Section section : sections) { - if (section.type == type) { - return section; - } - } - throw new IllegalArgumentException("No such map item: " + type); - } - - public void writeHeader(Dex.Section out) throws IOException { - out.write(DexFormat.apiToMagic(DexFormat.API_NO_EXTENDED_OPCODES).getBytes("UTF-8")); - out.writeInt(checksum); - out.write(signature); - out.writeInt(fileSize); - out.writeInt(SizeOf.HEADER_ITEM); - out.writeInt(DexFormat.ENDIAN_TAG); - out.writeInt(linkSize); - out.writeInt(linkOff); - out.writeInt(mapList.off); - out.writeInt(stringIds.size); - out.writeInt(stringIds.off); - out.writeInt(typeIds.size); - out.writeInt(typeIds.off); - out.writeInt(protoIds.size); - out.writeInt(protoIds.off); - out.writeInt(fieldIds.size); - out.writeInt(fieldIds.off); - out.writeInt(methodIds.size); - out.writeInt(methodIds.off); - out.writeInt(classDefs.size); - out.writeInt(classDefs.off); - out.writeInt(dataSize); - out.writeInt(dataOff); - } - - public void writeMap(Dex.Section out) throws IOException { - int count = 0; - for (Section section : sections) { - if (section.exists()) { - count++; - } - } - - out.writeInt(count); - for (Section section : sections) { - if (section.exists()) { - out.writeShort(section.type); - out.writeShort((short) 0); - out.writeInt(section.size); - out.writeInt(section.off); - } - } - } - - public static class Section implements Comparable

{ - public final short type; - public int size = 0; - public int off = -1; - public int byteCount = 0; - - public Section(int type) { - this.type = (short) type; - } - - public boolean exists() { - return size > 0; - } - - public int compareTo(Section section) { - if (off != section.off) { - return off < section.off ? -1 : 1; - } - return 0; - } - - @Override public String toString() { - return String.format("Section[type=%#x,off=%#x,size=%#x]", type, off, size); - } - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dex/TypeList.java b/third-party/java/dx-from-kitkat/src/com/android/dex/TypeList.java deleted file mode 100644 index 123e82c9ae0..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dex/TypeList.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dex; - -import com.android.dex.util.Unsigned; - -public final class TypeList implements Comparable { - - public static final TypeList EMPTY = new TypeList(null, Dex.EMPTY_SHORT_ARRAY); - - private final Dex dex; - private final short[] types; - - public TypeList(Dex dex, short[] types) { - this.dex = dex; - this.types = types; - } - - public short[] getTypes() { - return types; - } - - @Override public int compareTo(TypeList other) { - for (int i = 0; i < types.length && i < other.types.length; i++) { - if (types[i] != other.types[i]) { - return Unsigned.compare(types[i], other.types[i]); - } - } - return Unsigned.compare(types.length, other.types.length); - } - - @Override public String toString() { - StringBuilder result = new StringBuilder(); - result.append("("); - for (int i = 0, typesLength = types.length; i < typesLength; i++) { - result.append(dex != null ? dex.typeNames().get(types[i]) : types[i]); - } - result.append(")"); - return result.toString(); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dex/util/ByteArrayByteInput.java b/third-party/java/dx-from-kitkat/src/com/android/dex/util/ByteArrayByteInput.java deleted file mode 100644 index 889a936c515..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dex/util/ByteArrayByteInput.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dex.util; - -public final class ByteArrayByteInput implements ByteInput { - - private final byte[] bytes; - private int position; - - public ByteArrayByteInput(byte... bytes) { - this.bytes = bytes; - } - - @Override public byte readByte() { - return bytes[position++]; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dex/util/ByteInput.java b/third-party/java/dx-from-kitkat/src/com/android/dex/util/ByteInput.java deleted file mode 100644 index f1a7196142f..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dex/util/ByteInput.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dex.util; - -/** - * A byte source. - */ -public interface ByteInput { - - /** - * Returns a byte. - * - * @throws IndexOutOfBoundsException if all bytes have been read. - */ - byte readByte(); -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dex/util/ByteOutput.java b/third-party/java/dx-from-kitkat/src/com/android/dex/util/ByteOutput.java deleted file mode 100644 index eb77040ecb8..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dex/util/ByteOutput.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dex.util; - -/** - * A byte sink. - */ -public interface ByteOutput { - - /** - * Writes a byte. - * - * @throws IndexOutOfBoundsException if all bytes have been written. - */ - void writeByte(int i); -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dex/util/ExceptionWithContext.java b/third-party/java/dx-from-kitkat/src/com/android/dex/util/ExceptionWithContext.java deleted file mode 100644 index 5dfd9547449..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dex/util/ExceptionWithContext.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dex.util; - -import java.io.PrintStream; -import java.io.PrintWriter; - -/** - * Exception which carries around structured context. - */ -public class ExceptionWithContext extends RuntimeException { - /** {@code non-null;} human-oriented context of the exception */ - private StringBuffer context; - - /** - * Augments the given exception with the given context, and return the - * result. The result is either the given exception if it was an - * {@link ExceptionWithContext}, or a newly-constructed exception if it - * was not. - * - * @param ex {@code non-null;} the exception to augment - * @param str {@code non-null;} context to add - * @return {@code non-null;} an appropriate instance - */ - public static ExceptionWithContext withContext(Throwable ex, String str) { - ExceptionWithContext ewc; - - if (ex instanceof ExceptionWithContext) { - ewc = (ExceptionWithContext) ex; - } else { - ewc = new ExceptionWithContext(ex); - } - - ewc.addContext(str); - return ewc; - } - - /** - * Constructs an instance. - * - * @param message human-oriented message - */ - public ExceptionWithContext(String message) { - this(message, null); - } - - /** - * Constructs an instance. - * - * @param cause {@code null-ok;} exception that caused this one - */ - public ExceptionWithContext(Throwable cause) { - this(null, cause); - } - - /** - * Constructs an instance. - * - * @param message human-oriented message - * @param cause {@code null-ok;} exception that caused this one - */ - public ExceptionWithContext(String message, Throwable cause) { - super((message != null) ? message : - (cause != null) ? cause.getMessage() : null, - cause); - - if (cause instanceof ExceptionWithContext) { - String ctx = ((ExceptionWithContext) cause).context.toString(); - context = new StringBuffer(ctx.length() + 200); - context.append(ctx); - } else { - context = new StringBuffer(200); - } - } - - /** {@inheritDoc} */ - @Override - public void printStackTrace(PrintStream out) { - super.printStackTrace(out); - out.println(context); - } - - /** {@inheritDoc} */ - @Override - public void printStackTrace(PrintWriter out) { - super.printStackTrace(out); - out.println(context); - } - - /** - * Adds a line of context to this instance. - * - * @param str {@code non-null;} new context - */ - public void addContext(String str) { - if (str == null) { - throw new NullPointerException("str == null"); - } - - context.append(str); - if (!str.endsWith("\n")) { - context.append('\n'); - } - } - - /** - * Gets the context. - * - * @return {@code non-null;} the context - */ - public String getContext() { - return context.toString(); - } - - /** - * Prints the message and context. - * - * @param out {@code non-null;} where to print to - */ - public void printContext(PrintStream out) { - out.println(getMessage()); - out.print(context); - } - - /** - * Prints the message and context. - * - * @param out {@code non-null;} where to print to - */ - public void printContext(PrintWriter out) { - out.println(getMessage()); - out.print(context); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dex/util/FileUtils.java b/third-party/java/dx-from-kitkat/src/com/android/dex/util/FileUtils.java deleted file mode 100644 index 0780ed02af9..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dex/util/FileUtils.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dex.util; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; - -/** - * File I/O utilities. - */ -public final class FileUtils { - private FileUtils() { - } - - /** - * Reads the named file, translating {@link IOException} to a - * {@link RuntimeException} of some sort. - * - * @param fileName {@code non-null;} name of the file to read - * @return {@code non-null;} contents of the file - */ - public static byte[] readFile(String fileName) { - File file = new File(fileName); - return readFile(file); - } - - /** - * Reads the given file, translating {@link IOException} to a - * {@link RuntimeException} of some sort. - * - * @param file {@code non-null;} the file to read - * @return {@code non-null;} contents of the file - */ - public static byte[] readFile(File file) { - if (!file.exists()) { - throw new RuntimeException(file + ": file not found"); - } - - if (!file.isFile()) { - throw new RuntimeException(file + ": not a file"); - } - - if (!file.canRead()) { - throw new RuntimeException(file + ": file not readable"); - } - - long longLength = file.length(); - int length = (int) longLength; - if (length != longLength) { - throw new RuntimeException(file + ": file too long"); - } - - byte[] result = new byte[length]; - - try (FileInputStream in = new FileInputStream(file)) { - int at = 0; - while (length > 0) { - int amt = in.read(result, at, length); - if (amt == -1) { - throw new RuntimeException(file + ": unexpected EOF"); - } - at += amt; - length -= amt; - } - } catch (IOException ex) { - throw new RuntimeException(file + ": trouble reading", ex); - } - - return result; - } - - /** - * Returns true if {@code fileName} names a .zip, .jar, or .apk. - */ - public static boolean hasArchiveSuffix(String fileName) { - return fileName.endsWith(".zip") - || fileName.endsWith(".jar") - || fileName.endsWith(".apk"); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dex/util/Unsigned.java b/third-party/java/dx-from-kitkat/src/com/android/dex/util/Unsigned.java deleted file mode 100644 index cb50d0a40a2..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dex/util/Unsigned.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dex.util; - -/** - * Unsigned arithmetic over Java's signed types. - */ -public final class Unsigned { - private Unsigned() {} - - public static int compare(short ushortA, short ushortB) { - if (ushortA == ushortB) { - return 0; - } - int a = ushortA & 0xFFFF; - int b = ushortB & 0xFFFF; - return a < b ? -1 : 1; - } - - public static int compare(int uintA, int uintB) { - if (uintA == uintB) { - return 0; - } - long a = uintA & 0xFFFFFFFFL; - long b = uintB & 0xFFFFFFFFL; - return a < b ? -1 : 1; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/Version.java b/third-party/java/dx-from-kitkat/src/com/android/dx/Version.java deleted file mode 100644 index e2529966e01..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/Version.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx; - -/** - * Version number for dx. - */ -public class Version { - /** {@code non-null;} version string */ - public static final String VERSION = "1.8"; -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttAnnotationDefault.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttAnnotationDefault.java deleted file mode 100644 index fe0b3abfe71..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttAnnotationDefault.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.attrib; - -import com.android.dx.rop.cst.Constant; - -/** - * Attribute class for {@code AnnotationDefault} attributes. - */ -public final class AttAnnotationDefault extends BaseAttribute { - /** {@code non-null;} attribute name for attributes of this type */ - public static final String ATTRIBUTE_NAME = "AnnotationDefault"; - - /** {@code non-null;} the annotation default value */ - private final Constant value; - - /** {@code >= 0;} attribute data length in the original classfile (not - * including the attribute header) */ - private final int byteLength; - - /** - * Constructs an instance. - * - * @param value {@code non-null;} the annotation default value - * @param byteLength {@code >= 0;} attribute data length in the original - * classfile (not including the attribute header) - */ - public AttAnnotationDefault(Constant value, int byteLength) { - super(ATTRIBUTE_NAME); - - if (value == null) { - throw new NullPointerException("value == null"); - } - - this.value = value; - this.byteLength = byteLength; - } - - /** {@inheritDoc} */ - public int byteLength() { - // Add six for the standard attribute header. - return byteLength + 6; - } - - /** - * Gets the annotation default value. - * - * @return {@code non-null;} the value - */ - public Constant getValue() { - return value; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttCode.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttCode.java deleted file mode 100644 index 8d34c69e93d..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttCode.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.attrib; - -import com.android.dx.cf.code.ByteCatchList; -import com.android.dx.cf.code.BytecodeArray; -import com.android.dx.cf.iface.AttributeList; -import com.android.dx.util.MutabilityException; - -/** - * Attribute class for standard {@code Code} attributes. - */ -public final class AttCode extends BaseAttribute { - /** {@code non-null;} attribute name for attributes of this type */ - public static final String ATTRIBUTE_NAME = "Code"; - - /** {@code >= 0;} the stack size */ - private final int maxStack; - - /** {@code >= 0;} the number of locals */ - private final int maxLocals; - - /** {@code non-null;} array containing the bytecode per se */ - private final BytecodeArray code; - - /** {@code non-null;} the exception table */ - private final ByteCatchList catches; - - /** {@code non-null;} the associated list of attributes */ - private final AttributeList attributes; - - /** - * Constructs an instance. - * - * @param maxStack {@code >= 0;} the stack size - * @param maxLocals {@code >= 0;} the number of locals - * @param code {@code non-null;} array containing the bytecode per se - * @param catches {@code non-null;} the exception table - * @param attributes {@code non-null;} the associated list of attributes - */ - public AttCode(int maxStack, int maxLocals, BytecodeArray code, - ByteCatchList catches, AttributeList attributes) { - super(ATTRIBUTE_NAME); - - if (maxStack < 0) { - throw new IllegalArgumentException("maxStack < 0"); - } - - if (maxLocals < 0) { - throw new IllegalArgumentException("maxLocals < 0"); - } - - if (code == null) { - throw new NullPointerException("code == null"); - } - - try { - if (catches.isMutable()) { - throw new MutabilityException("catches.isMutable()"); - } - } catch (NullPointerException ex) { - // Translate the exception. - throw new NullPointerException("catches == null"); - } - - try { - if (attributes.isMutable()) { - throw new MutabilityException("attributes.isMutable()"); - } - } catch (NullPointerException ex) { - // Translate the exception. - throw new NullPointerException("attributes == null"); - } - - this.maxStack = maxStack; - this.maxLocals = maxLocals; - this.code = code; - this.catches = catches; - this.attributes = attributes; - } - - public int byteLength() { - return 10 + code.byteLength() + catches.byteLength() + - attributes.byteLength(); - } - - /** - * Gets the maximum stack size. - * - * @return {@code >= 0;} the maximum stack size - */ - public int getMaxStack() { - return maxStack; - } - - /** - * Gets the number of locals. - * - * @return {@code >= 0;} the number of locals - */ - public int getMaxLocals() { - return maxLocals; - } - - /** - * Gets the bytecode array. - * - * @return {@code non-null;} the bytecode array - */ - public BytecodeArray getCode() { - return code; - } - - /** - * Gets the exception table. - * - * @return {@code non-null;} the exception table - */ - public ByteCatchList getCatches() { - return catches; - } - - /** - * Gets the associated attribute list. - * - * @return {@code non-null;} the attribute list - */ - public AttributeList getAttributes() { - return attributes; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttConstantValue.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttConstantValue.java deleted file mode 100644 index aa6d1b315ee..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttConstantValue.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.attrib; - -import com.android.dx.rop.cst.CstDouble; -import com.android.dx.rop.cst.CstFloat; -import com.android.dx.rop.cst.CstInteger; -import com.android.dx.rop.cst.CstLong; -import com.android.dx.rop.cst.CstString; -import com.android.dx.rop.cst.TypedConstant; - -/** - * Attribute class for standard {@code ConstantValue} attributes. - */ -public final class AttConstantValue extends BaseAttribute { - /** {@code non-null;} attribute name for attributes of this type */ - public static final String ATTRIBUTE_NAME = "ConstantValue"; - - /** {@code non-null;} the constant value */ - private final TypedConstant constantValue; - - /** - * Constructs an instance. - * - * @param constantValue {@code non-null;} the constant value, which must - * be an instance of one of: {@code CstString}, - * {@code CstInteger}, {@code CstLong}, - * {@code CstFloat}, or {@code CstDouble} - */ - public AttConstantValue(TypedConstant constantValue) { - super(ATTRIBUTE_NAME); - - if (!((constantValue instanceof CstString) || - (constantValue instanceof CstInteger) || - (constantValue instanceof CstLong) || - (constantValue instanceof CstFloat) || - (constantValue instanceof CstDouble))) { - if (constantValue == null) { - throw new NullPointerException("constantValue == null"); - } - throw new IllegalArgumentException("bad type for constantValue"); - } - - this.constantValue = constantValue; - } - - /** {@inheritDoc} */ - public int byteLength() { - return 8; - } - - /** - * Gets the constant value of this instance. The returned value - * is an instance of one of: {@code CstString}, - * {@code CstInteger}, {@code CstLong}, - * {@code CstFloat}, or {@code CstDouble}. - * - * @return {@code non-null;} the constant value - */ - public TypedConstant getConstantValue() { - return constantValue; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttDeprecated.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttDeprecated.java deleted file mode 100644 index d440aae71dc..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttDeprecated.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.attrib; - -/** - * Attribute class for standard {@code Deprecated} attributes. - */ -public final class AttDeprecated extends BaseAttribute { - /** {@code non-null;} attribute name for attributes of this type */ - public static final String ATTRIBUTE_NAME = "Deprecated"; - - /** - * Constructs an instance. - */ - public AttDeprecated() { - super(ATTRIBUTE_NAME); - } - - /** {@inheritDoc} */ - public int byteLength() { - return 6; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttEnclosingMethod.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttEnclosingMethod.java deleted file mode 100644 index 6717e15e989..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttEnclosingMethod.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.attrib; - -import com.android.dx.rop.cst.CstNat; -import com.android.dx.rop.cst.CstType; - -/** - * Attribute class for standards-track {@code EnclosingMethod} - * attributes. - */ -public final class AttEnclosingMethod extends BaseAttribute { - /** {@code non-null;} attribute name for attributes of this type */ - public static final String ATTRIBUTE_NAME = "EnclosingMethod"; - - /** {@code non-null;} the innermost enclosing class */ - private final CstType type; - - /** {@code null-ok;} the name-and-type of the innermost enclosing method, if any */ - private final CstNat method; - - /** - * Constructs an instance. - * - * @param type {@code non-null;} the innermost enclosing class - * @param method {@code null-ok;} the name-and-type of the innermost enclosing - * method, if any - */ - public AttEnclosingMethod(CstType type, CstNat method) { - super(ATTRIBUTE_NAME); - - if (type == null) { - throw new NullPointerException("type == null"); - } - - this.type = type; - this.method = method; - } - - /** {@inheritDoc} */ - public int byteLength() { - return 10; - } - - /** - * Gets the innermost enclosing class. - * - * @return {@code non-null;} the innermost enclosing class - */ - public CstType getEnclosingClass() { - return type; - } - - /** - * Gets the name-and-type of the innermost enclosing method, if - * any. - * - * @return {@code null-ok;} the name-and-type of the innermost enclosing - * method, if any - */ - public CstNat getMethod() { - return method; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttExceptions.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttExceptions.java deleted file mode 100644 index a17e009a838..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttExceptions.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.attrib; - -import com.android.dx.rop.type.TypeList; -import com.android.dx.util.MutabilityException; - -/** - * Attribute class for standard {@code Exceptions} attributes. - */ -public final class AttExceptions extends BaseAttribute { - /** {@code non-null;} attribute name for attributes of this type */ - public static final String ATTRIBUTE_NAME = "Exceptions"; - - /** {@code non-null;} list of exception classes */ - private final TypeList exceptions; - - /** - * Constructs an instance. - * - * @param exceptions {@code non-null;} list of classes, presumed but not - * verified to be subclasses of {@code Throwable} - */ - public AttExceptions(TypeList exceptions) { - super(ATTRIBUTE_NAME); - - try { - if (exceptions.isMutable()) { - throw new MutabilityException("exceptions.isMutable()"); - } - } catch (NullPointerException ex) { - // Translate the exception. - throw new NullPointerException("exceptions == null"); - } - - this.exceptions = exceptions; - } - - /** {@inheritDoc} */ - public int byteLength() { - return 8 + exceptions.size() * 2; - } - - /** - * Gets the list of classes associated with this instance. In - * general, these classes are not pre-verified to be subclasses of - * {@code Throwable}. - * - * @return {@code non-null;} the list of classes - */ - public TypeList getExceptions() { - return exceptions; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttInnerClasses.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttInnerClasses.java deleted file mode 100644 index 77a4b087a4c..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttInnerClasses.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.attrib; - -import com.android.dx.util.MutabilityException; - -/** - * Attribute class for standard {@code InnerClasses} attributes. - */ -public final class AttInnerClasses extends BaseAttribute { - /** {@code non-null;} attribute name for attributes of this type */ - public static final String ATTRIBUTE_NAME = "InnerClasses"; - - /** {@code non-null;} list of inner class entries */ - private final InnerClassList innerClasses; - - /** - * Constructs an instance. - * - * @param innerClasses {@code non-null;} list of inner class entries - */ - public AttInnerClasses(InnerClassList innerClasses) { - super(ATTRIBUTE_NAME); - - try { - if (innerClasses.isMutable()) { - throw new MutabilityException("innerClasses.isMutable()"); - } - } catch (NullPointerException ex) { - // Translate the exception. - throw new NullPointerException("innerClasses == null"); - } - - this.innerClasses = innerClasses; - } - - /** {@inheritDoc} */ - public int byteLength() { - return 8 + innerClasses.size() * 8; - } - - /** - * Gets the list of "inner class" entries associated with this instance. - * - * @return {@code non-null;} the list - */ - public InnerClassList getInnerClasses() { - return innerClasses; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttLineNumberTable.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttLineNumberTable.java deleted file mode 100644 index 5eac8cbec7f..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttLineNumberTable.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.attrib; - -import com.android.dx.cf.code.LineNumberList; -import com.android.dx.util.MutabilityException; - -/** - * Attribute class for standard {@code LineNumberTable} attributes. - */ -public final class AttLineNumberTable extends BaseAttribute { - /** {@code non-null;} attribute name for attributes of this type */ - public static final String ATTRIBUTE_NAME = "LineNumberTable"; - - /** {@code non-null;} list of line number entries */ - private final LineNumberList lineNumbers; - - /** - * Constructs an instance. - * - * @param lineNumbers {@code non-null;} list of line number entries - */ - public AttLineNumberTable(LineNumberList lineNumbers) { - super(ATTRIBUTE_NAME); - - try { - if (lineNumbers.isMutable()) { - throw new MutabilityException("lineNumbers.isMutable()"); - } - } catch (NullPointerException ex) { - // Translate the exception. - throw new NullPointerException("lineNumbers == null"); - } - - this.lineNumbers = lineNumbers; - } - - /** {@inheritDoc} */ - public int byteLength() { - return 8 + 4 * lineNumbers.size(); - } - - /** - * Gets the list of "line number" entries associated with this instance. - * - * @return {@code non-null;} the list - */ - public LineNumberList getLineNumbers() { - return lineNumbers; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttLocalVariableTable.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttLocalVariableTable.java deleted file mode 100644 index 1d2b4aa0138..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttLocalVariableTable.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.attrib; - -import com.android.dx.cf.code.LocalVariableList; - -/** - * Attribute class for standard {@code LocalVariableTable} attributes. - */ -public final class AttLocalVariableTable extends BaseLocalVariables { - /** {@code non-null;} attribute name for attributes of this type */ - public static final String ATTRIBUTE_NAME = "LocalVariableTable"; - - /** - * Constructs an instance. - * - * @param localVariables {@code non-null;} list of local variable entries - */ - public AttLocalVariableTable(LocalVariableList localVariables) { - super(ATTRIBUTE_NAME, localVariables); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttLocalVariableTypeTable.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttLocalVariableTypeTable.java deleted file mode 100644 index 2520bf60422..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttLocalVariableTypeTable.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.attrib; - -import com.android.dx.cf.code.LocalVariableList; - -/** - * Attribute class for standard {@code LocalVariableTypeTable} attributes. - */ -public final class AttLocalVariableTypeTable extends BaseLocalVariables { - /** {@code non-null;} attribute name for attributes of this type */ - public static final String ATTRIBUTE_NAME = "LocalVariableTypeTable"; - - /** - * Constructs an instance. - * - * @param localVariables {@code non-null;} list of local variable entries - */ - public AttLocalVariableTypeTable(LocalVariableList localVariables) { - super(ATTRIBUTE_NAME, localVariables); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttRuntimeInvisibleAnnotations.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttRuntimeInvisibleAnnotations.java deleted file mode 100644 index d3afe277ffa..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttRuntimeInvisibleAnnotations.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.attrib; - -import com.android.dx.rop.annotation.Annotations; - -/** - * Attribute class for standard {@code RuntimeInvisibleAnnotations} - * attributes. - */ -public final class AttRuntimeInvisibleAnnotations extends BaseAnnotations { - /** {@code non-null;} attribute name for attributes of this type */ - public static final String ATTRIBUTE_NAME = "RuntimeInvisibleAnnotations"; - - /** - * Constructs an instance. - * - * @param annotations {@code non-null;} the list of annotations - * @param byteLength {@code >= 0;} attribute data length in the original - * classfile (not including the attribute header) - */ - public AttRuntimeInvisibleAnnotations(Annotations annotations, - int byteLength) { - super(ATTRIBUTE_NAME, annotations, byteLength); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttRuntimeInvisibleParameterAnnotations.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttRuntimeInvisibleParameterAnnotations.java deleted file mode 100644 index c9c51369410..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttRuntimeInvisibleParameterAnnotations.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.attrib; - -import com.android.dx.rop.annotation.AnnotationsList; - -/** - * Attribute class for standard - * {@code RuntimeInvisibleParameterAnnotations} attributes. - */ -public final class AttRuntimeInvisibleParameterAnnotations - extends BaseParameterAnnotations { - /** {@code non-null;} attribute name for attributes of this type */ - public static final String ATTRIBUTE_NAME = - "RuntimeInvisibleParameterAnnotations"; - - /** - * Constructs an instance. - * - * @param parameterAnnotations {@code non-null;} the parameter annotations - * @param byteLength {@code >= 0;} attribute data length in the original - * classfile (not including the attribute header) - */ - public AttRuntimeInvisibleParameterAnnotations( - AnnotationsList parameterAnnotations, int byteLength) { - super(ATTRIBUTE_NAME, parameterAnnotations, byteLength); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttRuntimeVisibleAnnotations.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttRuntimeVisibleAnnotations.java deleted file mode 100644 index a6a640d535c..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttRuntimeVisibleAnnotations.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.attrib; - -import com.android.dx.rop.annotation.Annotations; - -/** - * Attribute class for standard {@code RuntimeVisibleAnnotations} - * attributes. - */ -public final class AttRuntimeVisibleAnnotations extends BaseAnnotations { - /** {@code non-null;} attribute name for attributes of this type */ - public static final String ATTRIBUTE_NAME = "RuntimeVisibleAnnotations"; - - /** - * Constructs an instance. - * - * @param annotations {@code non-null;} the list of annotations - * @param byteLength {@code >= 0;} attribute data length in the original - * classfile (not including the attribute header) - */ - public AttRuntimeVisibleAnnotations(Annotations annotations, - int byteLength) { - super(ATTRIBUTE_NAME, annotations, byteLength); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttRuntimeVisibleParameterAnnotations.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttRuntimeVisibleParameterAnnotations.java deleted file mode 100644 index 177eb4c9b4b..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttRuntimeVisibleParameterAnnotations.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.attrib; - -import com.android.dx.rop.annotation.AnnotationsList; - -/** - * Attribute class for standard {@code RuntimeVisibleParameterAnnotations} - * attributes. - */ -public final class AttRuntimeVisibleParameterAnnotations - extends BaseParameterAnnotations { - /** {@code non-null;} attribute name for attributes of this type */ - public static final String ATTRIBUTE_NAME = - "RuntimeVisibleParameterAnnotations"; - - /** - * Constructs an instance. - * - * @param annotations {@code non-null;} the parameter annotations - * @param byteLength {@code >= 0;} attribute data length in the original - * classfile (not including the attribute header) - */ - public AttRuntimeVisibleParameterAnnotations( - AnnotationsList annotations, int byteLength) { - super(ATTRIBUTE_NAME, annotations, byteLength); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttSignature.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttSignature.java deleted file mode 100644 index 52def9c8b06..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttSignature.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.attrib; - -import com.android.dx.rop.cst.CstString; - -/** - * Attribute class for standards-track {@code Signature} attributes. - */ -public final class AttSignature extends BaseAttribute { - /** {@code non-null;} attribute name for attributes of this type */ - public static final String ATTRIBUTE_NAME = "Signature"; - - /** {@code non-null;} the signature string */ - private final CstString signature; - - /** - * Constructs an instance. - * - * @param signature {@code non-null;} the signature string - */ - public AttSignature(CstString signature) { - super(ATTRIBUTE_NAME); - - if (signature == null) { - throw new NullPointerException("signature == null"); - } - - this.signature = signature; - } - - /** {@inheritDoc} */ - public int byteLength() { - return 8; - } - - /** - * Gets the signature string. - * - * @return {@code non-null;} the signature string - */ - public CstString getSignature() { - return signature; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttSourceFile.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttSourceFile.java deleted file mode 100644 index cc19d275004..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttSourceFile.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.attrib; - -import com.android.dx.rop.cst.CstString; - -/** - * Attribute class for standard {@code SourceFile} attributes. - */ -public final class AttSourceFile extends BaseAttribute { - /** {@code non-null;} attribute name for attributes of this type */ - public static final String ATTRIBUTE_NAME = "SourceFile"; - - /** {@code non-null;} name of the source file */ - private final CstString sourceFile; - - /** - * Constructs an instance. - * - * @param sourceFile {@code non-null;} the name of the source file - */ - public AttSourceFile(CstString sourceFile) { - super(ATTRIBUTE_NAME); - - if (sourceFile == null) { - throw new NullPointerException("sourceFile == null"); - } - - this.sourceFile = sourceFile; - } - - /** {@inheritDoc} */ - public int byteLength() { - return 8; - } - - /** - * Gets the source file name of this instance. - * - * @return {@code non-null;} the source file - */ - public CstString getSourceFile() { - return sourceFile; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttSynthetic.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttSynthetic.java deleted file mode 100644 index e3841eb86b6..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/AttSynthetic.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.attrib; - -/** - * Attribute class for standard {@code Synthetic} attributes. - */ -public final class AttSynthetic extends BaseAttribute { - /** {@code non-null;} attribute name for attributes of this type */ - public static final String ATTRIBUTE_NAME = "Synthetic"; - - /** - * Constructs an instance. - */ - public AttSynthetic() { - super(ATTRIBUTE_NAME); - } - - /** {@inheritDoc} */ - public int byteLength() { - return 6; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/BaseAnnotations.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/BaseAnnotations.java deleted file mode 100644 index bc138afe7e8..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/BaseAnnotations.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.attrib; - -import com.android.dx.rop.annotation.Annotations; -import com.android.dx.util.MutabilityException; - -/** - * Base class for annotations attributes. - */ -public abstract class BaseAnnotations extends BaseAttribute { - /** {@code non-null;} list of annotations */ - private final Annotations annotations; - - /** {@code >= 0;} attribute data length in the original classfile (not - * including the attribute header) */ - private final int byteLength; - - /** - * Constructs an instance. - * - * @param attributeName {@code non-null;} the name of the attribute - * @param annotations {@code non-null;} the list of annotations - * @param byteLength {@code >= 0;} attribute data length in the original - * classfile (not including the attribute header) - */ - public BaseAnnotations(String attributeName, Annotations annotations, - int byteLength) { - super(attributeName); - - try { - if (annotations.isMutable()) { - throw new MutabilityException("annotations.isMutable()"); - } - } catch (NullPointerException ex) { - // Translate the exception. - throw new NullPointerException("annotations == null"); - } - - this.annotations = annotations; - this.byteLength = byteLength; - } - - /** {@inheritDoc} */ - public final int byteLength() { - // Add six for the standard attribute header. - return byteLength + 6; - } - - /** - * Gets the list of annotations associated with this instance. - * - * @return {@code non-null;} the list - */ - public final Annotations getAnnotations() { - return annotations; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/BaseAttribute.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/BaseAttribute.java deleted file mode 100644 index 99617250b0b..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/BaseAttribute.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.attrib; - -import com.android.dx.cf.iface.Attribute; - -/** - * Base implementation of {@link Attribute}, which directly stores - * the attribute name but leaves the rest up to subclasses. - */ -public abstract class BaseAttribute implements Attribute { - /** {@code non-null;} attribute name */ - private final String name; - - /** - * Constructs an instance. - * - * @param name {@code non-null;} attribute name - */ - public BaseAttribute(String name) { - if (name == null) { - throw new NullPointerException("name == null"); - } - - this.name = name; - } - - /** {@inheritDoc} */ - public String getName() { - return name; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/BaseLocalVariables.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/BaseLocalVariables.java deleted file mode 100644 index 27cd6fb9e88..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/BaseLocalVariables.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.attrib; - -import com.android.dx.cf.code.LocalVariableList; -import com.android.dx.util.MutabilityException; - -/** - * Base attribute class for standard {@code LocalVariableTable} - * and {@code LocalVariableTypeTable} attributes. - */ -public abstract class BaseLocalVariables extends BaseAttribute { - /** {@code non-null;} list of local variable entries */ - private final LocalVariableList localVariables; - - /** - * Constructs an instance. - * - * @param name {@code non-null;} attribute name - * @param localVariables {@code non-null;} list of local variable entries - */ - public BaseLocalVariables(String name, - LocalVariableList localVariables) { - super(name); - - try { - if (localVariables.isMutable()) { - throw new MutabilityException("localVariables.isMutable()"); - } - } catch (NullPointerException ex) { - // Translate the exception. - throw new NullPointerException("localVariables == null"); - } - - this.localVariables = localVariables; - } - - /** {@inheritDoc} */ - public final int byteLength() { - return 8 + localVariables.size() * 10; - } - - /** - * Gets the list of "local variable" entries associated with this instance. - * - * @return {@code non-null;} the list - */ - public final LocalVariableList getLocalVariables() { - return localVariables; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/BaseParameterAnnotations.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/BaseParameterAnnotations.java deleted file mode 100644 index 791f8cdfc6a..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/BaseParameterAnnotations.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.attrib; - -import com.android.dx.rop.annotation.AnnotationsList; -import com.android.dx.util.MutabilityException; - -/** - * Base class for parameter annotation list attributes. - */ -public abstract class BaseParameterAnnotations extends BaseAttribute { - /** {@code non-null;} list of annotations */ - private final AnnotationsList parameterAnnotations; - - /** {@code >= 0;} attribute data length in the original classfile (not - * including the attribute header) */ - private final int byteLength; - - /** - * Constructs an instance. - * - * @param attributeName {@code non-null;} the name of the attribute - * @param parameterAnnotations {@code non-null;} the annotations - * @param byteLength {@code >= 0;} attribute data length in the original - * classfile (not including the attribute header) - */ - public BaseParameterAnnotations(String attributeName, - AnnotationsList parameterAnnotations, int byteLength) { - super(attributeName); - - try { - if (parameterAnnotations.isMutable()) { - throw new MutabilityException( - "parameterAnnotations.isMutable()"); - } - } catch (NullPointerException ex) { - // Translate the exception. - throw new NullPointerException("parameterAnnotations == null"); - } - - this.parameterAnnotations = parameterAnnotations; - this.byteLength = byteLength; - } - - /** {@inheritDoc} */ - public final int byteLength() { - // Add six for the standard attribute header. - return byteLength + 6; - } - - /** - * Gets the list of annotation lists associated with this instance. - * - * @return {@code non-null;} the list - */ - public final AnnotationsList getParameterAnnotations() { - return parameterAnnotations; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/InnerClassList.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/InnerClassList.java deleted file mode 100644 index 830118c5aa8..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/InnerClassList.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.attrib; - -import com.android.dx.rop.cst.CstString; -import com.android.dx.rop.cst.CstType; -import com.android.dx.util.FixedSizeList; - -/** - * List of "inner class" entries, which are the contents of - * {@code InnerClasses} attributes. - */ -public final class InnerClassList extends FixedSizeList { - /** - * Constructs an instance. - * - * @param count the number of elements to be in the list of inner classes - */ - public InnerClassList(int count) { - super(count); - } - - /** - * Gets the indicated item. - * - * @param n {@code >= 0;} which item - * @return {@code null-ok;} the indicated item - */ - public Item get(int n) { - return (Item) get0(n); - } - - /** - * Sets the item at the given index. - * - * @param n {@code >= 0, < size();} which class - * @param innerClass {@code non-null;} class this item refers to - * @param outerClass {@code null-ok;} outer class that this class is a - * member of, if any - * @param innerName {@code null-ok;} original simple name of this class, - * if not anonymous - * @param accessFlags original declared access flags - */ - public void set(int n, CstType innerClass, CstType outerClass, - CstString innerName, int accessFlags) { - set0(n, new Item(innerClass, outerClass, innerName, accessFlags)); - } - - /** - * Item in an inner classes list. - */ - public static class Item { - /** {@code non-null;} class this item refers to */ - private final CstType innerClass; - - /** {@code null-ok;} outer class that this class is a member of, if any */ - private final CstType outerClass; - - /** {@code null-ok;} original simple name of this class, if not anonymous */ - private final CstString innerName; - - /** original declared access flags */ - private final int accessFlags; - - /** - * Constructs an instance. - * - * @param innerClass {@code non-null;} class this item refers to - * @param outerClass {@code null-ok;} outer class that this class is a - * member of, if any - * @param innerName {@code null-ok;} original simple name of this - * class, if not anonymous - * @param accessFlags original declared access flags - */ - public Item(CstType innerClass, CstType outerClass, - CstString innerName, int accessFlags) { - if (innerClass == null) { - throw new NullPointerException("innerClass == null"); - } - - this.innerClass = innerClass; - this.outerClass = outerClass; - this.innerName = innerName; - this.accessFlags = accessFlags; - } - - /** - * Gets the class this item refers to. - * - * @return {@code non-null;} the class - */ - public CstType getInnerClass() { - return innerClass; - } - - /** - * Gets the outer class that this item's class is a member of, if any. - * - * @return {@code null-ok;} the class - */ - public CstType getOuterClass() { - return outerClass; - } - - /** - * Gets the original name of this item's class, if not anonymous. - * - * @return {@code null-ok;} the name - */ - public CstString getInnerName() { - return innerName; - } - - /** - * Gets the original declared access flags. - * - * @return the access flags - */ - public int getAccessFlags() { - return accessFlags; - } - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/RawAttribute.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/RawAttribute.java deleted file mode 100644 index e905dd1d073..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/RawAttribute.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.attrib; - -import com.android.dx.rop.cst.ConstantPool; -import com.android.dx.util.ByteArray; - -/** - * Raw attribute, for holding onto attributes that are unrecognized. - */ -public final class RawAttribute extends BaseAttribute { - /** {@code non-null;} attribute data */ - private final ByteArray data; - - /** - * {@code null-ok;} constant pool to use for resolution of cpis in {@link - * #data} - */ - private final ConstantPool pool; - - /** - * Constructs an instance. - * - * @param name {@code non-null;} attribute name - * @param data {@code non-null;} attribute data - * @param pool {@code null-ok;} constant pool to use for cpi resolution - */ - public RawAttribute(String name, ByteArray data, ConstantPool pool) { - super(name); - - if (data == null) { - throw new NullPointerException("data == null"); - } - - this.data = data; - this.pool = pool; - } - - /** - * Constructs an instance from a sub-array of a {@link ByteArray}. - * - * @param name {@code non-null;} attribute name - * @param data {@code non-null;} array containing the attribute data - * @param offset offset in {@code data} to the attribute data - * @param length length of the attribute data, in bytes - * @param pool {@code null-ok;} constant pool to use for cpi resolution - */ - public RawAttribute(String name, ByteArray data, int offset, - int length, ConstantPool pool) { - this(name, data.slice(offset, offset + length), pool); - } - - /** - * Get the raw data of the attribute. - * - * @return {@code non-null;} the data - */ - public ByteArray getData() { - return data; - } - - /** {@inheritDoc} */ - public int byteLength() { - return data.size() + 6; - } - - /** - * Gets the constant pool to use for cpi resolution, if any. It - * presumably came from the class file that this attribute came - * from. - * - * @return {@code null-ok;} the constant pool - */ - public ConstantPool getPool() { - return pool; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/package.html b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/package.html deleted file mode 100644 index 8125079a412..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/attrib/package.html +++ /dev/null @@ -1,11 +0,0 @@ - -

Implementation of containers and utilities for all the standard Java -attribute types.

- -

PACKAGES USED: -

    -
  • com.android.dx.cf.iface
  • -
  • com.android.dx.rop.pool
  • -
  • com.android.dx.util
  • -
- diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/BaseMachine.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/BaseMachine.java deleted file mode 100644 index 7bff2ff2f0c..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/BaseMachine.java +++ /dev/null @@ -1,579 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.code; - -import com.android.dx.rop.code.LocalItem; -import com.android.dx.rop.code.RegisterSpec; -import com.android.dx.rop.cst.Constant; -import com.android.dx.rop.type.Prototype; -import com.android.dx.rop.type.StdTypeList; -import com.android.dx.rop.type.Type; -import com.android.dx.rop.type.TypeBearer; -import java.util.ArrayList; - -/** - * Base implementation of {@link Machine}. - * - *

Note: For the most part, the documentation for this class - * ignores the distinction between {@link Type} and {@link - * TypeBearer}.

- */ -public abstract class BaseMachine implements Machine { - /* {@code non-null;} the prototype for the associated method */ - private final Prototype prototype; - - /** {@code non-null;} primary arguments */ - private TypeBearer[] args; - - /** {@code >= 0;} number of primary arguments */ - private int argCount; - - /** {@code null-ok;} type of the operation, if salient */ - private Type auxType; - - /** auxiliary {@code int} argument */ - private int auxInt; - - /** {@code null-ok;} auxiliary constant argument */ - private Constant auxCst; - - /** auxiliary branch target argument */ - private int auxTarget; - - /** {@code null-ok;} auxiliary switch cases argument */ - private SwitchList auxCases; - - /** {@code null-ok;} auxiliary initial value list for newarray */ - private ArrayList auxInitValues; - - /** {@code >= -1;} last local accessed */ - private int localIndex; - - /** specifies if local has info in the local variable table */ - private boolean localInfo; - - /** {@code null-ok;} local target spec, if salient and calculated */ - private RegisterSpec localTarget; - - /** {@code non-null;} results */ - private TypeBearer[] results; - - /** - * {@code >= -1;} count of the results, or {@code -1} if no results - * have been set - */ - private int resultCount; - - /** - * Constructs an instance. - * - * @param prototype {@code non-null;} the prototype for the - * associated method - */ - public BaseMachine(Prototype prototype) { - if (prototype == null) { - throw new NullPointerException("prototype == null"); - } - - this.prototype = prototype; - args = new TypeBearer[10]; - results = new TypeBearer[6]; - clearArgs(); - } - - /** {@inheritDoc} */ - public Prototype getPrototype() { - return prototype; - } - - /** {@inheritDoc} */ - public final void clearArgs() { - argCount = 0; - auxType = null; - auxInt = 0; - auxCst = null; - auxTarget = 0; - auxCases = null; - auxInitValues = null; - localIndex = -1; - localInfo = false; - localTarget = null; - resultCount = -1; - } - - /** {@inheritDoc} */ - public final void popArgs(Frame frame, int count) { - ExecutionStack stack = frame.getStack(); - - clearArgs(); - - if (count > args.length) { - // Grow args, and add a little extra room to grow even more. - args = new TypeBearer[count + 10]; - } - - for (int i = count - 1; i >= 0; i--) { - args[i] = stack.pop(); - } - - argCount = count; - } - - /** {@inheritDoc} */ - public void popArgs(Frame frame, Prototype prototype) { - StdTypeList types = prototype.getParameterTypes(); - int size = types.size(); - - // Use the above method to do the actual popping... - popArgs(frame, size); - - // ...and then verify the popped types. - - for (int i = 0; i < size; i++) { - if (! Merger.isPossiblyAssignableFrom(types.getType(i), args[i])) { - throw new SimException("at stack depth " + (size - 1 - i) + - ", expected type " + types.getType(i).toHuman() + - " but found " + args[i].getType().toHuman()); - } - } - } - - public final void popArgs(Frame frame, Type type) { - // Use the above method to do the actual popping... - popArgs(frame, 1); - - // ...and then verify the popped type. - if (! Merger.isPossiblyAssignableFrom(type, args[0])) { - throw new SimException("expected type " + type.toHuman() + - " but found " + args[0].getType().toHuman()); - } - } - - /** {@inheritDoc} */ - public final void popArgs(Frame frame, Type type1, Type type2) { - // Use the above method to do the actual popping... - popArgs(frame, 2); - - // ...and then verify the popped types. - - if (! Merger.isPossiblyAssignableFrom(type1, args[0])) { - throw new SimException("expected type " + type1.toHuman() + - " but found " + args[0].getType().toHuman()); - } - - if (! Merger.isPossiblyAssignableFrom(type2, args[1])) { - throw new SimException("expected type " + type2.toHuman() + - " but found " + args[1].getType().toHuman()); - } - } - - /** {@inheritDoc} */ - public final void popArgs(Frame frame, Type type1, Type type2, - Type type3) { - // Use the above method to do the actual popping... - popArgs(frame, 3); - - // ...and then verify the popped types. - - if (! Merger.isPossiblyAssignableFrom(type1, args[0])) { - throw new SimException("expected type " + type1.toHuman() + - " but found " + args[0].getType().toHuman()); - } - - if (! Merger.isPossiblyAssignableFrom(type2, args[1])) { - throw new SimException("expected type " + type2.toHuman() + - " but found " + args[1].getType().toHuman()); - } - - if (! Merger.isPossiblyAssignableFrom(type3, args[2])) { - throw new SimException("expected type " + type3.toHuman() + - " but found " + args[2].getType().toHuman()); - } - } - - /** {@inheritDoc} */ - public final void localArg(Frame frame, int idx) { - clearArgs(); - args[0] = frame.getLocals().get(idx); - argCount = 1; - localIndex = idx; - } - - /** {@inheritDoc} */ - public final void localInfo(boolean local) { - localInfo = local; - } - - /** {@inheritDoc} */ - public final void auxType(Type type) { - auxType = type; - } - - /** {@inheritDoc} */ - public final void auxIntArg(int value) { - auxInt = value; - } - - /** {@inheritDoc} */ - public final void auxCstArg(Constant cst) { - if (cst == null) { - throw new NullPointerException("cst == null"); - } - - auxCst = cst; - } - - /** {@inheritDoc} */ - public final void auxTargetArg(int target) { - auxTarget = target; - } - - /** {@inheritDoc} */ - public final void auxSwitchArg(SwitchList cases) { - if (cases == null) { - throw new NullPointerException("cases == null"); - } - - auxCases = cases; - } - - /** {@inheritDoc} */ - public final void auxInitValues(ArrayList initValues) { - auxInitValues = initValues; - } - - /** {@inheritDoc} */ - public final void localTarget(int idx, Type type, LocalItem local) { - localTarget = RegisterSpec.makeLocalOptional(idx, type, local); - } - - /** - * Gets the number of primary arguments. - * - * @return {@code >= 0;} the number of primary arguments - */ - protected final int argCount() { - return argCount; - } - - /** - * Gets the width of the arguments (where a category-2 value counts as - * two). - * - * @return {@code >= 0;} the argument width - */ - protected final int argWidth() { - int result = 0; - - for (int i = 0; i < argCount; i++) { - result += args[i].getType().getCategory(); - } - - return result; - } - - /** - * Gets the {@code n}th primary argument. - * - * @param n {@code >= 0, < argCount();} which argument - * @return {@code non-null;} the indicated argument - */ - protected final TypeBearer arg(int n) { - if (n >= argCount) { - throw new IllegalArgumentException("n >= argCount"); - } - - try { - return args[n]; - } catch (ArrayIndexOutOfBoundsException ex) { - // Translate the exception. - throw new IllegalArgumentException("n < 0"); - } - } - - /** - * Gets the type auxiliary argument. - * - * @return {@code null-ok;} the salient type - */ - protected final Type getAuxType() { - return auxType; - } - - /** - * Gets the {@code int} auxiliary argument. - * - * @return the argument value - */ - protected final int getAuxInt() { - return auxInt; - } - - /** - * Gets the constant auxiliary argument. - * - * @return {@code null-ok;} the argument value - */ - protected final Constant getAuxCst() { - return auxCst; - } - - /** - * Gets the branch target auxiliary argument. - * - * @return the argument value - */ - protected final int getAuxTarget() { - return auxTarget; - } - - /** - * Gets the switch cases auxiliary argument. - * - * @return {@code null-ok;} the argument value - */ - protected final SwitchList getAuxCases() { - return auxCases; - } - - /** - * Gets the init values auxiliary argument. - * - * @return {@code null-ok;} the argument value - */ - protected final ArrayList getInitValues() { - return auxInitValues; - } - /** - * Gets the last local index accessed. - * - * @return {@code >= -1;} the salient local index or {@code -1} if none - * was set since the last time {@link #clearArgs} was called - */ - protected final int getLocalIndex() { - return localIndex; - } - - /** - * Gets whether the loaded local has info in the local variable table. - * - * @return {@code true} if local arg has info in the local variable table - */ - protected final boolean getLocalInfo() { - return localInfo; - } - - /** - * Gets the target local register spec of the current operation, if any. - * The local target spec is the combination of the values indicated - * by a previous call to {@link #localTarget} with the type of what - * should be the sole result set by a call to {@link #setResult} (or - * the combination {@link #clearResult} then {@link #addResult}. - * - * @param isMove {@code true} if the operation being performed on the - * local is a move. This will cause constant values to be propagated - * to the returned local - * @return {@code null-ok;} the salient register spec or {@code null} if no - * local target was set since the last time {@link #clearArgs} was - * called - */ - protected final RegisterSpec getLocalTarget(boolean isMove) { - if (localTarget == null) { - return null; - } - - if (resultCount != 1) { - throw new SimException("local target with " + - ((resultCount == 0) ? "no" : "multiple") + " results"); - } - - TypeBearer result = results[0]; - Type resultType = result.getType(); - Type localType = localTarget.getType(); - - if (resultType == localType) { - /* - * If this is to be a move operation and the result is a - * known value, make the returned localTarget embody that - * value. - */ - if (isMove) { - return localTarget.withType(result); - } else { - return localTarget; - } - } - - if (! Merger.isPossiblyAssignableFrom(localType, resultType)) { - // The result and local types are inconsistent. Complain! - throwLocalMismatch(resultType, localType); - return null; - } - - if (localType == Type.OBJECT) { - /* - * The result type is more specific than the local type, - * so use that instead. - */ - localTarget = localTarget.withType(result); - } - - return localTarget; - } - - /** - * Clears the results. - */ - protected final void clearResult() { - resultCount = 0; - } - - /** - * Sets the results list to be the given single value. - * - *

Note: If there is more than one result value, the - * others may be added by using {@link #addResult}.

- * - * @param result {@code non-null;} result value - */ - protected final void setResult(TypeBearer result) { - if (result == null) { - throw new NullPointerException("result == null"); - } - - results[0] = result; - resultCount = 1; - } - - /** - * Adds an additional element to the list of results. - * - * @see #setResult - * - * @param result {@code non-null;} result value - */ - protected final void addResult(TypeBearer result) { - if (result == null) { - throw new NullPointerException("result == null"); - } - - results[resultCount] = result; - resultCount++; - } - - /** - * Gets the count of results. This throws an exception if results were - * never set. (Explicitly clearing the results counts as setting them.) - * - * @return {@code >= 0;} the count - */ - protected final int resultCount() { - if (resultCount < 0) { - throw new SimException("results never set"); - } - - return resultCount; - } - - /** - * Gets the width of the results (where a category-2 value counts as - * two). - * - * @return {@code >= 0;} the result width - */ - protected final int resultWidth() { - int width = 0; - - for (int i = 0; i < resultCount; i++) { - width += results[i].getType().getCategory(); - } - - return width; - } - - /** - * Gets the {@code n}th result value. - * - * @param n {@code >= 0, < resultCount();} which result - * @return {@code non-null;} the indicated result value - */ - protected final TypeBearer result(int n) { - if (n >= resultCount) { - throw new IllegalArgumentException("n >= resultCount"); - } - - try { - return results[n]; - } catch (ArrayIndexOutOfBoundsException ex) { - // Translate the exception. - throw new IllegalArgumentException("n < 0"); - } - } - - /** - * Stores the results of the latest operation into the given frame. If - * there is a local target (see {@link #localTarget}), then the sole - * result is stored to that target; otherwise any results are pushed - * onto the stack. - * - * @param frame {@code non-null;} frame to operate on - */ - protected final void storeResults(Frame frame) { - if (resultCount < 0) { - throw new SimException("results never set"); - } - - if (resultCount == 0) { - // Nothing to do. - return; - } - - if (localTarget != null) { - /* - * Note: getLocalTarget() doesn't necessarily return - * localTarget directly. - */ - frame.getLocals().set(getLocalTarget(false)); - } else { - ExecutionStack stack = frame.getStack(); - for (int i = 0; i < resultCount; i++) { - if (localInfo) { - stack.setLocal(); - } - stack.push(results[i]); - } - } - } - - /** - * Throws an exception that indicates a mismatch in local variable - * types. - * - * @param found {@code non-null;} the encountered type - * @param local {@code non-null;} the local variable's claimed type - */ - public static void throwLocalMismatch(TypeBearer found, - TypeBearer local) { - throw new SimException("local variable type mismatch: " + - "attempt to set or access a value of type " + - found.toHuman() + - " using a local variable of type " + - local.toHuman() + - ". This is symptomatic of .class transformation tools " + - "that ignore local variable information."); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/BasicBlocker.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/BasicBlocker.java deleted file mode 100644 index 8fb9560f853..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/BasicBlocker.java +++ /dev/null @@ -1,452 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.code; - -import com.android.dx.rop.cst.Constant; -import com.android.dx.rop.cst.CstMemberRef; -import com.android.dx.rop.cst.CstString; -import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.type.Type; -import com.android.dx.util.Bits; -import com.android.dx.util.IntList; -import java.util.ArrayList; - -/** - * Utility that identifies basic blocks in bytecode. - */ -public final class BasicBlocker implements BytecodeArray.Visitor { - /** {@code non-null;} method being converted */ - private final ConcreteMethod method; - - /** - * {@code non-null;} work set; bits indicate offsets in need of - * examination - */ - private final int[] workSet; - - /** - * {@code non-null;} live set; bits indicate potentially-live - * opcodes; contrawise, a bit that isn't on is either in the - * middle of an instruction or is a definitely-dead opcode - */ - private final int[] liveSet; - - /** - * {@code non-null;} block start set; bits indicate the starts of - * basic blocks, including the opcodes that start blocks of - * definitely-dead code - */ - private final int[] blockSet; - - /** - * {@code non-null, sparse;} for each instruction offset to a branch of - * some sort, the list of targets for that instruction - */ - private final IntList[] targetLists; - - /** - * {@code non-null, sparse;} for each instruction offset to a throwing - * instruction, the list of exception handlers for that instruction - */ - private final ByteCatchList[] catchLists; - - /** offset of the previously parsed bytecode */ - private int previousOffset; - - /** - * Identifies and enumerates the basic blocks in the given method, - * returning a list of them. The returned list notably omits any - * definitely-dead code that is identified in the process. - * - * @param method {@code non-null;} method to convert - * @return {@code non-null;} list of basic blocks - */ - public static ByteBlockList identifyBlocks(ConcreteMethod method) { - BasicBlocker bb = new BasicBlocker(method); - - bb.doit(); - return bb.getBlockList(); - } - - /** - * Constructs an instance. This class is not publicly instantiable; use - * {@link #identifyBlocks}. - * - * @param method {@code non-null;} method to convert - */ - private BasicBlocker(ConcreteMethod method) { - if (method == null) { - throw new NullPointerException("method == null"); - } - - this.method = method; - - /* - * The "+1" below is so the idx-past-end is also valid, - * avoiding a special case, but without preventing - * flow-of-control falling past the end of the method from - * getting properly reported. - */ - int sz = method.getCode().size() + 1; - - workSet = Bits.makeBitSet(sz); - liveSet = Bits.makeBitSet(sz); - blockSet = Bits.makeBitSet(sz); - targetLists = new IntList[sz]; - catchLists = new ByteCatchList[sz]; - previousOffset = -1; - } - - /* - * Note: These methods are defined implementation of the interface - * BytecodeArray.Visitor; since the class isn't publicly - * instantiable, no external code ever gets a chance to actually - * call these methods. - */ - - /** {@inheritDoc} */ - public void visitInvalid(int opcode, int offset, int length) { - visitCommon(offset, length, true); - } - - /** {@inheritDoc} */ - public void visitNoArgs(int opcode, int offset, int length, Type type) { - switch (opcode) { - case ByteOps.IRETURN: - case ByteOps.RETURN: { - visitCommon(offset, length, false); - targetLists[offset] = IntList.EMPTY; - break; - } - case ByteOps.ATHROW: { - visitCommon(offset, length, false); - visitThrowing(offset, length, false); - break; - } - case ByteOps.IALOAD: - case ByteOps.LALOAD: - case ByteOps.FALOAD: - case ByteOps.DALOAD: - case ByteOps.AALOAD: - case ByteOps.BALOAD: - case ByteOps.CALOAD: - case ByteOps.SALOAD: - case ByteOps.IASTORE: - case ByteOps.LASTORE: - case ByteOps.FASTORE: - case ByteOps.DASTORE: - case ByteOps.AASTORE: - case ByteOps.BASTORE: - case ByteOps.CASTORE: - case ByteOps.SASTORE: - case ByteOps.ARRAYLENGTH: - case ByteOps.MONITORENTER: - case ByteOps.MONITOREXIT: { - /* - * These instructions can all throw, so they have to end - * the block they appear in (since throws are branches). - */ - visitCommon(offset, length, true); - visitThrowing(offset, length, true); - break; - } - case ByteOps.IDIV: - case ByteOps.IREM: { - /* - * The int and long versions of division and remainder may - * throw, but not the other types. - */ - visitCommon(offset, length, true); - if ((type == Type.INT) || (type == Type.LONG)) { - visitThrowing(offset, length, true); - } - break; - } - default: { - visitCommon(offset, length, true); - break; - } - } - } - - /** {@inheritDoc} */ - public void visitLocal(int opcode, int offset, int length, - int idx, Type type, int value) { - if (opcode == ByteOps.RET) { - visitCommon(offset, length, false); - targetLists[offset] = IntList.EMPTY; - } else { - visitCommon(offset, length, true); - } - } - - /** {@inheritDoc} */ - public void visitConstant(int opcode, int offset, int length, - Constant cst, int value) { - visitCommon(offset, length, true); - - if ((cst instanceof CstMemberRef) || (cst instanceof CstType) || - (cst instanceof CstString)) { - /* - * Instructions with these sorts of constants have the - * possibility of throwing, so this instruction needs to - * end its block (since it can throw, and possible-throws - * are branch points). - */ - visitThrowing(offset, length, true); - } - } - - /** {@inheritDoc} */ - public void visitBranch(int opcode, int offset, int length, - int target) { - switch (opcode) { - case ByteOps.GOTO: { - visitCommon(offset, length, false); - targetLists[offset] = IntList.makeImmutable(target); - break; - } - case ByteOps.JSR: { - /* - * Each jsr is quarantined into a separate block (containing - * only the jsr instruction) but is otherwise treated - * as a conditional branch. (That is to say, both its - * target and next instruction begin new blocks.) - */ - addWorkIfNecessary(offset, true); - // Fall through to next case... - } - default: { - int next = offset + length; - visitCommon(offset, length, true); - addWorkIfNecessary(next, true); - targetLists[offset] = IntList.makeImmutable(next, target); - break; - } - } - - addWorkIfNecessary(target, true); - } - - /** {@inheritDoc} */ - public void visitSwitch(int opcode, int offset, int length, - SwitchList cases, int padding) { - visitCommon(offset, length, false); - addWorkIfNecessary(cases.getDefaultTarget(), true); - - int sz = cases.size(); - for (int i = 0; i < sz; i++) { - addWorkIfNecessary(cases.getTarget(i), true); - } - - targetLists[offset] = cases.getTargets(); - } - - /** {@inheritDoc} */ - public void visitNewarray(int offset, int length, CstType type, - ArrayList intVals) { - visitCommon(offset, length, true); - visitThrowing(offset, length, true); - } - - /** - * Extracts the list of basic blocks from the bit sets. - * - * @return {@code non-null;} the list of basic blocks - */ - private ByteBlockList getBlockList() { - BytecodeArray bytes = method.getCode(); - ByteBlock[] bbs = new ByteBlock[bytes.size()]; - int count = 0; - - for (int at = 0, next; /*at*/; at = next) { - next = Bits.findFirst(blockSet, at + 1); - if (next < 0) { - break; - } - - if (Bits.get(liveSet, at)) { - /* - * Search backward for the branch or throwing - * instruction at the end of this block, if any. If - * there isn't any, then "next" is the sole target. - */ - IntList targets = null; - int targetsAt = -1; - ByteCatchList blockCatches; - - for (int i = next - 1; i >= at; i--) { - targets = targetLists[i]; - if (targets != null) { - targetsAt = i; - break; - } - } - - if (targets == null) { - targets = IntList.makeImmutable(next); - blockCatches = ByteCatchList.EMPTY; - } else { - blockCatches = catchLists[targetsAt]; - if (blockCatches == null) { - blockCatches = ByteCatchList.EMPTY; - } - } - - bbs[count] = - new ByteBlock(at, at, next, targets, blockCatches); - count++; - } - } - - ByteBlockList result = new ByteBlockList(count); - for (int i = 0; i < count; i++) { - result.set(i, bbs[i]); - } - - return result; - } - - /** - * Does basic block identification. - */ - private void doit() { - BytecodeArray bytes = method.getCode(); - ByteCatchList catches = method.getCatches(); - int catchSz = catches.size(); - - /* - * Start by setting offset 0 as the start of a block and in need - * of work... - */ - Bits.set(workSet, 0); - Bits.set(blockSet, 0); - - /* - * And then process the work set, add new work based on - * exception ranges that are active, and iterate until there's - * nothing left to work on. - */ - while (!Bits.isEmpty(workSet)) { - try { - bytes.processWorkSet(workSet, this); - } catch (IllegalArgumentException ex) { - // Translate the exception. - throw new SimException("flow of control falls off " + - "end of method", - ex); - } - - for (int i = 0; i < catchSz; i++) { - ByteCatchList.Item item = catches.get(i); - int start = item.getStartPc(); - int end = item.getEndPc(); - if (Bits.anyInRange(liveSet, start, end)) { - Bits.set(blockSet, start); - Bits.set(blockSet, end); - addWorkIfNecessary(item.getHandlerPc(), true); - } - } - } - } - - /** - * Sets a bit in the work set, but only if the instruction in question - * isn't yet known to be possibly-live. - * - * @param offset offset to the instruction in question - * @param blockStart {@code true} iff this instruction starts a - * basic block - */ - private void addWorkIfNecessary(int offset, boolean blockStart) { - if (!Bits.get(liveSet, offset)) { - Bits.set(workSet, offset); - } - - if (blockStart) { - Bits.set(blockSet, offset); - } - } - - /** - * Helper method used by all the visitor methods. - * - * @param offset offset to the instruction - * @param length length of the instruction, in bytes - * @param nextIsLive {@code true} iff the instruction after - * the indicated one is possibly-live (because this one isn't an - * unconditional branch, a return, or a switch) - */ - private void visitCommon(int offset, int length, boolean nextIsLive) { - Bits.set(liveSet, offset); - - if (nextIsLive) { - /* - * If the next instruction is flowed to by this one, just - * add it to the work set, and then a subsequent visit*() - * will deal with it as appropriate. - */ - addWorkIfNecessary(offset + length, false); - } else { - /* - * If the next instruction isn't flowed to by this one, - * then mark it as a start of a block but *don't* add it - * to the work set, so that in the final phase we can know - * dead code blocks as those marked as blocks but not also marked - * live. - */ - Bits.set(blockSet, offset + length); - } - } - - /** - * Helper method used by all the visitor methods that deal with - * opcodes that possibly throw. This method should be called after calling - * {@link #visitCommon}. - * - * @param offset offset to the instruction - * @param length length of the instruction, in bytes - * @param nextIsLive {@code true} iff the instruction after - * the indicated one is possibly-live (because this one isn't an - * unconditional throw) - */ - private void visitThrowing(int offset, int length, boolean nextIsLive) { - int next = offset + length; - - if (nextIsLive) { - addWorkIfNecessary(next, true); - } - - ByteCatchList catches = method.getCatches().listFor(offset); - catchLists[offset] = catches; - targetLists[offset] = catches.toTargetList(nextIsLive ? next : -1); - } - - /** - * {@inheritDoc} - */ - public void setPreviousOffset(int offset) { - previousOffset = offset; - } - - /** - * {@inheritDoc} - */ - public int getPreviousOffset() { - return previousOffset; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/ByteBlock.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/ByteBlock.java deleted file mode 100644 index 73bbbab4204..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/ByteBlock.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.code; - -import com.android.dx.util.Hex; -import com.android.dx.util.IntList; -import com.android.dx.util.LabeledItem; - -/** - * Representation of a basic block in a bytecode array. - */ -public final class ByteBlock implements LabeledItem { - /** {@code >= 0;} label for this block */ - private final int label; - - /** {@code >= 0;} bytecode offset (inclusive) of the start of the block */ - private final int start; - - /** {@code > start;} bytecode offset (exclusive) of the end of the block */ - private final int end; - - /** {@code non-null;} list of successors that this block may branch to */ - private final IntList successors; - - /** {@code non-null;} list of exceptions caught and their handler targets */ - private final ByteCatchList catches; - - /** - * Constructs an instance. - * - * @param label {@code >= 0;} target label for this block - * @param start {@code >= 0;} bytecode offset (inclusive) of the start - * of the block - * @param end {@code > start;} bytecode offset (exclusive) of the end - * of the block - * @param successors {@code non-null;} list of successors that this block may - * branch to - * @param catches {@code non-null;} list of exceptions caught and their - * handler targets - */ - public ByteBlock(int label, int start, int end, IntList successors, - ByteCatchList catches) { - if (label < 0) { - throw new IllegalArgumentException("label < 0"); - } - - if (start < 0) { - throw new IllegalArgumentException("start < 0"); - } - - if (end <= start) { - throw new IllegalArgumentException("end <= start"); - } - - if (successors == null) { - throw new NullPointerException("targets == null"); - } - - int sz = successors.size(); - for (int i = 0; i < sz; i++) { - if (successors.get(i) < 0) { - throw new IllegalArgumentException("successors[" + i + - "] == " + - successors.get(i)); - } - } - - if (catches == null) { - throw new NullPointerException("catches == null"); - } - - this.label = label; - this.start = start; - this.end = end; - this.successors = successors; - this.catches = catches; - } - - /** {@inheritDoc} */ - @Override - public String toString() { - return '{' + Hex.u2(label) + ": " + Hex.u2(start) + ".." + - Hex.u2(end) + '}'; - } - - /** - * Gets the label of this block. - * - * @return {@code >= 0;} the label - */ - public int getLabel() { - return label; - } - - /** - * Gets the bytecode offset (inclusive) of the start of this block. - * - * @return {@code >= 0;} the start offset - */ - public int getStart() { - return start; - } - - /** - * Gets the bytecode offset (exclusive) of the end of this block. - * - * @return {@code > getStart();} the end offset - */ - public int getEnd() { - return end; - } - - /** - * Gets the list of successors that this block may branch to - * non-exceptionally. - * - * @return {@code non-null;} the successor list - */ - public IntList getSuccessors() { - return successors; - } - - /** - * Gets the list of exceptions caught and their handler targets. - * - * @return {@code non-null;} the catch list - */ - public ByteCatchList getCatches() { - return catches; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/ByteBlockList.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/ByteBlockList.java deleted file mode 100644 index 5370c951fb7..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/ByteBlockList.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.code; - -import com.android.dx.util.Hex; -import com.android.dx.util.LabeledList; - -/** - * List of {@link ByteBlock} instances. - */ -public final class ByteBlockList extends LabeledList { - - /** - * Constructs an instance. - * - * @param size {@code >= 0;} the number of elements to be in the list - */ - public ByteBlockList(int size) { - super(size); - } - - /** - * Gets the indicated element. It is an error to call this with the - * index for an element which was never set; if you do that, this - * will throw {@code NullPointerException}. - * - * @param n {@code >= 0, < size();} which element - * @return {@code non-null;} the indicated element - */ - public ByteBlock get(int n) { - return (ByteBlock) get0(n); - } - - /** - * Gets the block with the given label. - * - * @param label the label to look for - * @return {@code non-null;} the block with the given label - */ - public ByteBlock labelToBlock(int label) { - int idx = indexOfLabel(label); - - if (idx < 0) { - throw new IllegalArgumentException("no such label: " - + Hex.u2(label)); - } - - return get(idx); - } - - /** - * Sets the element at the given index. - * - * @param n {@code >= 0, < size();} which element - * @param bb {@code null-ok;} the value to store - */ - public void set(int n, ByteBlock bb) { - super.set(n, bb); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/ByteCatchList.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/ByteCatchList.java deleted file mode 100644 index 36c37afe53b..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/ByteCatchList.java +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.code; - -import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.type.StdTypeList; -import com.android.dx.rop.type.TypeList; -import com.android.dx.util.FixedSizeList; -import com.android.dx.util.IntList; - -/** - * List of catch entries, that is, the elements of an "exception table," - * which is part of a standard {@code Code} attribute. - */ -public final class ByteCatchList extends FixedSizeList { - /** {@code non-null;} convenient zero-entry instance */ - public static final ByteCatchList EMPTY = new ByteCatchList(0); - - /** - * Constructs an instance. - * - * @param count the number of elements to be in the table - */ - public ByteCatchList(int count) { - super(count); - } - - /** - * Gets the total length of this structure in bytes, when included in - * a {@code Code} attribute. The returned value includes the - * two bytes for {@code exception_table_length}. - * - * @return {@code >= 2;} the total length, in bytes - */ - public int byteLength() { - return 2 + size() * 8; - } - - /** - * Gets the indicated item. - * - * @param n {@code >= 0;} which item - * @return {@code null-ok;} the indicated item - */ - public Item get(int n) { - return (Item) get0(n); - } - - /** - * Sets the item at the given index. - * - * @param n {@code >= 0, < size();} which entry to set - * @param item {@code non-null;} the item - */ - public void set(int n, Item item) { - if (item == null) { - throw new NullPointerException("item == null"); - } - - set0(n, item); - } - - /** - * Sets the item at the given index. - * - * @param n {@code >= 0, < size();} which entry to set - * @param startPc {@code >= 0;} the start pc (inclusive) of the handler's range - * @param endPc {@code >= startPc;} the end pc (exclusive) of the - * handler's range - * @param handlerPc {@code >= 0;} the pc of the exception handler - * @param exceptionClass {@code null-ok;} the exception class or - * {@code null} to catch all exceptions with this handler - */ - public void set(int n, int startPc, int endPc, int handlerPc, - CstType exceptionClass) { - set0(n, new Item(startPc, endPc, handlerPc, exceptionClass)); - } - - /** - * Gets the list of items active at the given address. The result is - * automatically made immutable. - * - * @param pc which address - * @return {@code non-null;} list of exception handlers active at - * {@code pc} - */ - public ByteCatchList listFor(int pc) { - int sz = size(); - Item[] resultArr = new Item[sz]; - int resultSz = 0; - - for (int i = 0; i < sz; i++) { - Item one = get(i); - if (one.covers(pc) && typeNotFound(one, resultArr, resultSz)) { - resultArr[resultSz] = one; - resultSz++; - } - } - - if (resultSz == 0) { - return EMPTY; - } - - ByteCatchList result = new ByteCatchList(resultSz); - for (int i = 0; i < resultSz; i++) { - result.set(i, resultArr[i]); - } - - result.setImmutable(); - return result; - } - - /** - * Helper method for {@link #listFor}, which tells whether a match - * is not found for the exception type of the given item in - * the given array. A match is considered to be either an exact type - * match or the class {@code Object} which represents a catch-all. - * - * @param item {@code non-null;} item with the exception type to look for - * @param arr {@code non-null;} array to search in - * @param count {@code non-null;} maximum number of elements in the array to check - * @return {@code true} iff the exception type is not found - */ - private static boolean typeNotFound(Item item, Item[] arr, int count) { - CstType type = item.getExceptionClass(); - - for (int i = 0; i < count; i++) { - CstType one = arr[i].getExceptionClass(); - if ((one == type) || (one == CstType.OBJECT)) { - return false; - } - } - - return true; - } - - /** - * Returns a target list corresponding to this instance. The result - * is a list of all the exception handler addresses, with the given - * {@code noException} address appended if appropriate. The - * result is automatically made immutable. - * - * @param noException {@code >= -1;} the no-exception address to append, or - * {@code -1} not to append anything - * @return {@code non-null;} list of exception targets, with - * {@code noException} appended if necessary - */ - public IntList toTargetList(int noException) { - if (noException < -1) { - throw new IllegalArgumentException("noException < -1"); - } - - boolean hasDefault = (noException >= 0); - int sz = size(); - - if (sz == 0) { - if (hasDefault) { - /* - * The list is empty, but there is a no-exception - * address; so, the result is just that address. - */ - return IntList.makeImmutable(noException); - } - /* - * The list is empty and there isn't even a no-exception - * address. - */ - return IntList.EMPTY; - } - - IntList result = new IntList(sz + (hasDefault ? 1 : 0)); - - for (int i = 0; i < sz; i++) { - result.add(get(i).getHandlerPc()); - } - - if (hasDefault) { - result.add(noException); - } - - result.setImmutable(); - return result; - } - - /** - * Returns a rop-style catches list equivalent to this one. - * - * @return {@code non-null;} the converted instance - */ - public TypeList toRopCatchList() { - int sz = size(); - if (sz == 0) { - return StdTypeList.EMPTY; - } - - StdTypeList result = new StdTypeList(sz); - - for (int i = 0; i < sz; i++) { - result.set(i, get(i).getExceptionClass().getClassType()); - } - - result.setImmutable(); - return result; - } - - /** - * Item in an exception handler list. - */ - public static class Item { - /** {@code >= 0;} the start pc (inclusive) of the handler's range */ - private final int startPc; - - /** {@code >= startPc;} the end pc (exclusive) of the handler's range */ - private final int endPc; - - /** {@code >= 0;} the pc of the exception handler */ - private final int handlerPc; - - /** {@code null-ok;} the exception class or {@code null} to catch all - * exceptions with this handler */ - private final CstType exceptionClass; - - /** - * Constructs an instance. - * - * @param startPc {@code >= 0;} the start pc (inclusive) of the - * handler's range - * @param endPc {@code >= startPc;} the end pc (exclusive) of the - * handler's range - * @param handlerPc {@code >= 0;} the pc of the exception handler - * @param exceptionClass {@code null-ok;} the exception class or - * {@code null} to catch all exceptions with this handler - */ - public Item(int startPc, int endPc, int handlerPc, - CstType exceptionClass) { - if (startPc < 0) { - throw new IllegalArgumentException("startPc < 0"); - } - - if (endPc < startPc) { - throw new IllegalArgumentException("endPc < startPc"); - } - - if (handlerPc < 0) { - throw new IllegalArgumentException("handlerPc < 0"); - } - - this.startPc = startPc; - this.endPc = endPc; - this.handlerPc = handlerPc; - this.exceptionClass = exceptionClass; - } - - /** - * Gets the start pc (inclusive) of the handler's range. - * - * @return {@code >= 0;} the start pc (inclusive) of the handler's range. - */ - public int getStartPc() { - return startPc; - } - - /** - * Gets the end pc (exclusive) of the handler's range. - * - * @return {@code >= startPc;} the end pc (exclusive) of the - * handler's range. - */ - public int getEndPc() { - return endPc; - } - - /** - * Gets the pc of the exception handler. - * - * @return {@code >= 0;} the pc of the exception handler - */ - public int getHandlerPc() { - return handlerPc; - } - - /** - * Gets the class of exception handled. - * - * @return {@code non-null;} the exception class; {@link CstType#OBJECT} - * if this entry handles all possible exceptions - */ - public CstType getExceptionClass() { - return (exceptionClass != null) ? - exceptionClass : CstType.OBJECT; - } - - /** - * Returns whether the given address is in the range of this item. - * - * @param pc the address - * @return {@code true} iff this item covers {@code pc} - */ - public boolean covers(int pc) { - return (pc >= startPc) && (pc < endPc); - } - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/ByteOps.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/ByteOps.java deleted file mode 100644 index 850346a9404..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/ByteOps.java +++ /dev/null @@ -1,650 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.code; - -import com.android.dx.util.Hex; - -/** - * Constants and utility methods for dealing with bytecode arrays at an - * opcode level. - */ -public class ByteOps { - // one constant per opcode - public static final int NOP = 0x00; - public static final int ACONST_NULL = 0x01; - public static final int ICONST_M1 = 0x02; - public static final int ICONST_0 = 0x03; - public static final int ICONST_1 = 0x04; - public static final int ICONST_2 = 0x05; - public static final int ICONST_3 = 0x06; - public static final int ICONST_4 = 0x07; - public static final int ICONST_5 = 0x08; - public static final int LCONST_0 = 0x09; - public static final int LCONST_1 = 0x0a; - public static final int FCONST_0 = 0x0b; - public static final int FCONST_1 = 0x0c; - public static final int FCONST_2 = 0x0d; - public static final int DCONST_0 = 0x0e; - public static final int DCONST_1 = 0x0f; - public static final int BIPUSH = 0x10; - public static final int SIPUSH = 0x11; - public static final int LDC = 0x12; - public static final int LDC_W = 0x13; - public static final int LDC2_W = 0x14; - public static final int ILOAD = 0x15; - public static final int LLOAD = 0x16; - public static final int FLOAD = 0x17; - public static final int DLOAD = 0x18; - public static final int ALOAD = 0x19; - public static final int ILOAD_0 = 0x1a; - public static final int ILOAD_1 = 0x1b; - public static final int ILOAD_2 = 0x1c; - public static final int ILOAD_3 = 0x1d; - public static final int LLOAD_0 = 0x1e; - public static final int LLOAD_1 = 0x1f; - public static final int LLOAD_2 = 0x20; - public static final int LLOAD_3 = 0x21; - public static final int FLOAD_0 = 0x22; - public static final int FLOAD_1 = 0x23; - public static final int FLOAD_2 = 0x24; - public static final int FLOAD_3 = 0x25; - public static final int DLOAD_0 = 0x26; - public static final int DLOAD_1 = 0x27; - public static final int DLOAD_2 = 0x28; - public static final int DLOAD_3 = 0x29; - public static final int ALOAD_0 = 0x2a; - public static final int ALOAD_1 = 0x2b; - public static final int ALOAD_2 = 0x2c; - public static final int ALOAD_3 = 0x2d; - public static final int IALOAD = 0x2e; - public static final int LALOAD = 0x2f; - public static final int FALOAD = 0x30; - public static final int DALOAD = 0x31; - public static final int AALOAD = 0x32; - public static final int BALOAD = 0x33; - public static final int CALOAD = 0x34; - public static final int SALOAD = 0x35; - public static final int ISTORE = 0x36; - public static final int LSTORE = 0x37; - public static final int FSTORE = 0x38; - public static final int DSTORE = 0x39; - public static final int ASTORE = 0x3a; - public static final int ISTORE_0 = 0x3b; - public static final int ISTORE_1 = 0x3c; - public static final int ISTORE_2 = 0x3d; - public static final int ISTORE_3 = 0x3e; - public static final int LSTORE_0 = 0x3f; - public static final int LSTORE_1 = 0x40; - public static final int LSTORE_2 = 0x41; - public static final int LSTORE_3 = 0x42; - public static final int FSTORE_0 = 0x43; - public static final int FSTORE_1 = 0x44; - public static final int FSTORE_2 = 0x45; - public static final int FSTORE_3 = 0x46; - public static final int DSTORE_0 = 0x47; - public static final int DSTORE_1 = 0x48; - public static final int DSTORE_2 = 0x49; - public static final int DSTORE_3 = 0x4a; - public static final int ASTORE_0 = 0x4b; - public static final int ASTORE_1 = 0x4c; - public static final int ASTORE_2 = 0x4d; - public static final int ASTORE_3 = 0x4e; - public static final int IASTORE = 0x4f; - public static final int LASTORE = 0x50; - public static final int FASTORE = 0x51; - public static final int DASTORE = 0x52; - public static final int AASTORE = 0x53; - public static final int BASTORE = 0x54; - public static final int CASTORE = 0x55; - public static final int SASTORE = 0x56; - public static final int POP = 0x57; - public static final int POP2 = 0x58; - public static final int DUP = 0x59; - public static final int DUP_X1 = 0x5a; - public static final int DUP_X2 = 0x5b; - public static final int DUP2 = 0x5c; - public static final int DUP2_X1 = 0x5d; - public static final int DUP2_X2 = 0x5e; - public static final int SWAP = 0x5f; - public static final int IADD = 0x60; - public static final int LADD = 0x61; - public static final int FADD = 0x62; - public static final int DADD = 0x63; - public static final int ISUB = 0x64; - public static final int LSUB = 0x65; - public static final int FSUB = 0x66; - public static final int DSUB = 0x67; - public static final int IMUL = 0x68; - public static final int LMUL = 0x69; - public static final int FMUL = 0x6a; - public static final int DMUL = 0x6b; - public static final int IDIV = 0x6c; - public static final int LDIV = 0x6d; - public static final int FDIV = 0x6e; - public static final int DDIV = 0x6f; - public static final int IREM = 0x70; - public static final int LREM = 0x71; - public static final int FREM = 0x72; - public static final int DREM = 0x73; - public static final int INEG = 0x74; - public static final int LNEG = 0x75; - public static final int FNEG = 0x76; - public static final int DNEG = 0x77; - public static final int ISHL = 0x78; - public static final int LSHL = 0x79; - public static final int ISHR = 0x7a; - public static final int LSHR = 0x7b; - public static final int IUSHR = 0x7c; - public static final int LUSHR = 0x7d; - public static final int IAND = 0x7e; - public static final int LAND = 0x7f; - public static final int IOR = 0x80; - public static final int LOR = 0x81; - public static final int IXOR = 0x82; - public static final int LXOR = 0x83; - public static final int IINC = 0x84; - public static final int I2L = 0x85; - public static final int I2F = 0x86; - public static final int I2D = 0x87; - public static final int L2I = 0x88; - public static final int L2F = 0x89; - public static final int L2D = 0x8a; - public static final int F2I = 0x8b; - public static final int F2L = 0x8c; - public static final int F2D = 0x8d; - public static final int D2I = 0x8e; - public static final int D2L = 0x8f; - public static final int D2F = 0x90; - public static final int I2B = 0x91; - public static final int I2C = 0x92; - public static final int I2S = 0x93; - public static final int LCMP = 0x94; - public static final int FCMPL = 0x95; - public static final int FCMPG = 0x96; - public static final int DCMPL = 0x97; - public static final int DCMPG = 0x98; - public static final int IFEQ = 0x99; - public static final int IFNE = 0x9a; - public static final int IFLT = 0x9b; - public static final int IFGE = 0x9c; - public static final int IFGT = 0x9d; - public static final int IFLE = 0x9e; - public static final int IF_ICMPEQ = 0x9f; - public static final int IF_ICMPNE = 0xa0; - public static final int IF_ICMPLT = 0xa1; - public static final int IF_ICMPGE = 0xa2; - public static final int IF_ICMPGT = 0xa3; - public static final int IF_ICMPLE = 0xa4; - public static final int IF_ACMPEQ = 0xa5; - public static final int IF_ACMPNE = 0xa6; - public static final int GOTO = 0xa7; - public static final int JSR = 0xa8; - public static final int RET = 0xa9; - public static final int TABLESWITCH = 0xaa; - public static final int LOOKUPSWITCH = 0xab; - public static final int IRETURN = 0xac; - public static final int LRETURN = 0xad; - public static final int FRETURN = 0xae; - public static final int DRETURN = 0xaf; - public static final int ARETURN = 0xb0; - public static final int RETURN = 0xb1; - public static final int GETSTATIC = 0xb2; - public static final int PUTSTATIC = 0xb3; - public static final int GETFIELD = 0xb4; - public static final int PUTFIELD = 0xb5; - public static final int INVOKEVIRTUAL = 0xb6; - public static final int INVOKESPECIAL = 0xb7; - public static final int INVOKESTATIC = 0xb8; - public static final int INVOKEINTERFACE = 0xb9; - public static final int INVOKEDYNAMIC = 0xba; - public static final int NEW = 0xbb; - public static final int NEWARRAY = 0xbc; - public static final int ANEWARRAY = 0xbd; - public static final int ARRAYLENGTH = 0xbe; - public static final int ATHROW = 0xbf; - public static final int CHECKCAST = 0xc0; - public static final int INSTANCEOF = 0xc1; - public static final int MONITORENTER = 0xc2; - public static final int MONITOREXIT = 0xc3; - public static final int WIDE = 0xc4; - public static final int MULTIANEWARRAY = 0xc5; - public static final int IFNULL = 0xc6; - public static final int IFNONNULL = 0xc7; - public static final int GOTO_W = 0xc8; - public static final int JSR_W = 0xc9; - - // a constant for each valid argument to "newarray" - - public static final int NEWARRAY_BOOLEAN = 4; - public static final int NEWARRAY_CHAR = 5; - public static final int NEWARRAY_FLOAT = 6; - public static final int NEWARRAY_DOUBLE = 7; - public static final int NEWARRAY_BYTE = 8; - public static final int NEWARRAY_SHORT = 9; - public static final int NEWARRAY_INT = 10; - public static final int NEWARRAY_LONG = 11; - - // a constant for each possible instruction format - - /** invalid */ - public static final int FMT_INVALID = 0; - - /** "-": {@code op} */ - public static final int FMT_NO_ARGS = 1; - - /** "0": {@code op}; implies {@code max_locals >= 1} */ - public static final int FMT_NO_ARGS_LOCALS_1 = 2; - - /** "1": {@code op}; implies {@code max_locals >= 2} */ - public static final int FMT_NO_ARGS_LOCALS_2 = 3; - - /** "2": {@code op}; implies {@code max_locals >= 3} */ - public static final int FMT_NO_ARGS_LOCALS_3 = 4; - - /** "3": {@code op}; implies {@code max_locals >= 4} */ - public static final int FMT_NO_ARGS_LOCALS_4 = 5; - - /** "4": {@code op}; implies {@code max_locals >= 5} */ - public static final int FMT_NO_ARGS_LOCALS_5 = 6; - - /** "b": {@code op target target} */ - public static final int FMT_BRANCH = 7; - - /** "c": {@code op target target target target} */ - public static final int FMT_WIDE_BRANCH = 8; - - /** "p": {@code op #cpi #cpi}; constant restricted as specified */ - public static final int FMT_CPI = 9; - - /** - * "l": {@code op local}; category-1 local; implies - * {@code max_locals} is at least two more than the given - * local number - */ - public static final int FMT_LOCAL_1 = 10; - - /** - * "m": {@code op local}; category-2 local; implies - * {@code max_locals} is at least two more than the given - * local number - */ - public static final int FMT_LOCAL_2 = 11; - - /** - * "y": {@code op #byte} ({@code bipush} and - * {@code newarray}) - */ - public static final int FMT_LITERAL_BYTE = 12; - - /** "I": {@code invokeinterface cpi cpi count 0} */ - public static final int FMT_INVOKEINTERFACE = 13; - - /** "L": {@code ldc #cpi}; constant restricted as specified */ - public static final int FMT_LDC = 14; - - /** "S": {@code sipush #byte #byte} */ - public static final int FMT_SIPUSH = 15; - - /** "T": {@code tableswitch ...} */ - public static final int FMT_TABLESWITCH = 16; - - /** "U": {@code lookupswitch ...} */ - public static final int FMT_LOOKUPSWITCH = 17; - - /** "M": {@code multianewarray cpi cpi dims} */ - public static final int FMT_MULTIANEWARRAY = 18; - - /** "W": {@code wide ...} */ - public static final int FMT_WIDE = 19; - - /** mask for the bits representing the opcode format */ - public static final int FMT_MASK = 0x1f; - - /** "I": flag bit for valid cp type for {@code Integer} */ - public static final int CPOK_Integer = 0x20; - - /** "F": flag bit for valid cp type for {@code Float} */ - public static final int CPOK_Float = 0x40; - - /** "J": flag bit for valid cp type for {@code Long} */ - public static final int CPOK_Long = 0x80; - - /** "D": flag bit for valid cp type for {@code Double} */ - public static final int CPOK_Double = 0x100; - - /** "c": flag bit for valid cp type for {@code Class} */ - public static final int CPOK_Class = 0x200; - - /** "s": flag bit for valid cp type for {@code String} */ - public static final int CPOK_String = 0x400; - - /** "f": flag bit for valid cp type for {@code Fieldref} */ - public static final int CPOK_Fieldref = 0x800; - - /** "m": flag bit for valid cp type for {@code Methodref} */ - public static final int CPOK_Methodref = 0x1000; - - /** "i": flag bit for valid cp type for {@code InterfaceMethodref} */ - public static final int CPOK_InterfaceMethodref = 0x2000; - - /** - * {@code non-null;} map from opcodes to format or'ed with allowed constant - * pool types - */ - private static final int[] OPCODE_INFO = new int[256]; - - /** {@code non-null;} map from opcodes to their names */ - private static final String[] OPCODE_NAMES = new String[256]; - - /** {@code non-null;} bigass string describing all the opcodes */ - private static final String OPCODE_DETAILS = - "00 - nop;" + - "01 - aconst_null;" + - "02 - iconst_m1;" + - "03 - iconst_0;" + - "04 - iconst_1;" + - "05 - iconst_2;" + - "06 - iconst_3;" + - "07 - iconst_4;" + - "08 - iconst_5;" + - "09 - lconst_0;" + - "0a - lconst_1;" + - "0b - fconst_0;" + - "0c - fconst_1;" + - "0d - fconst_2;" + - "0e - dconst_0;" + - "0f - dconst_1;" + - "10 y bipush;" + - "11 S sipush;" + - "12 L:IFcs ldc;" + - "13 p:IFcs ldc_w;" + - "14 p:DJ ldc2_w;" + - "15 l iload;" + - "16 m lload;" + - "17 l fload;" + - "18 m dload;" + - "19 l aload;" + - "1a 0 iload_0;" + - "1b 1 iload_1;" + - "1c 2 iload_2;" + - "1d 3 iload_3;" + - "1e 1 lload_0;" + - "1f 2 lload_1;" + - "20 3 lload_2;" + - "21 4 lload_3;" + - "22 0 fload_0;" + - "23 1 fload_1;" + - "24 2 fload_2;" + - "25 3 fload_3;" + - "26 1 dload_0;" + - "27 2 dload_1;" + - "28 3 dload_2;" + - "29 4 dload_3;" + - "2a 0 aload_0;" + - "2b 1 aload_1;" + - "2c 2 aload_2;" + - "2d 3 aload_3;" + - "2e - iaload;" + - "2f - laload;" + - "30 - faload;" + - "31 - daload;" + - "32 - aaload;" + - "33 - baload;" + - "34 - caload;" + - "35 - saload;" + - "36 - istore;" + - "37 - lstore;" + - "38 - fstore;" + - "39 - dstore;" + - "3a - astore;" + - "3b 0 istore_0;" + - "3c 1 istore_1;" + - "3d 2 istore_2;" + - "3e 3 istore_3;" + - "3f 1 lstore_0;" + - "40 2 lstore_1;" + - "41 3 lstore_2;" + - "42 4 lstore_3;" + - "43 0 fstore_0;" + - "44 1 fstore_1;" + - "45 2 fstore_2;" + - "46 3 fstore_3;" + - "47 1 dstore_0;" + - "48 2 dstore_1;" + - "49 3 dstore_2;" + - "4a 4 dstore_3;" + - "4b 0 astore_0;" + - "4c 1 astore_1;" + - "4d 2 astore_2;" + - "4e 3 astore_3;" + - "4f - iastore;" + - "50 - lastore;" + - "51 - fastore;" + - "52 - dastore;" + - "53 - aastore;" + - "54 - bastore;" + - "55 - castore;" + - "56 - sastore;" + - "57 - pop;" + - "58 - pop2;" + - "59 - dup;" + - "5a - dup_x1;" + - "5b - dup_x2;" + - "5c - dup2;" + - "5d - dup2_x1;" + - "5e - dup2_x2;" + - "5f - swap;" + - "60 - iadd;" + - "61 - ladd;" + - "62 - fadd;" + - "63 - dadd;" + - "64 - isub;" + - "65 - lsub;" + - "66 - fsub;" + - "67 - dsub;" + - "68 - imul;" + - "69 - lmul;" + - "6a - fmul;" + - "6b - dmul;" + - "6c - idiv;" + - "6d - ldiv;" + - "6e - fdiv;" + - "6f - ddiv;" + - "70 - irem;" + - "71 - lrem;" + - "72 - frem;" + - "73 - drem;" + - "74 - ineg;" + - "75 - lneg;" + - "76 - fneg;" + - "77 - dneg;" + - "78 - ishl;" + - "79 - lshl;" + - "7a - ishr;" + - "7b - lshr;" + - "7c - iushr;" + - "7d - lushr;" + - "7e - iand;" + - "7f - land;" + - "80 - ior;" + - "81 - lor;" + - "82 - ixor;" + - "83 - lxor;" + - "84 l iinc;" + - "85 - i2l;" + - "86 - i2f;" + - "87 - i2d;" + - "88 - l2i;" + - "89 - l2f;" + - "8a - l2d;" + - "8b - f2i;" + - "8c - f2l;" + - "8d - f2d;" + - "8e - d2i;" + - "8f - d2l;" + - "90 - d2f;" + - "91 - i2b;" + - "92 - i2c;" + - "93 - i2s;" + - "94 - lcmp;" + - "95 - fcmpl;" + - "96 - fcmpg;" + - "97 - dcmpl;" + - "98 - dcmpg;" + - "99 b ifeq;" + - "9a b ifne;" + - "9b b iflt;" + - "9c b ifge;" + - "9d b ifgt;" + - "9e b ifle;" + - "9f b if_icmpeq;" + - "a0 b if_icmpne;" + - "a1 b if_icmplt;" + - "a2 b if_icmpge;" + - "a3 b if_icmpgt;" + - "a4 b if_icmple;" + - "a5 b if_acmpeq;" + - "a6 b if_acmpne;" + - "a7 b goto;" + - "a8 b jsr;" + - "a9 l ret;" + - "aa T tableswitch;" + - "ab U lookupswitch;" + - "ac - ireturn;" + - "ad - lreturn;" + - "ae - freturn;" + - "af - dreturn;" + - "b0 - areturn;" + - "b1 - return;" + - "b2 p:f getstatic;" + - "b3 p:f putstatic;" + - "b4 p:f getfield;" + - "b5 p:f putfield;" + - "b6 p:m invokevirtual;" + - "b7 p:m invokespecial;" + - "b8 p:m invokestatic;" + - "b9 I:i invokeinterface;" + - "bb p:c new;" + - "bc y newarray;" + - "bd p:c anewarray;" + - "be - arraylength;" + - "bf - athrow;" + - "c0 p:c checkcast;" + - "c1 p:c instanceof;" + - "c2 - monitorenter;" + - "c3 - monitorexit;" + - "c4 W wide;" + - "c5 M:c multianewarray;" + - "c6 b ifnull;" + - "c7 b ifnonnull;" + - "c8 c goto_w;" + - "c9 c jsr_w;"; - - static { - // Set up OPCODE_INFO and OPCODE_NAMES. - String s = OPCODE_DETAILS; - int len = s.length(); - - for (int i = 0; i < len; /*i*/) { - int idx = (Character.digit(s.charAt(i), 16) << 4) | - Character.digit(s.charAt(i + 1), 16); - int info; - switch (s.charAt(i + 3)) { - case '-': info = FMT_NO_ARGS; break; - case '0': info = FMT_NO_ARGS_LOCALS_1; break; - case '1': info = FMT_NO_ARGS_LOCALS_2; break; - case '2': info = FMT_NO_ARGS_LOCALS_3; break; - case '3': info = FMT_NO_ARGS_LOCALS_4; break; - case '4': info = FMT_NO_ARGS_LOCALS_5; break; - case 'b': info = FMT_BRANCH; break; - case 'c': info = FMT_WIDE_BRANCH; break; - case 'p': info = FMT_CPI; break; - case 'l': info = FMT_LOCAL_1; break; - case 'm': info = FMT_LOCAL_2; break; - case 'y': info = FMT_LITERAL_BYTE; break; - case 'I': info = FMT_INVOKEINTERFACE; break; - case 'L': info = FMT_LDC; break; - case 'S': info = FMT_SIPUSH; break; - case 'T': info = FMT_TABLESWITCH; break; - case 'U': info = FMT_LOOKUPSWITCH; break; - case 'M': info = FMT_MULTIANEWARRAY; break; - case 'W': info = FMT_WIDE; break; - default: info = FMT_INVALID; break; - } - - i += 5; - if (s.charAt(i - 1) == ':') { - inner: - for (;;) { - switch (s.charAt(i)) { - case 'I': info |= CPOK_Integer; break; - case 'F': info |= CPOK_Float; break; - case 'J': info |= CPOK_Long; break; - case 'D': info |= CPOK_Double; break; - case 'c': info |= CPOK_Class; break; - case 's': info |= CPOK_String; break; - case 'f': info |= CPOK_Fieldref; break; - case 'm': info |= CPOK_Methodref; break; - case 'i': info |= CPOK_InterfaceMethodref; break; - default: break inner; - } - i++; - } - i++; - } - - int endAt = s.indexOf(';', i); - OPCODE_INFO[idx] = info; - OPCODE_NAMES[idx] = s.substring(i, endAt); - i = endAt + 1; - } - } - - /** - * This class is uninstantiable. - */ - private ByteOps() { - // This space intentionally left blank. - } - - /** - * Gets the name of the given opcode. - * - * @param opcode {@code >= 0, <= 255;} the opcode - * @return {@code non-null;} its name - */ - public static String opName(int opcode) { - String result = OPCODE_NAMES[opcode]; - - if (result == null) { - result = "unused_" + Hex.u1(opcode); - OPCODE_NAMES[opcode] = result; - } - - return result; - } - - /** - * Gets the format and allowed cp types of the given opcode. - * - * @param opcode {@code >= 0, <= 255;} the opcode - * @return its format and allowed cp types - */ - public static int opInfo(int opcode) { - return OPCODE_INFO[opcode]; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/BytecodeArray.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/BytecodeArray.java deleted file mode 100644 index 83e8ae846d6..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/BytecodeArray.java +++ /dev/null @@ -1,1423 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.code; - -import com.android.dx.cf.iface.ParseException; -import com.android.dx.rop.cst.Constant; -import com.android.dx.rop.cst.ConstantPool; -import com.android.dx.rop.cst.CstDouble; -import com.android.dx.rop.cst.CstFloat; -import com.android.dx.rop.cst.CstInteger; -import com.android.dx.rop.cst.CstKnownNull; -import com.android.dx.rop.cst.CstLiteralBits; -import com.android.dx.rop.cst.CstLong; -import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.type.Type; -import com.android.dx.util.Bits; -import com.android.dx.util.ByteArray; -import com.android.dx.util.Hex; -import java.util.ArrayList; - -/** - * Bytecode array, which is part of a standard {@code Code} attribute. - */ -public final class BytecodeArray { - /** {@code non-null;} underlying bytes */ - private final ByteArray bytes; - - /** - * {@code non-null;} constant pool to use when resolving constant - * pool indices - */ - private final ConstantPool pool; - - /** - * Constructs an instance. - * - * @param bytes {@code non-null;} underlying bytes - * @param pool {@code non-null;} constant pool to use when - * resolving constant pool indices - */ - public BytecodeArray(ByteArray bytes, ConstantPool pool) { - if (bytes == null) { - throw new NullPointerException("bytes == null"); - } - - if (pool == null) { - throw new NullPointerException("pool == null"); - } - - this.bytes = bytes; - this.pool = pool; - } - - /** - * Gets the underlying byte array. - * - * @return {@code non-null;} the byte array - */ - public ByteArray getBytes() { - return bytes; - } - - /** - * Gets the size of the bytecode array, per se. - * - * @return {@code >= 0;} the length of the bytecode array - */ - public int size() { - return bytes.size(); - } - - /** - * Gets the total length of this structure in bytes, when included in - * a {@code Code} attribute. The returned value includes the - * array size plus four bytes for {@code code_length}. - * - * @return {@code >= 4;} the total length, in bytes - */ - public int byteLength() { - return 4 + bytes.size(); - } - - /** - * Parses each instruction in the array, in order. - * - * @param visitor {@code null-ok;} visitor to call back to for - * each instruction - */ - public void forEach(Visitor visitor) { - int sz = bytes.size(); - int at = 0; - - while (at < sz) { - /* - * Don't record the previous offset here, so that we get to see the - * raw code that initializes the array - */ - at += parseInstruction(at, visitor); - } - } - - /** - * Finds the offset to each instruction in the bytecode array. The - * result is a bit set with the offset of each opcode-per-se flipped on. - * - * @see Bits - * @return {@code non-null;} appropriately constructed bit set - */ - public int[] getInstructionOffsets() { - int sz = bytes.size(); - int[] result = Bits.makeBitSet(sz); - int at = 0; - - while (at < sz) { - Bits.set(result, at, true); - int length = parseInstruction(at, null); - at += length; - } - - return result; - } - - /** - * Processes the given "work set" by repeatedly finding the lowest bit - * in the set, clearing it, and parsing and visiting the instruction at - * the indicated offset (that is, the bit index), repeating until the - * work set is empty. It is expected that the visitor will regularly - * set new bits in the work set during the process. - * - * @param workSet {@code non-null;} the work set to process - * @param visitor {@code non-null;} visitor to call back to for - * each instruction - */ - public void processWorkSet(int[] workSet, Visitor visitor) { - if (visitor == null) { - throw new NullPointerException("visitor == null"); - } - - for (;;) { - int offset = Bits.findFirst(workSet, 0); - if (offset < 0) { - break; - } - Bits.clear(workSet, offset); - parseInstruction(offset, visitor); - visitor.setPreviousOffset(offset); - } - } - - /** - * Parses the instruction at the indicated offset. Indicate the - * result by calling the visitor if supplied and by returning the - * number of bytes consumed by the instruction. - * - *

In order to simplify further processing, the opcodes passed - * to the visitor are canonicalized, altering the opcode to a more - * universal one and making formerly implicit arguments - * explicit. In particular:

- * - *
    - *
  • The opcodes to push literal constants of primitive types all become - * {@code ldc}. - * E.g., {@code fconst_0}, {@code sipush}, and - * {@code lconst_0} qualify for this treatment.
  • - *
  • {@code aconst_null} becomes {@code ldc} of a - * "known null."
  • - *
  • Shorthand local variable accessors become the corresponding - * longhand. E.g. {@code aload_2} becomes {@code aload}.
  • - *
  • {@code goto_w} and {@code jsr_w} become {@code goto} - * and {@code jsr} (respectively).
  • - *
  • {@code ldc_w} becomes {@code ldc}.
  • - *
  • {@code tableswitch} becomes {@code lookupswitch}. - *
  • Arithmetic, array, and value-returning ops are collapsed - * to the {@code int} variant opcode, with the {@code type} - * argument set to indicate the actual type. E.g., - * {@code fadd} becomes {@code iadd}, but - * {@code type} is passed as {@code Type.FLOAT} in that - * case. Similarly, {@code areturn} becomes - * {@code ireturn}. (However, {@code return} remains - * unchanged.
  • - *
  • Local variable access ops are collapsed to the {@code int} - * variant opcode, with the {@code type} argument set to indicate - * the actual type. E.g., {@code aload} becomes {@code iload}, - * but {@code type} is passed as {@code Type.OBJECT} in - * that case.
  • - *
  • Numeric conversion ops ({@code i2l}, etc.) are left alone - * to avoid too much confustion, but their {@code type} is - * the pushed type. E.g., {@code i2b} gets type - * {@code Type.INT}, and {@code f2d} gets type - * {@code Type.DOUBLE}. Other unaltered opcodes also get - * their pushed type. E.g., {@code arraylength} gets type - * {@code Type.INT}.
  • - *
- * - * @param offset {@code >= 0, < bytes.size();} offset to the start of the - * instruction - * @param visitor {@code null-ok;} visitor to call back to - * @return the length of the instruction, in bytes - */ - public int parseInstruction(int offset, Visitor visitor) { - if (visitor == null) { - visitor = new BaseVisitor(); - } - - try { - int opcode = bytes.getUnsignedByte(offset); - int info = ByteOps.opInfo(opcode); - int fmt = info & ByteOps.FMT_MASK; - - switch (opcode) { - case ByteOps.NOP: { - visitor.visitNoArgs(opcode, offset, 1, Type.VOID); - return 1; - } - case ByteOps.ACONST_NULL: { - visitor.visitConstant(ByteOps.LDC, offset, 1, - CstKnownNull.THE_ONE, 0); - return 1; - } - case ByteOps.ICONST_M1: { - visitor.visitConstant(ByteOps.LDC, offset, 1, - CstInteger.VALUE_M1, -1); - return 1; - } - case ByteOps.ICONST_0: { - visitor.visitConstant(ByteOps.LDC, offset, 1, - CstInteger.VALUE_0, 0); - return 1; - } - case ByteOps.ICONST_1: { - visitor.visitConstant(ByteOps.LDC, offset, 1, - CstInteger.VALUE_1, 1); - return 1; - } - case ByteOps.ICONST_2: { - visitor.visitConstant(ByteOps.LDC, offset, 1, - CstInteger.VALUE_2, 2); - return 1; - } - case ByteOps.ICONST_3: { - visitor.visitConstant(ByteOps.LDC, offset, 1, - CstInteger.VALUE_3, 3); - return 1; - } - case ByteOps.ICONST_4: { - visitor.visitConstant(ByteOps.LDC, offset, 1, - CstInteger.VALUE_4, 4); - return 1; - } - case ByteOps.ICONST_5: { - visitor.visitConstant(ByteOps.LDC, offset, 1, - CstInteger.VALUE_5, 5); - return 1; - } - case ByteOps.LCONST_0: { - visitor.visitConstant(ByteOps.LDC, offset, 1, - CstLong.VALUE_0, 0); - return 1; - } - case ByteOps.LCONST_1: { - visitor.visitConstant(ByteOps.LDC, offset, 1, - CstLong.VALUE_1, 0); - return 1; - } - case ByteOps.FCONST_0: { - visitor.visitConstant(ByteOps.LDC, offset, 1, - CstFloat.VALUE_0, 0); - return 1; - } - case ByteOps.FCONST_1: { - visitor.visitConstant(ByteOps.LDC, offset, 1, - CstFloat.VALUE_1, 0); - return 1; - } - case ByteOps.FCONST_2: { - visitor.visitConstant(ByteOps.LDC, offset, 1, - CstFloat.VALUE_2, 0); - return 1; - } - case ByteOps.DCONST_0: { - visitor.visitConstant(ByteOps.LDC, offset, 1, - CstDouble.VALUE_0, 0); - return 1; - } - case ByteOps.DCONST_1: { - visitor.visitConstant(ByteOps.LDC, offset, 1, - CstDouble.VALUE_1, 0); - return 1; - } - case ByteOps.BIPUSH: { - int value = bytes.getByte(offset + 1); - visitor.visitConstant(ByteOps.LDC, offset, 2, - CstInteger.make(value), value); - return 2; - } - case ByteOps.SIPUSH: { - int value = bytes.getShort(offset + 1); - visitor.visitConstant(ByteOps.LDC, offset, 3, - CstInteger.make(value), value); - return 3; - } - case ByteOps.LDC: { - int idx = bytes.getUnsignedByte(offset + 1); - Constant cst = pool.get(idx); - int value = (cst instanceof CstInteger) ? - ((CstInteger) cst).getValue() : 0; - visitor.visitConstant(ByteOps.LDC, offset, 2, cst, value); - return 2; - } - case ByteOps.LDC_W: { - int idx = bytes.getUnsignedShort(offset + 1); - Constant cst = pool.get(idx); - int value = (cst instanceof CstInteger) ? - ((CstInteger) cst).getValue() : 0; - visitor.visitConstant(ByteOps.LDC, offset, 3, cst, value); - return 3; - } - case ByteOps.LDC2_W: { - int idx = bytes.getUnsignedShort(offset + 1); - Constant cst = pool.get(idx); - visitor.visitConstant(ByteOps.LDC2_W, offset, 3, cst, 0); - return 3; - } - case ByteOps.ILOAD: { - int idx = bytes.getUnsignedByte(offset + 1); - visitor.visitLocal(ByteOps.ILOAD, offset, 2, idx, - Type.INT, 0); - return 2; - } - case ByteOps.LLOAD: { - int idx = bytes.getUnsignedByte(offset + 1); - visitor.visitLocal(ByteOps.ILOAD, offset, 2, idx, - Type.LONG, 0); - return 2; - } - case ByteOps.FLOAD: { - int idx = bytes.getUnsignedByte(offset + 1); - visitor.visitLocal(ByteOps.ILOAD, offset, 2, idx, - Type.FLOAT, 0); - return 2; - } - case ByteOps.DLOAD: { - int idx = bytes.getUnsignedByte(offset + 1); - visitor.visitLocal(ByteOps.ILOAD, offset, 2, idx, - Type.DOUBLE, 0); - return 2; - } - case ByteOps.ALOAD: { - int idx = bytes.getUnsignedByte(offset + 1); - visitor.visitLocal(ByteOps.ILOAD, offset, 2, idx, - Type.OBJECT, 0); - return 2; - } - case ByteOps.ILOAD_0: - case ByteOps.ILOAD_1: - case ByteOps.ILOAD_2: - case ByteOps.ILOAD_3: { - int idx = opcode - ByteOps.ILOAD_0; - visitor.visitLocal(ByteOps.ILOAD, offset, 1, idx, - Type.INT, 0); - return 1; - } - case ByteOps.LLOAD_0: - case ByteOps.LLOAD_1: - case ByteOps.LLOAD_2: - case ByteOps.LLOAD_3: { - int idx = opcode - ByteOps.LLOAD_0; - visitor.visitLocal(ByteOps.ILOAD, offset, 1, idx, - Type.LONG, 0); - return 1; - } - case ByteOps.FLOAD_0: - case ByteOps.FLOAD_1: - case ByteOps.FLOAD_2: - case ByteOps.FLOAD_3: { - int idx = opcode - ByteOps.FLOAD_0; - visitor.visitLocal(ByteOps.ILOAD, offset, 1, idx, - Type.FLOAT, 0); - return 1; - } - case ByteOps.DLOAD_0: - case ByteOps.DLOAD_1: - case ByteOps.DLOAD_2: - case ByteOps.DLOAD_3: { - int idx = opcode - ByteOps.DLOAD_0; - visitor.visitLocal(ByteOps.ILOAD, offset, 1, idx, - Type.DOUBLE, 0); - return 1; - } - case ByteOps.ALOAD_0: - case ByteOps.ALOAD_1: - case ByteOps.ALOAD_2: - case ByteOps.ALOAD_3: { - int idx = opcode - ByteOps.ALOAD_0; - visitor.visitLocal(ByteOps.ILOAD, offset, 1, idx, - Type.OBJECT, 0); - return 1; - } - case ByteOps.IALOAD: { - visitor.visitNoArgs(ByteOps.IALOAD, offset, 1, Type.INT); - return 1; - } - case ByteOps.LALOAD: { - visitor.visitNoArgs(ByteOps.IALOAD, offset, 1, Type.LONG); - return 1; - } - case ByteOps.FALOAD: { - visitor.visitNoArgs(ByteOps.IALOAD, offset, 1, - Type.FLOAT); - return 1; - } - case ByteOps.DALOAD: { - visitor.visitNoArgs(ByteOps.IALOAD, offset, 1, - Type.DOUBLE); - return 1; - } - case ByteOps.AALOAD: { - visitor.visitNoArgs(ByteOps.IALOAD, offset, 1, - Type.OBJECT); - return 1; - } - case ByteOps.BALOAD: { - /* - * Note: This is a load from either a byte[] or a - * boolean[]. - */ - visitor.visitNoArgs(ByteOps.IALOAD, offset, 1, Type.BYTE); - return 1; - } - case ByteOps.CALOAD: { - visitor.visitNoArgs(ByteOps.IALOAD, offset, 1, Type.CHAR); - return 1; - } - case ByteOps.SALOAD: { - visitor.visitNoArgs(ByteOps.IALOAD, offset, 1, - Type.SHORT); - return 1; - } - case ByteOps.ISTORE: { - int idx = bytes.getUnsignedByte(offset + 1); - visitor.visitLocal(ByteOps.ISTORE, offset, 2, idx, - Type.INT, 0); - return 2; - } - case ByteOps.LSTORE: { - int idx = bytes.getUnsignedByte(offset + 1); - visitor.visitLocal(ByteOps.ISTORE, offset, 2, idx, - Type.LONG, 0); - return 2; - } - case ByteOps.FSTORE: { - int idx = bytes.getUnsignedByte(offset + 1); - visitor.visitLocal(ByteOps.ISTORE, offset, 2, idx, - Type.FLOAT, 0); - return 2; - } - case ByteOps.DSTORE: { - int idx = bytes.getUnsignedByte(offset + 1); - visitor.visitLocal(ByteOps.ISTORE, offset, 2, idx, - Type.DOUBLE, 0); - return 2; - } - case ByteOps.ASTORE: { - int idx = bytes.getUnsignedByte(offset + 1); - visitor.visitLocal(ByteOps.ISTORE, offset, 2, idx, - Type.OBJECT, 0); - return 2; - } - case ByteOps.ISTORE_0: - case ByteOps.ISTORE_1: - case ByteOps.ISTORE_2: - case ByteOps.ISTORE_3: { - int idx = opcode - ByteOps.ISTORE_0; - visitor.visitLocal(ByteOps.ISTORE, offset, 1, idx, - Type.INT, 0); - return 1; - } - case ByteOps.LSTORE_0: - case ByteOps.LSTORE_1: - case ByteOps.LSTORE_2: - case ByteOps.LSTORE_3: { - int idx = opcode - ByteOps.LSTORE_0; - visitor.visitLocal(ByteOps.ISTORE, offset, 1, idx, - Type.LONG, 0); - return 1; - } - case ByteOps.FSTORE_0: - case ByteOps.FSTORE_1: - case ByteOps.FSTORE_2: - case ByteOps.FSTORE_3: { - int idx = opcode - ByteOps.FSTORE_0; - visitor.visitLocal(ByteOps.ISTORE, offset, 1, idx, - Type.FLOAT, 0); - return 1; - } - case ByteOps.DSTORE_0: - case ByteOps.DSTORE_1: - case ByteOps.DSTORE_2: - case ByteOps.DSTORE_3: { - int idx = opcode - ByteOps.DSTORE_0; - visitor.visitLocal(ByteOps.ISTORE, offset, 1, idx, - Type.DOUBLE, 0); - return 1; - } - case ByteOps.ASTORE_0: - case ByteOps.ASTORE_1: - case ByteOps.ASTORE_2: - case ByteOps.ASTORE_3: { - int idx = opcode - ByteOps.ASTORE_0; - visitor.visitLocal(ByteOps.ISTORE, offset, 1, idx, - Type.OBJECT, 0); - return 1; - } - case ByteOps.IASTORE: { - visitor.visitNoArgs(ByteOps.IASTORE, offset, 1, Type.INT); - return 1; - } - case ByteOps.LASTORE: { - visitor.visitNoArgs(ByteOps.IASTORE, offset, 1, - Type.LONG); - return 1; - } - case ByteOps.FASTORE: { - visitor.visitNoArgs(ByteOps.IASTORE, offset, 1, - Type.FLOAT); - return 1; - } - case ByteOps.DASTORE: { - visitor.visitNoArgs(ByteOps.IASTORE, offset, 1, - Type.DOUBLE); - return 1; - } - case ByteOps.AASTORE: { - visitor.visitNoArgs(ByteOps.IASTORE, offset, 1, - Type.OBJECT); - return 1; - } - case ByteOps.BASTORE: { - /* - * Note: This is a load from either a byte[] or a - * boolean[]. - */ - visitor.visitNoArgs(ByteOps.IASTORE, offset, 1, - Type.BYTE); - return 1; - } - case ByteOps.CASTORE: { - visitor.visitNoArgs(ByteOps.IASTORE, offset, 1, - Type.CHAR); - return 1; - } - case ByteOps.SASTORE: { - visitor.visitNoArgs(ByteOps.IASTORE, offset, 1, - Type.SHORT); - return 1; - } - case ByteOps.POP: - case ByteOps.POP2: - case ByteOps.DUP: - case ByteOps.DUP_X1: - case ByteOps.DUP_X2: - case ByteOps.DUP2: - case ByteOps.DUP2_X1: - case ByteOps.DUP2_X2: - case ByteOps.SWAP: { - visitor.visitNoArgs(opcode, offset, 1, Type.VOID); - return 1; - } - case ByteOps.IADD: - case ByteOps.ISUB: - case ByteOps.IMUL: - case ByteOps.IDIV: - case ByteOps.IREM: - case ByteOps.INEG: - case ByteOps.ISHL: - case ByteOps.ISHR: - case ByteOps.IUSHR: - case ByteOps.IAND: - case ByteOps.IOR: - case ByteOps.IXOR: { - visitor.visitNoArgs(opcode, offset, 1, Type.INT); - return 1; - } - case ByteOps.LADD: - case ByteOps.LSUB: - case ByteOps.LMUL: - case ByteOps.LDIV: - case ByteOps.LREM: - case ByteOps.LNEG: - case ByteOps.LSHL: - case ByteOps.LSHR: - case ByteOps.LUSHR: - case ByteOps.LAND: - case ByteOps.LOR: - case ByteOps.LXOR: { - /* - * It's "opcode - 1" because, conveniently enough, all - * these long ops are one past the int variants. - */ - visitor.visitNoArgs(opcode - 1, offset, 1, Type.LONG); - return 1; - } - case ByteOps.FADD: - case ByteOps.FSUB: - case ByteOps.FMUL: - case ByteOps.FDIV: - case ByteOps.FREM: - case ByteOps.FNEG: { - /* - * It's "opcode - 2" because, conveniently enough, all - * these float ops are two past the int variants. - */ - visitor.visitNoArgs(opcode - 2, offset, 1, Type.FLOAT); - return 1; - } - case ByteOps.DADD: - case ByteOps.DSUB: - case ByteOps.DMUL: - case ByteOps.DDIV: - case ByteOps.DREM: - case ByteOps.DNEG: { - /* - * It's "opcode - 3" because, conveniently enough, all - * these double ops are three past the int variants. - */ - visitor.visitNoArgs(opcode - 3, offset, 1, Type.DOUBLE); - return 1; - } - case ByteOps.IINC: { - int idx = bytes.getUnsignedByte(offset + 1); - int value = bytes.getByte(offset + 2); - visitor.visitLocal(opcode, offset, 3, idx, - Type.INT, value); - return 3; - } - case ByteOps.I2L: - case ByteOps.F2L: - case ByteOps.D2L: { - visitor.visitNoArgs(opcode, offset, 1, Type.LONG); - return 1; - } - case ByteOps.I2F: - case ByteOps.L2F: - case ByteOps.D2F: { - visitor.visitNoArgs(opcode, offset, 1, Type.FLOAT); - return 1; - } - case ByteOps.I2D: - case ByteOps.L2D: - case ByteOps.F2D: { - visitor.visitNoArgs(opcode, offset, 1, Type.DOUBLE); - return 1; - } - case ByteOps.L2I: - case ByteOps.F2I: - case ByteOps.D2I: - case ByteOps.I2B: - case ByteOps.I2C: - case ByteOps.I2S: - case ByteOps.LCMP: - case ByteOps.FCMPL: - case ByteOps.FCMPG: - case ByteOps.DCMPL: - case ByteOps.DCMPG: - case ByteOps.ARRAYLENGTH: { - visitor.visitNoArgs(opcode, offset, 1, Type.INT); - return 1; - } - case ByteOps.IFEQ: - case ByteOps.IFNE: - case ByteOps.IFLT: - case ByteOps.IFGE: - case ByteOps.IFGT: - case ByteOps.IFLE: - case ByteOps.IF_ICMPEQ: - case ByteOps.IF_ICMPNE: - case ByteOps.IF_ICMPLT: - case ByteOps.IF_ICMPGE: - case ByteOps.IF_ICMPGT: - case ByteOps.IF_ICMPLE: - case ByteOps.IF_ACMPEQ: - case ByteOps.IF_ACMPNE: - case ByteOps.GOTO: - case ByteOps.JSR: - case ByteOps.IFNULL: - case ByteOps.IFNONNULL: { - int target = offset + bytes.getShort(offset + 1); - visitor.visitBranch(opcode, offset, 3, target); - return 3; - } - case ByteOps.RET: { - int idx = bytes.getUnsignedByte(offset + 1); - visitor.visitLocal(opcode, offset, 2, idx, - Type.RETURN_ADDRESS, 0); - return 2; - } - case ByteOps.TABLESWITCH: { - return parseTableswitch(offset, visitor); - } - case ByteOps.LOOKUPSWITCH: { - return parseLookupswitch(offset, visitor); - } - case ByteOps.IRETURN: { - visitor.visitNoArgs(ByteOps.IRETURN, offset, 1, Type.INT); - return 1; - } - case ByteOps.LRETURN: { - visitor.visitNoArgs(ByteOps.IRETURN, offset, 1, - Type.LONG); - return 1; - } - case ByteOps.FRETURN: { - visitor.visitNoArgs(ByteOps.IRETURN, offset, 1, - Type.FLOAT); - return 1; - } - case ByteOps.DRETURN: { - visitor.visitNoArgs(ByteOps.IRETURN, offset, 1, - Type.DOUBLE); - return 1; - } - case ByteOps.ARETURN: { - visitor.visitNoArgs(ByteOps.IRETURN, offset, 1, - Type.OBJECT); - return 1; - } - case ByteOps.RETURN: - case ByteOps.ATHROW: - case ByteOps.MONITORENTER: - case ByteOps.MONITOREXIT: { - visitor.visitNoArgs(opcode, offset, 1, Type.VOID); - return 1; - } - case ByteOps.GETSTATIC: - case ByteOps.PUTSTATIC: - case ByteOps.GETFIELD: - case ByteOps.PUTFIELD: - case ByteOps.INVOKEVIRTUAL: - case ByteOps.INVOKESPECIAL: - case ByteOps.INVOKESTATIC: - case ByteOps.NEW: - case ByteOps.ANEWARRAY: - case ByteOps.CHECKCAST: - case ByteOps.INSTANCEOF: { - int idx = bytes.getUnsignedShort(offset + 1); - Constant cst = pool.get(idx); - visitor.visitConstant(opcode, offset, 3, cst, 0); - return 3; - } - case ByteOps.INVOKEINTERFACE: { - int idx = bytes.getUnsignedShort(offset + 1); - int count = bytes.getUnsignedByte(offset + 3); - int expectZero = bytes.getUnsignedByte(offset + 4); - Constant cst = pool.get(idx); - visitor.visitConstant(opcode, offset, 5, cst, - count | (expectZero << 8)); - return 5; - } - case ByteOps.INVOKEDYNAMIC: { - throw new ParseException("invokedynamic not supported"); - } - case ByteOps.NEWARRAY: { - return parseNewarray(offset, visitor); - } - case ByteOps.WIDE: { - return parseWide(offset, visitor); - } - case ByteOps.MULTIANEWARRAY: { - int idx = bytes.getUnsignedShort(offset + 1); - int dimensions = bytes.getUnsignedByte(offset + 3); - Constant cst = pool.get(idx); - visitor.visitConstant(opcode, offset, 4, cst, dimensions); - return 4; - } - case ByteOps.GOTO_W: - case ByteOps.JSR_W: { - int target = offset + bytes.getInt(offset + 1); - int newop = - (opcode == ByteOps.GOTO_W) ? ByteOps.GOTO : - ByteOps.JSR; - visitor.visitBranch(newop, offset, 5, target); - return 5; - } - default: { - visitor.visitInvalid(opcode, offset, 1); - return 1; - } - } - } catch (SimException ex) { - ex.addContext("...at bytecode offset " + Hex.u4(offset)); - throw ex; - } catch (RuntimeException ex) { - SimException se = new SimException(ex); - se.addContext("...at bytecode offset " + Hex.u4(offset)); - throw se; - } - } - - /** - * Helper to deal with {@code tableswitch}. - * - * @param offset the offset to the {@code tableswitch} opcode itself - * @param visitor {@code non-null;} visitor to use - * @return instruction length, in bytes - */ - private int parseTableswitch(int offset, Visitor visitor) { - int at = (offset + 4) & ~3; // "at" skips the padding. - - // Collect the padding. - int padding = 0; - for (int i = offset + 1; i < at; i++) { - padding = (padding << 8) | bytes.getUnsignedByte(i); - } - - int defaultTarget = offset + bytes.getInt(at); - int low = bytes.getInt(at + 4); - int high = bytes.getInt(at + 8); - int count = high - low + 1; - at += 12; - - if (low > high) { - throw new SimException("low / high inversion"); - } - - SwitchList cases = new SwitchList(count); - for (int i = 0; i < count; i++) { - int target = offset + bytes.getInt(at); - at += 4; - cases.add(low + i, target); - } - cases.setDefaultTarget(defaultTarget); - cases.removeSuperfluousDefaults(); - cases.setImmutable(); - - int length = at - offset; - visitor.visitSwitch(ByteOps.LOOKUPSWITCH, offset, length, cases, - padding); - - return length; - } - - /** - * Helper to deal with {@code lookupswitch}. - * - * @param offset the offset to the {@code lookupswitch} opcode itself - * @param visitor {@code non-null;} visitor to use - * @return instruction length, in bytes - */ - private int parseLookupswitch(int offset, Visitor visitor) { - int at = (offset + 4) & ~3; // "at" skips the padding. - - // Collect the padding. - int padding = 0; - for (int i = offset + 1; i < at; i++) { - padding = (padding << 8) | bytes.getUnsignedByte(i); - } - - int defaultTarget = offset + bytes.getInt(at); - int npairs = bytes.getInt(at + 4); - at += 8; - - SwitchList cases = new SwitchList(npairs); - for (int i = 0; i < npairs; i++) { - int match = bytes.getInt(at); - int target = offset + bytes.getInt(at + 4); - at += 8; - cases.add(match, target); - } - cases.setDefaultTarget(defaultTarget); - cases.removeSuperfluousDefaults(); - cases.setImmutable(); - - int length = at - offset; - visitor.visitSwitch(ByteOps.LOOKUPSWITCH, offset, length, cases, - padding); - - return length; - } - - /** - * Helper to deal with {@code newarray}. - * - * @param offset the offset to the {@code newarray} opcode itself - * @param visitor {@code non-null;} visitor to use - * @return instruction length, in bytes - */ - private int parseNewarray(int offset, Visitor visitor) { - int value = bytes.getUnsignedByte(offset + 1); - CstType type; - switch (value) { - case ByteOps.NEWARRAY_BOOLEAN: { - type = CstType.BOOLEAN_ARRAY; - break; - } - case ByteOps.NEWARRAY_CHAR: { - type = CstType.CHAR_ARRAY; - break; - } - case ByteOps.NEWARRAY_DOUBLE: { - type = CstType.DOUBLE_ARRAY; - break; - } - case ByteOps.NEWARRAY_FLOAT: { - type = CstType.FLOAT_ARRAY; - break; - } - case ByteOps.NEWARRAY_BYTE: { - type = CstType.BYTE_ARRAY; - break; - } - case ByteOps.NEWARRAY_SHORT: { - type = CstType.SHORT_ARRAY; - break; - } - case ByteOps.NEWARRAY_INT: { - type = CstType.INT_ARRAY; - break; - } - case ByteOps.NEWARRAY_LONG: { - type = CstType.LONG_ARRAY; - break; - } - default: { - throw new SimException("bad newarray code " + - Hex.u1(value)); - } - } - - // Revisit the previous bytecode to find out the length of the array - int previousOffset = visitor.getPreviousOffset(); - ConstantParserVisitor constantVisitor = new ConstantParserVisitor(); - int arrayLength = 0; - - /* - * For visitors that don't record the previous offset, -1 will be - * seen here - */ - if (previousOffset >= 0) { - parseInstruction(previousOffset, constantVisitor); - if (constantVisitor.cst instanceof CstInteger && - constantVisitor.length + previousOffset == offset) { - arrayLength = constantVisitor.value; - - } - } - - /* - * Try to match the array initialization idiom. For example, if the - * subsequent code is initializing an int array, we are expecting the - * following pattern repeatedly: - * dup - * push index - * push value - * *astore - * - * where the index value will be incrimented sequentially from 0 up. - */ - int nInit = 0; - int curOffset = offset+2; - int lastOffset = curOffset; - ArrayList initVals = new ArrayList(); - - if (arrayLength != 0) { - while (true) { - boolean punt = false; - - // First, check if the next bytecode is dup. - int nextByte = bytes.getUnsignedByte(curOffset++); - if (nextByte != ByteOps.DUP) - break; - - /* - * Next, check if the expected array index is pushed to - * the stack. - */ - parseInstruction(curOffset, constantVisitor); - if (constantVisitor.length == 0 || - !(constantVisitor.cst instanceof CstInteger) || - constantVisitor.value != nInit) - break; - - // Next, fetch the init value and record it. - curOffset += constantVisitor.length; - - /* - * Next, find out what kind of constant is pushed onto - * the stack. - */ - parseInstruction(curOffset, constantVisitor); - if (constantVisitor.length == 0 || - !(constantVisitor.cst instanceof CstLiteralBits)) - break; - - curOffset += constantVisitor.length; - initVals.add(constantVisitor.cst); - - nextByte = bytes.getUnsignedByte(curOffset++); - // Now, check if the value is stored to the array properly. - switch (value) { - case ByteOps.NEWARRAY_BYTE: - case ByteOps.NEWARRAY_BOOLEAN: { - if (nextByte != ByteOps.BASTORE) { - punt = true; - } - break; - } - case ByteOps.NEWARRAY_CHAR: { - if (nextByte != ByteOps.CASTORE) { - punt = true; - } - break; - } - case ByteOps.NEWARRAY_DOUBLE: { - if (nextByte != ByteOps.DASTORE) { - punt = true; - } - break; - } - case ByteOps.NEWARRAY_FLOAT: { - if (nextByte != ByteOps.FASTORE) { - punt = true; - } - break; - } - case ByteOps.NEWARRAY_SHORT: { - if (nextByte != ByteOps.SASTORE) { - punt = true; - } - break; - } - case ByteOps.NEWARRAY_INT: { - if (nextByte != ByteOps.IASTORE) { - punt = true; - } - break; - } - case ByteOps.NEWARRAY_LONG: { - if (nextByte != ByteOps.LASTORE) { - punt = true; - } - break; - } - default: - punt = true; - break; - } - if (punt) { - break; - } - lastOffset = curOffset; - nInit++; - } - } - - /* - * For singleton arrays it is still more economical to - * generate the aput. - */ - if (nInit < 2 || nInit != arrayLength) { - visitor.visitNewarray(offset, 2, type, null); - return 2; - } else { - visitor.visitNewarray(offset, lastOffset - offset, type, initVals); - return lastOffset - offset; - } - } - - - /** - * Helper to deal with {@code wide}. - * - * @param offset the offset to the {@code wide} opcode itself - * @param visitor {@code non-null;} visitor to use - * @return instruction length, in bytes - */ - private int parseWide(int offset, Visitor visitor) { - int opcode = bytes.getUnsignedByte(offset + 1); - int idx = bytes.getUnsignedShort(offset + 2); - switch (opcode) { - case ByteOps.ILOAD: { - visitor.visitLocal(ByteOps.ILOAD, offset, 4, idx, - Type.INT, 0); - return 4; - } - case ByteOps.LLOAD: { - visitor.visitLocal(ByteOps.ILOAD, offset, 4, idx, - Type.LONG, 0); - return 4; - } - case ByteOps.FLOAD: { - visitor.visitLocal(ByteOps.ILOAD, offset, 4, idx, - Type.FLOAT, 0); - return 4; - } - case ByteOps.DLOAD: { - visitor.visitLocal(ByteOps.ILOAD, offset, 4, idx, - Type.DOUBLE, 0); - return 4; - } - case ByteOps.ALOAD: { - visitor.visitLocal(ByteOps.ILOAD, offset, 4, idx, - Type.OBJECT, 0); - return 4; - } - case ByteOps.ISTORE: { - visitor.visitLocal(ByteOps.ISTORE, offset, 4, idx, - Type.INT, 0); - return 4; - } - case ByteOps.LSTORE: { - visitor.visitLocal(ByteOps.ISTORE, offset, 4, idx, - Type.LONG, 0); - return 4; - } - case ByteOps.FSTORE: { - visitor.visitLocal(ByteOps.ISTORE, offset, 4, idx, - Type.FLOAT, 0); - return 4; - } - case ByteOps.DSTORE: { - visitor.visitLocal(ByteOps.ISTORE, offset, 4, idx, - Type.DOUBLE, 0); - return 4; - } - case ByteOps.ASTORE: { - visitor.visitLocal(ByteOps.ISTORE, offset, 4, idx, - Type.OBJECT, 0); - return 4; - } - case ByteOps.RET: { - visitor.visitLocal(opcode, offset, 4, idx, - Type.RETURN_ADDRESS, 0); - return 4; - } - case ByteOps.IINC: { - int value = bytes.getShort(offset + 4); - visitor.visitLocal(opcode, offset, 6, idx, - Type.INT, value); - return 6; - } - default: { - visitor.visitInvalid(ByteOps.WIDE, offset, 1); - return 1; - } - } - } - - /** - * Instruction visitor interface. - */ - public interface Visitor { - /** - * Visits an invalid instruction. - * - * @param opcode the opcode - * @param offset offset to the instruction - * @param length length of the instruction, in bytes - */ - public void visitInvalid(int opcode, int offset, int length); - - /** - * Visits an instruction which has no inline arguments - * (implicit or explicit). - * - * @param opcode the opcode - * @param offset offset to the instruction - * @param length length of the instruction, in bytes - * @param type {@code non-null;} type the instruction operates on - */ - public void visitNoArgs(int opcode, int offset, int length, - Type type); - - /** - * Visits an instruction which has a local variable index argument. - * - * @param opcode the opcode - * @param offset offset to the instruction - * @param length length of the instruction, in bytes - * @param idx the local variable index - * @param type {@code non-null;} the type of the accessed value - * @param value additional literal integer argument, if salient (i.e., - * for {@code iinc}) - */ - public void visitLocal(int opcode, int offset, int length, - int idx, Type type, int value); - - /** - * Visits an instruction which has a (possibly synthetic) - * constant argument, and possibly also an - * additional literal integer argument. In the case of - * {@code multianewarray}, the argument is the count of - * dimensions. In the case of {@code invokeinterface}, - * the argument is the parameter count or'ed with the - * should-be-zero value left-shifted by 8. In the case of entries - * of type {@code int}, the {@code value} field always - * holds the raw value (for convenience of clients). - * - *

Note: In order to avoid giving it a barely-useful - * visitor all its own, {@code newarray} also uses this - * form, passing {@code value} as the array type code and - * {@code cst} as a {@link CstType} instance - * corresponding to the array type.

- * - * @param opcode the opcode - * @param offset offset to the instruction - * @param length length of the instruction, in bytes - * @param cst {@code non-null;} the constant - * @param value additional literal integer argument, if salient - * (ignore if not) - */ - public void visitConstant(int opcode, int offset, int length, - Constant cst, int value); - - /** - * Visits an instruction which has a branch target argument. - * - * @param opcode the opcode - * @param offset offset to the instruction - * @param length length of the instruction, in bytes - * @param target the absolute (not relative) branch target - */ - public void visitBranch(int opcode, int offset, int length, - int target); - - /** - * Visits a switch instruction. - * - * @param opcode the opcode - * @param offset offset to the instruction - * @param length length of the instruction, in bytes - * @param cases {@code non-null;} list of (value, target) - * pairs, plus the default target - * @param padding the bytes found in the padding area (if any), - * packed - */ - public void visitSwitch(int opcode, int offset, int length, - SwitchList cases, int padding); - - /** - * Visits a newarray instruction. - * - * @param offset offset to the instruction - * @param length length of the instruction, in bytes - * @param type {@code non-null;} the type of the array - * @param initVals {@code non-null;} list of bytecode offsets - * for init values - */ - public void visitNewarray(int offset, int length, CstType type, - ArrayList initVals); - - /** - * Set previous bytecode offset - * @param offset offset of the previous fully parsed bytecode - */ - public void setPreviousOffset(int offset); - - /** - * Get previous bytecode offset - * @return return the recored offset of the previous bytecode - */ - public int getPreviousOffset(); - } - - /** - * Base implementation of {@link Visitor}, which has empty method - * bodies for all methods. - */ - public static class BaseVisitor implements Visitor { - - /** offset of the previously parsed bytecode */ - private int previousOffset; - - BaseVisitor() { - previousOffset = -1; - } - - /** {@inheritDoc} */ - public void visitInvalid(int opcode, int offset, int length) { - // This space intentionally left blank. - } - - /** {@inheritDoc} */ - public void visitNoArgs(int opcode, int offset, int length, - Type type) { - // This space intentionally left blank. - } - - /** {@inheritDoc} */ - public void visitLocal(int opcode, int offset, int length, - int idx, Type type, int value) { - // This space intentionally left blank. - } - - /** {@inheritDoc} */ - public void visitConstant(int opcode, int offset, int length, - Constant cst, int value) { - // This space intentionally left blank. - } - - /** {@inheritDoc} */ - public void visitBranch(int opcode, int offset, int length, - int target) { - // This space intentionally left blank. - } - - /** {@inheritDoc} */ - public void visitSwitch(int opcode, int offset, int length, - SwitchList cases, int padding) { - // This space intentionally left blank. - } - - /** {@inheritDoc} */ - public void visitNewarray(int offset, int length, CstType type, - ArrayList initValues) { - // This space intentionally left blank. - } - - /** {@inheritDoc} */ - public void setPreviousOffset(int offset) { - previousOffset = offset; - } - - /** {@inheritDoc} */ - public int getPreviousOffset() { - return previousOffset; - } - } - - /** - * Implementation of {@link Visitor}, which just pays attention - * to constant values. - */ - class ConstantParserVisitor extends BaseVisitor { - Constant cst; - int length; - int value; - - /** Empty constructor */ - ConstantParserVisitor() { - } - - private void clear() { - length = 0; - } - - /** {@inheritDoc} */ - @Override - public void visitInvalid(int opcode, int offset, int length) { - clear(); - } - - /** {@inheritDoc} */ - @Override - public void visitNoArgs(int opcode, int offset, int length, - Type type) { - clear(); - } - - /** {@inheritDoc} */ - @Override - public void visitLocal(int opcode, int offset, int length, - int idx, Type type, int value) { - clear(); - } - - /** {@inheritDoc} */ - @Override - public void visitConstant(int opcode, int offset, int length, - Constant cst, int value) { - this.cst = cst; - this.length = length; - this.value = value; - } - - /** {@inheritDoc} */ - @Override - public void visitBranch(int opcode, int offset, int length, - int target) { - clear(); - } - - /** {@inheritDoc} */ - @Override - public void visitSwitch(int opcode, int offset, int length, - SwitchList cases, int padding) { - clear(); - } - - /** {@inheritDoc} */ - @Override - public void visitNewarray(int offset, int length, CstType type, - ArrayList initVals) { - clear(); - } - - /** {@inheritDoc} */ - @Override - public void setPreviousOffset(int offset) { - // Intentionally left empty - } - - /** {@inheritDoc} */ - @Override - public int getPreviousOffset() { - // Intentionally left empty - return -1; - } - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/ConcreteMethod.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/ConcreteMethod.java deleted file mode 100644 index 39c23995edb..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/ConcreteMethod.java +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.code; - -import com.android.dx.cf.attrib.AttCode; -import com.android.dx.cf.attrib.AttLineNumberTable; -import com.android.dx.cf.attrib.AttLocalVariableTable; -import com.android.dx.cf.attrib.AttLocalVariableTypeTable; -import com.android.dx.cf.iface.AttributeList; -import com.android.dx.cf.iface.ClassFile; -import com.android.dx.cf.iface.Method; -import com.android.dx.rop.code.AccessFlags; -import com.android.dx.rop.code.SourcePosition; -import com.android.dx.rop.cst.CstNat; -import com.android.dx.rop.cst.CstString; -import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.type.Prototype; - -/** - * Container for all the giblets that make up a concrete Java bytecode method. - * It implements {@link Method}, so it provides all the original access - * (by delegation), but it also constructs and keeps useful versions of - * stuff extracted from the method's {@code Code} attribute. - */ -public final class ConcreteMethod implements Method { - /** {@code non-null;} method being wrapped */ - private final Method method; - - /** - * {@code null-ok;} the class's {@code SourceFile} attribute value, - * if any - */ - private final CstString sourceFile; - - /** - * whether the class that this method is part of is defined with - * {@code ACC_SUPER} - */ - private final boolean accSuper; - - /** {@code non-null;} the code attribute */ - private final AttCode attCode; - - /** {@code non-null;} line number list */ - private final LineNumberList lineNumbers; - - /** {@code non-null;} local variable list */ - private final LocalVariableList localVariables; - - /** - * Constructs an instance. - * - * @param method {@code non-null;} the method to be based on - * @param cf {@code non-null;} the class file that contains this method - * @param keepLines whether to keep the line number information - * (if any) - * @param keepLocals whether to keep the local variable - * information (if any) - */ - public ConcreteMethod(Method method, ClassFile cf, boolean keepLines, boolean keepLocals) { - this(method, cf.getAccessFlags(), cf.getSourceFile(), keepLines, keepLocals); - } - - public ConcreteMethod(Method method, int accessFlags, CstString sourceFile, - boolean keepLines, boolean keepLocals) { - this.method = method; - this.accSuper = (accessFlags & AccessFlags.ACC_SUPER) != 0; - this.sourceFile = sourceFile; - - AttributeList attribs = method.getAttributes(); - this.attCode = (AttCode) attribs.findFirst(AttCode.ATTRIBUTE_NAME); - - AttributeList codeAttribs = attCode.getAttributes(); - - /* - * Combine all LineNumberTable attributes into one, with the - * combined result saved into the instance. The following code - * isn't particularly efficient for doing merges, but as far - * as I know, this situation rarely occurs "in the - * wild," so there's not much point in optimizing for it. - */ - LineNumberList lineNumbers = LineNumberList.EMPTY; - if (keepLines) { - for (AttLineNumberTable lnt = (AttLineNumberTable) - codeAttribs.findFirst(AttLineNumberTable.ATTRIBUTE_NAME); - lnt != null; - lnt = (AttLineNumberTable) codeAttribs.findNext(lnt)) { - lineNumbers = LineNumberList.concat(lineNumbers, - lnt.getLineNumbers()); - } - } - this.lineNumbers = lineNumbers; - - LocalVariableList localVariables = LocalVariableList.EMPTY; - if (keepLocals) { - /* - * Do likewise (and with the same caveat) for - * LocalVariableTable and LocalVariableTypeTable attributes. - * This combines both of these kinds of attribute into a - * single LocalVariableList. - */ - for (AttLocalVariableTable lvt = (AttLocalVariableTable) - codeAttribs.findFirst( - AttLocalVariableTable.ATTRIBUTE_NAME); - lvt != null; - lvt = (AttLocalVariableTable) codeAttribs.findNext(lvt)) { - localVariables = - LocalVariableList.concat(localVariables, - lvt.getLocalVariables()); - } - - LocalVariableList typeList = LocalVariableList.EMPTY; - for (AttLocalVariableTypeTable lvtt = (AttLocalVariableTypeTable) - codeAttribs.findFirst( - AttLocalVariableTypeTable.ATTRIBUTE_NAME); - lvtt != null; - lvtt = - (AttLocalVariableTypeTable) codeAttribs.findNext(lvtt)) { - typeList = - LocalVariableList.concat(typeList, - lvtt.getLocalVariables()); - } - - if (typeList.size() != 0) { - localVariables = - LocalVariableList.mergeDescriptorsAndSignatures( - localVariables, typeList); - } - } - this.localVariables = localVariables; - } - - /** {@inheritDoc} */ - public CstNat getNat() { - return method.getNat(); - } - - /** {@inheritDoc} */ - public CstString getName() { - return method.getName(); - } - - /** {@inheritDoc} */ - public CstString getDescriptor() { - return method.getDescriptor(); - } - - /** {@inheritDoc} */ - public int getAccessFlags() { - return method.getAccessFlags(); - } - - /** {@inheritDoc} */ - public AttributeList getAttributes() { - return method.getAttributes(); - } - - /** {@inheritDoc} */ - public CstType getDefiningClass() { - return method.getDefiningClass(); - } - - /** {@inheritDoc} */ - public Prototype getEffectiveDescriptor() { - return method.getEffectiveDescriptor(); - } - - /** - * Gets whether the class that this method is part of is defined with - * {@code ACC_SUPER}. - * - * @return the {@code ACC_SUPER} value - */ - public boolean getAccSuper() { - return accSuper; - } - - /** - * Gets the maximum stack size. - * - * @return {@code >= 0;} the maximum stack size - */ - public int getMaxStack() { - return attCode.getMaxStack(); - } - - /** - * Gets the number of locals. - * - * @return {@code >= 0;} the number of locals - */ - public int getMaxLocals() { - return attCode.getMaxLocals(); - } - - /** - * Gets the bytecode array. - * - * @return {@code non-null;} the bytecode array - */ - public BytecodeArray getCode() { - return attCode.getCode(); - } - - /** - * Gets the exception table. - * - * @return {@code non-null;} the exception table - */ - public ByteCatchList getCatches() { - return attCode.getCatches(); - } - - /** - * Gets the line number list. - * - * @return {@code non-null;} the line number list - */ - public LineNumberList getLineNumbers() { - return lineNumbers; - } - - /** - * Gets the local variable list. - * - * @return {@code non-null;} the local variable list - */ - public LocalVariableList getLocalVariables() { - return localVariables; - } - - /** - * Returns a {@link SourcePosition} instance corresponding to the - * given bytecode offset. - * - * @param offset {@code >= 0;} the bytecode offset - * @return {@code non-null;} an appropriate instance - */ - public SourcePosition makeSourcePosistion(int offset) { - return new SourcePosition(sourceFile, offset, - lineNumbers.pcToLine(offset)); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/ExecutionStack.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/ExecutionStack.java deleted file mode 100644 index 696abc80a30..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/ExecutionStack.java +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.code; - -import com.android.dex.util.ExceptionWithContext; -import com.android.dx.rop.type.Type; -import com.android.dx.rop.type.TypeBearer; -import com.android.dx.util.Hex; -import com.android.dx.util.MutabilityControl; - -/** - * Representation of a Java method execution stack. - * - *

Note: For the most part, the documentation for this class - * ignores the distinction between {@link Type} and {@link - * TypeBearer}.

- */ -public final class ExecutionStack extends MutabilityControl { - /** {@code non-null;} array of stack contents */ - private final TypeBearer[] stack; - - /** - * {@code non-null;} array specifying whether stack contents have entries - * in the local variable table - */ - private final boolean[] local; - /** - * {@code >= 0;} stack pointer (points one past the end) / current stack - * size - */ - private int stackPtr; - - /** - * Constructs an instance. - * - * @param maxStack {@code >= 0;} the maximum size of the stack for this - * instance - */ - public ExecutionStack(int maxStack) { - super(maxStack != 0); - stack = new TypeBearer[maxStack]; - local = new boolean[maxStack]; - stackPtr = 0; - } - - /** - * Makes and returns a mutable copy of this instance. - * - * @return {@code non-null;} the copy - */ - public ExecutionStack copy() { - ExecutionStack result = new ExecutionStack(stack.length); - - System.arraycopy(stack, 0, result.stack, 0, stack.length); - System.arraycopy(local, 0, result.local, 0, local.length); - result.stackPtr = stackPtr; - - return result; - } - - /** - * Annotates (adds context to) the given exception with information - * about this instance. - * - * @param ex {@code non-null;} the exception to annotate - */ - public void annotate(ExceptionWithContext ex) { - int limit = stackPtr - 1; - - for (int i = 0; i <= limit; i++) { - String idx = (i == limit) ? "top0" : Hex.u2(limit - i); - - ex.addContext("stack[" + idx + "]: " + - stackElementString(stack[i])); - } - } - - /** - * Replaces all the occurrences of the given uninitialized type in - * this stack with its initialized equivalent. - * - * @param type {@code non-null;} type to replace - */ - public void makeInitialized(Type type) { - if (stackPtr == 0) { - // We have to check for this before checking for immutability. - return; - } - - throwIfImmutable(); - - Type initializedType = type.getInitializedType(); - - for (int i = 0; i < stackPtr; i++) { - if (stack[i] == type) { - stack[i] = initializedType; - } - } - } - - /** - * Gets the maximum stack size for this instance. - * - * @return {@code >= 0;} the max stack size - */ - public int getMaxStack() { - return stack.length; - } - - /** - * Gets the current stack size. - * - * @return {@code >= 0, < getMaxStack();} the current stack size - */ - public int size() { - return stackPtr; - } - - /** - * Clears the stack. (That is, this method pops everything off.) - */ - public void clear() { - throwIfImmutable(); - - for (int i = 0; i < stackPtr; i++) { - stack[i] = null; - local[i] = false; - } - - stackPtr = 0; - } - - /** - * Pushes a value of the given type onto the stack. - * - * @param type {@code non-null;} type of the value - * @throws SimException thrown if there is insufficient room on the - * stack for the value - */ - public void push(TypeBearer type) { - throwIfImmutable(); - - int category; - - try { - type = type.getFrameType(); - category = type.getType().getCategory(); - } catch (NullPointerException ex) { - // Elucidate the exception. - throw new NullPointerException("type == null"); - } - - if ((stackPtr + category) > stack.length) { - throwSimException("overflow"); - return; - } - - if (category == 2) { - stack[stackPtr] = null; - stackPtr++; - } - - stack[stackPtr] = type; - stackPtr++; - } - - /** - * Flags the next value pushed onto the stack as having local info. - */ - public void setLocal() { - throwIfImmutable(); - - local[stackPtr] = true; - } - - /** - * Peeks at the {@code n}th element down from the top of the stack. - * {@code n == 0} means to peek at the top of the stack. Note that - * this will return {@code null} if the indicated element is the - * deeper half of a category-2 value. - * - * @param n {@code >= 0;} which element to peek at - * @return {@code null-ok;} the type of value stored at that element - * @throws SimException thrown if {@code n >= size()} - */ - public TypeBearer peek(int n) { - if (n < 0) { - throw new IllegalArgumentException("n < 0"); - } - - if (n >= stackPtr) { - return throwSimException("underflow"); - } - - return stack[stackPtr - n - 1]; - } - - /** - * Peeks at the {@code n}th element down from the top of the - * stack, returning whether or not it has local info. - * - * @param n {@code >= 0;} which element to peek at - * @return {@code true} if the value has local info, {@code false} otherwise - * @throws SimException thrown if {@code n >= size()} - */ - public boolean peekLocal(int n) { - if (n < 0) { - throw new IllegalArgumentException("n < 0"); - } - - if (n >= stackPtr) { - throw new SimException("stack: underflow"); - } - - return local[stackPtr - n - 1]; - } - - /** - * Peeks at the {@code n}th element down from the top of the - * stack, returning the type per se, as opposed to the - * type-bearer. This method is just a convenient shorthand - * for {@code peek(n).getType()}. - * - * @see #peek - */ - public Type peekType(int n) { - return peek(n).getType(); - } - - /** - * Pops the top element off of the stack. - * - * @return {@code non-null;} the type formerly on the top of the stack - * @throws SimException thrown if the stack is empty - */ - public TypeBearer pop() { - throwIfImmutable(); - - TypeBearer result = peek(0); - - stack[stackPtr - 1] = null; - local[stackPtr - 1] = false; - stackPtr -= result.getType().getCategory(); - - return result; - } - - /** - * Changes an element already on a stack. This method is useful in limited - * contexts, particularly when merging two instances. As such, it places - * the following restriction on its behavior: You may only replace - * values with other values of the same category. - * - * @param n {@code >= 0;} which element to change, where {@code 0} is - * the top element of the stack - * @param type {@code non-null;} type of the new value - * @throws SimException thrown if {@code n >= size()} or - * the action is otherwise prohibited - */ - public void change(int n, TypeBearer type) { - throwIfImmutable(); - - try { - type = type.getFrameType(); - } catch (NullPointerException ex) { - // Elucidate the exception. - throw new NullPointerException("type == null"); - } - - int idx = stackPtr - n - 1; - TypeBearer orig = stack[idx]; - - if ((orig == null) || - (orig.getType().getCategory() != type.getType().getCategory())) { - throwSimException("incompatible substitution: " + - stackElementString(orig) + " -> " + - stackElementString(type)); - } - - stack[idx] = type; - } - - /** - * Merges this stack with another stack. A new instance is returned if - * this merge results in a change. If no change results, this instance is - * returned. See {@link Merger#mergeStack(ExecutionStack,ExecutionStack) - * Merger.mergeStack()} - * - * @param other {@code non-null;} a stack to merge with - * @return {@code non-null;} the result of the merge - */ - public ExecutionStack merge(ExecutionStack other) { - try { - return Merger.mergeStack(this, other); - } catch (SimException ex) { - ex.addContext("underlay stack:"); - this.annotate(ex); - ex.addContext("overlay stack:"); - other.annotate(ex); - throw ex; - } - } - - /** - * Gets the string form for a stack element. This is the same as - * {@code toString()} except that {@code null} is converted - * to {@code ""}. - * - * @param type {@code null-ok;} the stack element - * @return {@code non-null;} the string form - */ - private static String stackElementString(TypeBearer type) { - if (type == null) { - return ""; - } - - return type.toString(); - } - - /** - * Throws a properly-formatted exception. - * - * @param msg {@code non-null;} useful message - * @return never (keeps compiler happy) - */ - private static TypeBearer throwSimException(String msg) { - throw new SimException("stack: " + msg); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/Frame.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/Frame.java deleted file mode 100644 index cb32b92d9f2..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/Frame.java +++ /dev/null @@ -1,415 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.code; - -import com.android.dex.util.ExceptionWithContext; -import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.type.StdTypeList; -import com.android.dx.rop.type.Type; -import com.android.dx.util.IntList; - -/** - * Representation of a Java method execution frame. A frame consists - * of a set of locals and a value stack, and it can be told to act on - * them to load and store values between them and an "arguments / - * results" area. - */ -public final class Frame { - /** {@code non-null;} the locals */ - private final LocalsArray locals; - - /** {@code non-null;} the stack */ - private final ExecutionStack stack; - - /** {@code null-ok;} stack of labels of subroutines that this block is nested in */ - private final IntList subroutines; - - /** - * Constructs an instance. - * - * @param locals {@code non-null;} the locals array to use - * @param stack {@code non-null;} the execution stack to use - */ - private Frame(LocalsArray locals, ExecutionStack stack) { - this(locals, stack, IntList.EMPTY); - } - - /** - * Constructs an instance. - * - * @param locals {@code non-null;} the locals array to use - * @param stack {@code non-null;} the execution stack to use - * @param subroutines {@code non-null;} list of subroutine start labels for - * subroutines this frame is nested in - */ - private Frame(LocalsArray locals, - ExecutionStack stack, IntList subroutines) { - if (locals == null) { - throw new NullPointerException("locals == null"); - } - - if (stack == null) { - throw new NullPointerException("stack == null"); - } - - subroutines.throwIfMutable(); - - this.locals = locals; - this.stack = stack; - this.subroutines = subroutines; - } - - /** - * Constructs an instance. The locals array initially consists of - * all-uninitialized values (represented as {@code null}s) and - * the stack starts out empty. - * - * @param maxLocals {@code >= 0;} the maximum number of locals this instance - * can refer to - * @param maxStack {@code >= 0;} the maximum size of the stack for this - * instance - */ - public Frame(int maxLocals, int maxStack) { - this(new OneLocalsArray(maxLocals), new ExecutionStack(maxStack)); - } - - /** - * Makes and returns a mutable copy of this instance. The copy - * contains copies of the locals and stack (that is, it doesn't - * share them with the original). - * - * @return {@code non-null;} the copy - */ - public Frame copy() { - return new Frame(locals.copy(), stack.copy(), subroutines); - } - - /** - * Makes this instance immutable. - */ - public void setImmutable() { - locals.setImmutable(); - stack.setImmutable(); - // "subroutines" is always immutable - } - - /** - * Replaces all the occurrences of the given uninitialized type in - * this frame with its initialized equivalent. - * - * @param type {@code non-null;} type to replace - */ - public void makeInitialized(Type type) { - locals.makeInitialized(type); - stack.makeInitialized(type); - } - - /** - * Gets the locals array for this instance. - * - * @return {@code non-null;} the locals array - */ - public LocalsArray getLocals() { - return locals; - } - - /** - * Gets the execution stack for this instance. - * - * @return {@code non-null;} the execution stack - */ - public ExecutionStack getStack() { - return stack; - } - - /** - * Returns the largest subroutine nesting this block may be in. An - * empty list is returned if this block is not in any subroutine. - * Subroutines are identified by the label of their start block. The - * list is ordered such that the deepest nesting (the actual subroutine - * this block is in) is the last label in the list. - * - * @return {@code non-null;} list as noted above - */ - public IntList getSubroutines() { - return subroutines; - } - - /** - * Initialize this frame with the method's parameters. Used for the first - * frame. - * - * @param params Type list of method parameters. - */ - public void initializeWithParameters(StdTypeList params) { - int at = 0; - int sz = params.size(); - - for (int i = 0; i < sz; i++) { - Type one = params.get(i); - locals.set(at, one); - at += one.getCategory(); - } - } - - /** - * Returns a Frame instance representing the frame state that should - * be used when returning from a subroutine. The stack state of all - * subroutine invocations is identical, but the locals state may differ. - * - * @param startLabel {@code >=0;} The label of the returning subroutine's - * start block - * @param subLabel {@code >=0;} A calling label of a subroutine - * @return {@code null-ok;} an appropriatly-constructed instance, or null - * if label is not in the set - */ - public Frame subFrameForLabel(int startLabel, int subLabel) { - LocalsArray subLocals = null; - - if (locals instanceof LocalsArraySet) { - subLocals = ((LocalsArraySet)locals).subArrayForLabel(subLabel); - } - - IntList newSubroutines; - try { - newSubroutines = subroutines.mutableCopy(); - - if (newSubroutines.pop() != startLabel) { - throw new RuntimeException("returning from invalid subroutine"); - } - newSubroutines.setImmutable(); - } catch (IndexOutOfBoundsException ex) { - throw new RuntimeException("returning from invalid subroutine"); - } catch (NullPointerException ex) { - throw new NullPointerException("can't return from non-subroutine"); - } - - return (subLocals == null) ? null - : new Frame(subLocals, stack, newSubroutines); - } - - /** - * Merges two frames. If the merged result is the same as this frame, - * then this instance is returned. - * - * @param other {@code non-null;} another frame - * @return {@code non-null;} the result of merging the two frames - */ - public Frame mergeWith(Frame other) { - LocalsArray resultLocals; - ExecutionStack resultStack; - IntList resultSubroutines; - - resultLocals = getLocals().merge(other.getLocals()); - resultStack = getStack().merge(other.getStack()); - resultSubroutines = mergeSubroutineLists(other.subroutines); - - resultLocals = adjustLocalsForSubroutines( - resultLocals, resultSubroutines); - - if ((resultLocals == getLocals()) - && (resultStack == getStack()) - && subroutines == resultSubroutines) { - return this; - } - - return new Frame(resultLocals, resultStack, resultSubroutines); - } - - /** - * Merges this frame's subroutine lists with another. The result - * is the deepest common nesting (effectively, the common prefix of the - * two lists). - * - * @param otherSubroutines label list of subroutine start blocks, from - * least-nested to most-nested. - * @return {@code non-null;} merged subroutine nest list as described above - */ - private IntList mergeSubroutineLists(IntList otherSubroutines) { - if (subroutines.equals(otherSubroutines)) { - return subroutines; - } - - IntList resultSubroutines = new IntList(); - - int szSubroutines = subroutines.size(); - int szOthers = otherSubroutines.size(); - for (int i = 0; i < szSubroutines && i < szOthers - && (subroutines.get(i) == otherSubroutines.get(i)); i++) { - resultSubroutines.add(i); - } - - resultSubroutines.setImmutable(); - - return resultSubroutines; - } - - /** - * Adjusts a locals array to account for a merged subroutines list. - * If a frame merge results in, effectively, a subroutine return through - * a throw then the current locals will be a LocalsArraySet that will - * need to be trimmed of all OneLocalsArray elements that relevent to - * the subroutine that is returning. - * - * @param locals {@code non-null;} LocalsArray from before a merge - * @param subroutines {@code non-null;} a label list of subroutine start blocks - * representing the subroutine nesting of the block being merged into. - * @return {@code non-null;} locals set appropriate for merge - */ - private static LocalsArray adjustLocalsForSubroutines( - LocalsArray locals, IntList subroutines) { - if (! (locals instanceof LocalsArraySet)) { - // nothing to see here - return locals; - } - - LocalsArraySet laSet = (LocalsArraySet)locals; - - if (subroutines.size() == 0) { - /* - * We've merged from a subroutine context to a non-subroutine - * context, likely via a throw. Our successor will only need - * to consider the primary locals state, not the state of - * all possible subroutine paths. - */ - - return laSet.getPrimary(); - } - - /* - * It's unclear to me if the locals set needs to be trimmed here. - * If it does, then I believe it is all of the calling blocks - * in the subroutine at the end of "subroutines" passed into - * this method that should be removed. - */ - return laSet; - } - - /** - * Merges this frame with the frame of a subroutine caller at - * {@code predLabel}. Only called on the frame at the first - * block of a subroutine. - * - * @param other {@code non-null;} another frame - * @param subLabel label of subroutine start block - * @param predLabel label of calling block - * @return {@code non-null;} the result of merging the two frames - */ - public Frame mergeWithSubroutineCaller(Frame other, int subLabel, - int predLabel) { - LocalsArray resultLocals; - ExecutionStack resultStack; - - resultLocals = getLocals().mergeWithSubroutineCaller( - other.getLocals(), predLabel); - resultStack = getStack().merge(other.getStack()); - - IntList newOtherSubroutines = other.subroutines.mutableCopy(); - newOtherSubroutines.add(subLabel); - newOtherSubroutines.setImmutable(); - - if ((resultLocals == getLocals()) - && (resultStack == getStack()) - && subroutines.equals(newOtherSubroutines)) { - return this; - } - - IntList resultSubroutines; - - if (subroutines.equals(newOtherSubroutines)) { - resultSubroutines = subroutines; - } else { - /* - * The new subroutines list should be the deepest of the two - * lists being merged, but the postfix of the resultant list - * must be equal to the shorter list. - */ - IntList nonResultSubroutines; - - if (subroutines.size() > newOtherSubroutines.size()) { - resultSubroutines = subroutines; - nonResultSubroutines = newOtherSubroutines; - } else { - resultSubroutines = newOtherSubroutines; - nonResultSubroutines = subroutines; - } - - int szResult = resultSubroutines.size(); - int szNonResult = nonResultSubroutines.size(); - - for (int i = szNonResult - 1; i >=0; i-- ) { - if (nonResultSubroutines.get(i) - != resultSubroutines.get( - i + (szResult - szNonResult))) { - throw new - RuntimeException("Incompatible merged subroutines"); - } - } - - } - - return new Frame(resultLocals, resultStack, resultSubroutines); - } - - /** - * Makes a frame for a subroutine start block, given that this is the - * ending frame of one of the subroutine's calling blocks. Subroutine - * calls may be nested and thus may have nested locals state, so we - * start with an initial state as seen by the subroutine, but keep track - * of the individual locals states that will be expected when the individual - * subroutine calls return. - * - * @param subLabel label of subroutine start block - * @param callerLabel {@code >=0;} label of the caller block where this frame - * came from. - * @return a new instance to begin a called subroutine. - */ - public Frame makeNewSubroutineStartFrame(int subLabel, int callerLabel) { - IntList newSubroutines = subroutines.mutableCopy(); - newSubroutines.add(subLabel); - Frame newFrame = new Frame(locals.getPrimary(), stack, - IntList.makeImmutable(subLabel)); - return newFrame.mergeWithSubroutineCaller(this, subLabel, callerLabel); - } - - /** - * Makes a new frame for an exception handler block invoked from this - * frame. - * - * @param exceptionClass exception that the handler block will handle - * @return new frame - */ - public Frame makeExceptionHandlerStartFrame(CstType exceptionClass) { - ExecutionStack newStack = getStack().copy(); - - newStack.clear(); - newStack.push(exceptionClass); - - return new Frame(getLocals(), newStack, subroutines); - } - - /** - * Annotates (adds context to) the given exception with information - * about this frame. - * - * @param ex {@code non-null;} the exception to annotate - */ - public void annotate(ExceptionWithContext ex) { - locals.annotate(ex); - stack.annotate(ex); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/LineNumberList.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/LineNumberList.java deleted file mode 100644 index f54f8b5e5fa..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/LineNumberList.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.code; - -import com.android.dx.util.FixedSizeList; - -/** - * List of "line number" entries, which are the contents of - * {@code LineNumberTable} attributes. - */ -public final class LineNumberList extends FixedSizeList { - /** {@code non-null;} zero-size instance */ - public static final LineNumberList EMPTY = new LineNumberList(0); - - /** - * Returns an instance which is the concatenation of the two given - * instances. - * - * @param list1 {@code non-null;} first instance - * @param list2 {@code non-null;} second instance - * @return {@code non-null;} combined instance - */ - public static LineNumberList concat(LineNumberList list1, - LineNumberList list2) { - if (list1 == EMPTY) { - // easy case - return list2; - } - - int sz1 = list1.size(); - int sz2 = list2.size(); - LineNumberList result = new LineNumberList(sz1 + sz2); - - for (int i = 0; i < sz1; i++) { - result.set(i, list1.get(i)); - } - - for (int i = 0; i < sz2; i++) { - result.set(sz1 + i, list2.get(i)); - } - - return result; - } - - /** - * Constructs an instance. - * - * @param count the number of elements to be in the list - */ - public LineNumberList(int count) { - super(count); - } - - /** - * Gets the indicated item. - * - * @param n {@code >= 0;} which item - * @return {@code null-ok;} the indicated item - */ - public Item get(int n) { - return (Item) get0(n); - } - - /** - * Sets the item at the given index. - * - * @param n {@code >= 0, < size();} which element - * @param item {@code non-null;} the item - */ - public void set(int n, Item item) { - if (item == null) { - throw new NullPointerException("item == null"); - } - - set0(n, item); - } - - /** - * Sets the item at the given index. - * - * @param n {@code >= 0, < size();} which element - * @param startPc {@code >= 0;} start pc of this item - * @param lineNumber {@code >= 0;} corresponding line number - */ - public void set(int n, int startPc, int lineNumber) { - set0(n, new Item(startPc, lineNumber)); - } - - /** - * Gets the line number associated with the given address. - * - * @param pc {@code >= 0;} the address to look up - * @return {@code >= -1;} the associated line number, or {@code -1} if - * none is known - */ - public int pcToLine(int pc) { - /* - * Line number entries don't have to appear in any particular - * order, so we have to do a linear search. TODO: If - * this turns out to be a bottleneck, consider sorting the - * list prior to use. - */ - int sz = size(); - int bestPc = -1; - int bestLine = -1; - - for (int i = 0; i < sz; i++) { - Item one = get(i); - int onePc = one.getStartPc(); - if ((onePc <= pc) && (onePc > bestPc)) { - bestPc = onePc; - bestLine = one.getLineNumber(); - if (bestPc == pc) { - // We can't do better than this - break; - } - } - } - - return bestLine; - } - - /** - * Item in a line number table. - */ - public static class Item { - /** {@code >= 0;} start pc of this item */ - private final int startPc; - - /** {@code >= 0;} corresponding line number */ - private final int lineNumber; - - /** - * Constructs an instance. - * - * @param startPc {@code >= 0;} start pc of this item - * @param lineNumber {@code >= 0;} corresponding line number - */ - public Item(int startPc, int lineNumber) { - if (startPc < 0) { - throw new IllegalArgumentException("startPc < 0"); - } - - if (lineNumber < 0) { - throw new IllegalArgumentException("lineNumber < 0"); - } - - this.startPc = startPc; - this.lineNumber = lineNumber; - } - - /** - * Gets the start pc of this item. - * - * @return the start pc - */ - public int getStartPc() { - return startPc; - } - - /** - * Gets the line number of this item. - * - * @return the line number - */ - public int getLineNumber() { - return lineNumber; - } - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/LocalVariableList.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/LocalVariableList.java deleted file mode 100644 index 4a0bae10ca9..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/LocalVariableList.java +++ /dev/null @@ -1,373 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.code; - -import com.android.dx.rop.code.LocalItem; -import com.android.dx.rop.cst.CstString; -import com.android.dx.rop.type.Type; -import com.android.dx.util.FixedSizeList; - -/** - * List of "local variable" entries, which are the contents of - * {@code LocalVariableTable} and {@code LocalVariableTypeTable} - * attributes, as well as combinations of the two. - */ -public final class LocalVariableList extends FixedSizeList { - /** {@code non-null;} zero-size instance */ - public static final LocalVariableList EMPTY = new LocalVariableList(0); - - /** - * Returns an instance which is the concatenation of the two given - * instances. The result is immutable. - * - * @param list1 {@code non-null;} first instance - * @param list2 {@code non-null;} second instance - * @return {@code non-null;} combined instance - */ - public static LocalVariableList concat(LocalVariableList list1, - LocalVariableList list2) { - if (list1 == EMPTY) { - // easy case - return list2; - } - - int sz1 = list1.size(); - int sz2 = list2.size(); - LocalVariableList result = new LocalVariableList(sz1 + sz2); - - for (int i = 0; i < sz1; i++) { - result.set(i, list1.get(i)); - } - - for (int i = 0; i < sz2; i++) { - result.set(sz1 + i, list2.get(i)); - } - - result.setImmutable(); - return result; - } - - /** - * Returns an instance which is the result of merging the two - * given instances, where one instance should have only type - * descriptors and the other only type signatures. The merged - * result is identical to the one with descriptors, except that - * any element whose {name, index, start, length} matches an - * element in the signature list gets augmented with the - * corresponding signature. The result is immutable. - * - * @param descriptorList {@code non-null;} list with descriptors - * @param signatureList {@code non-null;} list with signatures - * @return {@code non-null;} the merged result - */ - public static LocalVariableList mergeDescriptorsAndSignatures( - LocalVariableList descriptorList, - LocalVariableList signatureList) { - int descriptorSize = descriptorList.size(); - LocalVariableList result = new LocalVariableList(descriptorSize); - - for (int i = 0; i < descriptorSize; i++) { - Item item = descriptorList.get(i); - Item signatureItem = signatureList.itemToLocal(item); - if (signatureItem != null) { - CstString signature = signatureItem.getSignature(); - item = item.withSignature(signature); - } - result.set(i, item); - } - - result.setImmutable(); - return result; - } - - /** - * Constructs an instance. - * - * @param count the number of elements to be in the list - */ - public LocalVariableList(int count) { - super(count); - } - - /** - * Gets the indicated item. - * - * @param n {@code >= 0;} which item - * @return {@code null-ok;} the indicated item - */ - public Item get(int n) { - return (Item) get0(n); - } - - /** - * Sets the item at the given index. - * - * @param n {@code >= 0, < size();} which element - * @param item {@code non-null;} the item - */ - public void set(int n, Item item) { - if (item == null) { - throw new NullPointerException("item == null"); - } - - set0(n, item); - } - - /** - * Sets the item at the given index. - * - *

Note: At least one of {@code descriptor} or - * {@code signature} must be passed as non-null.

- * - * @param n {@code >= 0, < size();} which element - * @param startPc {@code >= 0;} the start pc of this variable's scope - * @param length {@code >= 0;} the length (in bytecodes) of this variable's - * scope - * @param name {@code non-null;} the variable's name - * @param descriptor {@code null-ok;} the variable's type descriptor - * @param signature {@code null-ok;} the variable's type signature - * @param index {@code >= 0;} the variable's local index - */ - public void set(int n, int startPc, int length, CstString name, - CstString descriptor, CstString signature, int index) { - set0(n, new Item(startPc, length, name, descriptor, signature, index)); - } - - /** - * Gets the local variable information in this instance which matches - * the given {@link com.android.dx.cf.code.LocalVariableList.Item} - * in all respects but the type descriptor and signature, if any. - * - * @param item {@code non-null;} local variable information to match - * @return {@code null-ok;} the corresponding local variable information stored - * in this instance, or {@code null} if there is no matching - * information - */ - public Item itemToLocal(Item item) { - int sz = size(); - - for (int i = 0; i < sz; i++) { - Item one = (Item) get0(i); - - if ((one != null) && one.matchesAllButType(item)) { - return one; - } - } - - return null; - } - - /** - * Gets the local variable information associated with a given address - * and local index, if any. Note: In standard classfiles, a - * variable's start point is listed as the address of the instruction - * just past the one that sets the variable. - * - * @param pc {@code >= 0;} the address to look up - * @param index {@code >= 0;} the local variable index - * @return {@code null-ok;} the associated local variable information, or - * {@code null} if none is known - */ - public Item pcAndIndexToLocal(int pc, int index) { - int sz = size(); - - for (int i = 0; i < sz; i++) { - Item one = (Item) get0(i); - - if ((one != null) && one.matchesPcAndIndex(pc, index)) { - return one; - } - } - - return null; - } - - /** - * Item in a local variable table. - */ - public static class Item { - /** {@code >= 0;} the start pc of this variable's scope */ - private final int startPc; - - /** {@code >= 0;} the length (in bytecodes) of this variable's scope */ - private final int length; - - /** {@code non-null;} the variable's name */ - private final CstString name; - - /** {@code null-ok;} the variable's type descriptor */ - private final CstString descriptor; - - /** {@code null-ok;} the variable's type signature */ - private final CstString signature; - - /** {@code >= 0;} the variable's local index */ - private final int index; - - /** - * Constructs an instance. - * - *

Note: At least one of {@code descriptor} or - * {@code signature} must be passed as non-null.

- * - * @param startPc {@code >= 0;} the start pc of this variable's scope - * @param length {@code >= 0;} the length (in bytecodes) of this variable's - * scope - * @param name {@code non-null;} the variable's name - * @param descriptor {@code null-ok;} the variable's type descriptor - * @param signature {@code null-ok;} the variable's type signature - * @param index {@code >= 0;} the variable's local index - */ - public Item(int startPc, int length, CstString name, - CstString descriptor, CstString signature, int index) { - if (startPc < 0) { - throw new IllegalArgumentException("startPc < 0"); - } - - if (length < 0) { - throw new IllegalArgumentException("length < 0"); - } - - if (name == null) { - throw new NullPointerException("name == null"); - } - - if ((descriptor == null) && (signature == null)) { - throw new NullPointerException( - "(descriptor == null) && (signature == null)"); - } - - if (index < 0) { - throw new IllegalArgumentException("index < 0"); - } - - this.startPc = startPc; - this.length = length; - this.name = name; - this.descriptor = descriptor; - this.signature = signature; - this.index = index; - } - - /** - * Gets the start pc of this variable's scope. - * - * @return {@code >= 0;} the start pc of this variable's scope - */ - public int getStartPc() { - return startPc; - } - - /** - * Gets the length (in bytecodes) of this variable's scope. - * - * @return {@code >= 0;} the length (in bytecodes) of this variable's scope - */ - public int getLength() { - return length; - } - - /** - * Gets the variable's type descriptor. - * - * @return {@code null-ok;} the variable's type descriptor - */ - public CstString getDescriptor() { - return descriptor; - } - - /** - * Gets the variable's LocalItem, a (name, signature) tuple - * - * @return {@code null-ok;} the variable's type descriptor - */ - public LocalItem getLocalItem() { - return LocalItem.make(name, signature); - } - - /** - * Gets the variable's type signature. Private because if you need this, - * you want getLocalItem() instead. - * - * @return {@code null-ok;} the variable's type signature - */ - private CstString getSignature() { - return signature; - } - - /** - * Gets the variable's local index. - * - * @return {@code >= 0;} the variable's local index - */ - public int getIndex() { - return index; - } - - /** - * Gets the variable's type descriptor. This is a convenient shorthand - * for {@code Type.intern(getDescriptor().getString())}. - * - * @return {@code non-null;} the variable's type - */ - public Type getType() { - return Type.intern(descriptor.getString()); - } - - /** - * Constructs and returns an instance which is identical to this - * one, except that the signature is changed to the given value. - * - * @param newSignature {@code non-null;} the new signature - * @return {@code non-null;} an appropriately-constructed instance - */ - public Item withSignature(CstString newSignature) { - return new Item(startPc, length, name, descriptor, newSignature, - index); - } - - /** - * Gets whether this instance matches (describes) the given - * address and index. - * - * @param pc {@code >= 0;} the address in question - * @param index {@code >= 0;} the local variable index in question - * @return {@code true} iff this instance matches {@code pc} - * and {@code index} - */ - public boolean matchesPcAndIndex(int pc, int index) { - return (index == this.index) && - (pc >= startPc) && - (pc < (startPc + length)); - } - - /** - * Gets whether this instance matches (describes) the given - * other instance exactly in all fields except type descriptor and - * type signature. - * - * @param other {@code non-null;} the instance to compare to - * @return {@code true} iff this instance matches - */ - public boolean matchesAllButType(Item other) { - return (startPc == other.startPc) - && (length == other.length) - && (index == other.index) - && name.equals(other.name); - } - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/LocalsArray.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/LocalsArray.java deleted file mode 100644 index 07ca96da6df..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/LocalsArray.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.code; - -import com.android.dex.util.ExceptionWithContext; -import com.android.dx.rop.code.RegisterSpec; -import com.android.dx.rop.type.Type; -import com.android.dx.rop.type.TypeBearer; -import com.android.dx.util.MutabilityControl; -import com.android.dx.util.ToHuman; - -/** - * Representation of an array of local variables, with Java semantics. - * - *

Note: For the most part, the documentation for this class - * ignores the distinction between {@link Type} and {@link - * TypeBearer}.

- */ -public abstract class LocalsArray extends MutabilityControl implements ToHuman { - - /** - * Constructs an instance, explicitly indicating the mutability. - * - * @param mutable {@code true} if this instance is mutable - */ - protected LocalsArray(boolean mutable) { - super(mutable); - } - - /** - * Makes and returns a mutable copy of this instance. - * - * @return {@code non-null;} the copy - */ - public abstract LocalsArray copy(); - - /** - * Annotates (adds context to) the given exception with information - * about this instance. - * - * @param ex {@code non-null;} the exception to annotate - */ - public abstract void annotate(ExceptionWithContext ex); - - /** - * Replaces all the occurrences of the given uninitialized type in - * this array with its initialized equivalent. - * - * @param type {@code non-null;} type to replace - */ - public abstract void makeInitialized(Type type); - - /** - * Gets the maximum number of locals this instance can refer to. - * - * @return the max locals - */ - public abstract int getMaxLocals(); - - /** - * Sets the type stored at the given local index. If the given type - * is category-2, then (a) the index must be at least two less than - * {@link #getMaxLocals} and (b) the next index gets invalidated - * by the operation. In case of either category, if the previous - * local contains a category-2 value, then it too is invalidated by - * this operation. - * - * @param idx {@code >= 0, < getMaxLocals();} which local - * @param type {@code non-null;} new type for the local at {@code idx} - */ - public abstract void set(int idx, TypeBearer type); - - /** - * Sets the type for the local indicated by the given register spec - * to that register spec (which includes type and optional name - * information). This is identical to calling - * {@code set(spec.getReg(), spec)}. - * - * @param spec {@code non-null;} register spec to use as the basis for the update - */ - public abstract void set(RegisterSpec spec); - - /** - * Invalidates the local at the given index. - * - * @param idx {@code >= 0, < getMaxLocals();} which local - */ - public abstract void invalidate(int idx); - - /** - * Gets the type stored at the given local index, or {@code null} - * if the given local is uninitialized / invalid. - * - * @param idx {@code >= 0, < getMaxLocals();} which local - * @return {@code null-ok;} the type of value stored in that local - */ - public abstract TypeBearer getOrNull(int idx); - - /** - * Gets the type stored at the given local index, only succeeding if - * the given local contains a valid type (though it is allowed to - * be an uninitialized instance). - * - * @param idx {@code >= 0, < getMaxLocals();} which local - * @return {@code non-null;} the type of value stored in that local - * @throws SimException thrown if {@code idx} is valid, but - * the contents are invalid - */ - public abstract TypeBearer get(int idx); - - /** - * Gets the type stored at the given local index, which is expected - * to be an initialized category-1 value. - * - * @param idx {@code >= 0, < getMaxLocals();} which local - * @return {@code non-null;} the type of value stored in that local - * @throws SimException thrown if {@code idx} is valid, but - * one of the following holds: (a) the local is invalid; (b) the local - * contains an uninitialized instance; (c) the local contains a - * category-2 value - */ - public abstract TypeBearer getCategory1(int idx); - - /** - * Gets the type stored at the given local index, which is expected - * to be a category-2 value. - * - * @param idx {@code >= 0, < getMaxLocals();} which local - * @return {@code non-null;} the type of value stored in that local - * @throws SimException thrown if {@code idx} is valid, but - * one of the following holds: (a) the local is invalid; (b) the local - * contains a category-1 value - */ - public abstract TypeBearer getCategory2(int idx); - - /** - * Merges this instance with {@code other}. If the merged result is - * the same as this instance, then this is returned (not a copy). - * - * @param other {@code non-null;} another LocalsArray - * @return {@code non-null;} the merge result, a new instance or this - */ - public abstract LocalsArray merge(LocalsArray other); - - /** - * Merges this instance with a {@code LocalsSet} from a subroutine - * caller. To be used when merging in the first block of a subroutine. - * - * @param other {@code other non-null;} another LocalsArray. The final locals - * state of a subroutine caller. - * @param predLabel the label of the subroutine caller block. - * @return {@code non-null;} the merge result, a new instance or this - */ - public abstract LocalsArraySet mergeWithSubroutineCaller - (LocalsArray other, int predLabel); - - /** - * Gets the locals set appropriate for the current execution context. - * That is, if this is a {@code OneLocalsArray} instance, then return - * {@code this}, otherwise return {@code LocalsArraySet}'s - * primary. - * - * @return locals for this execution context. - */ - protected abstract OneLocalsArray getPrimary(); - -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/LocalsArraySet.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/LocalsArraySet.java deleted file mode 100644 index c4b7da9f348..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/LocalsArraySet.java +++ /dev/null @@ -1,460 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.code; - -import com.android.dex.util.ExceptionWithContext; -import com.android.dx.rop.code.RegisterSpec; -import com.android.dx.rop.type.Type; -import com.android.dx.rop.type.TypeBearer; -import com.android.dx.util.Hex; -import java.util.ArrayList; - -/** - * Representation of a set of local variable arrays, with Java semantics. - * This peculiar case is to support in-method subroutines, which can - * have different locals sets for each caller. - * - *

Note: For the most part, the documentation for this class - * ignores the distinction between {@link com.android.dx.rop.type.Type} and {@link - * com.android.dx.rop.type.TypeBearer}.

- */ -public class LocalsArraySet extends LocalsArray { - - /** - * The primary LocalsArray represents the locals as seen from - * the subroutine itself, which is the merged representation of all the - * individual locals states. - */ - private final OneLocalsArray primary; - - /** - * Indexed by label of caller block: the locals specific to each caller's - * invocation of the subroutine. - */ - private final ArrayList secondaries; - - /** - * Constructs an instance. The locals array initially consists of - * all-uninitialized values (represented as {@code null}s). - * - * @param maxLocals {@code >= 0;} the maximum number of locals this instance - * can refer to - */ - public LocalsArraySet(int maxLocals) { - super(maxLocals != 0); - primary = new OneLocalsArray(maxLocals); - secondaries = new ArrayList(); - } - - /** - * Constructs an instance with the specified primary and secondaries set. - * - * @param primary {@code non-null;} primary locals to use - * @param secondaries {@code non-null;} secondaries set, indexed by subroutine - * caller label. - */ - public LocalsArraySet(OneLocalsArray primary, - ArrayList secondaries) { - super(primary.getMaxLocals() > 0); - - this.primary = primary; - this.secondaries = secondaries; - } - - /** - * Constructs an instance which is a copy of another. - * - * @param toCopy {@code non-null;} instance to copy. - */ - private LocalsArraySet(LocalsArraySet toCopy) { - super(toCopy.getMaxLocals() > 0); - - primary = toCopy.primary.copy(); - secondaries = new ArrayList(toCopy.secondaries.size()); - - int sz = toCopy.secondaries.size(); - for (int i = 0; i < sz; i++) { - LocalsArray la = toCopy.secondaries.get(i); - - if (la == null) { - secondaries.add(null); - } else { - secondaries.add(la.copy()); - } - } - } - - - /** @inheritDoc */ - @Override - public void setImmutable() { - primary.setImmutable(); - - for (LocalsArray la : secondaries) { - if (la != null) { - la.setImmutable(); - } - } - super.setImmutable(); - } - - /** @inheritDoc */ - @Override - public LocalsArray copy() { - return new LocalsArraySet(this); - } - - /** @inheritDoc */ - @Override - public void annotate(ExceptionWithContext ex) { - ex.addContext("(locals array set; primary)"); - primary.annotate(ex); - - int sz = secondaries.size(); - for (int label = 0; label < sz; label++) { - LocalsArray la = secondaries.get(label); - - if (la != null) { - ex.addContext("(locals array set: primary for caller " - + Hex.u2(label) + ')'); - - la.getPrimary().annotate(ex); - } - } - } - - /** {@inheritDoc*/ - public String toHuman() { - StringBuilder sb = new StringBuilder(); - - sb.append("(locals array set; primary)\n"); - - sb.append(getPrimary().toHuman()); - sb.append('\n'); - - int sz = secondaries.size(); - for (int label = 0; label < sz; label++) { - LocalsArray la = secondaries.get(label); - - if (la != null) { - sb.append("(locals array set: primary for caller " - + Hex.u2(label) + ")\n"); - - sb.append(la.getPrimary().toHuman()); - sb.append('\n'); - } - } - - return sb.toString(); - } - - /** @inheritDoc */ - @Override - public void makeInitialized(Type type) { - int len = primary.getMaxLocals(); - - if (len == 0) { - // We have to check for this before checking for immutability. - return; - } - - throwIfImmutable(); - - primary.makeInitialized(type); - - for (LocalsArray la : secondaries) { - if (la != null) { - la.makeInitialized(type); - } - } - } - - /** @inheritDoc */ - @Override - public int getMaxLocals() { - return primary.getMaxLocals(); - } - - /** @inheritDoc */ - @Override - public void set(int idx, TypeBearer type) { - throwIfImmutable(); - - primary.set(idx, type); - - for (LocalsArray la : secondaries) { - if (la != null) { - la.set(idx, type); - } - } - } - - /** @inheritDoc */ - @Override - public void set(RegisterSpec spec) { - set(spec.getReg(), spec); - } - - /** @inheritDoc */ - @Override - public void invalidate(int idx) { - throwIfImmutable(); - - primary.invalidate(idx); - - for (LocalsArray la : secondaries) { - if (la != null) { - la.invalidate(idx); - } - } - } - - /** @inheritDoc */ - @Override - public TypeBearer getOrNull(int idx) { - return primary.getOrNull(idx); - } - - /** @inheritDoc */ - @Override - public TypeBearer get(int idx) { - return primary.get(idx); - } - - /** @inheritDoc */ - @Override - public TypeBearer getCategory1(int idx) { - return primary.getCategory1(idx); - } - - /** @inheritDoc */ - @Override - public TypeBearer getCategory2(int idx) { - return primary.getCategory2(idx); - } - - /** - * Merges this set with another {@code LocalsArraySet} instance. - * - * @param other {@code non-null;} to merge - * @return {@code non-null;} this instance if merge was a no-op, or - * new merged instance. - */ - private LocalsArraySet mergeWithSet(LocalsArraySet other) { - OneLocalsArray newPrimary; - ArrayList newSecondaries; - boolean secondariesChanged = false; - - newPrimary = primary.merge(other.getPrimary()); - - int sz1 = secondaries.size(); - int sz2 = other.secondaries.size(); - int sz = Math.max(sz1, sz2); - newSecondaries = new ArrayList(sz); - - for (int i = 0; i < sz; i++) { - LocalsArray la1 = (i < sz1 ? secondaries.get(i) : null); - LocalsArray la2 = (i < sz2 ? other.secondaries.get(i) : null); - LocalsArray resultla = null; - - if (la1 == la2) { - resultla = la1; - } else if (la1 == null) { - resultla = la2; - } else if (la2 == null) { - resultla = la1; - } else { - try { - resultla = la1.merge(la2); - } catch (SimException ex) { - ex.addContext( - "Merging locals set for caller block " + Hex.u2(i)); - } - } - - secondariesChanged = secondariesChanged || (la1 != resultla); - - newSecondaries.add(resultla); - } - - if ((primary == newPrimary) && ! secondariesChanged ) { - return this; - } - - return new LocalsArraySet(newPrimary, newSecondaries); - } - - /** - * Merges this set with a {@code OneLocalsArray} instance. - * - * @param other {@code non-null;} to merge - * @return {@code non-null;} this instance if merge was a no-op, or - * new merged instance. - */ - private LocalsArraySet mergeWithOne(OneLocalsArray other) { - OneLocalsArray newPrimary; - ArrayList newSecondaries; - boolean secondariesChanged = false; - - newPrimary = primary.merge(other.getPrimary()); - newSecondaries = new ArrayList(secondaries.size()); - - int sz = secondaries.size(); - for (int i = 0; i < sz; i++) { - LocalsArray la = secondaries.get(i); - LocalsArray resultla = null; - - if (la != null) { - try { - resultla = la.merge(other); - } catch (SimException ex) { - ex.addContext("Merging one locals against caller block " - + Hex.u2(i)); - } - } - - secondariesChanged = secondariesChanged || (la != resultla); - - newSecondaries.add(resultla); - } - - if ((primary == newPrimary) && ! secondariesChanged ) { - return this; - } - - return new LocalsArraySet(newPrimary, newSecondaries); - } - - /** @inheritDoc */ - @Override - public LocalsArraySet merge(LocalsArray other) { - LocalsArraySet result; - - try { - if (other instanceof LocalsArraySet) { - result = mergeWithSet((LocalsArraySet) other); - } else { - result = mergeWithOne((OneLocalsArray) other); - } - } catch (SimException ex) { - ex.addContext("underlay locals:"); - annotate(ex); - ex.addContext("overlay locals:"); - other.annotate(ex); - throw ex; - } - - result.setImmutable(); - return result; - } - - /** - * Gets the {@code LocalsArray} instance for a specified subroutine - * caller label, or null if label has no locals associated with it. - * - * @param label {@code >= 0;} subroutine caller label - * @return {@code null-ok;} locals if available. - */ - private LocalsArray getSecondaryForLabel(int label) { - if (label >= secondaries.size()) { - return null; - } - - return secondaries.get(label); - } - - /** {@inheritDoc} */ - @Override - public LocalsArraySet mergeWithSubroutineCaller - (LocalsArray other, int predLabel) { - - LocalsArray mine = getSecondaryForLabel(predLabel); - LocalsArray newSecondary; - OneLocalsArray newPrimary; - - newPrimary = primary.merge(other.getPrimary()); - - if (mine == other) { - newSecondary = mine; - } else if (mine == null) { - newSecondary = other; - } else { - newSecondary = mine.merge(other); - } - - if ((newSecondary == mine) && (newPrimary == primary)) { - return this; - } else { - /* - * We're going to re-build a primary as a merge of all the - * secondaries. - */ - newPrimary = null; - - int szSecondaries = secondaries.size(); - int sz = Math.max(predLabel + 1, szSecondaries); - ArrayList newSecondaries = new ArrayList(sz); - for (int i = 0; i < sz; i++) { - LocalsArray la = null; - - if (i == predLabel) { - /* - * This LocalsArray always replaces any existing one, - * since this is the result of a refined iteration. - */ - la = newSecondary; - } else if (i < szSecondaries) { - la = secondaries.get(i); - } - - if (la != null) { - if (newPrimary == null) { - newPrimary = la.getPrimary(); - } else { - newPrimary = newPrimary.merge(la.getPrimary()); - } - } - - newSecondaries.add(la); - } - - LocalsArraySet result - = new LocalsArraySet(newPrimary, newSecondaries); - result.setImmutable(); - return result; - } - } - - /** - * Returns a LocalsArray instance representing the locals state that should - * be used when returning to a subroutine caller. - * - * @param subLabel {@code >= 0;} A calling label of a subroutine - * @return {@code null-ok;} an instance for this subroutine, or null if subroutine - * is not in this set. - */ - public LocalsArray subArrayForLabel(int subLabel) { - LocalsArray result = getSecondaryForLabel(subLabel); - return result; - } - - /**{@inheritDoc}*/ - @Override - protected OneLocalsArray getPrimary() { - return primary; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/Machine.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/Machine.java deleted file mode 100644 index a1905059ffb..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/Machine.java +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.code; - -import com.android.dx.rop.code.LocalItem; -import com.android.dx.rop.cst.Constant; -import com.android.dx.rop.type.Prototype; -import com.android.dx.rop.type.Type; -import java.util.ArrayList; - -/** - * Interface for machines capable of executing bytecode by acting - * upon a {@link Frame}. A machine conceptually contains four arbitrary-value - * argument slots, slots for several literal-value arguments, and slots for - * branch target information. - */ -public interface Machine { - /** - * Gets the effective prototype of the method that this instance is - * being used for. The effective prototype includes an initial - * {@code this} argument for instance methods. - * - * @return {@code non-null;} the method prototype - */ - public Prototype getPrototype(); - - /** - * Clears the regular and auxiliary arguments area. - */ - public void clearArgs(); - - /** - * Pops the given number of values from the stack (of either category), - * and store them in the arguments area, indicating that there are now - * that many arguments. Also, clear the auxiliary arguments. - * - * @param frame {@code non-null;} frame to operate on - * @param count {@code >= 0;} number of values to pop - */ - public void popArgs(Frame frame, int count); - - /** - * Pops values from the stack of the types indicated by the given - * {@code Prototype} (popped in reverse of the argument - * order, so the first prototype argument type is for the deepest - * element of the stack), and store them in the arguments area, - * indicating that there are now that many arguments. Also, clear - * the auxiliary arguments. - * - * @param frame {@code non-null;} frame to operate on - * @param prototype {@code non-null;} prototype indicating arguments to pop - */ - public void popArgs(Frame frame, Prototype prototype); - - /** - * Pops a value from the stack of the indicated type, and store it - * in the arguments area, indicating that there are now that many - * arguments. Also, clear the auxiliary arguments. - * - * @param frame {@code non-null;} frame to operate on - * @param type {@code non-null;} type of the argument - */ - public void popArgs(Frame frame, Type type); - - /** - * Pops values from the stack of the indicated types (popped in - * reverse argument order, so the first indicated type is for the - * deepest element of the stack), and store them in the arguments - * area, indicating that there are now that many arguments. Also, - * clear the auxiliary arguments. - * - * @param frame {@code non-null;} frame to operate on - * @param type1 {@code non-null;} type of the first argument - * @param type2 {@code non-null;} type of the second argument - */ - public void popArgs(Frame frame, Type type1, Type type2); - - /** - * Pops values from the stack of the indicated types (popped in - * reverse argument order, so the first indicated type is for the - * deepest element of the stack), and store them in the arguments - * area, indicating that there are now that many arguments. Also, - * clear the auxiliary arguments. - * - * @param frame {@code non-null;} frame to operate on - * @param type1 {@code non-null;} type of the first argument - * @param type2 {@code non-null;} type of the second argument - * @param type3 {@code non-null;} type of the third argument - */ - public void popArgs(Frame frame, Type type1, Type type2, Type type3); - - /** - * Loads the local variable with the given index as the sole argument in - * the arguments area. Also, clear the auxiliary arguments. - * - * @param frame {@code non-null;} frame to operate on - * @param idx {@code >= 0;} the local variable index - */ - public void localArg(Frame frame, int idx); - - /** - * Used to specify if a loaded local variable has info in the local - * variable table. - * - * @param local {@code true} if local arg has info in local variable table - */ - public void localInfo(boolean local); - - /** - * Indicates that the salient type of this operation is as - * given. This differentiates between, for example, the various - * arithmetic opcodes, which, by the time they hit a - * {@code Machine} are collapsed to the {@code int} - * variant. (See {@link BytecodeArray#parseInstruction} for - * details.) - * - * @param type {@code non-null;} the salient type of the upcoming operation - */ - public void auxType(Type type); - - /** - * Indicates that there is an auxiliary (inline, not stack) - * argument of type {@code int}, with the given value. - * - *

Note: Perhaps unintuitively, the stack manipulation - * ops (e.g., {@code dup} and {@code swap}) use this to - * indicate the result stack pattern with a straightforward hex - * encoding of the push order starting with least-significant - * nibbles getting pushed first). For example, an all-category-1 - * {@code dup2_x1} sets this to {@code 0x12312}, and the - * other form of that op sets this to - * {@code 0x121}.

- * - *

Also Note: For {@code switch*} instructions, this is - * used to indicate the padding value (which is only useful for - * verification).

- * - * @param value the argument value - */ - public void auxIntArg(int value); - - /** - * Indicates that there is an auxiliary (inline, not stack) object - * argument, with the value based on the given constant. - * - *

Note: Some opcodes use both {@code int} and - * constant auxiliary arguments.

- * - * @param cst {@code non-null;} the constant containing / referencing - * the value - */ - public void auxCstArg(Constant cst); - - /** - * Indicates that there is an auxiliary (inline, not stack) argument - * indicating a branch target. - * - * @param target the argument value - */ - public void auxTargetArg(int target); - - /** - * Indicates that there is an auxiliary (inline, not stack) argument - * consisting of a {@code switch*} table. - * - *

Note: This is generally used in conjunction with - * {@link #auxIntArg} (which holds the padding).

- * - * @param cases {@code non-null;} the list of key-target pairs, plus the default - * target - */ - public void auxSwitchArg(SwitchList cases); - - /** - * Indicates that there is an auxiliary (inline, not stack) argument - * consisting of a list of initial values for a newly created array. - * - * @param initValues {@code non-null;} the list of constant values to initialize - * the array - */ - public void auxInitValues(ArrayList initValues); - - /** - * Indicates that the target of this operation is the given local. - * - * @param idx {@code >= 0;} the local variable index - * @param type {@code non-null;} the type of the local - * @param local {@code null-ok;} the name and signature of the local, if known - */ - public void localTarget(int idx, Type type, LocalItem local); - - /** - * "Runs" the indicated opcode in an appropriate way, using the arguments - * area as appropriate, and modifying the given frame in response. - * - * @param frame {@code non-null;} frame to operate on - * @param offset {@code >= 0;} byte offset in the method to the opcode being - * run - * @param opcode {@code >= 0;} the opcode to run - */ - public void run(Frame frame, int offset, int opcode); -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/Merger.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/Merger.java deleted file mode 100644 index 51c31c3a37e..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/Merger.java +++ /dev/null @@ -1,305 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.code; - -import com.android.dx.rop.type.Type; -import com.android.dx.rop.type.TypeBearer; -import com.android.dx.util.Hex; - -/** - * Utility methods to merge various frame information. - */ -public final class Merger { - /** - * This class is uninstantiable. - */ - private Merger() { - // This space intentionally left blank. - } - - /** - * Merges two locals arrays. If the merged result is the same as the first - * argument, then return the first argument (not a copy). - * - * @param locals1 {@code non-null;} a locals array - * @param locals2 {@code non-null;} another locals array - * @return {@code non-null;} the result of merging the two locals arrays - */ - public static OneLocalsArray mergeLocals(OneLocalsArray locals1, - OneLocalsArray locals2) { - if (locals1 == locals2) { - // Easy out. - return locals1; - } - - int sz = locals1.getMaxLocals(); - OneLocalsArray result = null; - - if (locals2.getMaxLocals() != sz) { - throw new SimException("mismatched maxLocals values"); - } - - for (int i = 0; i < sz; i++) { - TypeBearer tb1 = locals1.getOrNull(i); - TypeBearer tb2 = locals2.getOrNull(i); - TypeBearer resultType = mergeType(tb1, tb2); - if (resultType != tb1) { - /* - * We only need to do anything when the result differs - * from what is in the first array, since that's what the - * result gets initialized to. - */ - if (result == null) { - result = locals1.copy(); - } - - if (resultType == null) { - result.invalidate(i); - } else { - result.set(i, resultType); - } - } - } - - if (result == null) { - return locals1; - } - - result.setImmutable(); - return result; - } - - /** - * Merges two stacks. If the merged result is the same as the first - * argument, then return the first argument (not a copy). - * - * @param stack1 {@code non-null;} a stack - * @param stack2 {@code non-null;} another stack - * @return {@code non-null;} the result of merging the two stacks - */ - public static ExecutionStack mergeStack(ExecutionStack stack1, - ExecutionStack stack2) { - if (stack1 == stack2) { - // Easy out. - return stack1; - } - - int sz = stack1.size(); - ExecutionStack result = null; - - if (stack2.size() != sz) { - throw new SimException("mismatched stack depths"); - } - - for (int i = 0; i < sz; i++) { - TypeBearer tb1 = stack1.peek(i); - TypeBearer tb2 = stack2.peek(i); - TypeBearer resultType = mergeType(tb1, tb2); - if (resultType != tb1) { - /* - * We only need to do anything when the result differs - * from what is in the first stack, since that's what the - * result gets initialized to. - */ - if (result == null) { - result = stack1.copy(); - } - - try { - if (resultType == null) { - throw new SimException("incompatible: " + tb1 + ", " + - tb2); - } else { - result.change(i, resultType); - } - } catch (SimException ex) { - ex.addContext("...while merging stack[" + Hex.u2(i) + "]"); - throw ex; - } - } - } - - if (result == null) { - return stack1; - } - - result.setImmutable(); - return result; - } - - /** - * Merges two frame types. - * - * @param ft1 {@code non-null;} a frame type - * @param ft2 {@code non-null;} another frame type - * @return {@code non-null;} the result of merging the two types - */ - public static TypeBearer mergeType(TypeBearer ft1, TypeBearer ft2) { - if ((ft1 == null) || ft1.equals(ft2)) { - return ft1; - } else if (ft2 == null) { - return null; - } else { - Type type1 = ft1.getType(); - Type type2 = ft2.getType(); - - if (type1 == type2) { - return type1; - } else if (type1.isReference() && type2.isReference()) { - if (type1 == Type.KNOWN_NULL) { - /* - * A known-null merges with any other reference type to - * be that reference type. - */ - return type2; - } else if (type2 == Type.KNOWN_NULL) { - /* - * The same as above, but this time it's type2 that's - * the known-null. - */ - return type1; - } else if (type1.isArray() && type2.isArray()) { - TypeBearer componentUnion = - mergeType(type1.getComponentType(), - type2.getComponentType()); - if (componentUnion == null) { - /* - * At least one of the types is a primitive type, - * so the merged result is just Object. - */ - return Type.OBJECT; - } - return ((Type) componentUnion).getArrayType(); - } else { - /* - * All other unequal reference types get merged to be - * Object in this phase. This is fine here, but it - * won't be the right thing to do in the verifier. - */ - return Type.OBJECT; - } - } else if (type1.isIntlike() && type2.isIntlike()) { - /* - * Merging two non-identical int-like types results in - * the type int. - */ - return Type.INT; - } else { - return null; - } - } - } - - /** - * Returns whether the given supertype is possibly assignable from - * the given subtype. This takes into account primitiveness, - * int-likeness, known-nullness, and array dimensions, but does - * not assume anything about class hierarchy other than that the - * type {@code Object} is the supertype of all reference - * types and all arrays are assignable to - * {@code Serializable} and {@code Cloneable}. - * - * @param supertypeBearer {@code non-null;} the supertype - * @param subtypeBearer {@code non-null;} the subtype - */ - public static boolean isPossiblyAssignableFrom(TypeBearer supertypeBearer, - TypeBearer subtypeBearer) { - Type supertype = supertypeBearer.getType(); - Type subtype = subtypeBearer.getType(); - - if (supertype.equals(subtype)) { - // Easy out. - return true; - } - - int superBt = supertype.getBasicType(); - int subBt = subtype.getBasicType(); - - // Treat return types as Object for the purposes of this method. - - if (superBt == Type.BT_ADDR) { - supertype = Type.OBJECT; - superBt = Type.BT_OBJECT; - } - - if (subBt == Type.BT_ADDR) { - subtype = Type.OBJECT; - subBt = Type.BT_OBJECT; - } - - if ((superBt != Type.BT_OBJECT) || (subBt != Type.BT_OBJECT)) { - /* - * No two distinct primitive types are assignable in this sense, - * unless they are both int-like. - */ - return supertype.isIntlike() && subtype.isIntlike(); - } - - // At this point, we know both types are reference types. - - if (supertype == Type.KNOWN_NULL) { - /* - * A known-null supertype is only assignable from another - * known-null (handled in the easy out at the top of the - * method). - */ - return false; - } else if (subtype == Type.KNOWN_NULL) { - /* - * A known-null subtype is in fact assignable to any - * reference type. - */ - return true; - } else if (supertype == Type.OBJECT) { - /* - * Object is assignable from any reference type. - */ - return true; - } else if (supertype.isArray()) { - // The supertype is an array type. - if (! subtype.isArray()) { - // The subtype isn't an array, and so can't be assignable. - return false; - } - - /* - * Strip off as many matched component types from both - * types as possible, and check the assignability of the - * results. - */ - do { - supertype = supertype.getComponentType(); - subtype = subtype.getComponentType(); - } while (supertype.isArray() && subtype.isArray()); - - return isPossiblyAssignableFrom(supertype, subtype); - } else if (subtype.isArray()) { - /* - * Other than Object (handled above), array types are - * assignable only to Serializable and Cloneable. - */ - return (supertype == Type.SERIALIZABLE) || - (supertype == Type.CLONEABLE); - } else { - /* - * All other unequal reference types are considered at - * least possibly assignable. - */ - return true; - } - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/OneLocalsArray.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/OneLocalsArray.java deleted file mode 100644 index 0286a706fe6..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/OneLocalsArray.java +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.code; - -import com.android.dex.util.ExceptionWithContext; -import com.android.dx.rop.code.RegisterSpec; -import com.android.dx.rop.type.Type; -import com.android.dx.rop.type.TypeBearer; -import com.android.dx.util.Hex; - -/** - * Representation of an array of local variables, with Java semantics. - * - *

Note: For the most part, the documentation for this class - * ignores the distinction between {@link com.android.dx.rop.type.Type} and {@link - * com.android.dx.rop.type.TypeBearer}.

- */ -public class OneLocalsArray extends LocalsArray { - /** {@code non-null;} actual array */ - private final TypeBearer[] locals; - - /** - * Constructs an instance. The locals array initially consists of - * all-uninitialized values (represented as {@code null}s). - * - * @param maxLocals {@code >= 0;} the maximum number of locals this instance - * can refer to - */ - public OneLocalsArray(int maxLocals) { - super(maxLocals != 0); - locals = new TypeBearer[maxLocals]; - } - - /** @inheritDoc */ - public OneLocalsArray copy() { - OneLocalsArray result = new OneLocalsArray(locals.length); - - System.arraycopy(locals, 0, result.locals, 0, locals.length); - - return result; - } - - /** @inheritDoc */ - public void annotate(ExceptionWithContext ex) { - for (int i = 0; i < locals.length; i++) { - TypeBearer type = locals[i]; - String s = (type == null) ? "" : type.toString(); - ex.addContext("locals[" + Hex.u2(i) + "]: " + s); - } - } - - /** {@inheritDoc*/ - public String toHuman() { - StringBuilder sb = new StringBuilder(); - - for (int i = 0; i < locals.length; i++) { - TypeBearer type = locals[i]; - String s = (type == null) ? "" : type.toString(); - sb.append("locals[" + Hex.u2(i) + "]: " + s + "\n"); - } - - return sb.toString(); - } - - /** @inheritDoc */ - public void makeInitialized(Type type) { - int len = locals.length; - - if (len == 0) { - // We have to check for this before checking for immutability. - return; - } - - throwIfImmutable(); - - Type initializedType = type.getInitializedType(); - - for (int i = 0; i < len; i++) { - if (locals[i] == type) { - locals[i] = initializedType; - } - } - } - - /** @inheritDoc */ - public int getMaxLocals() { - return locals.length; - } - - /** @inheritDoc */ - public void set(int idx, TypeBearer type) { - throwIfImmutable(); - - try { - type = type.getFrameType(); - } catch (NullPointerException ex) { - // Elucidate the exception - throw new NullPointerException("type == null"); - } - - if (idx < 0) { - throw new IndexOutOfBoundsException("idx < 0"); - } - - // Make highest possible out-of-bounds check happen first. - if (type.getType().isCategory2()) { - locals[idx + 1] = null; - } - - locals[idx] = type; - - if (idx != 0) { - TypeBearer prev = locals[idx - 1]; - if ((prev != null) && prev.getType().isCategory2()) { - locals[idx - 1] = null; - } - } - } - - /** @inheritDoc */ - public void set(RegisterSpec spec) { - set(spec.getReg(), spec); - } - - /** @inheritDoc */ - public void invalidate(int idx) { - throwIfImmutable(); - locals[idx] = null; - } - - /** @inheritDoc */ - public TypeBearer getOrNull(int idx) { - return locals[idx]; - } - - /** @inheritDoc */ - public TypeBearer get(int idx) { - TypeBearer result = locals[idx]; - - if (result == null) { - return throwSimException(idx, "invalid"); - } - - return result; - } - - /** @inheritDoc */ - public TypeBearer getCategory1(int idx) { - TypeBearer result = get(idx); - Type type = result.getType(); - - if (type.isUninitialized()) { - return throwSimException(idx, "uninitialized instance"); - } - - if (type.isCategory2()) { - return throwSimException(idx, "category-2"); - } - - return result; - } - - /** @inheritDoc */ - public TypeBearer getCategory2(int idx) { - TypeBearer result = get(idx); - - if (result.getType().isCategory1()) { - return throwSimException(idx, "category-1"); - } - - return result; - } - - /** @inheritDoc */ - @Override - public LocalsArray merge(LocalsArray other) { - if (other instanceof OneLocalsArray) { - return merge((OneLocalsArray)other); - } else { //LocalsArraySet - // LocalsArraySet knows how to merge me. - return other.merge(this); - } - } - - /** - * Merges this OneLocalsArray instance with another OneLocalsArray - * instance. A more-refined version of {@link #merge(LocalsArray) merge} - * which is called by that method when appropriate. - * - * @param other locals array with which to merge - * @return this instance if merge was a no-op, or a new instance if - * the merge resulted in a change. - */ - public OneLocalsArray merge(OneLocalsArray other) { - try { - return Merger.mergeLocals(this, other); - } catch (SimException ex) { - ex.addContext("underlay locals:"); - annotate(ex); - ex.addContext("overlay locals:"); - other.annotate(ex); - throw ex; - } - } - - /** @inheritDoc */ - @Override - public LocalsArraySet mergeWithSubroutineCaller - (LocalsArray other, int predLabel) { - - LocalsArraySet result = new LocalsArraySet(getMaxLocals()); - return result.mergeWithSubroutineCaller(other, predLabel); - } - - /**{@inheritDoc}*/ - @Override - protected OneLocalsArray getPrimary() { - return this; - } - - /** - * Throws a properly-formatted exception. - * - * @param idx the salient local index - * @param msg {@code non-null;} useful message - * @return never (keeps compiler happy) - */ - private static TypeBearer throwSimException(int idx, String msg) { - throw new SimException("local " + Hex.u2(idx) + ": " + msg); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/ReturnAddress.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/ReturnAddress.java deleted file mode 100644 index ee36450d1ce..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/ReturnAddress.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.code; - -import com.android.dx.rop.type.Type; -import com.android.dx.rop.type.TypeBearer; -import com.android.dx.util.Hex; - -/** - * Representation of a subroutine return address. In Java verification, - * somewhat counterintuitively, the salient bit of information you need to - * know about a return address is the start address of the subroutine - * being returned from, not the address being returned to, so that's - * what instances of this class hang onto. - */ -public final class ReturnAddress implements TypeBearer { - /** {@code >= 0;} the start address of the subroutine being returned from */ - private final int subroutineAddress; - - /** - * Constructs an instance. - * - * @param subroutineAddress {@code >= 0;} the start address of the - * subroutine being returned from - */ - public ReturnAddress(int subroutineAddress) { - if (subroutineAddress < 0) { - throw new IllegalArgumentException("subroutineAddress < 0"); - } - - this.subroutineAddress = subroutineAddress; - } - - /** {@inheritDoc} */ - @Override - public String toString() { - return (""); - } - - /** {@inheritDoc} */ - public String toHuman() { - return toString(); - } - - /** {@inheritDoc} */ - public Type getType() { - return Type.RETURN_ADDRESS; - } - - /** {@inheritDoc} */ - public TypeBearer getFrameType() { - return this; - } - - /** {@inheritDoc} */ - public int getBasicType() { - return Type.RETURN_ADDRESS.getBasicType(); - } - - /** {@inheritDoc} */ - public int getBasicFrameType() { - return Type.RETURN_ADDRESS.getBasicFrameType(); - } - - /** {@inheritDoc} */ - public boolean isConstant() { - return false; - } - - /** {@inheritDoc} */ - @Override - public boolean equals(Object other) { - if (!(other instanceof ReturnAddress)) { - return false; - } - - return subroutineAddress == ((ReturnAddress) other).subroutineAddress; - } - - /** {@inheritDoc} */ - @Override - public int hashCode() { - return subroutineAddress; - } - - /** - * Gets the subroutine address. - * - * @return {@code >= 0;} the subroutine address - */ - public int getSubroutineAddress() { - return subroutineAddress; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/Ropper.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/Ropper.java deleted file mode 100644 index c318b4c721f..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/Ropper.java +++ /dev/null @@ -1,1689 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.code; - -import com.android.dx.rop.code.AccessFlags; -import com.android.dx.rop.code.BasicBlock; -import com.android.dx.rop.code.BasicBlockList; -import com.android.dx.rop.code.Insn; -import com.android.dx.rop.code.InsnList; -import com.android.dx.rop.code.PlainCstInsn; -import com.android.dx.rop.code.PlainInsn; -import com.android.dx.rop.code.RegisterSpec; -import com.android.dx.rop.code.RegisterSpecList; -import com.android.dx.rop.code.Rop; -import com.android.dx.rop.code.RopMethod; -import com.android.dx.rop.code.Rops; -import com.android.dx.rop.code.SourcePosition; -import com.android.dx.rop.code.ThrowingCstInsn; -import com.android.dx.rop.code.ThrowingInsn; -import com.android.dx.rop.code.TranslationAdvice; -import com.android.dx.rop.cst.CstInteger; -import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.type.Prototype; -import com.android.dx.rop.type.StdTypeList; -import com.android.dx.rop.type.Type; -import com.android.dx.rop.type.TypeList; -import com.android.dx.util.Bits; -import com.android.dx.util.Hex; -import com.android.dx.util.IntList; -import java.util.ArrayList; -import java.util.BitSet; -import java.util.HashMap; - -/** - * Utility that converts a basic block list into a list of register-oriented - * blocks. - */ -public final class Ropper { - /** label offset for the parameter assignment block */ - private static final int PARAM_ASSIGNMENT = -1; - - /** label offset for the return block */ - private static final int RETURN = -2; - - /** label offset for the synchronized method final return block */ - private static final int SYNCH_RETURN = -3; - - /** label offset for the first synchronized method setup block */ - private static final int SYNCH_SETUP_1 = -4; - - /** label offset for the second synchronized method setup block */ - private static final int SYNCH_SETUP_2 = -5; - - /** - * label offset for the first synchronized method exception - * handler block - */ - private static final int SYNCH_CATCH_1 = -6; - - /** - * label offset for the second synchronized method exception - * handler block - */ - private static final int SYNCH_CATCH_2 = -7; - - /** number of special label offsets */ - private static final int SPECIAL_LABEL_COUNT = 7; - - /** {@code non-null;} method being converted */ - private final ConcreteMethod method; - - /** {@code non-null;} original block list */ - private final ByteBlockList blocks; - - /** max locals of the method */ - private final int maxLocals; - - /** max label (exclusive) of any original bytecode block */ - private final int maxLabel; - - /** {@code non-null;} simulation machine to use */ - private final RopperMachine machine; - - /** {@code non-null;} simulator to use */ - private final Simulator sim; - - /** - * {@code non-null;} sparse array mapping block labels to initial frame - * contents, if known - */ - private final Frame[] startFrames; - - /** {@code non-null;} output block list in-progress */ - private final ArrayList result; - - /** - * {@code non-null;} list of subroutine-nest labels - * (See {@link Frame#getSubroutines} associated with each result block. - * Parallel to {@link Ropper#result}. - */ - private final ArrayList resultSubroutines; - - /** - * {@code non-null;} for each block (by label) that is used as an exception - * handler, the type of exception it catches - */ - private final Type[] catchTypes; - - /** - * whether an exception-handler block for a synchronized method was - * ever required - */ - private boolean synchNeedsExceptionHandler; - - /** - * {@code non-null;} list of subroutines indexed by label of start - * address */ - private final Subroutine[] subroutines; - - /** true if {@code subroutines} is non-empty */ - private boolean hasSubroutines; - - /** - * Keeps track of subroutines that exist in java form and are inlined in - * Rop form. - */ - private class Subroutine { - /** list of all blocks that jsr to this subroutine */ - private BitSet callerBlocks; - /** List of all blocks that return from this subroutine */ - private BitSet retBlocks; - /** first block in this subroutine */ - private int startBlock; - - /** - * Constructs instance. - * - * @param startBlock First block of the subroutine. - */ - Subroutine(int startBlock) { - this.startBlock = startBlock; - retBlocks = new BitSet(maxLabel); - callerBlocks = new BitSet(maxLabel); - hasSubroutines = true; - } - - /** - * Constructs instance. - * - * @param startBlock First block of the subroutine. - * @param retBlock one of the ret blocks (final blocks) of this - * subroutine. - */ - Subroutine(int startBlock, int retBlock) { - this(startBlock); - addRetBlock(retBlock); - } - - /** - * @return {@code >= 0;} the label of the subroutine's start block. - */ - int getStartBlock() { - return startBlock; - } - - /** - * Adds a label to the list of ret blocks (final blocks) for this - * subroutine. - * - * @param retBlock ret block label - */ - void addRetBlock(int retBlock) { - retBlocks.set(retBlock); - } - - /** - * Adds a label to the list of caller blocks for this subroutine. - * - * @param label a block that invokes this subroutine. - */ - void addCallerBlock(int label) { - callerBlocks.set(label); - } - - /** - * Generates a list of subroutine successors. Note: successor blocks - * could be listed more than once. This is ok, because this successor - * list (and the block it's associated with) will be copied and inlined - * before we leave the ropper. Redundent successors will result in - * redundent (no-op) merges. - * - * @return all currently known successors - * (return destinations) for that subroutine - */ - IntList getSuccessors() { - IntList successors = new IntList(callerBlocks.size()); - - /* - * For each subroutine caller, get it's target. If the - * target is us, add the ret target (subroutine successor) - * to our list - */ - - for (int label = callerBlocks.nextSetBit(0); label >= 0; - label = callerBlocks.nextSetBit(label+1)) { - BasicBlock subCaller = labelToBlock(label); - successors.add(subCaller.getSuccessors().get(0)); - } - - successors.setImmutable(); - - return successors; - } - - /** - * Merges the specified frame into this subroutine's successors, - * setting {@code workSet} as appropriate. To be called with - * the frame of a subroutine ret block. - * - * @param frame {@code non-null;} frame from ret block to merge - * @param workSet {@code non-null;} workset to update - */ - void mergeToSuccessors(Frame frame, int[] workSet) { - for (int label = callerBlocks.nextSetBit(0); label >= 0; - label = callerBlocks.nextSetBit(label+1)) { - BasicBlock subCaller = labelToBlock(label); - int succLabel = subCaller.getSuccessors().get(0); - - Frame subFrame = frame.subFrameForLabel(startBlock, label); - - if (subFrame != null) { - mergeAndWorkAsNecessary(succLabel, -1, null, - subFrame, workSet); - } else { - Bits.set(workSet, label); - } - } - } - } - - /** - * Converts a {@link ConcreteMethod} to a {@link RopMethod}. - * - * @param method {@code non-null;} method to convert - * @param advice {@code non-null;} translation advice to use - * @return {@code non-null;} the converted instance - */ - public static RopMethod convert(ConcreteMethod method, - TranslationAdvice advice) { - try { - Ropper r = new Ropper(method, advice); - r.doit(); - return r.getRopMethod(); - } catch (SimException ex) { - ex.addContext("...while working on method " + - method.getNat().toHuman()); - throw ex; - } - } - - /** - * Constructs an instance. This class is not publicly instantiable; use - * {@link #convert}. - * - * @param method {@code non-null;} method to convert - * @param advice {@code non-null;} translation advice to use - */ - private Ropper(ConcreteMethod method, TranslationAdvice advice) { - if (method == null) { - throw new NullPointerException("method == null"); - } - - if (advice == null) { - throw new NullPointerException("advice == null"); - } - - this.method = method; - this.blocks = BasicBlocker.identifyBlocks(method); - this.maxLabel = blocks.getMaxLabel(); - this.maxLocals = method.getMaxLocals(); - this.machine = new RopperMachine(this, method, advice); - this.sim = new Simulator(machine, method); - this.startFrames = new Frame[maxLabel]; - this.subroutines = new Subroutine[maxLabel]; - - /* - * The "* 2 + 10" below is to conservatively believe that every - * block is an exception handler target and should also - * take care of enough other possible extra overhead such that - * the underlying array is unlikely to need resizing. - */ - this.result = new ArrayList(blocks.size() * 2 + 10); - this.resultSubroutines = - new ArrayList(blocks.size() * 2 + 10); - - this.catchTypes = new Type[maxLabel]; - this.synchNeedsExceptionHandler = false; - - /* - * Set up the first stack frame with the right limits, but leave it - * empty here (to be filled in outside of the constructor). - */ - startFrames[0] = new Frame(maxLocals, method.getMaxStack()); - } - - /** - * Gets the first (lowest) register number to use as the temporary - * area when unwinding stack manipulation ops. - * - * @return {@code >= 0;} the first register to use - */ - /*package*/ int getFirstTempStackReg() { - /* - * We use the register that is just past the deepest possible - * stack element, plus one if the method is synchronized to - * avoid overlapping with the synch register. We don't need to - * do anything else special at this level, since later passes - * will merely notice the highest register used by explicit - * inspection. - */ - int regCount = getNormalRegCount(); - return isSynchronized() ? regCount + 1 : regCount; - } - - /** - * Gets the label for the exception handler setup block corresponding - * to the given label. - * - * @param label {@code >= 0;} the original label - * @return {@code >= 0;} the corresponding exception handler setup label - */ - private int getExceptionSetupLabel(int label) { - return maxLabel + label; - } - - /** - * Gets the label for the given special-purpose block. The given label - * should be one of the static constants defined by this class. - * - * @param label {@code < 0;} the special label constant - * @return {@code >= 0;} the actual label value to use - */ - private int getSpecialLabel(int label) { - /* - * The label is bitwise-complemented so that mistakes where - * LABEL is used instead of getSpecialLabel(LABEL) cause a - * failure at block construction time, since negative labels - * are illegal. We multiply maxLabel by 2 since 0..maxLabel - * (exclusive) are the original blocks and - * maxLabel..(maxLabel*2) are reserved for exception handler - * setup blocks (see getExceptionSetupLabel(), above). - */ - return (maxLabel * 2) + ~label; - } - - /** - * Gets the minimum label for unreserved use. - * - * @return {@code >= 0;} the minimum label - */ - private int getMinimumUnreservedLabel() { - /* - * The labels below ((maxLabel * 2) + SPECIAL_LABEL_COUNT) are - * reserved for particular uses. - */ - - return (maxLabel * 2) + SPECIAL_LABEL_COUNT; - } - - /** - * Gets an arbitrary unreserved and available label. - * - * @return {@code >= 0;} the label - */ - private int getAvailableLabel() { - int candidate = getMinimumUnreservedLabel(); - - for (BasicBlock bb : result) { - int label = bb.getLabel(); - if (label >= candidate) { - candidate = label + 1; - } - } - - return candidate; - } - - /** - * Gets whether the method being translated is synchronized. - * - * @return whether the method being translated is synchronized - */ - private boolean isSynchronized() { - int accessFlags = method.getAccessFlags(); - return (accessFlags & AccessFlags.ACC_SYNCHRONIZED) != 0; - } - - /** - * Gets whether the method being translated is static. - * - * @return whether the method being translated is static - */ - private boolean isStatic() { - int accessFlags = method.getAccessFlags(); - return (accessFlags & AccessFlags.ACC_STATIC) != 0; - } - - /** - * Gets the total number of registers used for "normal" purposes (i.e., - * for the straightforward translation from the original Java). - * - * @return {@code >= 0;} the total number of registers used - */ - private int getNormalRegCount() { - return maxLocals + method.getMaxStack(); - } - - /** - * Gets the register spec to use to hold the object to synchronize on, - * for a synchronized method. - * - * @return {@code non-null;} the register spec - */ - private RegisterSpec getSynchReg() { - /* - * We use the register that is just past the deepest possible - * stack element, with a minimum of v1 since v0 is what's - * always used to hold the caught exception when unwinding. We - * don't need to do anything else special at this level, since - * later passes will merely notice the highest register used - * by explicit inspection. - */ - int reg = getNormalRegCount(); - return RegisterSpec.make((reg < 1) ? 1 : reg, Type.OBJECT); - } - - /** - * Searches {@link #result} for a block with the given label. Returns its - * index if found, or returns {@code -1} if there is no such block. - * - * @param label the label to look for - * @return {@code >= -1;} the index for the block with the given label or - * {@code -1} if there is no such block - */ - private int labelToResultIndex(int label) { - int sz = result.size(); - for (int i = 0; i < sz; i++) { - BasicBlock one = result.get(i); - if (one.getLabel() == label) { - return i; - } - } - - return -1; - } - - /** - * Searches {@link #result} for a block with the given label. Returns it if - * found, or throws an exception if there is no such block. - * - * @param label the label to look for - * @return {@code non-null;} the block with the given label - */ - private BasicBlock labelToBlock(int label) { - int idx = labelToResultIndex(label); - - if (idx < 0) { - throw new IllegalArgumentException("no such label " + - Hex.u2(label)); - } - - return result.get(idx); - } - - /** - * Adds a block to the output result. - * - * @param block {@code non-null;} the block to add - * @param subroutines {@code non-null;} subroutine label list - * as described in {@link Frame#getSubroutines} - */ - private void addBlock(BasicBlock block, IntList subroutines) { - if (block == null) { - throw new NullPointerException("block == null"); - } - - result.add(block); - subroutines.throwIfMutable(); - resultSubroutines.add(subroutines); - } - - /** - * Adds or replace a block in the output result. If this is a - * replacement, then any extra blocks that got added with the - * original get removed as a result of calling this method. - * - * @param block {@code non-null;} the block to add or replace - * @param subroutines {@code non-null;} subroutine label list - * as described in {@link Frame#getSubroutines} - * @return {@code true} if the block was replaced or - * {@code false} if it was added for the first time - */ - private boolean addOrReplaceBlock(BasicBlock block, IntList subroutines) { - if (block == null) { - throw new NullPointerException("block == null"); - } - - int idx = labelToResultIndex(block.getLabel()); - boolean ret; - - if (idx < 0) { - ret = false; - } else { - /* - * We are replacing a pre-existing block, so find any - * blocks that got added as part of the original and - * remove those too. Such blocks are (possibly indirect) - * successors of this block which are out of the range of - * normally-translated blocks. - */ - removeBlockAndSpecialSuccessors(idx); - ret = true; - } - - result.add(block); - subroutines.throwIfMutable(); - resultSubroutines.add(subroutines); - return ret; - } - - /** - * Adds or replaces a block in the output result. Do not delete - * any successors. - * - * @param block {@code non-null;} the block to add or replace - * @param subroutines {@code non-null;} subroutine label list - * as described in {@link Frame#getSubroutines} - * @return {@code true} if the block was replaced or - * {@code false} if it was added for the first time - */ - private boolean addOrReplaceBlockNoDelete(BasicBlock block, - IntList subroutines) { - if (block == null) { - throw new NullPointerException("block == null"); - } - - int idx = labelToResultIndex(block.getLabel()); - boolean ret; - - if (idx < 0) { - ret = false; - } else { - result.remove(idx); - resultSubroutines.remove(idx); - ret = true; - } - - result.add(block); - subroutines.throwIfMutable(); - resultSubroutines.add(subroutines); - return ret; - } - - /** - * Helper for {@link #addOrReplaceBlock} which recursively removes - * the given block and all blocks that are (direct and indirect) - * successors of it whose labels indicate that they are not in the - * normally-translated range. - * - * @param idx {@code non-null;} block to remove (etc.) - */ - private void removeBlockAndSpecialSuccessors(int idx) { - int minLabel = getMinimumUnreservedLabel(); - BasicBlock block = result.get(idx); - IntList successors = block.getSuccessors(); - int sz = successors.size(); - - result.remove(idx); - resultSubroutines.remove(idx); - - for (int i = 0; i < sz; i++) { - int label = successors.get(i); - if (label >= minLabel) { - idx = labelToResultIndex(label); - if (idx < 0) { - throw new RuntimeException("Invalid label " - + Hex.u2(label)); - } - removeBlockAndSpecialSuccessors(idx); - } - } - } - - /** - * Extracts the resulting {@link RopMethod} from the instance. - * - * @return {@code non-null;} the method object - */ - private RopMethod getRopMethod() { - - // Construct the final list of blocks. - - int sz = result.size(); - BasicBlockList bbl = new BasicBlockList(sz); - for (int i = 0; i < sz; i++) { - bbl.set(i, result.get(i)); - } - bbl.setImmutable(); - - // Construct the method object to wrap it all up. - - /* - * Note: The parameter assignment block is always the first - * that should be executed, hence the second argument to the - * constructor. - */ - return new RopMethod(bbl, getSpecialLabel(PARAM_ASSIGNMENT)); - } - - /** - * Does the conversion. - */ - private void doit() { - int[] workSet = Bits.makeBitSet(maxLabel); - - Bits.set(workSet, 0); - addSetupBlocks(); - setFirstFrame(); - - for (;;) { - int offset = Bits.findFirst(workSet, 0); - if (offset < 0) { - break; - } - Bits.clear(workSet, offset); - ByteBlock block = blocks.labelToBlock(offset); - Frame frame = startFrames[offset]; - try { - processBlock(block, frame, workSet); - } catch (SimException ex) { - ex.addContext("...while working on block " + Hex.u2(offset)); - throw ex; - } - } - - addReturnBlock(); - addSynchExceptionHandlerBlock(); - addExceptionSetupBlocks(); - - if (hasSubroutines) { - // Subroutines are very rare, so skip this step if it's n/a - inlineSubroutines(); - } - } - - /** - * Sets up the first frame to contain all the incoming parameters in - * locals. - */ - private void setFirstFrame() { - Prototype desc = method.getEffectiveDescriptor(); - startFrames[0].initializeWithParameters(desc.getParameterTypes()); - startFrames[0].setImmutable(); - } - - /** - * Processes the given block. - * - * @param block {@code non-null;} block to process - * @param frame {@code non-null;} start frame for the block - * @param workSet {@code non-null;} bits representing work to do, - * which this method may add to - */ - private void processBlock(ByteBlock block, Frame frame, int[] workSet) { - // Prepare the list of caught exceptions for this block. - ByteCatchList catches = block.getCatches(); - machine.startBlock(catches.toRopCatchList()); - - /* - * Using a copy of the given frame, simulate each instruction, - * calling into machine for each. - */ - frame = frame.copy(); - sim.simulate(block, frame); - frame.setImmutable(); - - int extraBlockCount = machine.getExtraBlockCount(); - ArrayList insns = machine.getInsns(); - int insnSz = insns.size(); - - /* - * Merge the frame into each possible non-exceptional - * successor. - */ - - int catchSz = catches.size(); - IntList successors = block.getSuccessors(); - - int startSuccessorIndex; - - Subroutine calledSubroutine = null; - if (machine.hasJsr()) { - /* - * If this frame ends in a JSR, only merge our frame with - * the subroutine start, not the subroutine's return target. - */ - startSuccessorIndex = 1; - - int subroutineLabel = successors.get(1); - - if (subroutines[subroutineLabel] == null) { - subroutines[subroutineLabel] = - new Subroutine (subroutineLabel); - } - - subroutines[subroutineLabel].addCallerBlock(block.getLabel()); - - calledSubroutine = subroutines[subroutineLabel]; - } else if (machine.hasRet()) { - /* - * This block ends in a ret, which means it's the final block - * in some subroutine. Ultimately, this block will be copied - * and inlined for each call and then disposed of. - */ - - ReturnAddress ra = machine.getReturnAddress(); - int subroutineLabel = ra.getSubroutineAddress(); - - if (subroutines[subroutineLabel] == null) { - subroutines[subroutineLabel] - = new Subroutine (subroutineLabel, block.getLabel()); - } else { - subroutines[subroutineLabel].addRetBlock(block.getLabel()); - } - - successors = subroutines[subroutineLabel].getSuccessors(); - subroutines[subroutineLabel] - .mergeToSuccessors(frame, workSet); - // Skip processing below since we just did it. - startSuccessorIndex = successors.size(); - } else if (machine.wereCatchesUsed()) { - /* - * If there are catches, then the first successors - * (which will either be all of them or all but the last one) - * are catch targets. - */ - startSuccessorIndex = catchSz; - } else { - startSuccessorIndex = 0; - } - - int succSz = successors.size(); - for (int i = startSuccessorIndex; i < succSz; - i++) { - int succ = successors.get(i); - try { - mergeAndWorkAsNecessary(succ, block.getLabel(), - calledSubroutine, frame, workSet); - } catch (SimException ex) { - ex.addContext("...while merging to block " + Hex.u2(succ)); - throw ex; - } - } - - if ((succSz == 0) && machine.returns()) { - /* - * The block originally contained a return, but it has - * been made to instead end with a goto, and we need to - * tell it at this point that its sole successor is the - * return block. This has to happen after the merge loop - * above, since, at this point, the return block doesn't - * actually exist; it gets synthesized at the end of - * processing the original blocks. - */ - successors = IntList.makeImmutable(getSpecialLabel(RETURN)); - succSz = 1; - } - - int primarySucc; - - if (succSz == 0) { - primarySucc = -1; - } else { - primarySucc = machine.getPrimarySuccessorIndex(); - if (primarySucc >= 0) { - primarySucc = successors.get(primarySucc); - } - } - - /* - * This variable is true only when the method is synchronized and - * the block being processed can possibly throw an exception. - */ - boolean synch = isSynchronized() && machine.canThrow(); - - if (synch || (catchSz != 0)) { - /* - * Deal with exception handlers: Merge an exception-catch - * frame into each possible exception handler, and - * construct a new set of successors to point at the - * exception handler setup blocks (which get synthesized - * at the very end of processing). - */ - boolean catchesAny = false; - IntList newSucc = new IntList(succSz); - for (int i = 0; i < catchSz; i++) { - ByteCatchList.Item one = catches.get(i); - CstType exceptionClass = one.getExceptionClass(); - int targ = one.getHandlerPc(); - - catchesAny |= (exceptionClass == CstType.OBJECT); - - Frame f = frame.makeExceptionHandlerStartFrame(exceptionClass); - - try { - mergeAndWorkAsNecessary(targ, block.getLabel(), - null, f, workSet); - } catch (SimException ex) { - ex.addContext("...while merging exception to block " + - Hex.u2(targ)); - throw ex; - } - - /* - * Set up the exception handler type, by setting it if - * the given handler has yet to be encountered, or by - * conservatively unioning if it has. - */ - Type already = catchTypes[targ]; - if (already == null) { - catchTypes[targ] = exceptionClass.getClassType(); - } else if (already != exceptionClass.getClassType()) { - catchTypes[targ] = Type.OBJECT; - } - - /* - * The synthesized exception setup block will have the - * label getExceptionSetupLabel(targ). - */ - newSucc.add(getExceptionSetupLabel(targ)); - } - - if (synch && !catchesAny) { - /* - * The method is synchronized and this block doesn't - * already have a catch-all handler, so add one to the - * end, both in the successors and in the throwing - * instruction(s) at the end of the block (which is where - * the caught classes live). - */ - newSucc.add(getSpecialLabel(SYNCH_CATCH_1)); - synchNeedsExceptionHandler = true; - - for (int i = insnSz - extraBlockCount - 1; i < insnSz; i++) { - Insn insn = insns.get(i); - if (insn.canThrow()) { - insn = insn.withAddedCatch(Type.OBJECT); - insns.set(i, insn); - } - } - } - - if (primarySucc >= 0) { - newSucc.add(primarySucc); - } - - newSucc.setImmutable(); - successors = newSucc; - } - - // Construct the final resulting block(s), and store it (them). - - int primarySuccListIndex = successors.indexOf(primarySucc); - - /* - * If there are any extra blocks, work backwards through the - * list of instructions, adding single-instruction blocks, and - * resetting the successors variables as appropriate. - */ - for (/*extraBlockCount*/; extraBlockCount > 0; extraBlockCount--) { - /* - * Some of the blocks that the RopperMachine wants added - * are for move-result insns, and these need goto insns as well. - */ - Insn extraInsn = insns.get(--insnSz); - boolean needsGoto - = extraInsn.getOpcode().getBranchingness() - == Rop.BRANCH_NONE; - InsnList il = new InsnList(needsGoto ? 2 : 1); - IntList extraBlockSuccessors = successors; - - il.set(0, extraInsn); - - if (needsGoto) { - il.set(1, new PlainInsn(Rops.GOTO, - extraInsn.getPosition(), null, - RegisterSpecList.EMPTY)); - /* - * Obviously, this block won't be throwing an exception - * so it should only have one successor. - */ - extraBlockSuccessors = IntList.makeImmutable(primarySucc); - } - il.setImmutable(); - - int label = getAvailableLabel(); - BasicBlock bb = new BasicBlock(label, il, extraBlockSuccessors, - primarySucc); - // All of these extra blocks will be in the same subroutine - addBlock(bb, frame.getSubroutines()); - - successors = successors.mutableCopy(); - successors.set(primarySuccListIndex, label); - successors.setImmutable(); - primarySucc = label; - } - - Insn lastInsn = (insnSz == 0) ? null : insns.get(insnSz - 1); - - /* - * Add a goto to the end of the block if it doesn't already - * end with a branch, to maintain the invariant that all - * blocks end with a branch of some sort or other. Note that - * it is possible for there to be blocks for which no - * instructions were ever output (e.g., only consist of pop* - * in the original Java bytecode). - */ - if ((lastInsn == null) || - (lastInsn.getOpcode().getBranchingness() == Rop.BRANCH_NONE)) { - SourcePosition pos = (lastInsn == null) ? SourcePosition.NO_INFO : - lastInsn.getPosition(); - insns.add(new PlainInsn(Rops.GOTO, pos, null, - RegisterSpecList.EMPTY)); - insnSz++; - } - - /* - * Construct a block for the remaining instructions (which in - * the usual case is all of them). - */ - - InsnList il = new InsnList(insnSz); - for (int i = 0; i < insnSz; i++) { - il.set(i, insns.get(i)); - } - il.setImmutable(); - - BasicBlock bb = - new BasicBlock(block.getLabel(), il, successors, primarySucc); - addOrReplaceBlock(bb, frame.getSubroutines()); - } - - /** - * Helper for {@link #processBlock}, which merges frames and - * adds to the work set, as necessary. - * - * @param label {@code >= 0;} label to work on - * @param pred predecessor label; must be {@code >= 0} when - * {@code label} is a subroutine start block and calledSubroutine - * is non-null. Otherwise, may be -1. - * @param calledSubroutine {@code null-ok;} a Subroutine instance if - * {@code label} is the first block in a subroutine. - * @param frame {@code non-null;} new frame for the labelled block - * @param workSet {@code non-null;} bits representing work to do, - * which this method may add to - */ - private void mergeAndWorkAsNecessary(int label, int pred, - Subroutine calledSubroutine, Frame frame, int[] workSet) { - Frame existing = startFrames[label]; - Frame merged; - - if (existing != null) { - /* - * Some other block also continues at this label. Merge - * the frames, and re-set the bit in the work set if there - * was a change. - */ - if (calledSubroutine != null) { - merged = existing.mergeWithSubroutineCaller(frame, - calledSubroutine.getStartBlock(), pred); - } else { - merged = existing.mergeWith(frame); - } - if (merged != existing) { - startFrames[label] = merged; - Bits.set(workSet, label); - } - } else { - // This is the first time this label has been encountered. - if (calledSubroutine != null) { - startFrames[label] - = frame.makeNewSubroutineStartFrame(label, pred); - } else { - startFrames[label] = frame; - } - Bits.set(workSet, label); - } - } - - /** - * Constructs and adds the blocks that perform setup for the rest of - * the method. This includes a first block which merely contains - * assignments from parameters to the same-numbered registers and - * a possible second block which deals with synchronization. - */ - private void addSetupBlocks() { - LocalVariableList localVariables = method.getLocalVariables(); - SourcePosition pos = method.makeSourcePosistion(0); - Prototype desc = method.getEffectiveDescriptor(); - StdTypeList params = desc.getParameterTypes(); - int sz = params.size(); - InsnList insns = new InsnList(sz + 1); - int at = 0; - - for (int i = 0; i < sz; i++) { - Type one = params.get(i); - LocalVariableList.Item local = - localVariables.pcAndIndexToLocal(0, at); - RegisterSpec result = (local == null) ? - RegisterSpec.make(at, one) : - RegisterSpec.makeLocalOptional(at, one, local.getLocalItem()); - - Insn insn = new PlainCstInsn(Rops.opMoveParam(one), pos, result, - RegisterSpecList.EMPTY, - CstInteger.make(at)); - insns.set(i, insn); - at += one.getCategory(); - } - - insns.set(sz, new PlainInsn(Rops.GOTO, pos, null, - RegisterSpecList.EMPTY)); - insns.setImmutable(); - - boolean synch = isSynchronized(); - int label = synch ? getSpecialLabel(SYNCH_SETUP_1) : 0; - BasicBlock bb = - new BasicBlock(getSpecialLabel(PARAM_ASSIGNMENT), insns, - IntList.makeImmutable(label), label); - addBlock(bb, IntList.EMPTY); - - if (synch) { - RegisterSpec synchReg = getSynchReg(); - Insn insn; - if (isStatic()) { - insn = new ThrowingCstInsn(Rops.CONST_OBJECT, pos, - RegisterSpecList.EMPTY, - StdTypeList.EMPTY, - method.getDefiningClass()); - insns = new InsnList(1); - insns.set(0, insn); - } else { - insns = new InsnList(2); - insn = new PlainCstInsn(Rops.MOVE_PARAM_OBJECT, pos, - synchReg, RegisterSpecList.EMPTY, - CstInteger.VALUE_0); - insns.set(0, insn); - insns.set(1, new PlainInsn(Rops.GOTO, pos, null, - RegisterSpecList.EMPTY)); - } - - int label2 = getSpecialLabel(SYNCH_SETUP_2); - insns.setImmutable(); - bb = new BasicBlock(label, insns, - IntList.makeImmutable(label2), label2); - addBlock(bb, IntList.EMPTY); - - insns = new InsnList(isStatic() ? 2 : 1); - - if (isStatic()) { - insns.set(0, new PlainInsn(Rops.opMoveResultPseudo(synchReg), - pos, synchReg, RegisterSpecList.EMPTY)); - } - - insn = new ThrowingInsn(Rops.MONITOR_ENTER, pos, - RegisterSpecList.make(synchReg), - StdTypeList.EMPTY); - insns.set(isStatic() ? 1 :0, insn); - insns.setImmutable(); - bb = new BasicBlock(label2, insns, IntList.makeImmutable(0), 0); - addBlock(bb, IntList.EMPTY); - } - } - - /** - * Constructs and adds the return block, if necessary. The return - * block merely contains an appropriate {@code return} - * instruction. - */ - private void addReturnBlock() { - Rop returnOp = machine.getReturnOp(); - - if (returnOp == null) { - /* - * The method being converted never returns normally, so there's - * no need for a return block. - */ - return; - } - - SourcePosition returnPos = machine.getReturnPosition(); - int label = getSpecialLabel(RETURN); - - if (isSynchronized()) { - InsnList insns = new InsnList(1); - Insn insn = new ThrowingInsn(Rops.MONITOR_EXIT, returnPos, - RegisterSpecList.make(getSynchReg()), - StdTypeList.EMPTY); - insns.set(0, insn); - insns.setImmutable(); - - int nextLabel = getSpecialLabel(SYNCH_RETURN); - BasicBlock bb = - new BasicBlock(label, insns, - IntList.makeImmutable(nextLabel), nextLabel); - addBlock(bb, IntList.EMPTY); - - label = nextLabel; - } - - InsnList insns = new InsnList(1); - TypeList sourceTypes = returnOp.getSources(); - RegisterSpecList sources; - - if (sourceTypes.size() == 0) { - sources = RegisterSpecList.EMPTY; - } else { - RegisterSpec source = RegisterSpec.make(0, sourceTypes.getType(0)); - sources = RegisterSpecList.make(source); - } - - Insn insn = new PlainInsn(returnOp, returnPos, null, sources); - insns.set(0, insn); - insns.setImmutable(); - - BasicBlock bb = new BasicBlock(label, insns, IntList.EMPTY, -1); - addBlock(bb, IntList.EMPTY); - } - - /** - * Constructs and adds, if necessary, the catch-all exception handler - * block to deal with unwinding the lock taken on entry to a synchronized - * method. - */ - private void addSynchExceptionHandlerBlock() { - if (!synchNeedsExceptionHandler) { - /* - * The method being converted either isn't synchronized or - * can't possibly throw exceptions in its main body, so - * there's no need for a synchronized method exception - * handler. - */ - return; - } - - SourcePosition pos = method.makeSourcePosistion(0); - RegisterSpec exReg = RegisterSpec.make(0, Type.THROWABLE); - BasicBlock bb; - Insn insn; - - InsnList insns = new InsnList(2); - insn = new PlainInsn(Rops.opMoveException(Type.THROWABLE), pos, - exReg, RegisterSpecList.EMPTY); - insns.set(0, insn); - insn = new ThrowingInsn(Rops.MONITOR_EXIT, pos, - RegisterSpecList.make(getSynchReg()), - StdTypeList.EMPTY); - insns.set(1, insn); - insns.setImmutable(); - - int label2 = getSpecialLabel(SYNCH_CATCH_2); - bb = new BasicBlock(getSpecialLabel(SYNCH_CATCH_1), insns, - IntList.makeImmutable(label2), label2); - addBlock(bb, IntList.EMPTY); - - insns = new InsnList(1); - insn = new ThrowingInsn(Rops.THROW, pos, - RegisterSpecList.make(exReg), - StdTypeList.EMPTY); - insns.set(0, insn); - insns.setImmutable(); - - bb = new BasicBlock(label2, insns, IntList.EMPTY, -1); - addBlock(bb, IntList.EMPTY); - } - - /** - * Creates the exception handler setup blocks. "maxLocals" - * below is because that's the register number corresponding - * to the sole element on a one-deep stack (which is the - * situation at the start of an exception handler block). - */ - private void addExceptionSetupBlocks() { - - int len = catchTypes.length; - for (int i = 0; i < len; i++) { - Type one = catchTypes[i]; - if (one != null) { - Insn proto = labelToBlock(i).getFirstInsn(); - SourcePosition pos = proto.getPosition(); - InsnList il = new InsnList(2); - - Insn insn = new PlainInsn(Rops.opMoveException(one), - pos, - RegisterSpec.make(maxLocals, one), - RegisterSpecList.EMPTY); - il.set(0, insn); - - insn = new PlainInsn(Rops.GOTO, pos, null, - RegisterSpecList.EMPTY); - il.set(1, insn); - il.setImmutable(); - - BasicBlock bb = new BasicBlock(getExceptionSetupLabel(i), - il, - IntList.makeImmutable(i), - i); - addBlock(bb, startFrames[i].getSubroutines()); - } - } - } - - /** - * Checks to see if the basic block is a subroutine caller block. - * - * @param bb {@code non-null;} the basic block in question - * @return true if this block calls a subroutine - */ - private boolean isSubroutineCaller(BasicBlock bb) { - IntList successors = bb.getSuccessors(); - if (successors.size() < 2) return false; - - int subLabel = successors.get(1); - - return (subLabel < subroutines.length) - && (subroutines[subLabel] != null); - } - - /** - * Inlines any subroutine calls. - */ - private void inlineSubroutines() { - final IntList reachableSubroutineCallerLabels = new IntList(4); - - /* - * Compile a list of all subroutine calls reachable - * through the normal (non-subroutine) flow. We do this first, since - * we'll be affecting the call flow as we go. - * - * Start at label 0 -- the param assignment block has nothing for us - */ - forEachNonSubBlockDepthFirst(0, new BasicBlock.Visitor() { - public void visitBlock(BasicBlock b) { - if (isSubroutineCaller(b)) { - reachableSubroutineCallerLabels.add(b.getLabel()); - } - } - }); - - /* - * Convert the resultSubroutines list, indexed by block index, - * to a label-to-subroutines mapping used by the inliner. - */ - int largestAllocedLabel = getAvailableLabel(); - ArrayList labelToSubroutines - = new ArrayList(largestAllocedLabel); - for (int i = 0; i < largestAllocedLabel; i++) { - labelToSubroutines.add(null); - } - - for (int i = 0; i < result.size(); i++) { - BasicBlock b = result.get(i); - if (b == null) { - continue; - } - IntList subroutineList = resultSubroutines.get(i); - labelToSubroutines.set(b.getLabel(), subroutineList); - } - - /* - * Inline all reachable subroutines. - * Inner subroutines will be inlined as they are encountered. - */ - int sz = reachableSubroutineCallerLabels.size(); - for (int i = 0 ; i < sz ; i++) { - int label = reachableSubroutineCallerLabels.get(i); - new SubroutineInliner( - new LabelAllocator(getAvailableLabel()), - labelToSubroutines) - .inlineSubroutineCalledFrom(labelToBlock(label)); - } - - // Now find the blocks that aren't reachable and remove them - deleteUnreachableBlocks(); - } - - /** - * Deletes all blocks that cannot be reached. This is run to delete - * original subroutine blocks after subroutine inlining. - */ - private void deleteUnreachableBlocks() { - final IntList reachableLabels = new IntList(result.size()); - - // subroutine inlining is done now and we won't update this list here - resultSubroutines.clear(); - - forEachNonSubBlockDepthFirst(getSpecialLabel(PARAM_ASSIGNMENT), - new BasicBlock.Visitor() { - - public void visitBlock(BasicBlock b) { - reachableLabels.add(b.getLabel()); - } - }); - - reachableLabels.sort(); - - for (int i = result.size() - 1 ; i >= 0 ; i--) { - if (reachableLabels.indexOf(result.get(i).getLabel()) < 0) { - result.remove(i); - // unnecessary here really, since subroutine inlining is done - //resultSubroutines.remove(i); - } - } - } - - /** - * Allocates labels, without requiring previously allocated labels - * to have been added to the blocks list. - */ - private static class LabelAllocator { - int nextAvailableLabel; - - /** - * @param startLabel available label to start allocating from - */ - LabelAllocator(int startLabel) { - nextAvailableLabel = startLabel; - } - - /** - * @return next available label - */ - int getNextLabel() { - return nextAvailableLabel++; - } - } - - /** - * Inlines a subroutine. Start by calling - * {@link #inlineSubroutineCalledFrom}. - */ - private class SubroutineInliner { - /** - * maps original label to the label that will be used by the - * inlined version - */ - private final HashMap origLabelToCopiedLabel; - - /** set of original labels that need to be copied */ - private final BitSet workList; - - /** the label of the original start block for this subroutine */ - private int subroutineStart; - - /** the label of the ultimate return block */ - private int subroutineSuccessor; - - /** used for generating new labels for copied blocks */ - private final LabelAllocator labelAllocator; - - /** - * A mapping, indexed by label, to subroutine nesting list. - * The subroutine nest list is as returned by - * {@link Frame#getSubroutines}. - */ - private final ArrayList labelToSubroutines; - - SubroutineInliner(final LabelAllocator labelAllocator, - ArrayList labelToSubroutines) { - origLabelToCopiedLabel = new HashMap(); - - workList = new BitSet(maxLabel); - - this.labelAllocator = labelAllocator; - this.labelToSubroutines = labelToSubroutines; - } - - /** - * Inlines a subroutine. - * - * @param b block where {@code jsr} occurred in the original bytecode - */ - void inlineSubroutineCalledFrom(final BasicBlock b) { - /* - * The 0th successor of a subroutine caller block is where - * the subroutine should return to. The 1st successor is - * the start block of the subroutine. - */ - subroutineSuccessor = b.getSuccessors().get(0); - subroutineStart = b.getSuccessors().get(1); - - /* - * This allocates an initial label and adds the first - * block to the worklist. - */ - int newSubStartLabel = mapOrAllocateLabel(subroutineStart); - - for (int label = workList.nextSetBit(0); label >= 0; - label = workList.nextSetBit(0)) { - workList.clear(label); - int newLabel = origLabelToCopiedLabel.get(label); - - copyBlock(label, newLabel); - - if (isSubroutineCaller(labelToBlock(label))) { - new SubroutineInliner(labelAllocator, labelToSubroutines) - .inlineSubroutineCalledFrom(labelToBlock(newLabel)); - } - } - - /* - * Replace the original caller block, since we now have a - * new successor - */ - - addOrReplaceBlockNoDelete( - new BasicBlock(b.getLabel(), b.getInsns(), - IntList.makeImmutable (newSubStartLabel), - newSubStartLabel), - labelToSubroutines.get(b.getLabel())); - } - - /** - * Copies a basic block, mapping its successors along the way. - * - * @param origLabel original block label - * @param newLabel label that the new block should have - */ - private void copyBlock(int origLabel, int newLabel) { - - BasicBlock origBlock = labelToBlock(origLabel); - - final IntList origSuccessors = origBlock.getSuccessors(); - IntList successors; - int primarySuccessor = -1; - Subroutine subroutine; - - if (isSubroutineCaller(origBlock)) { - /* - * A subroutine call inside a subroutine call. - * Set up so we can recurse. The caller block should have - * it's first successor be a copied block that will be - * the subroutine's return point. It's second successor will - * be copied when we recurse, and remains as the original - * label of the start of the inner subroutine. - */ - - successors = IntList.makeImmutable( - mapOrAllocateLabel(origSuccessors.get(0)), - origSuccessors.get(1)); - // primary successor will be set when this block is replaced - } else if (null - != (subroutine = subroutineFromRetBlock(origLabel))) { - /* - * this is a ret block -- its successor - * should be subroutineSuccessor - */ - - // Sanity check - if (subroutine.startBlock != subroutineStart) { - throw new RuntimeException ( - "ret instruction returns to label " - + Hex.u2 (subroutine.startBlock) - + " expected: " + Hex.u2(subroutineStart)); - } - - successors = IntList.makeImmutable(subroutineSuccessor); - primarySuccessor = subroutineSuccessor; - } else { - // Map all the successor labels - - int origPrimary = origBlock.getPrimarySuccessor(); - int sz = origSuccessors.size(); - - successors = new IntList(sz); - - for (int i = 0 ; i < sz ; i++) { - int origSuccLabel = origSuccessors.get(i); - int newSuccLabel = mapOrAllocateLabel(origSuccLabel); - - successors.add(newSuccLabel); - - if (origPrimary == origSuccLabel) { - primarySuccessor = newSuccLabel; - } - } - - successors.setImmutable(); - } - - addBlock ( - new BasicBlock(newLabel, - filterMoveReturnAddressInsns(origBlock.getInsns()), - successors, primarySuccessor), - labelToSubroutines.get(newLabel)); - } - - /** - * Checks to see if a specified label is involved in a specified - * subroutine. - * - * @param label {@code >= 0;} a basic block label - * @param subroutineStart {@code >= 0;} a subroutine as identified - * by the label of its start block - * @return true if the block is dominated by the subroutine call - */ - private boolean involvedInSubroutine(int label, int subroutineStart) { - IntList subroutinesList = labelToSubroutines.get(label); - return (subroutinesList != null && subroutinesList.size() > 0 - && subroutinesList.top() == subroutineStart); - } - - /** - * Maps the label of a pre-copied block to the label of the inlined - * block, allocating a new label and adding it to the worklist - * if necessary. If the origLabel is a "special" label, it - * is returned exactly and not scheduled for duplication: copying - * never proceeds past a special label, which likely is the function - * return block or an immediate predecessor. - * - * @param origLabel label of original, pre-copied block - * @return label for new, inlined block - */ - private int mapOrAllocateLabel(int origLabel) { - int resultLabel; - Integer mappedLabel = origLabelToCopiedLabel.get(origLabel); - - if (mappedLabel != null) { - resultLabel = mappedLabel; - } else if (!involvedInSubroutine(origLabel,subroutineStart)) { - /* - * A subroutine has ended by some means other than a "ret" - * (which really means a throw caught later). - */ - resultLabel = origLabel; - } else { - resultLabel = labelAllocator.getNextLabel(); - workList.set(origLabel); - origLabelToCopiedLabel.put(origLabel, resultLabel); - - // The new label has the same frame as the original label - while (labelToSubroutines.size() <= resultLabel) { - labelToSubroutines.add(null); - } - labelToSubroutines.set(resultLabel, - labelToSubroutines.get(origLabel)); - } - - return resultLabel; - } - } - - /** - * Finds a {@code Subroutine} that is returned from by a {@code ret} in - * a given block. - * - * @param label A block that originally contained a {@code ret} instruction - * @return {@code null-ok;} found subroutine or {@code null} if none - * was found - */ - private Subroutine subroutineFromRetBlock(int label) { - for (int i = subroutines.length - 1 ; i >= 0 ; i--) { - if (subroutines[i] != null) { - Subroutine subroutine = subroutines[i]; - - if (subroutine.retBlocks.get(label)) { - return subroutine; - } - } - } - - return null; - } - - - /** - * Removes all {@code move-return-address} instructions, returning a new - * {@code InsnList} if necessary. The {@code move-return-address} - * insns are dead code after subroutines have been inlined. - * - * @param insns {@code InsnList} that may contain - * {@code move-return-address} insns - * @return {@code InsnList} with {@code move-return-address} removed - */ - private InsnList filterMoveReturnAddressInsns(InsnList insns) { - int sz; - int newSz = 0; - - // First see if we need to filter, and if so what the new size will be - sz = insns.size(); - for (int i = 0; i < sz; i++) { - if (insns.get(i).getOpcode() != Rops.MOVE_RETURN_ADDRESS) { - newSz++; - } - } - - if (newSz == sz) { - return insns; - } - - // Make a new list without the MOVE_RETURN_ADDRESS insns - InsnList newInsns = new InsnList(newSz); - - int newIndex = 0; - for (int i = 0; i < sz; i++) { - Insn insn = insns.get(i); - if (insn.getOpcode() != Rops.MOVE_RETURN_ADDRESS) { - newInsns.set(newIndex++, insn); - } - } - - newInsns.setImmutable(); - return newInsns; - } - - /** - * Visits each non-subroutine block once in depth-first successor order. - * - * @param firstLabel label of start block - * @param v callback interface - */ - private void forEachNonSubBlockDepthFirst(int firstLabel, - BasicBlock.Visitor v) { - forEachNonSubBlockDepthFirst0(labelToBlock(firstLabel), - v, new BitSet(maxLabel)); - } - - /** - * Visits each block once in depth-first successor order, ignoring - * {@code jsr} targets. Worker for {@link #forEachNonSubBlockDepthFirst}. - * - * @param next next block to visit - * @param v callback interface - * @param visited set of blocks already visited - */ - private void forEachNonSubBlockDepthFirst0( - BasicBlock next, BasicBlock.Visitor v, BitSet visited) { - v.visitBlock(next); - visited.set(next.getLabel()); - - IntList successors = next.getSuccessors(); - int sz = successors.size(); - - for (int i = 0; i < sz; i++) { - int succ = successors.get(i); - - if (visited.get(succ)) { - continue; - } - - if (isSubroutineCaller(next) && i > 0) { - // ignore jsr targets - continue; - } - - /* - * Ignore missing labels: they're successors of - * subroutines that never invoke a ret. - */ - int idx = labelToResultIndex(succ); - if (idx >= 0) { - forEachNonSubBlockDepthFirst0(result.get(idx), v, visited); - } - } - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/RopperMachine.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/RopperMachine.java deleted file mode 100644 index f1b8db41250..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/RopperMachine.java +++ /dev/null @@ -1,962 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.code; - -import com.android.dx.rop.code.FillArrayDataInsn; -import com.android.dx.rop.code.Insn; -import com.android.dx.rop.code.PlainCstInsn; -import com.android.dx.rop.code.PlainInsn; -import com.android.dx.rop.code.RegOps; -import com.android.dx.rop.code.RegisterSpec; -import com.android.dx.rop.code.RegisterSpecList; -import com.android.dx.rop.code.Rop; -import com.android.dx.rop.code.Rops; -import com.android.dx.rop.code.SourcePosition; -import com.android.dx.rop.code.SwitchInsn; -import com.android.dx.rop.code.ThrowingCstInsn; -import com.android.dx.rop.code.ThrowingInsn; -import com.android.dx.rop.code.TranslationAdvice; -import com.android.dx.rop.cst.Constant; -import com.android.dx.rop.cst.CstFieldRef; -import com.android.dx.rop.cst.CstInteger; -import com.android.dx.rop.cst.CstMethodRef; -import com.android.dx.rop.cst.CstNat; -import com.android.dx.rop.cst.CstString; -import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.type.Type; -import com.android.dx.rop.type.TypeBearer; -import com.android.dx.rop.type.TypeList; -import com.android.dx.util.IntList; -import java.util.ArrayList; - -/** - * Machine implementation for use by {@link Ropper}. - */ -/*package*/ final class RopperMachine extends ValueAwareMachine { - /** {@code non-null;} array reflection class */ - private static final CstType ARRAY_REFLECT_TYPE = - new CstType(Type.internClassName("java/lang/reflect/Array")); - - /** - * {@code non-null;} method constant for use in converting - * {@code multianewarray} instructions - */ - private static final CstMethodRef MULTIANEWARRAY_METHOD = - new CstMethodRef(ARRAY_REFLECT_TYPE, - new CstNat(new CstString("newInstance"), - new CstString("(Ljava/lang/Class;[I)" + - "Ljava/lang/Object;"))); - - /** {@code non-null;} {@link Ropper} controlling this instance */ - private final Ropper ropper; - - /** {@code non-null;} method being converted */ - private final ConcreteMethod method; - - /** {@code non-null;} translation advice */ - private final TranslationAdvice advice; - - /** max locals of the method */ - private final int maxLocals; - - /** {@code non-null;} instructions for the rop basic block in-progress */ - private final ArrayList insns; - - /** {@code non-null;} catches for the block currently being processed */ - private TypeList catches; - - /** whether the catches have been used in an instruction */ - private boolean catchesUsed; - - /** whether the block contains a {@code return} */ - private boolean returns; - - /** primary successor index */ - private int primarySuccessorIndex; - - /** {@code >= 0;} number of extra basic blocks required */ - private int extraBlockCount; - - /** true if last processed block ends with a jsr or jsr_W*/ - private boolean hasJsr; - - /** true if an exception can be thrown by the last block processed */ - private boolean blockCanThrow; - - /** - * If non-null, the ReturnAddress that was used by the terminating ret - * instruction. If null, there was no ret instruction encountered. - */ - - private ReturnAddress returnAddress; - - /** - * {@code null-ok;} the appropriate {@code return} op or {@code null} - * if it is not yet known - */ - private Rop returnOp; - - /** - * {@code null-ok;} the source position for the return block or {@code null} - * if it is not yet known - */ - private SourcePosition returnPosition; - - /** - * Constructs an instance. - * - * @param ropper {@code non-null;} ropper controlling this instance - * @param method {@code non-null;} method being converted - * @param advice {@code non-null;} translation advice to use - */ - public RopperMachine(Ropper ropper, ConcreteMethod method, - TranslationAdvice advice) { - super(method.getEffectiveDescriptor()); - - if (ropper == null) { - throw new NullPointerException("ropper == null"); - } - - if (advice == null) { - throw new NullPointerException("advice == null"); - } - - this.ropper = ropper; - this.method = method; - this.advice = advice; - this.maxLocals = method.getMaxLocals(); - this.insns = new ArrayList(25); - this.catches = null; - this.catchesUsed = false; - this.returns = false; - this.primarySuccessorIndex = -1; - this.extraBlockCount = 0; - this.blockCanThrow = false; - this.returnOp = null; - this.returnPosition = null; - } - - /** - * Gets the instructions array. It is shared and gets modified by - * subsequent calls to this instance. - * - * @return {@code non-null;} the instructions array - */ - public ArrayList getInsns() { - return insns; - } - - /** - * Gets the return opcode encountered, if any. - * - * @return {@code null-ok;} the return opcode - */ - public Rop getReturnOp() { - return returnOp; - } - - /** - * Gets the return position, if known. - * - * @return {@code null-ok;} the return position - */ - public SourcePosition getReturnPosition() { - return returnPosition; - } - - /** - * Gets ready to start working on a new block. This will clear the - * {@link #insns} list, set {@link #catches}, reset whether it has - * been used, reset whether the block contains a - * {@code return}, and reset {@link #primarySuccessorIndex}. - */ - public void startBlock(TypeList catches) { - this.catches = catches; - - insns.clear(); - catchesUsed = false; - returns = false; - primarySuccessorIndex = 0; - extraBlockCount = 0; - blockCanThrow = false; - hasJsr = false; - returnAddress = null; - } - - /** - * Gets whether {@link #catches} was used. This indicates that the - * last instruction in the block is one of the ones that can throw. - * - * @return whether {@code catches} has been used - */ - public boolean wereCatchesUsed() { - return catchesUsed; - } - - /** - * Gets whether the block just processed ended with a - * {@code return}. - * - * @return whether the block returns - */ - public boolean returns() { - return returns; - } - - /** - * Gets the primary successor index. This is the index into the - * successors list where the primary may be found or - * {@code -1} if there are successors but no primary - * successor. This may return something other than - * {@code -1} in the case of an instruction with no - * successors at all (primary or otherwise). - * - * @return {@code >= -1;} the primary successor index - */ - public int getPrimarySuccessorIndex() { - return primarySuccessorIndex; - } - - /** - * Gets how many extra blocks will be needed to represent the - * block currently being translated. Each extra block should consist - * of one instruction from the end of the original block. - * - * @return {@code >= 0;} the number of extra blocks needed - */ - public int getExtraBlockCount() { - return extraBlockCount; - } - - /** - * @return true if at least one of the insn processed since the last - * call to startBlock() can throw. - */ - public boolean canThrow() { - return blockCanThrow; - } - - /** - * @return true if a JSR has ben encountered since the last call to - * startBlock() - */ - public boolean hasJsr() { - return hasJsr; - } - - /** - * @return {@code true} if a {@code ret} has ben encountered since - * the last call to {@code startBlock()} - */ - public boolean hasRet() { - return returnAddress != null; - } - - /** - * @return {@code null-ok;} return address of a {@code ret} - * instruction if encountered since last call to startBlock(). - * {@code null} if no ret instruction encountered. - */ - public ReturnAddress getReturnAddress() { - return returnAddress; - } - - /** {@inheritDoc} */ - @Override - public void run(Frame frame, int offset, int opcode) { - /* - * This is the stack pointer after the opcode's arguments have been - * popped. - */ - int stackPointer = maxLocals + frame.getStack().size(); - - // The sources have to be retrieved before super.run() gets called. - RegisterSpecList sources = getSources(opcode, stackPointer); - int sourceCount = sources.size(); - - super.run(frame, offset, opcode); - - SourcePosition pos = method.makeSourcePosistion(offset); - RegisterSpec localTarget = getLocalTarget(opcode == ByteOps.ISTORE); - int destCount = resultCount(); - RegisterSpec dest; - - if (destCount == 0) { - dest = null; - switch (opcode) { - case ByteOps.POP: - case ByteOps.POP2: { - // These simply don't appear in the rop form. - return; - } - } - } else if (localTarget != null) { - dest = localTarget; - } else if (destCount == 1) { - dest = RegisterSpec.make(stackPointer, result(0)); - } else { - /* - * This clause only ever applies to the stack manipulation - * ops that have results (that is, dup* and swap but not - * pop*). - * - * What we do is first move all the source registers into - * the "temporary stack" area defined for the method, and - * then move stuff back down onto the main "stack" in the - * arrangement specified by the stack op pattern. - * - * Note: This code ends up emitting a lot of what will - * turn out to be superfluous moves (e.g., moving back and - * forth to the same local when doing a dup); however, - * that makes this code a bit easier (and goodness knows - * it doesn't need any extra complexity), and all the SSA - * stuff is going to want to deal with this sort of - * superfluous assignment anyway, so it should be a wash - * in the end. - */ - int scratchAt = ropper.getFirstTempStackReg(); - RegisterSpec[] scratchRegs = new RegisterSpec[sourceCount]; - - for (int i = 0; i < sourceCount; i++) { - RegisterSpec src = sources.get(i); - TypeBearer type = src.getTypeBearer(); - RegisterSpec scratch = src.withReg(scratchAt); - insns.add(new PlainInsn(Rops.opMove(type), pos, scratch, src)); - scratchRegs[i] = scratch; - scratchAt += src.getCategory(); - } - - for (int pattern = getAuxInt(); pattern != 0; pattern >>= 4) { - int which = (pattern & 0x0f) - 1; - RegisterSpec scratch = scratchRegs[which]; - TypeBearer type = scratch.getTypeBearer(); - insns.add(new PlainInsn(Rops.opMove(type), pos, - scratch.withReg(stackPointer), - scratch)); - stackPointer += type.getType().getCategory(); - } - return; - } - - TypeBearer destType = (dest != null) ? dest : Type.VOID; - Constant cst = getAuxCst(); - int ropOpcode; - Rop rop; - Insn insn; - - if (opcode == ByteOps.MULTIANEWARRAY) { - blockCanThrow = true; - - // Add the extra instructions for handling multianewarray. - - extraBlockCount = 6; - - /* - * Add an array constructor for the int[] containing all the - * dimensions. - */ - RegisterSpec dimsReg = - RegisterSpec.make(dest.getNextReg(), Type.INT_ARRAY); - rop = Rops.opFilledNewArray(Type.INT_ARRAY, sourceCount); - insn = new ThrowingCstInsn(rop, pos, sources, catches, - CstType.INT_ARRAY); - insns.add(insn); - - // Add a move-result for the new-filled-array - rop = Rops.opMoveResult(Type.INT_ARRAY); - insn = new PlainInsn(rop, pos, dimsReg, RegisterSpecList.EMPTY); - insns.add(insn); - - /* - * Add a const-class instruction for the specified array - * class. - */ - - /* - * Remove as many dimensions from the originally specified - * class as are given in the explicit list of dimensions, - * so as to pass the right component class to the standard - * Java library array constructor. - */ - Type componentType = ((CstType) cst).getClassType(); - for (int i = 0; i < sourceCount; i++) { - componentType = componentType.getComponentType(); - } - - RegisterSpec classReg = - RegisterSpec.make(dest.getReg(), Type.CLASS); - - if (componentType.isPrimitive()) { - /* - * The component type is primitive (e.g., int as opposed - * to Integer), so we have to fetch the corresponding - * TYPE class. - */ - CstFieldRef typeField = - CstFieldRef.forPrimitiveType(componentType); - insn = new ThrowingCstInsn(Rops.GET_STATIC_OBJECT, pos, - RegisterSpecList.EMPTY, - catches, typeField); - } else { - /* - * The component type is an object type, so just make a - * normal class reference. - */ - insn = new ThrowingCstInsn(Rops.CONST_OBJECT, pos, - RegisterSpecList.EMPTY, catches, - new CstType(componentType)); - } - - insns.add(insn); - - // Add a move-result-pseudo for the get-static or const - rop = Rops.opMoveResultPseudo(classReg.getType()); - insn = new PlainInsn(rop, pos, classReg, RegisterSpecList.EMPTY); - insns.add(insn); - - /* - * Add a call to the "multianewarray method," that is, - * Array.newInstance(class, dims). Note: The result type - * of newInstance() is Object, which is why the last - * instruction in this sequence is a cast to the right - * type for the original instruction. - */ - - RegisterSpec objectReg = - RegisterSpec.make(dest.getReg(), Type.OBJECT); - - insn = new ThrowingCstInsn( - Rops.opInvokeStatic(MULTIANEWARRAY_METHOD.getPrototype()), - pos, RegisterSpecList.make(classReg, dimsReg), - catches, MULTIANEWARRAY_METHOD); - insns.add(insn); - - // Add a move-result. - rop = Rops.opMoveResult(MULTIANEWARRAY_METHOD.getPrototype() - .getReturnType()); - insn = new PlainInsn(rop, pos, objectReg, RegisterSpecList.EMPTY); - insns.add(insn); - - /* - * And finally, set up for the remainder of this method to - * add an appropriate cast. - */ - - opcode = ByteOps.CHECKCAST; - sources = RegisterSpecList.make(objectReg); - } else if (opcode == ByteOps.JSR) { - // JSR has no Rop instruction - hasJsr = true; - return; - } else if (opcode == ByteOps.RET) { - try { - returnAddress = (ReturnAddress)arg(0); - } catch (ClassCastException ex) { - throw new RuntimeException( - "Argument to RET was not a ReturnAddress", ex); - } - // RET has no Rop instruction. - return; - } - - ropOpcode = jopToRopOpcode(opcode, cst); - rop = Rops.ropFor(ropOpcode, destType, sources, cst); - - Insn moveResult = null; - if (dest != null && rop.isCallLike()) { - /* - * We're going to want to have a move-result in the next - * basic block. - */ - extraBlockCount++; - - moveResult = new PlainInsn( - Rops.opMoveResult(((CstMethodRef) cst).getPrototype() - .getReturnType()), pos, dest, RegisterSpecList.EMPTY); - - dest = null; - } else if (dest != null && rop.canThrow()) { - /* - * We're going to want to have a move-result-pseudo in the - * next basic block. - */ - extraBlockCount++; - - moveResult = new PlainInsn( - Rops.opMoveResultPseudo(dest.getTypeBearer()), - pos, dest, RegisterSpecList.EMPTY); - - dest = null; - } - if (ropOpcode == RegOps.NEW_ARRAY) { - /* - * In the original bytecode, this was either a primitive - * array constructor "newarray" or an object array - * constructor "anewarray". In the former case, there is - * no explicit constant, and in the latter, the constant - * is for the element type and not the array type. The rop - * instruction form for both of these is supposed to be - * the resulting array type, so we initialize / alter - * "cst" here, accordingly. Conveniently enough, the rop - * opcode already gets constructed with the proper array - * type. - */ - cst = CstType.intern(rop.getResult()); - } else if ((cst == null) && (sourceCount == 2)) { - TypeBearer firstType = sources.get(0).getTypeBearer(); - TypeBearer lastType = sources.get(1).getTypeBearer(); - - if ((lastType.isConstant() || firstType.isConstant()) && - advice.hasConstantOperation(rop, sources.get(0), - sources.get(1))) { - - if (lastType.isConstant()) { - /* - * The target architecture has an instruction that can - * build in the constant found in the second argument, - * so pull it out of the sources and just use it as a - * constant here. - */ - cst = (Constant) lastType; - sources = sources.withoutLast(); - - // For subtraction, change to addition and invert constant - if (rop.getOpcode() == RegOps.SUB) { - ropOpcode = RegOps.ADD; - CstInteger cstInt = (CstInteger) lastType; - cst = CstInteger.make(-cstInt.getValue()); - } - } else { - /* - * The target architecture has an instruction that can - * build in the constant found in the first argument, - * so pull it out of the sources and just use it as a - * constant here. - */ - cst = (Constant) firstType; - sources = sources.withoutFirst(); - } - - rop = Rops.ropFor(ropOpcode, destType, sources, cst); - } - } - - SwitchList cases = getAuxCases(); - ArrayList initValues = getInitValues(); - boolean canThrow = rop.canThrow(); - - blockCanThrow |= canThrow; - - if (cases != null) { - if (cases.size() == 0) { - // It's a default-only switch statement. It can happen! - insn = new PlainInsn(Rops.GOTO, pos, null, - RegisterSpecList.EMPTY); - primarySuccessorIndex = 0; - } else { - IntList values = cases.getValues(); - insn = new SwitchInsn(rop, pos, dest, sources, values); - primarySuccessorIndex = values.size(); - } - } else if (ropOpcode == RegOps.RETURN) { - /* - * Returns get turned into the combination of a move (if - * non-void and if the return doesn't already mention - * register 0) and a goto (to the return block). - */ - if (sources.size() != 0) { - RegisterSpec source = sources.get(0); - TypeBearer type = source.getTypeBearer(); - if (source.getReg() != 0) { - insns.add(new PlainInsn(Rops.opMove(type), pos, - RegisterSpec.make(0, type), - source)); - } - } - insn = new PlainInsn(Rops.GOTO, pos, null, RegisterSpecList.EMPTY); - primarySuccessorIndex = 0; - updateReturnOp(rop, pos); - returns = true; - } else if (cst != null) { - if (canThrow) { - insn = - new ThrowingCstInsn(rop, pos, sources, catches, cst); - catchesUsed = true; - primarySuccessorIndex = catches.size(); - } else { - insn = new PlainCstInsn(rop, pos, dest, sources, cst); - } - } else if (canThrow) { - insn = new ThrowingInsn(rop, pos, sources, catches); - catchesUsed = true; - if (opcode == ByteOps.ATHROW) { - /* - * The op athrow is the only one where it's possible - * to have non-empty successors and yet not have a - * primary successor. - */ - primarySuccessorIndex = -1; - } else { - primarySuccessorIndex = catches.size(); - } - } else { - insn = new PlainInsn(rop, pos, dest, sources); - } - - insns.add(insn); - - if (moveResult != null) { - insns.add(moveResult); - } - - /* - * If initValues is non-null, it means that the parser has - * seen a group of compatible constant initialization - * bytecodes that are applied to the current newarray. The - * action we take here is to convert these initialization - * bytecodes into a single fill-array-data ROP which lays out - * all the constant values in a table. - */ - if (initValues != null) { - extraBlockCount++; - insn = new FillArrayDataInsn(Rops.FILL_ARRAY_DATA, pos, - RegisterSpecList.make(moveResult.getResult()), initValues, - cst); - insns.add(insn); - } - } - - /** - * Helper for {@link #run}, which gets the list of sources for the. - * instruction. - * - * @param opcode the opcode being translated - * @param stackPointer {@code >= 0;} the stack pointer after the - * instruction's arguments have been popped - * @return {@code non-null;} the sources - */ - private RegisterSpecList getSources(int opcode, int stackPointer) { - int count = argCount(); - - if (count == 0) { - // We get an easy out if there aren't any sources. - return RegisterSpecList.EMPTY; - } - - int localIndex = getLocalIndex(); - RegisterSpecList sources; - - if (localIndex >= 0) { - // The instruction is operating on a local variable. - sources = new RegisterSpecList(1); - sources.set(0, RegisterSpec.make(localIndex, arg(0))); - } else { - sources = new RegisterSpecList(count); - int regAt = stackPointer; - for (int i = 0; i < count; i++) { - RegisterSpec spec = RegisterSpec.make(regAt, arg(i)); - sources.set(i, spec); - regAt += spec.getCategory(); - } - - switch (opcode) { - case ByteOps.IASTORE: { - /* - * The Java argument order for array stores is - * (array, index, value), but the rop argument - * order is (value, array, index). The following - * code gets the right arguments in the right - * places. - */ - if (count != 3) { - throw new RuntimeException("shouldn't happen"); - } - RegisterSpec array = sources.get(0); - RegisterSpec index = sources.get(1); - RegisterSpec value = sources.get(2); - sources.set(0, value); - sources.set(1, array); - sources.set(2, index); - break; - } - case ByteOps.PUTFIELD: { - /* - * Similar to above: The Java argument order for - * putfield is (object, value), but the rop - * argument order is (value, object). - */ - if (count != 2) { - throw new RuntimeException("shouldn't happen"); - } - RegisterSpec obj = sources.get(0); - RegisterSpec value = sources.get(1); - sources.set(0, value); - sources.set(1, obj); - break; - } - } - } - - sources.setImmutable(); - return sources; - } - - /** - * Sets or updates the information about the return block. - * - * @param op {@code non-null;} the opcode to use - * @param pos {@code non-null;} the position to use - */ - private void updateReturnOp(Rop op, SourcePosition pos) { - if (op == null) { - throw new NullPointerException("op == null"); - } - - if (pos == null) { - throw new NullPointerException("pos == null"); - } - - if (returnOp == null) { - returnOp = op; - returnPosition = pos; - } else { - if (returnOp != op) { - throw new SimException("return op mismatch: " + op + ", " + - returnOp); - } - - if (pos.getLine() > returnPosition.getLine()) { - // Pick the largest line number to be the "canonical" return. - returnPosition = pos; - } - } - } - - /** - * Gets the register opcode for the given Java opcode. - * - * @param jop {@code >= 0;} the Java opcode - * @param cst {@code null-ok;} the constant argument, if any - * @return {@code >= 0;} the corresponding register opcode - */ - private int jopToRopOpcode(int jop, Constant cst) { - switch (jop) { - case ByteOps.POP: - case ByteOps.POP2: - case ByteOps.DUP: - case ByteOps.DUP_X1: - case ByteOps.DUP_X2: - case ByteOps.DUP2: - case ByteOps.DUP2_X1: - case ByteOps.DUP2_X2: - case ByteOps.SWAP: - case ByteOps.JSR: - case ByteOps.RET: - case ByteOps.MULTIANEWARRAY: { - // These need to be taken care of specially. - break; - } - case ByteOps.NOP: { - return RegOps.NOP; - } - case ByteOps.LDC: - case ByteOps.LDC2_W: { - return RegOps.CONST; - } - case ByteOps.ILOAD: - case ByteOps.ISTORE: { - return RegOps.MOVE; - } - case ByteOps.IALOAD: { - return RegOps.AGET; - } - case ByteOps.IASTORE: { - return RegOps.APUT; - } - case ByteOps.IADD: - case ByteOps.IINC: { - return RegOps.ADD; - } - case ByteOps.ISUB: { - return RegOps.SUB; - } - case ByteOps.IMUL: { - return RegOps.MUL; - } - case ByteOps.IDIV: { - return RegOps.DIV; - } - case ByteOps.IREM: { - return RegOps.REM; - } - case ByteOps.INEG: { - return RegOps.NEG; - } - case ByteOps.ISHL: { - return RegOps.SHL; - } - case ByteOps.ISHR: { - return RegOps.SHR; - } - case ByteOps.IUSHR: { - return RegOps.USHR; - } - case ByteOps.IAND: { - return RegOps.AND; - } - case ByteOps.IOR: { - return RegOps.OR; - } - case ByteOps.IXOR: { - return RegOps.XOR; - } - case ByteOps.I2L: - case ByteOps.I2F: - case ByteOps.I2D: - case ByteOps.L2I: - case ByteOps.L2F: - case ByteOps.L2D: - case ByteOps.F2I: - case ByteOps.F2L: - case ByteOps.F2D: - case ByteOps.D2I: - case ByteOps.D2L: - case ByteOps.D2F: { - return RegOps.CONV; - } - case ByteOps.I2B: { - return RegOps.TO_BYTE; - } - case ByteOps.I2C: { - return RegOps.TO_CHAR; - } - case ByteOps.I2S: { - return RegOps.TO_SHORT; - } - case ByteOps.LCMP: - case ByteOps.FCMPL: - case ByteOps.DCMPL: { - return RegOps.CMPL; - } - case ByteOps.FCMPG: - case ByteOps.DCMPG: { - return RegOps.CMPG; - } - case ByteOps.IFEQ: - case ByteOps.IF_ICMPEQ: - case ByteOps.IF_ACMPEQ: - case ByteOps.IFNULL: { - return RegOps.IF_EQ; - } - case ByteOps.IFNE: - case ByteOps.IF_ICMPNE: - case ByteOps.IF_ACMPNE: - case ByteOps.IFNONNULL: { - return RegOps.IF_NE; - } - case ByteOps.IFLT: - case ByteOps.IF_ICMPLT: { - return RegOps.IF_LT; - } - case ByteOps.IFGE: - case ByteOps.IF_ICMPGE: { - return RegOps.IF_GE; - } - case ByteOps.IFGT: - case ByteOps.IF_ICMPGT: { - return RegOps.IF_GT; - } - case ByteOps.IFLE: - case ByteOps.IF_ICMPLE: { - return RegOps.IF_LE; - } - case ByteOps.GOTO: { - return RegOps.GOTO; - } - case ByteOps.LOOKUPSWITCH: { - return RegOps.SWITCH; - } - case ByteOps.IRETURN: - case ByteOps.RETURN: { - return RegOps.RETURN; - } - case ByteOps.GETSTATIC: { - return RegOps.GET_STATIC; - } - case ByteOps.PUTSTATIC: { - return RegOps.PUT_STATIC; - } - case ByteOps.GETFIELD: { - return RegOps.GET_FIELD; - } - case ByteOps.PUTFIELD: { - return RegOps.PUT_FIELD; - } - case ByteOps.INVOKEVIRTUAL: { - return RegOps.INVOKE_VIRTUAL; - } - case ByteOps.INVOKESPECIAL: { - /* - * Determine whether the opcode should be - * INVOKE_DIRECT or INVOKE_SUPER. See vmspec-2 section 6 - * on "invokespecial" as well as section 4.8.2 (7th - * bullet point) for the gory details. - */ - CstMethodRef ref = (CstMethodRef) cst; - if (ref.isInstanceInit() || - (ref.getDefiningClass() == method.getDefiningClass()) || - !method.getAccSuper()) { - return RegOps.INVOKE_DIRECT; - } - return RegOps.INVOKE_SUPER; - } - case ByteOps.INVOKESTATIC: { - return RegOps.INVOKE_STATIC; - } - case ByteOps.INVOKEINTERFACE: { - return RegOps.INVOKE_INTERFACE; - } - case ByteOps.NEW: { - return RegOps.NEW_INSTANCE; - } - case ByteOps.NEWARRAY: - case ByteOps.ANEWARRAY: { - return RegOps.NEW_ARRAY; - } - case ByteOps.ARRAYLENGTH: { - return RegOps.ARRAY_LENGTH; - } - case ByteOps.ATHROW: { - return RegOps.THROW; - } - case ByteOps.CHECKCAST: { - return RegOps.CHECK_CAST; - } - case ByteOps.INSTANCEOF: { - return RegOps.INSTANCE_OF; - } - case ByteOps.MONITORENTER: { - return RegOps.MONITOR_ENTER; - } - case ByteOps.MONITOREXIT: { - return RegOps.MONITOR_EXIT; - } - } - - throw new RuntimeException("shouldn't happen"); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/SimException.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/SimException.java deleted file mode 100644 index 7cbab04c78a..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/SimException.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.code; - -import com.android.dex.util.ExceptionWithContext; - -/** - * Exception from simulation. - */ -public class SimException - extends ExceptionWithContext { - public SimException(String message) { - super(message); - } - - public SimException(Throwable cause) { - super(cause); - } - - public SimException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/Simulator.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/Simulator.java deleted file mode 100644 index 35e62281bb9..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/Simulator.java +++ /dev/null @@ -1,771 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.code; - -import com.android.dx.rop.code.LocalItem; -import com.android.dx.rop.cst.Constant; -import com.android.dx.rop.cst.CstFieldRef; -import com.android.dx.rop.cst.CstInteger; -import com.android.dx.rop.cst.CstInterfaceMethodRef; -import com.android.dx.rop.cst.CstMethodRef; -import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.type.Prototype; -import com.android.dx.rop.type.Type; -import com.android.dx.util.Hex; -import java.util.ArrayList; - -/** - * Class which knows how to simulate the effects of executing bytecode. - * - *

Note: This class is not thread-safe. If multiple threads - * need to use a single instance, they must synchronize access explicitly - * between themselves.

- */ -public class Simulator { - /** - * {@code non-null;} canned error message for local variable - * table mismatches - */ - private static final String LOCAL_MISMATCH_ERROR = - "This is symptomatic of .class transformation tools that ignore " + - "local variable information."; - - /** {@code non-null;} machine to use when simulating */ - private final Machine machine; - - /** {@code non-null;} array of bytecode */ - private final BytecodeArray code; - - /** {@code non-null;} local variable information */ - private final LocalVariableList localVariables; - - /** {@code non-null;} visitor instance to use */ - private final SimVisitor visitor; - - /** - * Constructs an instance. - * - * @param machine {@code non-null;} machine to use when simulating - * @param method {@code non-null;} method data to use - */ - public Simulator(Machine machine, ConcreteMethod method) { - if (machine == null) { - throw new NullPointerException("machine == null"); - } - - if (method == null) { - throw new NullPointerException("method == null"); - } - - this.machine = machine; - this.code = method.getCode(); - this.localVariables = method.getLocalVariables(); - this.visitor = new SimVisitor(); - } - - /** - * Simulates the effect of executing the given basic block. This modifies - * the passed-in frame to represent the end result. - * - * @param bb {@code non-null;} the basic block - * @param frame {@code non-null;} frame to operate on - */ - public void simulate(ByteBlock bb, Frame frame) { - int end = bb.getEnd(); - - visitor.setFrame(frame); - - try { - for (int off = bb.getStart(); off < end; /*off*/) { - int length = code.parseInstruction(off, visitor); - visitor.setPreviousOffset(off); - off += length; - } - } catch (SimException ex) { - frame.annotate(ex); - throw ex; - } - } - - /** - * Simulates the effect of the instruction at the given offset, by - * making appropriate calls on the given frame. - * - * @param offset {@code >= 0;} offset of the instruction to simulate - * @param frame {@code non-null;} frame to operate on - * @return the length of the instruction, in bytes - */ - public int simulate(int offset, Frame frame) { - visitor.setFrame(frame); - return code.parseInstruction(offset, visitor); - } - - /** - * Constructs an "illegal top-of-stack" exception, for the stack - * manipulation opcodes. - */ - private static SimException illegalTos() { - return new SimException("stack mismatch: illegal " + - "top-of-stack for opcode"); - } - - /** - * Returns the required array type for an array load or store - * instruction, based on a given implied type and an observed - * actual array type. - * - *

The interesting cases here have to do with object arrays, - * byte[]s, boolean[]s, and - * known-nulls.

- * - *

In the case of arrays of objects, we want to narrow the type - * to the actual array present on the stack, as long as what is - * present is an object type. Similarly, due to a quirk of the - * original bytecode representation, the instructions for dealing - * with byte[] and boolean[] are - * undifferentiated, and we aim here to return whichever one was - * actually present on the stack.

- * - *

In the case where there is a known-null on the stack where - * an array is expected, we just fall back to the implied type of - * the instruction. Due to the quirk described above, this means - * that source code that uses boolean[] might get - * translated surprisingly -- but correctly -- into an instruction - * that specifies a byte[]. It will be correct, - * because should the code actually execute, it will necessarily - * throw a NullPointerException, and it won't matter - * what opcode variant is used to achieve that result.

- * - * @param impliedType {@code non-null;} type implied by the - * instruction; is not an array type - * @param foundArrayType {@code non-null;} type found on the - * stack; is either an array type or a known-null - * @return {@code non-null;} the array type that should be - * required in this context - */ - private static Type requiredArrayTypeFor(Type impliedType, - Type foundArrayType) { - if (foundArrayType == Type.KNOWN_NULL) { - return impliedType.getArrayType(); - } - - if ((impliedType == Type.OBJECT) - && foundArrayType.isArray() - && foundArrayType.getComponentType().isReference()) { - return foundArrayType; - } - - if ((impliedType == Type.BYTE) - && (foundArrayType == Type.BOOLEAN_ARRAY)) { - /* - * Per above, an instruction with implied byte[] is also - * allowed to be used on boolean[]. - */ - return Type.BOOLEAN_ARRAY; - } - - return impliedType.getArrayType(); - } - - /** - * Bytecode visitor used during simulation. - */ - private class SimVisitor implements BytecodeArray.Visitor { - /** - * {@code non-null;} machine instance to use (just to avoid excessive - * cross-object field access) - */ - private final Machine machine; - - /** - * {@code null-ok;} frame to use; set with each call to - * {@link Simulator#simulate} - */ - private Frame frame; - - /** offset of the previous bytecode */ - private int previousOffset; - - /** - * Constructs an instance. - */ - public SimVisitor() { - this.machine = Simulator.this.machine; - this.frame = null; - } - - /** - * Sets the frame to act on. - * - * @param frame {@code non-null;} the frame - */ - public void setFrame(Frame frame) { - if (frame == null) { - throw new NullPointerException("frame == null"); - } - - this.frame = frame; - } - - /** {@inheritDoc} */ - public void visitInvalid(int opcode, int offset, int length) { - throw new SimException("invalid opcode " + Hex.u1(opcode)); - } - - /** {@inheritDoc} */ - public void visitNoArgs(int opcode, int offset, int length, - Type type) { - switch (opcode) { - case ByteOps.NOP: { - machine.clearArgs(); - break; - } - case ByteOps.INEG: { - machine.popArgs(frame, type); - break; - } - case ByteOps.I2L: - case ByteOps.I2F: - case ByteOps.I2D: - case ByteOps.I2B: - case ByteOps.I2C: - case ByteOps.I2S: { - machine.popArgs(frame, Type.INT); - break; - } - case ByteOps.L2I: - case ByteOps.L2F: - case ByteOps.L2D: { - machine.popArgs(frame, Type.LONG); - break; - } - case ByteOps.F2I: - case ByteOps.F2L: - case ByteOps.F2D: { - machine.popArgs(frame, Type.FLOAT); - break; - } - case ByteOps.D2I: - case ByteOps.D2L: - case ByteOps.D2F: { - machine.popArgs(frame, Type.DOUBLE); - break; - } - case ByteOps.RETURN: { - machine.clearArgs(); - checkReturnType(Type.VOID); - break; - } - case ByteOps.IRETURN: { - Type checkType = type; - if (type == Type.OBJECT) { - /* - * For an object return, use the best-known - * type of the popped value. - */ - checkType = frame.getStack().peekType(0); - } - machine.popArgs(frame, type); - checkReturnType(checkType); - break; - } - case ByteOps.POP: { - Type peekType = frame.getStack().peekType(0); - if (peekType.isCategory2()) { - throw illegalTos(); - } - machine.popArgs(frame, 1); - break; - } - case ByteOps.ARRAYLENGTH: { - Type arrayType = frame.getStack().peekType(0); - if (!arrayType.isArrayOrKnownNull()) { - throw new SimException("type mismatch: expected " + - "array type but encountered " + - arrayType.toHuman()); - } - machine.popArgs(frame, Type.OBJECT); - break; - } - case ByteOps.ATHROW: - case ByteOps.MONITORENTER: - case ByteOps.MONITOREXIT: { - machine.popArgs(frame, Type.OBJECT); - break; - } - case ByteOps.IALOAD: { - /* - * See comment on requiredArrayTypeFor() for explanation - * about what's going on here. - */ - Type foundArrayType = frame.getStack().peekType(1); - Type requiredArrayType = - requiredArrayTypeFor(type, foundArrayType); - - // Make type agree with the discovered requiredArrayType. - type = requiredArrayType.getComponentType(); - - machine.popArgs(frame, requiredArrayType, Type.INT); - break; - } - case ByteOps.IADD: - case ByteOps.ISUB: - case ByteOps.IMUL: - case ByteOps.IDIV: - case ByteOps.IREM: - case ByteOps.IAND: - case ByteOps.IOR: - case ByteOps.IXOR: { - machine.popArgs(frame, type, type); - break; - } - case ByteOps.ISHL: - case ByteOps.ISHR: - case ByteOps.IUSHR: { - machine.popArgs(frame, type, Type.INT); - break; - } - case ByteOps.LCMP: { - machine.popArgs(frame, Type.LONG, Type.LONG); - break; - } - case ByteOps.FCMPL: - case ByteOps.FCMPG: { - machine.popArgs(frame, Type.FLOAT, Type.FLOAT); - break; - } - case ByteOps.DCMPL: - case ByteOps.DCMPG: { - machine.popArgs(frame, Type.DOUBLE, Type.DOUBLE); - break; - } - case ByteOps.IASTORE: { - /* - * See comment on requiredArrayTypeFor() for - * explanation about what's going on here. In - * addition to that, the category 1 vs. 2 thing - * below is to deal with the fact that, if the - * element type is category 2, we have to skip - * over one extra stack slot to find the array. - */ - ExecutionStack stack = frame.getStack(); - int peekDepth = type.isCategory1() ? 2 : 3; - Type foundArrayType = stack.peekType(peekDepth); - boolean foundArrayLocal = stack.peekLocal(peekDepth); - - Type requiredArrayType = - requiredArrayTypeFor(type, foundArrayType); - - /* - * Make type agree with the discovered requiredArrayType - * if it has local info. - */ - if (foundArrayLocal) { - type = requiredArrayType.getComponentType(); - } - - machine.popArgs(frame, requiredArrayType, Type.INT, type); - break; - } - case ByteOps.POP2: - case ByteOps.DUP2: { - ExecutionStack stack = frame.getStack(); - int pattern; - - if (stack.peekType(0).isCategory2()) { - // "form 2" in vmspec-2 - machine.popArgs(frame, 1); - pattern = 0x11; - } else if (stack.peekType(1).isCategory1()) { - // "form 1" - machine.popArgs(frame, 2); - pattern = 0x2121; - } else { - throw illegalTos(); - } - - if (opcode == ByteOps.DUP2) { - machine.auxIntArg(pattern); - } - break; - } - case ByteOps.DUP: { - Type peekType = frame.getStack().peekType(0); - - if (peekType.isCategory2()) { - throw illegalTos(); - } - - machine.popArgs(frame, 1); - machine.auxIntArg(0x11); - break; - } - case ByteOps.DUP_X1: { - ExecutionStack stack = frame.getStack(); - - if (!(stack.peekType(0).isCategory1() && - stack.peekType(1).isCategory1())) { - throw illegalTos(); - } - - machine.popArgs(frame, 2); - machine.auxIntArg(0x212); - break; - } - case ByteOps.DUP_X2: { - ExecutionStack stack = frame.getStack(); - - if (stack.peekType(0).isCategory2()) { - throw illegalTos(); - } - - if (stack.peekType(1).isCategory2()) { - // "form 2" in vmspec-2 - machine.popArgs(frame, 2); - machine.auxIntArg(0x212); - } else if (stack.peekType(2).isCategory1()) { - // "form 1" - machine.popArgs(frame, 3); - machine.auxIntArg(0x3213); - } else { - throw illegalTos(); - } - break; - } - case ByteOps.DUP2_X1: { - ExecutionStack stack = frame.getStack(); - - if (stack.peekType(0).isCategory2()) { - // "form 2" in vmspec-2 - if (stack.peekType(2).isCategory2()) { - throw illegalTos(); - } - machine.popArgs(frame, 2); - machine.auxIntArg(0x212); - } else { - // "form 1" - if (stack.peekType(1).isCategory2() || - stack.peekType(2).isCategory2()) { - throw illegalTos(); - } - machine.popArgs(frame, 3); - machine.auxIntArg(0x32132); - } - break; - } - case ByteOps.DUP2_X2: { - ExecutionStack stack = frame.getStack(); - - if (stack.peekType(0).isCategory2()) { - if (stack.peekType(2).isCategory2()) { - // "form 4" in vmspec-2 - machine.popArgs(frame, 2); - machine.auxIntArg(0x212); - } else if (stack.peekType(3).isCategory1()) { - // "form 2" - machine.popArgs(frame, 3); - machine.auxIntArg(0x3213); - } else { - throw illegalTos(); - } - } else if (stack.peekType(1).isCategory1()) { - if (stack.peekType(2).isCategory2()) { - // "form 3" - machine.popArgs(frame, 3); - machine.auxIntArg(0x32132); - } else if (stack.peekType(3).isCategory1()) { - // "form 1" - machine.popArgs(frame, 4); - machine.auxIntArg(0x432143); - } else { - throw illegalTos(); - } - } else { - throw illegalTos(); - } - break; - } - case ByteOps.SWAP: { - ExecutionStack stack = frame.getStack(); - - if (!(stack.peekType(0).isCategory1() && - stack.peekType(1).isCategory1())) { - throw illegalTos(); - } - - machine.popArgs(frame, 2); - machine.auxIntArg(0x12); - break; - } - default: { - visitInvalid(opcode, offset, length); - return; - } - } - - machine.auxType(type); - machine.run(frame, offset, opcode); - } - - /** - * Checks whether the prototype is compatible with returning the - * given type, and throws if not. - * - * @param encountered {@code non-null;} the encountered return type - */ - private void checkReturnType(Type encountered) { - Type returnType = machine.getPrototype().getReturnType(); - - /* - * Check to see if the prototype's return type is - * possibly assignable from the type we encountered. This - * takes care of all the salient cases (types are the same, - * they're compatible primitive types, etc.). - */ - if (!Merger.isPossiblyAssignableFrom(returnType, encountered)) { - throw new SimException("return type mismatch: prototype " + - "indicates " + returnType.toHuman() + - ", but encountered type " + encountered.toHuman()); - } - } - - /** {@inheritDoc} */ - public void visitLocal(int opcode, int offset, int length, - int idx, Type type, int value) { - /* - * Note that the "type" parameter is always the simplest - * type based on the original opcode, e.g., "int" for - * "iload" (per se) and "Object" for "aload". So, when - * possible, we replace the type with the one indicated in - * the local variable table, though we still need to check - * to make sure it's valid for the opcode. - * - * The reason we use (offset + length) for the localOffset - * for a store is because it is only after the store that - * the local type becomes valid. On the other hand, the - * type associated with a load is valid at the start of - * the instruction. - */ - int localOffset = - (opcode == ByteOps.ISTORE) ? (offset + length) : offset; - LocalVariableList.Item local = - localVariables.pcAndIndexToLocal(localOffset, idx); - Type localType; - - if (local != null) { - localType = local.getType(); - if (localType.getBasicFrameType() != - type.getBasicFrameType()) { - BaseMachine.throwLocalMismatch(type, localType); - return; - } - } else { - localType = type; - } - - switch (opcode) { - case ByteOps.ILOAD: - case ByteOps.RET: { - machine.localArg(frame, idx); - machine.localInfo(local != null); - machine.auxType(type); - break; - } - case ByteOps.ISTORE: { - LocalItem item - = (local == null) ? null : local.getLocalItem(); - machine.popArgs(frame, type); - machine.auxType(type); - machine.localTarget(idx, localType, item); - break; - } - case ByteOps.IINC: { - LocalItem item - = (local == null) ? null : local.getLocalItem(); - machine.localArg(frame, idx); - machine.localTarget(idx, localType, item); - machine.auxType(type); - machine.auxIntArg(value); - machine.auxCstArg(CstInteger.make(value)); - break; - } - default: { - visitInvalid(opcode, offset, length); - return; - } - } - - machine.run(frame, offset, opcode); - } - - /** {@inheritDoc} */ - public void visitConstant(int opcode, int offset, int length, - Constant cst, int value) { - switch (opcode) { - case ByteOps.ANEWARRAY: { - machine.popArgs(frame, Type.INT); - break; - } - case ByteOps.PUTSTATIC: { - Type fieldType = ((CstFieldRef) cst).getType(); - machine.popArgs(frame, fieldType); - break; - } - case ByteOps.GETFIELD: - case ByteOps.CHECKCAST: - case ByteOps.INSTANCEOF: { - machine.popArgs(frame, Type.OBJECT); - break; - } - case ByteOps.PUTFIELD: { - Type fieldType = ((CstFieldRef) cst).getType(); - machine.popArgs(frame, Type.OBJECT, fieldType); - break; - } - case ByteOps.INVOKEINTERFACE: { - /* - * Convert the interface method ref into a normal - * method ref. - */ - cst = ((CstInterfaceMethodRef) cst).toMethodRef(); - // and fall through... - } - case ByteOps.INVOKEVIRTUAL: - case ByteOps.INVOKESPECIAL: { - /* - * Get the instance prototype, and use it to direct - * the machine. - */ - Prototype prototype = - ((CstMethodRef) cst).getPrototype(false); - machine.popArgs(frame, prototype); - break; - } - case ByteOps.INVOKESTATIC: { - /* - * Get the static prototype, and use it to direct - * the machine. - */ - Prototype prototype = - ((CstMethodRef) cst).getPrototype(true); - machine.popArgs(frame, prototype); - break; - } - case ByteOps.MULTIANEWARRAY: { - /* - * The "value" here is the count of dimensions to - * create. Make a prototype of that many "int" - * types, and tell the machine to pop them. This - * isn't the most efficient way in the world to do - * this, but then again, multianewarray is pretty - * darn rare and so not worth much effort - * optimizing for. - */ - Prototype prototype = - Prototype.internInts(Type.VOID, value); - machine.popArgs(frame, prototype); - break; - } - default: { - machine.clearArgs(); - break; - } - } - - machine.auxIntArg(value); - machine.auxCstArg(cst); - machine.run(frame, offset, opcode); - } - - /** {@inheritDoc} */ - public void visitBranch(int opcode, int offset, int length, - int target) { - switch (opcode) { - case ByteOps.IFEQ: - case ByteOps.IFNE: - case ByteOps.IFLT: - case ByteOps.IFGE: - case ByteOps.IFGT: - case ByteOps.IFLE: { - machine.popArgs(frame, Type.INT); - break; - } - case ByteOps.IFNULL: - case ByteOps.IFNONNULL: { - machine.popArgs(frame, Type.OBJECT); - break; - } - case ByteOps.IF_ICMPEQ: - case ByteOps.IF_ICMPNE: - case ByteOps.IF_ICMPLT: - case ByteOps.IF_ICMPGE: - case ByteOps.IF_ICMPGT: - case ByteOps.IF_ICMPLE: { - machine.popArgs(frame, Type.INT, Type.INT); - break; - } - case ByteOps.IF_ACMPEQ: - case ByteOps.IF_ACMPNE: { - machine.popArgs(frame, Type.OBJECT, Type.OBJECT); - break; - } - case ByteOps.GOTO: - case ByteOps.JSR: - case ByteOps.GOTO_W: - case ByteOps.JSR_W: { - machine.clearArgs(); - break; - } - default: { - visitInvalid(opcode, offset, length); - return; - } - } - - machine.auxTargetArg(target); - machine.run(frame, offset, opcode); - } - - /** {@inheritDoc} */ - public void visitSwitch(int opcode, int offset, int length, - SwitchList cases, int padding) { - machine.popArgs(frame, Type.INT); - machine.auxIntArg(padding); - machine.auxSwitchArg(cases); - machine.run(frame, offset, opcode); - } - - /** {@inheritDoc} */ - public void visitNewarray(int offset, int length, CstType type, - ArrayList initValues) { - machine.popArgs(frame, Type.INT); - machine.auxInitValues(initValues); - machine.auxCstArg(type); - machine.run(frame, offset, ByteOps.NEWARRAY); - } - - /** {@inheritDoc} */ - public void setPreviousOffset(int offset) { - previousOffset = offset; - } - - /** {@inheritDoc} */ - public int getPreviousOffset() { - return previousOffset; - } - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/SwitchList.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/SwitchList.java deleted file mode 100644 index 621d728f620..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/SwitchList.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.code; - -import com.android.dx.util.IntList; -import com.android.dx.util.MutabilityControl; - -/** - * List of (value, target) mappings representing the choices of a - * {@code tableswitch} or {@code lookupswitch} instruction. It - * also holds the default target for the switch. - */ -public final class SwitchList extends MutabilityControl { - /** {@code non-null;} list of test values */ - private final IntList values; - - /** - * {@code non-null;} list of targets corresponding to the test values; there - * is always one extra element in the target list, to hold the - * default target - */ - private final IntList targets; - - /** ultimate size of the list */ - private int size; - - /** - * Constructs an instance. - * - * @param size {@code >= 0;} the number of elements to be in the table - */ - public SwitchList(int size) { - super(true); - this.values = new IntList(size); - this.targets = new IntList(size + 1); - this.size = size; - } - - /** {@inheritDoc} */ - @Override - public void setImmutable() { - values.setImmutable(); - targets.setImmutable(); - super.setImmutable(); - } - - /** - * Gets the size of the list. - * - * @return {@code >= 0;} the list size - */ - public int size() { - return size; - } - - /** - * Gets the indicated test value. - * - * @param n {@code >= 0;}, < size(); which index - * @return the test value - */ - public int getValue(int n) { - return values.get(n); - } - - /** - * Gets the indicated target. Asking for the target at {@code size()} - * returns the default target. - * - * @param n {@code >= 0, <= size();} which index - * @return {@code >= 0;} the target - */ - public int getTarget(int n) { - return targets.get(n); - } - - /** - * Gets the default target. This is just a shorthand for - * {@code getTarget(size())}. - * - * @return {@code >= 0;} the default target - */ - public int getDefaultTarget() { - return targets.get(size); - } - - /** - * Gets the list of all targets. This includes one extra element at the - * end of the list, which holds the default target. - * - * @return {@code non-null;} the target list - */ - public IntList getTargets() { - return targets; - } - - /** - * Gets the list of all case values. - * - * @return {@code non-null;} the case value list - */ - public IntList getValues() { - return values; - } - - /** - * Sets the default target. It is only valid to call this method - * when all the non-default elements have been set. - * - * @param target {@code >= 0;} the absolute (not relative) default target - * address - */ - public void setDefaultTarget(int target) { - throwIfImmutable(); - - if (target < 0) { - throw new IllegalArgumentException("target < 0"); - } - - if (targets.size() != size) { - throw new RuntimeException("non-default elements not all set"); - } - - targets.add(target); - } - - /** - * Adds the given item. - * - * @param value the test value - * @param target {@code >= 0;} the absolute (not relative) target address - */ - public void add(int value, int target) { - throwIfImmutable(); - - if (target < 0) { - throw new IllegalArgumentException("target < 0"); - } - - values.add(value); - targets.add(target); - } - - /** - * Shrinks this instance if possible, removing test elements that - * refer to the default target. This is only valid after the instance - * is fully populated, including the default target (naturally). - */ - public void removeSuperfluousDefaults() { - throwIfImmutable(); - - int sz = size; - - if (sz != (targets.size() - 1)) { - throw new IllegalArgumentException("incomplete instance"); - } - - int defaultTarget = targets.get(sz); - int at = 0; - - for (int i = 0; i < sz; i++) { - int target = targets.get(i); - if (target != defaultTarget) { - if (i != at) { - targets.set(at, target); - values.set(at, values.get(i)); - } - at++; - } - } - - if (at != sz) { - values.shrink(at); - targets.set(at, defaultTarget); - targets.shrink(at + 1); - size = at; - } - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/ValueAwareMachine.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/ValueAwareMachine.java deleted file mode 100644 index de75db55b9d..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/ValueAwareMachine.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.code; - -import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.type.Prototype; -import com.android.dx.rop.type.Type; -import com.android.dx.rop.type.TypeBearer; -import com.android.dx.util.Hex; - -/** - * {@link Machine} which keeps track of known values but does not do - * smart/realistic reference type calculations. - */ -public class ValueAwareMachine extends BaseMachine { - /** - * Constructs an instance. - * - * @param prototype {@code non-null;} the prototype for the associated - * method - */ - public ValueAwareMachine(Prototype prototype) { - super(prototype); - } - - /** {@inheritDoc} */ - public void run(Frame frame, int offset, int opcode) { - switch (opcode) { - case ByteOps.NOP: - case ByteOps.IASTORE: - case ByteOps.POP: - case ByteOps.POP2: - case ByteOps.IFEQ: - case ByteOps.IFNE: - case ByteOps.IFLT: - case ByteOps.IFGE: - case ByteOps.IFGT: - case ByteOps.IFLE: - case ByteOps.IF_ICMPEQ: - case ByteOps.IF_ICMPNE: - case ByteOps.IF_ICMPLT: - case ByteOps.IF_ICMPGE: - case ByteOps.IF_ICMPGT: - case ByteOps.IF_ICMPLE: - case ByteOps.IF_ACMPEQ: - case ByteOps.IF_ACMPNE: - case ByteOps.GOTO: - case ByteOps.RET: - case ByteOps.LOOKUPSWITCH: - case ByteOps.IRETURN: - case ByteOps.RETURN: - case ByteOps.PUTSTATIC: - case ByteOps.PUTFIELD: - case ByteOps.ATHROW: - case ByteOps.MONITORENTER: - case ByteOps.MONITOREXIT: - case ByteOps.IFNULL: - case ByteOps.IFNONNULL: { - // Nothing to do for these ops in this class. - clearResult(); - break; - } - case ByteOps.LDC: - case ByteOps.LDC2_W: { - setResult((TypeBearer) getAuxCst()); - break; - } - case ByteOps.ILOAD: - case ByteOps.ISTORE: { - setResult(arg(0)); - break; - } - case ByteOps.IALOAD: - case ByteOps.IADD: - case ByteOps.ISUB: - case ByteOps.IMUL: - case ByteOps.IDIV: - case ByteOps.IREM: - case ByteOps.INEG: - case ByteOps.ISHL: - case ByteOps.ISHR: - case ByteOps.IUSHR: - case ByteOps.IAND: - case ByteOps.IOR: - case ByteOps.IXOR: - case ByteOps.IINC: - case ByteOps.I2L: - case ByteOps.I2F: - case ByteOps.I2D: - case ByteOps.L2I: - case ByteOps.L2F: - case ByteOps.L2D: - case ByteOps.F2I: - case ByteOps.F2L: - case ByteOps.F2D: - case ByteOps.D2I: - case ByteOps.D2L: - case ByteOps.D2F: - case ByteOps.I2B: - case ByteOps.I2C: - case ByteOps.I2S: - case ByteOps.LCMP: - case ByteOps.FCMPL: - case ByteOps.FCMPG: - case ByteOps.DCMPL: - case ByteOps.DCMPG: - case ByteOps.ARRAYLENGTH: { - setResult(getAuxType()); - break; - } - case ByteOps.DUP: - case ByteOps.DUP_X1: - case ByteOps.DUP_X2: - case ByteOps.DUP2: - case ByteOps.DUP2_X1: - case ByteOps.DUP2_X2: - case ByteOps.SWAP: { - clearResult(); - for (int pattern = getAuxInt(); pattern != 0; pattern >>= 4) { - int which = (pattern & 0x0f) - 1; - addResult(arg(which)); - } - break; - } - - case ByteOps.JSR: { - setResult(new ReturnAddress(getAuxTarget())); - break; - } - case ByteOps.GETSTATIC: - case ByteOps.GETFIELD: - case ByteOps.INVOKEVIRTUAL: - case ByteOps.INVOKESTATIC: - case ByteOps.INVOKEINTERFACE: { - Type type = ((TypeBearer) getAuxCst()).getType(); - if (type == Type.VOID) { - clearResult(); - } else { - setResult(type); - } - break; - } - case ByteOps.INVOKESPECIAL: { - Type thisType = arg(0).getType(); - if (thisType.isUninitialized()) { - frame.makeInitialized(thisType); - } - Type type = ((TypeBearer) getAuxCst()).getType(); - if (type == Type.VOID) { - clearResult(); - } else { - setResult(type); - } - break; - } - case ByteOps.NEW: { - Type type = ((CstType) getAuxCst()).getClassType(); - setResult(type.asUninitialized(offset)); - break; - } - case ByteOps.NEWARRAY: - case ByteOps.CHECKCAST: - case ByteOps.MULTIANEWARRAY: { - Type type = ((CstType) getAuxCst()).getClassType(); - setResult(type); - break; - } - case ByteOps.ANEWARRAY: { - Type type = ((CstType) getAuxCst()).getClassType(); - setResult(type.getArrayType()); - break; - } - case ByteOps.INSTANCEOF: { - setResult(Type.INT); - break; - } - default: { - throw new RuntimeException("shouldn't happen: " + - Hex.u1(opcode)); - } - } - - storeResults(frame); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/package.html b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/package.html deleted file mode 100644 index abd4e9bec06..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/code/package.html +++ /dev/null @@ -1,10 +0,0 @@ - -

Implementation of classes having to do with Java simulation, such as -is needed for verification or stack-to-register conversion.

- -

PACKAGES USED: -

    -
  • com.android.dx.rop.pool
  • -
  • com.android.dx.util
  • -
- diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/cst/ConstantPoolParser.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/cst/ConstantPoolParser.java deleted file mode 100644 index 036c8802a63..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/cst/ConstantPoolParser.java +++ /dev/null @@ -1,377 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.cst; - -import static com.android.dx.cf.cst.ConstantTags.CONSTANT_Class; -import static com.android.dx.cf.cst.ConstantTags.CONSTANT_Double; -import static com.android.dx.cf.cst.ConstantTags.CONSTANT_Fieldref; -import static com.android.dx.cf.cst.ConstantTags.CONSTANT_Float; -import static com.android.dx.cf.cst.ConstantTags.CONSTANT_Integer; -import static com.android.dx.cf.cst.ConstantTags.CONSTANT_InterfaceMethodref; -import static com.android.dx.cf.cst.ConstantTags.CONSTANT_Long; -import static com.android.dx.cf.cst.ConstantTags.CONSTANT_Methodref; -import static com.android.dx.cf.cst.ConstantTags.CONSTANT_NameAndType; -import static com.android.dx.cf.cst.ConstantTags.CONSTANT_String; -import static com.android.dx.cf.cst.ConstantTags.CONSTANT_Utf8; -import static com.android.dx.cf.cst.ConstantTags.CONSTANT_MethodHandle; -import static com.android.dx.cf.cst.ConstantTags.CONSTANT_MethodType; -import static com.android.dx.cf.cst.ConstantTags.CONSTANT_InvokeDynamic; -import com.android.dx.cf.iface.ParseException; -import com.android.dx.cf.iface.ParseObserver; -import com.android.dx.rop.cst.Constant; -import com.android.dx.rop.cst.CstDouble; -import com.android.dx.rop.cst.CstFieldRef; -import com.android.dx.rop.cst.CstFloat; -import com.android.dx.rop.cst.CstInteger; -import com.android.dx.rop.cst.CstInterfaceMethodRef; -import com.android.dx.rop.cst.CstLong; -import com.android.dx.rop.cst.CstMethodRef; -import com.android.dx.rop.cst.CstNat; -import com.android.dx.rop.cst.CstString; -import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.cst.StdConstantPool; -import com.android.dx.rop.type.Type; -import com.android.dx.util.ByteArray; -import com.android.dx.util.Hex; -import java.util.BitSet; - -/** - * Parser for a constant pool embedded in a class file. - */ -public final class ConstantPoolParser { - /** {@code non-null;} the bytes of the constant pool */ - private final ByteArray bytes; - - /** {@code non-null;} actual parsed constant pool contents */ - private final StdConstantPool pool; - - /** {@code non-null;} byte offsets to each cst */ - private final int[] offsets; - - /** - * -1 || >= 10; the end offset of this constant pool in the - * {@code byte[]} which it came from or {@code -1} if not - * yet parsed - */ - private int endOffset; - - /** {@code null-ok;} parse observer, if any */ - private ParseObserver observer; - - /** - * Constructs an instance. - * - * @param bytes {@code non-null;} the bytes of the file - */ - public ConstantPoolParser(ByteArray bytes) { - int size = bytes.getUnsignedShort(8); // constant_pool_count - - this.bytes = bytes; - this.pool = new StdConstantPool(size); - this.offsets = new int[size]; - this.endOffset = -1; - } - - /** - * Sets the parse observer for this instance. - * - * @param observer {@code null-ok;} the observer - */ - public void setObserver(ParseObserver observer) { - this.observer = observer; - } - - /** - * Gets the end offset of this constant pool in the {@code byte[]} - * which it came from. - * - * @return {@code >= 10;} the end offset - */ - public int getEndOffset() { - parseIfNecessary(); - return endOffset; - } - - /** - * Gets the actual constant pool. - * - * @return {@code non-null;} the constant pool - */ - public StdConstantPool getPool() { - parseIfNecessary(); - return pool; - } - - /** - * Runs {@link #parse} if it has not yet been run successfully. - */ - private void parseIfNecessary() { - if (endOffset < 0) { - parse(); - } - } - - /** - * Does the actual parsing. - */ - private void parse() { - determineOffsets(); - - if (observer != null) { - observer.parsed(bytes, 8, 2, - "constant_pool_count: " + Hex.u2(offsets.length)); - observer.parsed(bytes, 10, 0, "\nconstant_pool:"); - observer.changeIndent(1); - } - - /* - * Track the constant value's original string type. True if constants[i] was - * a CONSTANT_Utf8, false for any other type including CONSTANT_string. - */ - BitSet wasUtf8 = new BitSet(offsets.length); - - for (int i = 1; i < offsets.length; i++) { - int offset = offsets[i]; - if ((offset != 0) && (pool.getOrNull(i) == null)) { - parse0(i, wasUtf8); - } - } - - if (observer != null) { - for (int i = 1; i < offsets.length; i++) { - Constant cst = pool.getOrNull(i); - if (cst == null) { - continue; - } - int offset = offsets[i]; - int nextOffset = endOffset; - for (int j = i + 1; j < offsets.length; j++) { - int off = offsets[j]; - if (off != 0) { - nextOffset = off; - break; - } - } - String human = wasUtf8.get(i) - ? Hex.u2(i) + ": utf8{\"" + cst.toHuman() + "\"}" - : Hex.u2(i) + ": " + cst.toString(); - observer.parsed(bytes, offset, nextOffset - offset, human); - } - - observer.changeIndent(-1); - observer.parsed(bytes, endOffset, 0, "end constant_pool"); - } - } - - /** - * Populates {@link #offsets} and also completely parse utf8 constants. - */ - private void determineOffsets() { - int at = 10; // offset from the start of the file to the first cst - int lastCategory; - - for (int i = 1; i < offsets.length; i += lastCategory) { - offsets[i] = at; - int tag = bytes.getUnsignedByte(at); - try { - switch (tag) { - case CONSTANT_Integer: - case CONSTANT_Float: - case CONSTANT_Fieldref: - case CONSTANT_Methodref: - case CONSTANT_InterfaceMethodref: - case CONSTANT_NameAndType: { - lastCategory = 1; - at += 5; - break; - } - case CONSTANT_Long: - case CONSTANT_Double: { - lastCategory = 2; - at += 9; - break; - } - case CONSTANT_Class: - case CONSTANT_String: { - lastCategory = 1; - at += 3; - break; - } - case CONSTANT_Utf8: { - lastCategory = 1; - at += bytes.getUnsignedShort(at + 1) + 3; - break; - } - case CONSTANT_MethodHandle: { - throw new ParseException("MethodHandle not supported"); - } - case CONSTANT_MethodType: { - throw new ParseException("MethodType not supported"); - } - case CONSTANT_InvokeDynamic: { - throw new ParseException("InvokeDynamic not supported"); - } - default: { - throw new ParseException("unknown tag byte: " + Hex.u1(tag)); - } - } - } catch (ParseException ex) { - ex.addContext("...while preparsing cst " + Hex.u2(i) + " at offset " + Hex.u4(at)); - throw ex; - } - } - - endOffset = at; - } - - /** - * Parses the constant for the given index if it hasn't already been - * parsed, also storing it in the constant pool. This will also - * have the side effect of parsing any entries the indicated one - * depends on. - * - * @param idx which constant - * @return {@code non-null;} the parsed constant - */ - private Constant parse0(int idx, BitSet wasUtf8) { - Constant cst = pool.getOrNull(idx); - if (cst != null) { - return cst; - } - - int at = offsets[idx]; - - try { - int tag = bytes.getUnsignedByte(at); - switch (tag) { - case CONSTANT_Utf8: { - cst = parseUtf8(at); - wasUtf8.set(idx); - break; - } - case CONSTANT_Integer: { - int value = bytes.getInt(at + 1); - cst = CstInteger.make(value); - break; - } - case CONSTANT_Float: { - int bits = bytes.getInt(at + 1); - cst = CstFloat.make(bits); - break; - } - case CONSTANT_Long: { - long value = bytes.getLong(at + 1); - cst = CstLong.make(value); - break; - } - case CONSTANT_Double: { - long bits = bytes.getLong(at + 1); - cst = CstDouble.make(bits); - break; - } - case CONSTANT_Class: { - int nameIndex = bytes.getUnsignedShort(at + 1); - CstString name = (CstString) parse0(nameIndex, wasUtf8); - cst = new CstType(Type.internClassName(name.getString())); - break; - } - case CONSTANT_String: { - int stringIndex = bytes.getUnsignedShort(at + 1); - cst = parse0(stringIndex, wasUtf8); - break; - } - case CONSTANT_Fieldref: { - int classIndex = bytes.getUnsignedShort(at + 1); - CstType type = (CstType) parse0(classIndex, wasUtf8); - int natIndex = bytes.getUnsignedShort(at + 3); - CstNat nat = (CstNat) parse0(natIndex, wasUtf8); - cst = new CstFieldRef(type, nat); - break; - } - case CONSTANT_Methodref: { - int classIndex = bytes.getUnsignedShort(at + 1); - CstType type = (CstType) parse0(classIndex, wasUtf8); - int natIndex = bytes.getUnsignedShort(at + 3); - CstNat nat = (CstNat) parse0(natIndex, wasUtf8); - cst = new CstMethodRef(type, nat); - break; - } - case CONSTANT_InterfaceMethodref: { - int classIndex = bytes.getUnsignedShort(at + 1); - CstType type = (CstType) parse0(classIndex, wasUtf8); - int natIndex = bytes.getUnsignedShort(at + 3); - CstNat nat = (CstNat) parse0(natIndex, wasUtf8); - cst = new CstInterfaceMethodRef(type, nat); - break; - } - case CONSTANT_NameAndType: { - int nameIndex = bytes.getUnsignedShort(at + 1); - CstString name = (CstString) parse0(nameIndex, wasUtf8); - int descriptorIndex = bytes.getUnsignedShort(at + 3); - CstString descriptor = (CstString) parse0(descriptorIndex, wasUtf8); - cst = new CstNat(name, descriptor); - break; - } - case CONSTANT_MethodHandle: { - throw new ParseException("MethodHandle not supported"); - } - case CONSTANT_MethodType: { - throw new ParseException("MethodType not supported"); - } - case CONSTANT_InvokeDynamic: { - throw new ParseException("InvokeDynamic not supported"); - } - default: { - throw new ParseException("unknown tag byte: " + Hex.u1(tag)); - } - } - } catch (ParseException ex) { - ex.addContext("...while parsing cst " + Hex.u2(idx) + - " at offset " + Hex.u4(at)); - throw ex; - } catch (RuntimeException ex) { - ParseException pe = new ParseException(ex); - pe.addContext("...while parsing cst " + Hex.u2(idx) + - " at offset " + Hex.u4(at)); - throw pe; - } - - pool.set(idx, cst); - return cst; - } - - /** - * Parses a utf8 constant. - * - * @param at offset to the start of the constant (where the tag byte is) - * @return {@code non-null;} the parsed value - */ - private CstString parseUtf8(int at) { - int length = bytes.getUnsignedShort(at + 1); - - at += 3; // Skip to the data. - - ByteArray ubytes = bytes.slice(at, at + length); - - try { - return new CstString(ubytes); - } catch (IllegalArgumentException ex) { - // Translate the exception - throw new ParseException(ex); - } - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/cst/ConstantTags.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/cst/ConstantTags.java deleted file mode 100644 index 56ef4d75ffc..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/cst/ConstantTags.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.cst; - -/** - * Tags for constant pool constants. - */ -public interface ConstantTags { - /** tag for a {@code CONSTANT_Utf8_info} */ - int CONSTANT_Utf8 = 1; - - /** tag for a {@code CONSTANT_Integer_info} */ - int CONSTANT_Integer = 3; - - /** tag for a {@code CONSTANT_Float_info} */ - int CONSTANT_Float = 4; - - /** tag for a {@code CONSTANT_Long_info} */ - int CONSTANT_Long = 5; - - /** tag for a {@code CONSTANT_Double_info} */ - int CONSTANT_Double = 6; - - /** tag for a {@code CONSTANT_Class_info} */ - int CONSTANT_Class = 7; - - /** tag for a {@code CONSTANT_String_info} */ - int CONSTANT_String = 8; - - /** tag for a {@code CONSTANT_Fieldref_info} */ - int CONSTANT_Fieldref = 9; - - /** tag for a {@code CONSTANT_Methodref_info} */ - int CONSTANT_Methodref = 10; - - /** tag for a {@code CONSTANT_InterfaceMethodref_info} */ - int CONSTANT_InterfaceMethodref = 11; - - /** tag for a {@code CONSTANT_NameAndType_info} */ - int CONSTANT_NameAndType = 12; - - /** tag for a {@code CONSTANT_MethodHandle} */ - int CONSTANT_MethodHandle = 15; - - /** tag for a {@code CONSTANT_MethodType} */ - int CONSTANT_MethodType = 16; - - /** tag for a {@code CONSTANT_InvokeDynamic} */ - int CONSTANT_InvokeDynamic = 18; -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/AnnotationParser.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/AnnotationParser.java deleted file mode 100644 index f7666944504..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/AnnotationParser.java +++ /dev/null @@ -1,470 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.direct; - -import com.android.dx.cf.iface.ParseException; -import com.android.dx.cf.iface.ParseObserver; -import com.android.dx.rop.annotation.Annotation; -import com.android.dx.rop.annotation.AnnotationVisibility; -import com.android.dx.rop.annotation.Annotations; -import com.android.dx.rop.annotation.AnnotationsList; -import com.android.dx.rop.annotation.NameValuePair; -import com.android.dx.rop.cst.Constant; -import com.android.dx.rop.cst.ConstantPool; -import com.android.dx.rop.cst.CstAnnotation; -import com.android.dx.rop.cst.CstArray; -import com.android.dx.rop.cst.CstBoolean; -import com.android.dx.rop.cst.CstByte; -import com.android.dx.rop.cst.CstChar; -import com.android.dx.rop.cst.CstDouble; -import com.android.dx.rop.cst.CstEnumRef; -import com.android.dx.rop.cst.CstFloat; -import com.android.dx.rop.cst.CstInteger; -import com.android.dx.rop.cst.CstLong; -import com.android.dx.rop.cst.CstNat; -import com.android.dx.rop.cst.CstShort; -import com.android.dx.rop.cst.CstString; -import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.type.Type; -import com.android.dx.util.ByteArray; -import com.android.dx.util.Hex; -import java.io.IOException; - -/** - * Parser for annotations. - */ -public final class AnnotationParser { - /** {@code non-null;} class file being parsed */ - private final DirectClassFile cf; - - /** {@code non-null;} constant pool to use */ - private final ConstantPool pool; - - /** {@code non-null;} bytes of the attribute data */ - private final ByteArray bytes; - - /** {@code null-ok;} parse observer, if any */ - private final ParseObserver observer; - - /** {@code non-null;} input stream to parse from */ - private final ByteArray.MyDataInputStream input; - - /** - * {@code non-null;} cursor for use when informing the observer of what - * was parsed - */ - private int parseCursor; - - /** - * Constructs an instance. - * - * @param cf {@code non-null;} class file to parse from - * @param offset {@code >= 0;} offset into the class file data to parse at - * @param length {@code >= 0;} number of bytes left in the attribute data - * @param observer {@code null-ok;} parse observer to notify, if any - */ - public AnnotationParser(DirectClassFile cf, int offset, int length, - ParseObserver observer) { - if (cf == null) { - throw new NullPointerException("cf == null"); - } - - this.cf = cf; - this.pool = cf.getConstantPool(); - this.observer = observer; - this.bytes = cf.getBytes().slice(offset, offset + length); - this.input = bytes.makeDataInputStream(); - this.parseCursor = 0; - } - - /** - * Parses an annotation value ({@code element_value}) attribute. - * - * @return {@code non-null;} the parsed constant value - */ - public Constant parseValueAttribute() { - Constant result; - - try { - result = parseValue(); - - if (input.available() != 0) { - throw new ParseException("extra data in attribute"); - } - } catch (IOException ex) { - // ByteArray.MyDataInputStream should never throw. - throw new RuntimeException("shouldn't happen", ex); - } - - return result; - } - - /** - * Parses a parameter annotation attribute. - * - * @param visibility {@code non-null;} visibility of the parsed annotations - * @return {@code non-null;} the parsed list of lists of annotations - */ - public AnnotationsList parseParameterAttribute( - AnnotationVisibility visibility) { - AnnotationsList result; - - try { - result = parseAnnotationsList(visibility); - - if (input.available() != 0) { - throw new ParseException("extra data in attribute"); - } - } catch (IOException ex) { - // ByteArray.MyDataInputStream should never throw. - throw new RuntimeException("shouldn't happen", ex); - } - - return result; - } - - /** - * Parses an annotation attribute, per se. - * - * @param visibility {@code non-null;} visibility of the parsed annotations - * @return {@code non-null;} the list of annotations read from the attribute - * data - */ - public Annotations parseAnnotationAttribute( - AnnotationVisibility visibility) { - Annotations result; - - try { - result = parseAnnotations(visibility); - - if (input.available() != 0) { - throw new ParseException("extra data in attribute"); - } - } catch (IOException ex) { - // ByteArray.MyDataInputStream should never throw. - throw new RuntimeException("shouldn't happen", ex); - } - - return result; - } - - /** - * Parses a list of annotation lists. - * - * @param visibility {@code non-null;} visibility of the parsed annotations - * @return {@code non-null;} the list of annotation lists read from the attribute - * data - */ - private AnnotationsList parseAnnotationsList( - AnnotationVisibility visibility) throws IOException { - int count = input.readUnsignedByte(); - - if (observer != null) { - parsed(1, "num_parameters: " + Hex.u1(count)); - } - - AnnotationsList outerList = new AnnotationsList(count); - - for (int i = 0; i < count; i++) { - if (observer != null) { - parsed(0, "parameter_annotations[" + i + "]:"); - changeIndent(1); - } - - Annotations annotations = parseAnnotations(visibility); - outerList.set(i, annotations); - - if (observer != null) { - observer.changeIndent(-1); - } - } - - outerList.setImmutable(); - return outerList; - } - - /** - * Parses an annotation list. - * - * @param visibility {@code non-null;} visibility of the parsed annotations - * @return {@code non-null;} the list of annotations read from the attribute - * data - */ - private Annotations parseAnnotations(AnnotationVisibility visibility) - throws IOException { - int count = input.readUnsignedShort(); - - if (observer != null) { - parsed(2, "num_annotations: " + Hex.u2(count)); - } - - Annotations annotations = new Annotations(); - - for (int i = 0; i < count; i++) { - if (observer != null) { - parsed(0, "annotations[" + i + "]:"); - changeIndent(1); - } - - Annotation annotation = parseAnnotation(visibility); - annotations.add(annotation); - - if (observer != null) { - observer.changeIndent(-1); - } - } - - annotations.setImmutable(); - return annotations; - } - - /** - * Parses a single annotation. - * - * @param visibility {@code non-null;} visibility of the parsed annotation - * @return {@code non-null;} the parsed annotation - */ - private Annotation parseAnnotation(AnnotationVisibility visibility) - throws IOException { - requireLength(4); - - int typeIndex = input.readUnsignedShort(); - int numElements = input.readUnsignedShort(); - CstString typeString = (CstString) pool.get(typeIndex); - CstType type = new CstType(Type.intern(typeString.getString())); - - if (observer != null) { - parsed(2, "type: " + type.toHuman()); - parsed(2, "num_elements: " + numElements); - } - - Annotation annotation = new Annotation(type, visibility); - - for (int i = 0; i < numElements; i++) { - if (observer != null) { - parsed(0, "elements[" + i + "]:"); - changeIndent(1); - } - - NameValuePair element = parseElement(); - annotation.add(element); - - if (observer != null) { - changeIndent(-1); - } - } - - annotation.setImmutable(); - return annotation; - } - - /** - * Parses a {@link NameValuePair}. - * - * @return {@code non-null;} the parsed element - */ - private NameValuePair parseElement() throws IOException { - requireLength(5); - - int elementNameIndex = input.readUnsignedShort(); - CstString elementName = (CstString) pool.get(elementNameIndex); - - if (observer != null) { - parsed(2, "element_name: " + elementName.toHuman()); - parsed(0, "value: "); - changeIndent(1); - } - - Constant value = parseValue(); - - if (observer != null) { - changeIndent(-1); - } - - return new NameValuePair(elementName, value); - } - - /** - * Parses an annotation value. - * - * @return {@code non-null;} the parsed value - */ - private Constant parseValue() throws IOException { - int tag = input.readUnsignedByte(); - - if (observer != null) { - CstString humanTag = new CstString(Character.toString((char) tag)); - parsed(1, "tag: " + humanTag.toQuoted()); - } - - switch (tag) { - case 'B': { - CstInteger value = (CstInteger) parseConstant(); - return CstByte.make(value.getValue()); - } - case 'C': { - CstInteger value = (CstInteger) parseConstant(); - int intValue = value.getValue(); - return CstChar.make(value.getValue()); - } - case 'D': { - CstDouble value = (CstDouble) parseConstant(); - return value; - } - case 'F': { - CstFloat value = (CstFloat) parseConstant(); - return value; - } - case 'I': { - CstInteger value = (CstInteger) parseConstant(); - return value; - } - case 'J': { - CstLong value = (CstLong) parseConstant(); - return value; - } - case 'S': { - CstInteger value = (CstInteger) parseConstant(); - return CstShort.make(value.getValue()); - } - case 'Z': { - CstInteger value = (CstInteger) parseConstant(); - return CstBoolean.make(value.getValue()); - } - case 'c': { - int classInfoIndex = input.readUnsignedShort(); - CstString value = (CstString) pool.get(classInfoIndex); - Type type = Type.internReturnType(value.getString()); - - if (observer != null) { - parsed(2, "class_info: " + type.toHuman()); - } - - return new CstType(type); - } - case 's': { - return parseConstant(); - } - case 'e': { - requireLength(4); - - int typeNameIndex = input.readUnsignedShort(); - int constNameIndex = input.readUnsignedShort(); - CstString typeName = (CstString) pool.get(typeNameIndex); - CstString constName = (CstString) pool.get(constNameIndex); - - if (observer != null) { - parsed(2, "type_name: " + typeName.toHuman()); - parsed(2, "const_name: " + constName.toHuman()); - } - - return new CstEnumRef(new CstNat(constName, typeName)); - } - case '@': { - Annotation annotation = - parseAnnotation(AnnotationVisibility.EMBEDDED); - return new CstAnnotation(annotation); - } - case '[': { - requireLength(2); - - int numValues = input.readUnsignedShort(); - CstArray.List list = new CstArray.List(numValues); - - if (observer != null) { - parsed(2, "num_values: " + numValues); - changeIndent(1); - } - - for (int i = 0; i < numValues; i++) { - if (observer != null) { - changeIndent(-1); - parsed(0, "element_value[" + i + "]:"); - changeIndent(1); - } - list.set(i, parseValue()); - } - - if (observer != null) { - changeIndent(-1); - } - - list.setImmutable(); - return new CstArray(list); - } - default: { - throw new ParseException("unknown annotation tag: " + - Hex.u1(tag)); - } - } - } - - /** - * Helper for {@link #parseValue}, which parses a constant reference - * and returns the referred-to constant value. - * - * @return {@code non-null;} the parsed value - */ - private Constant parseConstant() throws IOException { - int constValueIndex = input.readUnsignedShort(); - Constant value = (Constant) pool.get(constValueIndex); - - if (observer != null) { - String human = (value instanceof CstString) - ? ((CstString) value).toQuoted() - : value.toHuman(); - parsed(2, "constant_value: " + human); - } - - return value; - } - - /** - * Helper which will throw an exception if the given number of bytes - * is not available to be read. - * - * @param requiredLength the number of required bytes - */ - private void requireLength(int requiredLength) throws IOException { - if (input.available() < requiredLength) { - throw new ParseException("truncated annotation attribute"); - } - } - - /** - * Helper which indicates that some bytes were just parsed. This should - * only be used (for efficiency sake) if the parse is known to be - * observed. - * - * @param length {@code >= 0;} number of bytes parsed - * @param message {@code non-null;} associated message - */ - private void parsed(int length, String message) { - observer.parsed(bytes, parseCursor, length, message); - parseCursor += length; - } - - /** - * Convenience wrapper that simply calls through to - * {@code observer.changeIndent()}. - * - * @param indent the amount to change the indent by - */ - private void changeIndent(int indent) { - observer.changeIndent(indent); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/AttributeFactory.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/AttributeFactory.java deleted file mode 100644 index f7486eb9cd5..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/AttributeFactory.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.direct; - -import com.android.dx.cf.attrib.RawAttribute; -import com.android.dx.cf.iface.Attribute; -import com.android.dx.cf.iface.ParseException; -import com.android.dx.cf.iface.ParseObserver; -import com.android.dx.rop.cst.ConstantPool; -import com.android.dx.rop.cst.CstString; -import com.android.dx.util.ByteArray; -import com.android.dx.util.Hex; - -/** - * Factory capable of instantiating various {@link Attribute} subclasses - * depending on the context and name. - */ -public class AttributeFactory { - /** context for attributes on class files */ - public static final int CTX_CLASS = 0; - - /** context for attributes on fields */ - public static final int CTX_FIELD = 1; - - /** context for attributes on methods */ - public static final int CTX_METHOD = 2; - - /** context for attributes on code attributes */ - public static final int CTX_CODE = 3; - - /** number of contexts */ - public static final int CTX_COUNT = 4; - - /** - * Constructs an instance. - */ - public AttributeFactory() { - // This space intentionally left blank. - } - - /** - * Parses and makes an attribute based on the bytes at the - * indicated position in the given array. This method figures out - * the name, and then does all the setup to call on to {@link #parse0}, - * which does the actual construction. - * - * @param cf {@code non-null;} class file to parse from - * @param context context to parse in; one of the {@code CTX_*} - * constants - * @param offset offset into {@code dcf}'s {@code bytes} - * to start parsing at - * @param observer {@code null-ok;} parse observer to report to, if any - * @return {@code non-null;} an appropriately-constructed {@link Attribute} - */ - public final Attribute parse(DirectClassFile cf, int context, int offset, - ParseObserver observer) { - if (cf == null) { - throw new NullPointerException("cf == null"); - } - - if ((context < 0) || (context >= CTX_COUNT)) { - throw new IllegalArgumentException("bad context"); - } - - CstString name = null; - - try { - ByteArray bytes = cf.getBytes(); - ConstantPool pool = cf.getConstantPool(); - int nameIdx = bytes.getUnsignedShort(offset); - int length = bytes.getInt(offset + 2); - - name = (CstString) pool.get(nameIdx); - - if (observer != null) { - observer.parsed(bytes, offset, 2, - "name: " + name.toHuman()); - observer.parsed(bytes, offset + 2, 4, - "length: " + Hex.u4(length)); - } - - return parse0(cf, context, name.getString(), offset + 6, length, - observer); - } catch (ParseException ex) { - ex.addContext("...while parsing " + - ((name != null) ? (name.toHuman() + " ") : "") + - "attribute at offset " + Hex.u4(offset)); - throw ex; - } - } - - /** - * Parses attribute content. The base class implements this by constructing - * an instance of {@link RawAttribute}. Subclasses are expected to - * override this to do something better in most cases. - * - * @param cf {@code non-null;} class file to parse from - * @param context context to parse in; one of the {@code CTX_*} - * constants - * @param name {@code non-null;} the attribute name - * @param offset offset into {@code bytes} to start parsing at; this - * is the offset to the start of attribute data, not to the header - * @param length the length of the attribute data - * @param observer {@code null-ok;} parse observer to report to, if any - * @return {@code non-null;} an appropriately-constructed {@link Attribute} - */ - protected Attribute parse0(DirectClassFile cf, int context, String name, - int offset, int length, - ParseObserver observer) { - ByteArray bytes = cf.getBytes(); - ConstantPool pool = cf.getConstantPool(); - Attribute result = new RawAttribute(name, bytes, offset, length, pool); - - if (observer != null) { - observer.parsed(bytes, offset, length, "attribute data"); - } - - return result; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/AttributeListParser.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/AttributeListParser.java deleted file mode 100644 index 2715e6a94b5..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/AttributeListParser.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.direct; - -import com.android.dx.cf.iface.Attribute; -import com.android.dx.cf.iface.ParseException; -import com.android.dx.cf.iface.ParseObserver; -import com.android.dx.cf.iface.StdAttributeList; -import com.android.dx.util.ByteArray; -import com.android.dx.util.Hex; - -/** - * Parser for lists of attributes. - */ -final /*package*/ class AttributeListParser { - /** {@code non-null;} the class file to parse from */ - private final DirectClassFile cf; - - /** attribute parsing context */ - private final int context; - - /** offset in the byte array of the classfile to the start of the list */ - private final int offset; - - /** {@code non-null;} attribute factory to use */ - private final AttributeFactory attributeFactory; - - /** {@code non-null;} list of parsed attributes */ - private final StdAttributeList list; - - /** {@code >= -1;} the end offset of this list in the byte array of the - * classfile, or {@code -1} if not yet parsed */ - private int endOffset; - - /** {@code null-ok;} parse observer, if any */ - private ParseObserver observer; - - /** - * Constructs an instance. - * - * @param cf {@code non-null;} class file to parse from - * @param context attribute parsing context (see {@link AttributeFactory}) - * @param offset offset in {@code bytes} to the start of the list - * @param attributeFactory {@code non-null;} attribute factory to use - */ - public AttributeListParser(DirectClassFile cf, int context, int offset, - AttributeFactory attributeFactory) { - if (cf == null) { - throw new NullPointerException("cf == null"); - } - - if (attributeFactory == null) { - throw new NullPointerException("attributeFactory == null"); - } - - int size = cf.getBytes().getUnsignedShort(offset); - - this.cf = cf; - this.context = context; - this.offset = offset; - this.attributeFactory = attributeFactory; - this.list = new StdAttributeList(size); - this.endOffset = -1; - } - - /** - * Sets the parse observer for this instance. - * - * @param observer {@code null-ok;} the observer - */ - public void setObserver(ParseObserver observer) { - this.observer = observer; - } - - /** - * Gets the end offset of this constant pool in the {@code byte[]} - * which it came from. - * - * @return {@code >= 0;} the end offset - */ - public int getEndOffset() { - parseIfNecessary(); - return endOffset; - } - - /** - * Gets the parsed list. - * - * @return {@code non-null;} the list - */ - public StdAttributeList getList() { - parseIfNecessary(); - return list; - } - - /** - * Runs {@link #parse} if it has not yet been run successfully. - */ - private void parseIfNecessary() { - if (endOffset < 0) { - parse(); - } - } - - /** - * Does the actual parsing. - */ - private void parse() { - int sz = list.size(); - int at = offset + 2; // Skip the count. - - ByteArray bytes = cf.getBytes(); - - if (observer != null) { - observer.parsed(bytes, offset, 2, - "attributes_count: " + Hex.u2(sz)); - } - - for (int i = 0; i < sz; i++) { - try { - if (observer != null) { - observer.parsed(bytes, at, 0, - "\nattributes[" + i + "]:\n"); - observer.changeIndent(1); - } - - Attribute attrib = - attributeFactory.parse(cf, context, at, observer); - - at += attrib.byteLength(); - list.set(i, attrib); - - if (observer != null) { - observer.changeIndent(-1); - observer.parsed(bytes, at, 0, - "end attributes[" + i + "]\n"); - } - } catch (ParseException ex) { - ex.addContext("...while parsing attributes[" + i + "]"); - throw ex; - } catch (RuntimeException ex) { - ParseException pe = new ParseException(ex); - pe.addContext("...while parsing attributes[" + i + "]"); - throw pe; - } - } - - endOffset = at; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/ClassPathOpener.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/ClassPathOpener.java deleted file mode 100644 index c9fe275cd68..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/ClassPathOpener.java +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.direct; - -import com.android.dex.util.FileUtils; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - -/** - * Opens all the class files found in a class path element. Path elements - * can point to class files, {jar,zip,apk} files, or directories containing - * class files. - */ -public class ClassPathOpener { - - /** {@code non-null;} pathname to start with */ - private final String pathname; - /** {@code non-null;} callback interface */ - private final Consumer consumer; - /** - * If true, sort such that classes appear before their inner - * classes and "package-info" occurs before all other classes in that - * package. - */ - private final boolean sort; - private FileNameFilter filter; - - /** - * Callback interface for {@code ClassOpener}. - */ - public interface Consumer { - - /** - * Provides the file name and byte array for a class path element. - * - * @param name {@code non-null;} filename of element. May not be a valid - * filesystem path. - * - * @param lastModified milliseconds since 1970-Jan-1 00:00:00 GMT - * @param bytes {@code non-null;} file data - * @return true on success. Result is or'd with all other results - * from {@code processFileBytes} and returned to the caller - * of {@code process()}. - */ - boolean processFileBytes(String name, long lastModified, byte[] bytes); - - /** - * Informs consumer that an exception occurred while processing - * this path element. Processing will continue if possible. - * - * @param ex {@code non-null;} exception - */ - void onException(Exception ex); - - /** - * Informs consumer that processing of an archive file has begun. - * - * @param file {@code non-null;} archive file being processed - */ - void onProcessArchiveStart(File file); - } - - /** - * Filter interface for {@code ClassOpener}. - */ - public interface FileNameFilter { - - boolean accept(String path); - } - - /** - * An accept all filter. - */ - public static final FileNameFilter acceptAll = new FileNameFilter() { - - @Override - public boolean accept(String path) { - return true; - } - }; - - /** - * Constructs an instance. - * - * @param pathname {@code non-null;} path element to process - * @param sort if true, sort such that classes appear before their inner - * classes and "package-info" occurs before all other classes in that - * package. - * @param consumer {@code non-null;} callback interface - */ - public ClassPathOpener(String pathname, boolean sort, Consumer consumer) { - this(pathname, sort, acceptAll, consumer); - } - - /** - * Constructs an instance. - * - * @param pathname {@code non-null;} path element to process - * @param sort if true, sort such that classes appear before their inner - * classes and "package-info" occurs before all other classes in that - * package. - * @param consumer {@code non-null;} callback interface - */ - public ClassPathOpener(String pathname, boolean sort, FileNameFilter filter, - Consumer consumer) { - this.pathname = pathname; - this.sort = sort; - this.consumer = consumer; - this.filter = filter; - } - - /** - * Processes a path element. - * - * @return the OR of all return values - * from {@code Consumer.processFileBytes()}. - */ - public boolean process() { - File file = new File(pathname); - - return processOne(file, true); - } - - /** - * Processes one file. - * - * @param file {@code non-null;} the file to process - * @param topLevel whether this is a top-level file (that is, - * specified directly on the commandline) - * @return whether any processing actually happened - */ - private boolean processOne(File file, boolean topLevel) { - try { - if (file.isDirectory()) { - return processDirectory(file, topLevel); - } - - String path = file.getPath(); - - if (path.endsWith(".zip") || - path.endsWith(".jar") || - path.endsWith(".apk")) { - return processArchive(file); - } - if (filter.accept(path)) { - byte[] bytes = FileUtils.readFile(file); - return consumer.processFileBytes(path, file.lastModified(), bytes); - } else { - return false; - } - } catch (Exception ex) { - consumer.onException(ex); - return false; - } - } - - /** - * Sorts java class names such that outer classes preceed their inner - * classes and "package-info" preceeds all other classes in its package. - * - * @param a {@code non-null;} first class name - * @param b {@code non-null;} second class name - * @return {@code compareTo()}-style result - */ - private static int compareClassNames(String a, String b) { - // Ensure inner classes sort second - a = a.replace('$','0'); - b = b.replace('$','0'); - - /* - * Assuming "package-info" only occurs at the end, ensures package-info - * sorts first. - */ - a = a.replace("package-info", ""); - b = b.replace("package-info", ""); - - return a.compareTo(b); - } - - /** - * Processes a directory recursively. - * - * @param dir {@code non-null;} file representing the directory - * @param topLevel whether this is a top-level directory (that is, - * specified directly on the commandline) - * @return whether any processing actually happened - */ - private boolean processDirectory(File dir, boolean topLevel) { - if (topLevel) { - dir = new File(dir, "."); - } - - File[] files = dir.listFiles(); - int len = files.length; - boolean any = false; - - if (sort) { - Arrays.sort(files, new Comparator() { - public int compare(File a, File b) { - return compareClassNames(a.getName(), b.getName()); - } - }); - } - - for (int i = 0; i < len; i++) { - any |= processOne(files[i], false); - } - - return any; - } - - /** - * Processes the contents of an archive ({@code .zip}, - * {@code .jar}, or {@code .apk}). - * - * @param file {@code non-null;} archive file to process - * @return whether any processing actually happened - * @throws IOException on i/o problem - */ - private boolean processArchive(File file) throws IOException { - ZipFile zip = new ZipFile(file); - ByteArrayOutputStream baos = new ByteArrayOutputStream(40000); - byte[] buf = new byte[20000]; - boolean any = false; - - ArrayList entriesList - = Collections.list(zip.entries()); - - if (sort) { - Collections.sort(entriesList, new Comparator() { - public int compare (ZipEntry a, ZipEntry b) { - return compareClassNames(a.getName(), b.getName()); - } - }); - } - - consumer.onProcessArchiveStart(file); - - for (ZipEntry one : entriesList) { - if (one.isDirectory()) { - continue; - } - - String path = one.getName(); - if (filter.accept(path)) { - InputStream in = zip.getInputStream(one); - - baos.reset(); - for (;;) { - int amt = in.read(buf); - if (amt < 0) { - break; - } - - baos.write(buf, 0, amt); - } - - in.close(); - - byte[] bytes = baos.toByteArray(); - any |= consumer.processFileBytes(path, one.getTime(), bytes); - } - } - - zip.close(); - return any; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/CodeObserver.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/CodeObserver.java deleted file mode 100644 index 4262cf82cb9..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/CodeObserver.java +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.direct; - -import com.android.dx.cf.code.ByteOps; -import com.android.dx.cf.code.BytecodeArray; -import com.android.dx.cf.code.SwitchList; -import com.android.dx.cf.iface.ParseObserver; -import com.android.dx.rop.cst.Constant; -import com.android.dx.rop.cst.CstDouble; -import com.android.dx.rop.cst.CstFloat; -import com.android.dx.rop.cst.CstInteger; -import com.android.dx.rop.cst.CstKnownNull; -import com.android.dx.rop.cst.CstLong; -import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.type.Type; -import com.android.dx.util.ByteArray; -import com.android.dx.util.Hex; -import java.util.ArrayList; - -/** - * Bytecode visitor to use when "observing" bytecode getting parsed. - */ -public class CodeObserver implements BytecodeArray.Visitor { - /** {@code non-null;} actual array of bytecode */ - private final ByteArray bytes; - - /** {@code non-null;} observer to inform of parsing */ - private final ParseObserver observer; - - /** - * Constructs an instance. - * - * @param bytes {@code non-null;} actual array of bytecode - * @param observer {@code non-null;} observer to inform of parsing - */ - public CodeObserver(ByteArray bytes, ParseObserver observer) { - if (bytes == null) { - throw new NullPointerException("bytes == null"); - } - - if (observer == null) { - throw new NullPointerException("observer == null"); - } - - this.bytes = bytes; - this.observer = observer; - } - - /** {@inheritDoc} */ - public void visitInvalid(int opcode, int offset, int length) { - observer.parsed(bytes, offset, length, header(offset)); - } - - /** {@inheritDoc} */ - public void visitNoArgs(int opcode, int offset, int length, Type type) { - observer.parsed(bytes, offset, length, header(offset)); - } - - /** {@inheritDoc} */ - public void visitLocal(int opcode, int offset, int length, - int idx, Type type, int value) { - String idxStr = (length <= 3) ? Hex.u1(idx) : Hex.u2(idx); - boolean argComment = (length == 1); - String valueStr = ""; - - if (opcode == ByteOps.IINC) { - valueStr = ", #" + - ((length <= 3) ? Hex.s1(value) : Hex.s2(value)); - } - - String catStr = ""; - if (type.isCategory2()) { - catStr = (argComment ? "," : " //") + " category-2"; - } - - observer.parsed(bytes, offset, length, - header(offset) + (argComment ? " // " : " ") + - idxStr + valueStr + catStr); - } - - /** {@inheritDoc} */ - public void visitConstant(int opcode, int offset, int length, - Constant cst, int value) { - if (cst instanceof CstKnownNull) { - // This is aconst_null. - visitNoArgs(opcode, offset, length, null); - return; - } - - if (cst instanceof CstInteger) { - visitLiteralInt(opcode, offset, length, value); - return; - } - - if (cst instanceof CstLong) { - visitLiteralLong(opcode, offset, length, - ((CstLong) cst).getValue()); - return; - } - - if (cst instanceof CstFloat) { - visitLiteralFloat(opcode, offset, length, - ((CstFloat) cst).getIntBits()); - return; - } - - if (cst instanceof CstDouble) { - visitLiteralDouble(opcode, offset, length, - ((CstDouble) cst).getLongBits()); - return; - } - - String valueStr = ""; - if (value != 0) { - valueStr = ", "; - if (opcode == ByteOps.MULTIANEWARRAY) { - valueStr += Hex.u1(value); - } else { - valueStr += Hex.u2(value); - } - } - - observer.parsed(bytes, offset, length, - header(offset) + " " + cst + valueStr); - } - - /** {@inheritDoc} */ - public void visitBranch(int opcode, int offset, int length, - int target) { - String targetStr = (length <= 3) ? Hex.u2(target) : Hex.u4(target); - observer.parsed(bytes, offset, length, - header(offset) + " " + targetStr); - } - - /** {@inheritDoc} */ - public void visitSwitch(int opcode, int offset, int length, - SwitchList cases, int padding) { - int sz = cases.size(); - StringBuffer sb = new StringBuffer(sz * 20 + 100); - - sb.append(header(offset)); - if (padding != 0) { - sb.append(" // padding: " + Hex.u4(padding)); - } - sb.append('\n'); - - for (int i = 0; i < sz; i++) { - sb.append(" "); - sb.append(Hex.s4(cases.getValue(i))); - sb.append(": "); - sb.append(Hex.u2(cases.getTarget(i))); - sb.append('\n'); - } - - sb.append(" default: "); - sb.append(Hex.u2(cases.getDefaultTarget())); - - observer.parsed(bytes, offset, length, sb.toString()); - } - - /** {@inheritDoc} */ - public void visitNewarray(int offset, int length, CstType cst, - ArrayList intVals) { - String commentOrSpace = (length == 1) ? " // " : " "; - String typeName = cst.getClassType().getComponentType().toHuman(); - - observer.parsed(bytes, offset, length, - header(offset) + commentOrSpace + typeName); - } - - /** {@inheritDoc} */ - public void setPreviousOffset(int offset) { - // Do nothing - } - - /** {@inheritDoc} */ - public int getPreviousOffset() { - return -1; - } - - /** - * Helper to produce the first bit of output for each instruction. - * - * @param offset the offset to the start of the instruction - */ - private String header(int offset) { - /* - * Note: This uses the original bytecode, not the - * possibly-transformed one. - */ - int opcode = bytes.getUnsignedByte(offset); - String name = ByteOps.opName(opcode); - - if (opcode == ByteOps.WIDE) { - opcode = bytes.getUnsignedByte(offset + 1); - name += " " + ByteOps.opName(opcode); - } - - return Hex.u2(offset) + ": " + name; - } - - /** - * Helper for {@link #visitConstant} where the constant is an - * {@code int}. - * - * @param opcode the opcode - * @param offset offset to the instruction - * @param length instruction length - * @param value constant value - */ - private void visitLiteralInt(int opcode, int offset, int length, - int value) { - String commentOrSpace = (length == 1) ? " // " : " "; - String valueStr; - - opcode = bytes.getUnsignedByte(offset); // Compare with orig op below. - if ((length == 1) || (opcode == ByteOps.BIPUSH)) { - valueStr = "#" + Hex.s1(value); - } else if (opcode == ByteOps.SIPUSH) { - valueStr = "#" + Hex.s2(value); - } else { - valueStr = "#" + Hex.s4(value); - } - - observer.parsed(bytes, offset, length, - header(offset) + commentOrSpace + valueStr); - } - - /** - * Helper for {@link #visitConstant} where the constant is a - * {@code long}. - * - * @param opcode the opcode - * @param offset offset to the instruction - * @param length instruction length - * @param value constant value - */ - private void visitLiteralLong(int opcode, int offset, int length, - long value) { - String commentOrLit = (length == 1) ? " // " : " #"; - String valueStr; - - if (length == 1) { - valueStr = Hex.s1((int) value); - } else { - valueStr = Hex.s8(value); - } - - observer.parsed(bytes, offset, length, - header(offset) + commentOrLit + valueStr); - } - - /** - * Helper for {@link #visitConstant} where the constant is a - * {@code float}. - * - * @param opcode the opcode - * @param offset offset to the instruction - * @param length instruction length - * @param bits constant value, as float-bits - */ - private void visitLiteralFloat(int opcode, int offset, int length, - int bits) { - String optArg = (length != 1) ? " #" + Hex.u4(bits) : ""; - - observer.parsed(bytes, offset, length, - header(offset) + optArg + " // " + - Float.intBitsToFloat(bits)); - } - - /** - * Helper for {@link #visitConstant} where the constant is a - * {@code double}. - * - * @param opcode the opcode - * @param offset offset to the instruction - * @param length instruction length - * @param bits constant value, as double-bits - */ - private void visitLiteralDouble(int opcode, int offset, int length, - long bits) { - String optArg = (length != 1) ? " #" + Hex.u8(bits) : ""; - - observer.parsed(bytes, offset, length, - header(offset) + optArg + " // " + - Double.longBitsToDouble(bits)); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/DirectClassFile.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/DirectClassFile.java deleted file mode 100644 index f908547cb5b..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/DirectClassFile.java +++ /dev/null @@ -1,646 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.direct; - -import com.android.dx.cf.attrib.AttSourceFile; -import com.android.dx.cf.cst.ConstantPoolParser; -import com.android.dx.cf.iface.Attribute; -import com.android.dx.cf.iface.AttributeList; -import com.android.dx.cf.iface.ClassFile; -import com.android.dx.cf.iface.FieldList; -import com.android.dx.cf.iface.MethodList; -import com.android.dx.cf.iface.ParseException; -import com.android.dx.cf.iface.ParseObserver; -import com.android.dx.cf.iface.StdAttributeList; -import com.android.dx.rop.code.AccessFlags; -import com.android.dx.rop.cst.ConstantPool; -import com.android.dx.rop.cst.CstString; -import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.cst.StdConstantPool; -import com.android.dx.rop.type.StdTypeList; -import com.android.dx.rop.type.Type; -import com.android.dx.rop.type.TypeList; -import com.android.dx.util.ByteArray; -import com.android.dx.util.Hex; - -/** - * Class file with info taken from a {@code byte[]} or slice thereof. - */ -public class DirectClassFile implements ClassFile { - /** the expected value of the ClassFile.magic field */ - private static final int CLASS_FILE_MAGIC = 0xcafebabe; - - /** - * minimum {@code .class} file major version - * - * See http://en.wikipedia.org/wiki/Java_class_file for an up-to-date - * list of version numbers. Currently known (taken from that table) are: - * - * J2SE 7.0 = 51 (0x33 hex), - * J2SE 6.0 = 50 (0x32 hex), - * J2SE 5.0 = 49 (0x31 hex), - * JDK 1.4 = 48 (0x30 hex), - * JDK 1.3 = 47 (0x2F hex), - * JDK 1.2 = 46 (0x2E hex), - * JDK 1.1 = 45 (0x2D hex). - * - * Valid ranges are typically of the form - * "A.0 through B.C inclusive" where A <= B and C >= 0, - * which is why we don't have a CLASS_FILE_MIN_MINOR_VERSION. - */ - private static final int CLASS_FILE_MIN_MAJOR_VERSION = 45; - - /** - * maximum {@code .class} file major version - * - * Note: if you change this, please change "java.class.version" in System.java. - */ - private static final int CLASS_FILE_MAX_MAJOR_VERSION = 51; - - /** maximum {@code .class} file minor version */ - private static final int CLASS_FILE_MAX_MINOR_VERSION = 0; - - /** - * {@code non-null;} the file path for the class, excluding any base directory - * specification - */ - private final String filePath; - - /** {@code non-null;} the bytes of the file */ - private final ByteArray bytes; - - /** - * whether to be strict about parsing; if - * {@code false}, this avoids doing checks that only exist - * for purposes of verification (such as magic number matching and - * path-package consistency checking) - */ - private final boolean strictParse; - - /** - * {@code null-ok;} the constant pool; only ever {@code null} - * before the constant pool is successfully parsed - */ - private StdConstantPool pool; - - /** - * the class file field {@code access_flags}; will be {@code -1} - * before the file is successfully parsed - */ - private int accessFlags; - - /** - * {@code null-ok;} the class file field {@code this_class}, - * interpreted as a type constant; only ever {@code null} - * before the file is successfully parsed - */ - private CstType thisClass; - - /** - * {@code null-ok;} the class file field {@code super_class}, interpreted - * as a type constant if non-zero - */ - private CstType superClass; - - /** - * {@code null-ok;} the class file field {@code interfaces}; only - * ever {@code null} before the file is successfully - * parsed - */ - private TypeList interfaces; - - /** - * {@code null-ok;} the class file field {@code fields}; only ever - * {@code null} before the file is successfully parsed - */ - private FieldList fields; - - /** - * {@code null-ok;} the class file field {@code methods}; only ever - * {@code null} before the file is successfully parsed - */ - private MethodList methods; - - /** - * {@code null-ok;} the class file field {@code attributes}; only - * ever {@code null} before the file is successfully - * parsed - */ - private StdAttributeList attributes; - - /** {@code null-ok;} attribute factory, if any */ - private AttributeFactory attributeFactory; - - /** {@code null-ok;} parse observer, if any */ - private ParseObserver observer; - - /** - * Returns the string form of an object or {@code "(none)"} - * (rather than {@code "null"}) for {@code null}. - * - * @param obj {@code null-ok;} the object to stringify - * @return {@code non-null;} the appropriate string form - */ - public static String stringOrNone(Object obj) { - if (obj == null) { - return "(none)"; - } - - return obj.toString(); - } - - /** - * Constructs an instance. - * - * @param bytes {@code non-null;} the bytes of the file - * @param filePath {@code non-null;} the file path for the class, - * excluding any base directory specification - * @param strictParse whether to be strict about parsing; if - * {@code false}, this avoids doing checks that only exist - * for purposes of verification (such as magic number matching and - * path-package consistency checking) - */ - public DirectClassFile(ByteArray bytes, String filePath, - boolean strictParse) { - if (bytes == null) { - throw new NullPointerException("bytes == null"); - } - - if (filePath == null) { - throw new NullPointerException("filePath == null"); - } - - this.filePath = filePath; - this.bytes = bytes; - this.strictParse = strictParse; - this.accessFlags = -1; - } - - /** - * Constructs an instance. - * - * @param bytes {@code non-null;} the bytes of the file - * @param filePath {@code non-null;} the file path for the class, - * excluding any base directory specification - * @param strictParse whether to be strict about parsing; if - * {@code false}, this avoids doing checks that only exist - * for purposes of verification (such as magic number matching and - * path-package consistency checking) - */ - public DirectClassFile(byte[] bytes, String filePath, - boolean strictParse) { - this(new ByteArray(bytes), filePath, strictParse); - } - - /** - * Sets the parse observer for this instance. - * - * @param observer {@code null-ok;} the observer - */ - public void setObserver(ParseObserver observer) { - this.observer = observer; - } - - /** - * Sets the attribute factory to use. - * - * @param attributeFactory {@code non-null;} the attribute factory - */ - public void setAttributeFactory(AttributeFactory attributeFactory) { - if (attributeFactory == null) { - throw new NullPointerException("attributeFactory == null"); - } - - this.attributeFactory = attributeFactory; - } - - /** - * Gets the path where this class file is located. - * - * @return {@code non-null;} the filePath - */ - public String getFilePath() { - return filePath; - } - - /** - * Gets the {@link ByteArray} that this instance's data comes from. - * - * @return {@code non-null;} the bytes - */ - public ByteArray getBytes() { - return bytes; - } - - /** {@inheritDoc} */ - public int getMagic() { - parseToInterfacesIfNecessary(); - return getMagic0(); - } - - /** {@inheritDoc} */ - public int getMinorVersion() { - parseToInterfacesIfNecessary(); - return getMinorVersion0(); - } - - /** {@inheritDoc} */ - public int getMajorVersion() { - parseToInterfacesIfNecessary(); - return getMajorVersion0(); - } - - /** {@inheritDoc} */ - public int getAccessFlags() { - parseToInterfacesIfNecessary(); - return accessFlags; - } - - /** {@inheritDoc} */ - public CstType getThisClass() { - parseToInterfacesIfNecessary(); - return thisClass; - } - - /** {@inheritDoc} */ - public CstType getSuperclass() { - parseToInterfacesIfNecessary(); - return superClass; - } - - /** {@inheritDoc} */ - public ConstantPool getConstantPool() { - parseToInterfacesIfNecessary(); - return pool; - } - - /** {@inheritDoc} */ - public TypeList getInterfaces() { - parseToInterfacesIfNecessary(); - return interfaces; - } - - /** {@inheritDoc} */ - public FieldList getFields() { - parseToEndIfNecessary(); - return fields; - } - - /** {@inheritDoc} */ - public MethodList getMethods() { - parseToEndIfNecessary(); - return methods; - } - - /** {@inheritDoc} */ - public AttributeList getAttributes() { - parseToEndIfNecessary(); - return attributes; - } - - /** {@inheritDoc} */ - public CstString getSourceFile() { - AttributeList attribs = getAttributes(); - Attribute attSf = attribs.findFirst(AttSourceFile.ATTRIBUTE_NAME); - - if (attSf instanceof AttSourceFile) { - return ((AttSourceFile) attSf).getSourceFile(); - } - - return null; - } - - /** - * Constructs and returns an instance of {@link TypeList} whose - * data comes from the bytes of this instance, interpreted as a - * list of constant pool indices for classes, which are in turn - * translated to type constants. Instance construction will fail - * if any of the (alleged) indices turn out not to refer to - * constant pool entries of type {@code Class}. - * - * @param offset offset into {@link #bytes} for the start of the - * data - * @param size number of elements in the list (not number of bytes) - * @return {@code non-null;} an appropriately-constructed class list - */ - public TypeList makeTypeList(int offset, int size) { - if (size == 0) { - return StdTypeList.EMPTY; - } - - if (pool == null) { - throw new IllegalStateException("pool not yet initialized"); - } - - return new DcfTypeList(bytes, offset, size, pool, observer); - } - - /** - * Gets the class file field {@code magic}, but without doing any - * checks or parsing first. - * - * @return the magic value - */ - public int getMagic0() { - return bytes.getInt(0); - } - - /** - * Gets the class file field {@code minor_version}, but - * without doing any checks or parsing first. - * - * @return the minor version - */ - public int getMinorVersion0() { - return bytes.getUnsignedShort(4); - } - - /** - * Gets the class file field {@code major_version}, but - * without doing any checks or parsing first. - * - * @return the major version - */ - public int getMajorVersion0() { - return bytes.getUnsignedShort(6); - } - - /** - * Runs {@link #parse} if it has not yet been run to cover up to - * the interfaces list. - */ - private void parseToInterfacesIfNecessary() { - if (accessFlags == -1) { - parse(); - } - } - - /** - * Runs {@link #parse} if it has not yet been run successfully. - */ - private void parseToEndIfNecessary() { - if (attributes == null) { - parse(); - } - } - - /** - * Does the parsing, handing exceptions. - */ - private void parse() { - try { - parse0(); - } catch (ParseException ex) { - ex.addContext("...while parsing " + filePath); - throw ex; - } catch (RuntimeException ex) { - ParseException pe = new ParseException(ex); - pe.addContext("...while parsing " + filePath); - throw pe; - } - } - - /** - * Sees if the .class file header magic/version are within - * range. - * - * @param magic the value of a classfile "magic" field - * @param minorVersion the value of a classfile "minor_version" field - * @param majorVersion the value of a classfile "major_version" field - * @return true iff the parameters are valid and within range - */ - private boolean isGoodVersion(int magic, int minorVersion, - int majorVersion) { - /* Valid version ranges are typically of the form - * "A.0 through B.C inclusive" where A <= B and C >= 0, - * which is why we don't have a CLASS_FILE_MIN_MINOR_VERSION. - */ - if (magic == CLASS_FILE_MAGIC && minorVersion >= 0) { - /* Check against max first to handle the case where - * MIN_MAJOR == MAX_MAJOR. - */ - if (majorVersion == CLASS_FILE_MAX_MAJOR_VERSION) { - if (minorVersion <= CLASS_FILE_MAX_MINOR_VERSION) { - return true; - } - } else if (majorVersion < CLASS_FILE_MAX_MAJOR_VERSION && - majorVersion >= CLASS_FILE_MIN_MAJOR_VERSION) { - return true; - } - } - - return false; - } - - /** - * Does the actual parsing. - */ - private void parse0() { - if (bytes.size() < 10) { - throw new ParseException("severely truncated class file"); - } - - if (observer != null) { - observer.parsed(bytes, 0, 0, "begin classfile"); - observer.parsed(bytes, 0, 4, "magic: " + Hex.u4(getMagic0())); - observer.parsed(bytes, 4, 2, - "minor_version: " + Hex.u2(getMinorVersion0())); - observer.parsed(bytes, 6, 2, - "major_version: " + Hex.u2(getMajorVersion0())); - } - - if (strictParse) { - /* Make sure that this looks like a valid class file with a - * version that we can handle. - */ - if (!isGoodVersion(getMagic0(), getMinorVersion0(), - getMajorVersion0())) { - throw new ParseException("bad class file magic (" + - Hex.u4(getMagic0()) + - ") or version (" + - Hex.u2(getMajorVersion0()) + "." + - Hex.u2(getMinorVersion0()) + ")"); - } - } - - ConstantPoolParser cpParser = new ConstantPoolParser(bytes); - cpParser.setObserver(observer); - pool = cpParser.getPool(); - pool.setImmutable(); - - int at = cpParser.getEndOffset(); - int accessFlags = bytes.getUnsignedShort(at); // u2 access_flags; - int cpi = bytes.getUnsignedShort(at + 2); // u2 this_class; - thisClass = (CstType) pool.get(cpi); - cpi = bytes.getUnsignedShort(at + 4); // u2 super_class; - superClass = (CstType) pool.get0Ok(cpi); - int count = bytes.getUnsignedShort(at + 6); // u2 interfaces_count - - if (observer != null) { - observer.parsed(bytes, at, 2, - "access_flags: " + - AccessFlags.classString(accessFlags)); - observer.parsed(bytes, at + 2, 2, "this_class: " + thisClass); - observer.parsed(bytes, at + 4, 2, "super_class: " + - stringOrNone(superClass)); - observer.parsed(bytes, at + 6, 2, - "interfaces_count: " + Hex.u2(count)); - if (count != 0) { - observer.parsed(bytes, at + 8, 0, "interfaces:"); - } - } - - at += 8; - interfaces = makeTypeList(at, count); - at += count * 2; - - if (strictParse) { - /* - * Make sure that the file/jar path matches the declared - * package/class name. - */ - String thisClassName = thisClass.getClassType().getClassName(); - if (!(filePath.endsWith(".class") && - filePath.startsWith(thisClassName) && - (filePath.length() == (thisClassName.length() + 6)))) { - throw new ParseException("class name (" + thisClassName + - ") does not match path (" + - filePath + ")"); - } - } - - /* - * Only set the instance variable accessFlags here, since - * that's what signals a successful parse of the first part of - * the file (through the interfaces list). - */ - this.accessFlags = accessFlags; - - FieldListParser flParser = - new FieldListParser(this, thisClass, at, attributeFactory); - flParser.setObserver(observer); - fields = flParser.getList(); - at = flParser.getEndOffset(); - - MethodListParser mlParser = - new MethodListParser(this, thisClass, at, attributeFactory); - mlParser.setObserver(observer); - methods = mlParser.getList(); - at = mlParser.getEndOffset(); - - AttributeListParser alParser = - new AttributeListParser(this, AttributeFactory.CTX_CLASS, at, - attributeFactory); - alParser.setObserver(observer); - attributes = alParser.getList(); - attributes.setImmutable(); - at = alParser.getEndOffset(); - - if (at != bytes.size()) { - throw new ParseException("extra bytes at end of class file, " + - "at offset " + Hex.u4(at)); - } - - if (observer != null) { - observer.parsed(bytes, at, 0, "end classfile"); - } - } - - /** - * Implementation of {@link TypeList} whose data comes directly - * from the bytes of an instance of this (outer) class, - * interpreted as a list of constant pool indices for classes - * which are in turn returned as type constants. Instance - * construction will fail if any of the (alleged) indices turn out - * not to refer to constant pool entries of type - * {@code Class}. - */ - private static class DcfTypeList implements TypeList { - /** {@code non-null;} array containing the data */ - private final ByteArray bytes; - - /** number of elements in the list (not number of bytes) */ - private final int size; - - /** {@code non-null;} the constant pool */ - private final StdConstantPool pool; - - /** - * Constructs an instance. - * - * @param bytes {@code non-null;} original classfile's bytes - * @param offset offset into {@link #bytes} for the start of the - * data - * @param size number of elements in the list (not number of bytes) - * @param pool {@code non-null;} the constant pool to use - * @param observer {@code null-ok;} parse observer to use, if any - */ - public DcfTypeList(ByteArray bytes, int offset, int size, - StdConstantPool pool, ParseObserver observer) { - if (size < 0) { - throw new IllegalArgumentException("size < 0"); - } - - bytes = bytes.slice(offset, offset + size * 2); - this.bytes = bytes; - this.size = size; - this.pool = pool; - - for (int i = 0; i < size; i++) { - offset = i * 2; - int idx = bytes.getUnsignedShort(offset); - CstType type; - try { - type = (CstType) pool.get(idx); - } catch (ClassCastException ex) { - // Translate the exception. - throw new RuntimeException("bogus class cpi", ex); - } - if (observer != null) { - observer.parsed(bytes, offset, 2, " " + type); - } - } - } - - /** {@inheritDoc} */ - public boolean isMutable() { - return false; - } - - /** {@inheritDoc} */ - public int size() { - return size; - } - - /** {@inheritDoc} */ - public int getWordCount() { - // It is the same as size because all elements are classes. - return size; - } - - /** {@inheritDoc} */ - public Type getType(int n) { - int idx = bytes.getUnsignedShort(n * 2); - return ((CstType) pool.get(idx)).getClassType(); - } - - /** {@inheritDoc} */ - public TypeList withAddedType(Type type) { - throw new UnsupportedOperationException("unsupported"); - } - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/FieldListParser.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/FieldListParser.java deleted file mode 100644 index 2d8280ddcb5..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/FieldListParser.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.direct; - -import com.android.dx.cf.iface.AttributeList; -import com.android.dx.cf.iface.Member; -import com.android.dx.cf.iface.StdField; -import com.android.dx.cf.iface.StdFieldList; -import com.android.dx.rop.code.AccessFlags; -import com.android.dx.rop.cst.CstNat; -import com.android.dx.rop.cst.CstType; - -/** - * Parser for lists of fields in a class file. - */ -final /*package*/ class FieldListParser extends MemberListParser { - /** {@code non-null;} list in progress */ - private final StdFieldList fields; - - /** - * Constructs an instance. - * - * @param cf {@code non-null;} the class file to parse from - * @param definer {@code non-null;} class being defined - * @param offset offset in {@code bytes} to the start of the list - * @param attributeFactory {@code non-null;} attribute factory to use - */ - public FieldListParser(DirectClassFile cf, CstType definer, int offset, - AttributeFactory attributeFactory) { - super(cf, definer, offset, attributeFactory); - fields = new StdFieldList(getCount()); - } - - /** - * Gets the parsed list. - * - * @return {@code non-null;} the parsed list - */ - public StdFieldList getList() { - parseIfNecessary(); - return fields; - } - - /** {@inheritDoc} */ - @Override - protected String humanName() { - return "field"; - } - - /** {@inheritDoc} */ - @Override - protected String humanAccessFlags(int accessFlags) { - return AccessFlags.fieldString(accessFlags); - } - - /** {@inheritDoc} */ - @Override - protected int getAttributeContext() { - return AttributeFactory.CTX_FIELD; - } - - /** {@inheritDoc} */ - @Override - protected Member set(int n, int accessFlags, CstNat nat, - AttributeList attributes) { - StdField field = - new StdField(getDefiner(), accessFlags, nat, attributes); - - fields.set(n, field); - return field; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/MemberListParser.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/MemberListParser.java deleted file mode 100644 index 605bab89629..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/MemberListParser.java +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.direct; - -import com.android.dx.cf.iface.AttributeList; -import com.android.dx.cf.iface.Member; -import com.android.dx.cf.iface.ParseException; -import com.android.dx.cf.iface.ParseObserver; -import com.android.dx.cf.iface.StdAttributeList; -import com.android.dx.rop.cst.ConstantPool; -import com.android.dx.rop.cst.CstNat; -import com.android.dx.rop.cst.CstString; -import com.android.dx.rop.cst.CstType; -import com.android.dx.util.ByteArray; -import com.android.dx.util.Hex; - -/** - * Parser for lists of class file members (that is, fields and methods). - */ -abstract /*package*/ class MemberListParser { - /** {@code non-null;} the class file to parse from */ - private final DirectClassFile cf; - - /** {@code non-null;} class being defined */ - private final CstType definer; - - /** offset in the byte array of the classfile to the start of the list */ - private final int offset; - - /** {@code non-null;} attribute factory to use */ - private final AttributeFactory attributeFactory; - - /** {@code >= -1;} the end offset of this list in the byte array of the - * classfile, or {@code -1} if not yet parsed */ - private int endOffset; - - /** {@code null-ok;} parse observer, if any */ - private ParseObserver observer; - - /** - * Constructs an instance. - * - * @param cf {@code non-null;} the class file to parse from - * @param definer {@code non-null;} class being defined - * @param offset offset in {@code bytes} to the start of the list - * @param attributeFactory {@code non-null;} attribute factory to use - */ - public MemberListParser(DirectClassFile cf, CstType definer, - int offset, AttributeFactory attributeFactory) { - if (cf == null) { - throw new NullPointerException("cf == null"); - } - - if (offset < 0) { - throw new IllegalArgumentException("offset < 0"); - } - - if (attributeFactory == null) { - throw new NullPointerException("attributeFactory == null"); - } - - this.cf = cf; - this.definer = definer; - this.offset = offset; - this.attributeFactory = attributeFactory; - this.endOffset = -1; - } - - /** - * Gets the end offset of this constant pool in the {@code byte[]} - * which it came from. - * - * @return {@code >= 0;} the end offset - */ - public int getEndOffset() { - parseIfNecessary(); - return endOffset; - } - - /** - * Sets the parse observer for this instance. - * - * @param observer {@code null-ok;} the observer - */ - public final void setObserver(ParseObserver observer) { - this.observer = observer; - } - - /** - * Runs {@link #parse} if it has not yet been run successfully. - */ - protected final void parseIfNecessary() { - if (endOffset < 0) { - parse(); - } - } - - /** - * Gets the count of elements in the list. - * - * @return the count - */ - protected final int getCount() { - ByteArray bytes = cf.getBytes(); - return bytes.getUnsignedShort(offset); - } - - /** - * Gets the class file being defined. - * - * @return {@code non-null;} the class - */ - protected final CstType getDefiner() { - return definer; - } - - /** - * Gets the human-oriented name for what this instance is parsing. - * Subclasses must override this method. - * - * @return {@code non-null;} the human oriented name - */ - protected abstract String humanName(); - - /** - * Gets the human-oriented string for the given access flags. - * Subclasses must override this method. - * - * @param accessFlags the flags - * @return {@code non-null;} the string form - */ - protected abstract String humanAccessFlags(int accessFlags); - - /** - * Gets the {@code CTX_*} constant to use when parsing attributes. - * Subclasses must override this method. - * - * @return {@code non-null;} the human oriented name - */ - protected abstract int getAttributeContext(); - - /** - * Sets an element in the list. Subclasses must override this method. - * - * @param n which element - * @param accessFlags the {@code access_flags} - * @param nat the interpreted name and type (based on the two - * {@code *_index} fields) - * @param attributes list of parsed attributes - * @return {@code non-null;} the constructed member - */ - protected abstract Member set(int n, int accessFlags, CstNat nat, - AttributeList attributes); - - /** - * Does the actual parsing. - */ - private void parse() { - int attributeContext = getAttributeContext(); - int count = getCount(); - int at = offset + 2; // Skip the count. - - ByteArray bytes = cf.getBytes(); - ConstantPool pool = cf.getConstantPool(); - - if (observer != null) { - observer.parsed(bytes, offset, 2, - humanName() + "s_count: " + Hex.u2(count)); - } - - for (int i = 0; i < count; i++) { - try { - int accessFlags = bytes.getUnsignedShort(at); - int nameIdx = bytes.getUnsignedShort(at + 2); - int descIdx = bytes.getUnsignedShort(at + 4); - CstString name = (CstString) pool.get(nameIdx); - CstString desc = (CstString) pool.get(descIdx); - - if (observer != null) { - observer.startParsingMember(bytes, at, name.getString(), - desc.getString()); - observer.parsed(bytes, at, 0, "\n" + humanName() + - "s[" + i + "]:\n"); - observer.changeIndent(1); - observer.parsed(bytes, at, 2, - "access_flags: " + - humanAccessFlags(accessFlags)); - observer.parsed(bytes, at + 2, 2, - "name: " + name.toHuman()); - observer.parsed(bytes, at + 4, 2, - "descriptor: " + desc.toHuman()); - } - - at += 6; - AttributeListParser parser = - new AttributeListParser(cf, attributeContext, at, - attributeFactory); - parser.setObserver(observer); - at = parser.getEndOffset(); - StdAttributeList attributes = parser.getList(); - attributes.setImmutable(); - CstNat nat = new CstNat(name, desc); - Member member = set(i, accessFlags, nat, attributes); - - if (observer != null) { - observer.changeIndent(-1); - observer.parsed(bytes, at, 0, "end " + humanName() + - "s[" + i + "]\n"); - observer.endParsingMember(bytes, at, name.getString(), - desc.getString(), member); - } - } catch (ParseException ex) { - ex.addContext("...while parsing " + humanName() + "s[" + i + - "]"); - throw ex; - } catch (RuntimeException ex) { - ParseException pe = new ParseException(ex); - pe.addContext("...while parsing " + humanName() + "s[" + i + - "]"); - throw pe; - } - } - - endOffset = at; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/MethodListParser.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/MethodListParser.java deleted file mode 100644 index 9e3494e67a4..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/MethodListParser.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.direct; - -import com.android.dx.cf.iface.AttributeList; -import com.android.dx.cf.iface.Member; -import com.android.dx.cf.iface.StdMethod; -import com.android.dx.cf.iface.StdMethodList; -import com.android.dx.rop.code.AccessFlags; -import com.android.dx.rop.cst.CstNat; -import com.android.dx.rop.cst.CstType; - -/** - * Parser for lists of methods in a class file. - */ -final /*package*/ class MethodListParser extends MemberListParser { - /** {@code non-null;} list in progress */ - final private StdMethodList methods; - - /** - * Constructs an instance. - * - * @param cf {@code non-null;} the class file to parse from - * @param definer {@code non-null;} class being defined - * @param offset offset in {@code bytes} to the start of the list - * @param attributeFactory {@code non-null;} attribute factory to use - */ - public MethodListParser(DirectClassFile cf, CstType definer, - int offset, AttributeFactory attributeFactory) { - super(cf, definer, offset, attributeFactory); - methods = new StdMethodList(getCount()); - } - - /** - * Gets the parsed list. - * - * @return {@code non-null;} the parsed list - */ - public StdMethodList getList() { - parseIfNecessary(); - return methods; - } - - /** {@inheritDoc} */ - @Override - protected String humanName() { - return "method"; - } - - /** {@inheritDoc} */ - @Override - protected String humanAccessFlags(int accessFlags) { - return AccessFlags.methodString(accessFlags); - } - - /** {@inheritDoc} */ - @Override - protected int getAttributeContext() { - return AttributeFactory.CTX_METHOD; - } - - /** {@inheritDoc} */ - @Override - protected Member set(int n, int accessFlags, CstNat nat, - AttributeList attributes) { - StdMethod meth = - new StdMethod(getDefiner(), accessFlags, nat, attributes); - - methods.set(n, meth); - return meth; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/StdAttributeFactory.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/StdAttributeFactory.java deleted file mode 100644 index 992809a0a04..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/StdAttributeFactory.java +++ /dev/null @@ -1,762 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.direct; - -import com.android.dx.cf.attrib.AttAnnotationDefault; -import com.android.dx.cf.attrib.AttCode; -import com.android.dx.cf.attrib.AttConstantValue; -import com.android.dx.cf.attrib.AttDeprecated; -import com.android.dx.cf.attrib.AttEnclosingMethod; -import com.android.dx.cf.attrib.AttExceptions; -import com.android.dx.cf.attrib.AttInnerClasses; -import com.android.dx.cf.attrib.AttLineNumberTable; -import com.android.dx.cf.attrib.AttLocalVariableTable; -import com.android.dx.cf.attrib.AttLocalVariableTypeTable; -import com.android.dx.cf.attrib.AttRuntimeInvisibleAnnotations; -import com.android.dx.cf.attrib.AttRuntimeInvisibleParameterAnnotations; -import com.android.dx.cf.attrib.AttRuntimeVisibleAnnotations; -import com.android.dx.cf.attrib.AttRuntimeVisibleParameterAnnotations; -import com.android.dx.cf.attrib.AttSignature; -import com.android.dx.cf.attrib.AttSourceFile; -import com.android.dx.cf.attrib.AttSynthetic; -import com.android.dx.cf.attrib.InnerClassList; -import com.android.dx.cf.code.ByteCatchList; -import com.android.dx.cf.code.BytecodeArray; -import com.android.dx.cf.code.LineNumberList; -import com.android.dx.cf.code.LocalVariableList; -import com.android.dx.cf.iface.Attribute; -import com.android.dx.cf.iface.ParseException; -import com.android.dx.cf.iface.ParseObserver; -import com.android.dx.cf.iface.StdAttributeList; -import com.android.dx.rop.annotation.AnnotationVisibility; -import com.android.dx.rop.annotation.Annotations; -import com.android.dx.rop.annotation.AnnotationsList; -import com.android.dx.rop.code.AccessFlags; -import com.android.dx.rop.cst.Constant; -import com.android.dx.rop.cst.ConstantPool; -import com.android.dx.rop.cst.CstNat; -import com.android.dx.rop.cst.CstString; -import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.cst.TypedConstant; -import com.android.dx.rop.type.TypeList; -import com.android.dx.util.ByteArray; -import com.android.dx.util.Hex; -import java.io.IOException; - -/** - * Standard subclass of {@link AttributeFactory}, which knows how to parse - * all the standard attribute types. - */ -public class StdAttributeFactory - extends AttributeFactory { - /** {@code non-null;} shared instance of this class */ - public static final StdAttributeFactory THE_ONE = - new StdAttributeFactory(); - - /** - * Constructs an instance. - */ - public StdAttributeFactory() { - // This space intentionally left blank. - } - - /** {@inheritDoc} */ - @Override - protected Attribute parse0(DirectClassFile cf, int context, String name, - int offset, int length, ParseObserver observer) { - switch (context) { - case CTX_CLASS: { - if (name == AttDeprecated.ATTRIBUTE_NAME) { - return deprecated(cf, offset, length, observer); - } - if (name == AttEnclosingMethod.ATTRIBUTE_NAME) { - return enclosingMethod(cf, offset, length, observer); - } - if (name == AttInnerClasses.ATTRIBUTE_NAME) { - return innerClasses(cf, offset, length, observer); - } - if (name == AttRuntimeInvisibleAnnotations.ATTRIBUTE_NAME) { - return runtimeInvisibleAnnotations(cf, offset, length, - observer); - } - if (name == AttRuntimeVisibleAnnotations.ATTRIBUTE_NAME) { - return runtimeVisibleAnnotations(cf, offset, length, - observer); - } - if (name == AttSynthetic.ATTRIBUTE_NAME) { - return synthetic(cf, offset, length, observer); - } - if (name == AttSignature.ATTRIBUTE_NAME) { - return signature(cf, offset, length, observer); - } - if (name == AttSourceFile.ATTRIBUTE_NAME) { - return sourceFile(cf, offset, length, observer); - } - break; - } - case CTX_FIELD: { - if (name == AttConstantValue.ATTRIBUTE_NAME) { - return constantValue(cf, offset, length, observer); - } - if (name == AttDeprecated.ATTRIBUTE_NAME) { - return deprecated(cf, offset, length, observer); - } - if (name == AttRuntimeInvisibleAnnotations.ATTRIBUTE_NAME) { - return runtimeInvisibleAnnotations(cf, offset, length, - observer); - } - if (name == AttRuntimeVisibleAnnotations.ATTRIBUTE_NAME) { - return runtimeVisibleAnnotations(cf, offset, length, - observer); - } - if (name == AttSignature.ATTRIBUTE_NAME) { - return signature(cf, offset, length, observer); - } - if (name == AttSynthetic.ATTRIBUTE_NAME) { - return synthetic(cf, offset, length, observer); - } - break; - } - case CTX_METHOD: { - if (name == AttAnnotationDefault.ATTRIBUTE_NAME) { - return annotationDefault(cf, offset, length, observer); - } - if (name == AttCode.ATTRIBUTE_NAME) { - return code(cf, offset, length, observer); - } - if (name == AttDeprecated.ATTRIBUTE_NAME) { - return deprecated(cf, offset, length, observer); - } - if (name == AttExceptions.ATTRIBUTE_NAME) { - return exceptions(cf, offset, length, observer); - } - if (name == AttRuntimeInvisibleAnnotations.ATTRIBUTE_NAME) { - return runtimeInvisibleAnnotations(cf, offset, length, - observer); - } - if (name == AttRuntimeVisibleAnnotations.ATTRIBUTE_NAME) { - return runtimeVisibleAnnotations(cf, offset, length, - observer); - } - if (name == AttRuntimeInvisibleParameterAnnotations. - ATTRIBUTE_NAME) { - return runtimeInvisibleParameterAnnotations( - cf, offset, length, observer); - } - if (name == AttRuntimeVisibleParameterAnnotations. - ATTRIBUTE_NAME) { - return runtimeVisibleParameterAnnotations( - cf, offset, length, observer); - } - if (name == AttSignature.ATTRIBUTE_NAME) { - return signature(cf, offset, length, observer); - } - if (name == AttSynthetic.ATTRIBUTE_NAME) { - return synthetic(cf, offset, length, observer); - } - break; - } - case CTX_CODE: { - if (name == AttLineNumberTable.ATTRIBUTE_NAME) { - return lineNumberTable(cf, offset, length, observer); - } - if (name == AttLocalVariableTable.ATTRIBUTE_NAME) { - return localVariableTable(cf, offset, length, observer); - } - if (name == AttLocalVariableTypeTable.ATTRIBUTE_NAME) { - return localVariableTypeTable(cf, offset, length, - observer); - } - break; - } - } - - return super.parse0(cf, context, name, offset, length, observer); - } - - /** - * Parses an {@code AnnotationDefault} attribute. - */ - private Attribute annotationDefault(DirectClassFile cf, - int offset, int length, ParseObserver observer) { - if (length < 2) { - throwSeverelyTruncated(); - } - - AnnotationParser ap = - new AnnotationParser(cf, offset, length, observer); - Constant cst = ap.parseValueAttribute(); - - return new AttAnnotationDefault(cst, length); - } - - /** - * Parses a {@code Code} attribute. - */ - private Attribute code(DirectClassFile cf, int offset, int length, - ParseObserver observer) { - if (length < 12) { - return throwSeverelyTruncated(); - } - - ByteArray bytes = cf.getBytes(); - ConstantPool pool = cf.getConstantPool(); - int maxStack = bytes.getUnsignedShort(offset); // u2 max_stack - int maxLocals = bytes.getUnsignedShort(offset + 2); // u2 max_locals - int codeLength = bytes.getInt(offset + 4); // u4 code_length - int origOffset = offset; - - if (observer != null) { - observer.parsed(bytes, offset, 2, - "max_stack: " + Hex.u2(maxStack)); - observer.parsed(bytes, offset + 2, 2, - "max_locals: " + Hex.u2(maxLocals)); - observer.parsed(bytes, offset + 4, 4, - "code_length: " + Hex.u4(codeLength)); - } - - offset += 8; - length -= 8; - - if (length < (codeLength + 4)) { - return throwTruncated(); - } - - int codeOffset = offset; - offset += codeLength; - length -= codeLength; - BytecodeArray code = - new BytecodeArray(bytes.slice(codeOffset, codeOffset + codeLength), - pool); - if (observer != null) { - code.forEach(new CodeObserver(code.getBytes(), observer)); - } - - // u2 exception_table_length - int exceptionTableLength = bytes.getUnsignedShort(offset); - ByteCatchList catches = (exceptionTableLength == 0) ? - ByteCatchList.EMPTY : - new ByteCatchList(exceptionTableLength); - - if (observer != null) { - observer.parsed(bytes, offset, 2, - "exception_table_length: " + - Hex.u2(exceptionTableLength)); - } - - offset += 2; - length -= 2; - - if (length < (exceptionTableLength * 8 + 2)) { - return throwTruncated(); - } - - for (int i = 0; i < exceptionTableLength; i++) { - if (observer != null) { - observer.changeIndent(1); - } - - int startPc = bytes.getUnsignedShort(offset); - int endPc = bytes.getUnsignedShort(offset + 2); - int handlerPc = bytes.getUnsignedShort(offset + 4); - int catchTypeIdx = bytes.getUnsignedShort(offset + 6); - CstType catchType = (CstType) pool.get0Ok(catchTypeIdx); - catches.set(i, startPc, endPc, handlerPc, catchType); - if (observer != null) { - observer.parsed(bytes, offset, 8, - Hex.u2(startPc) + ".." + Hex.u2(endPc) + - " -> " + Hex.u2(handlerPc) + " " + - ((catchType == null) ? "" : - catchType.toHuman())); - } - offset += 8; - length -= 8; - - if (observer != null) { - observer.changeIndent(-1); - } - } - - catches.setImmutable(); - - AttributeListParser parser = - new AttributeListParser(cf, CTX_CODE, offset, this); - parser.setObserver(observer); - - StdAttributeList attributes = parser.getList(); - attributes.setImmutable(); - - int attributeByteCount = parser.getEndOffset() - offset; - if (attributeByteCount != length) { - return throwBadLength(attributeByteCount + (offset - origOffset)); - } - - return new AttCode(maxStack, maxLocals, code, catches, attributes); - } - - /** - * Parses a {@code ConstantValue} attribute. - */ - private Attribute constantValue(DirectClassFile cf, int offset, int length, - ParseObserver observer) { - if (length != 2) { - return throwBadLength(2); - } - - ByteArray bytes = cf.getBytes(); - ConstantPool pool = cf.getConstantPool(); - int idx = bytes.getUnsignedShort(offset); - TypedConstant cst = (TypedConstant) pool.get(idx); - Attribute result = new AttConstantValue(cst); - - if (observer != null) { - observer.parsed(bytes, offset, 2, "value: " + cst); - } - - return result; - } - - /** - * Parses a {@code Deprecated} attribute. - */ - private Attribute deprecated(DirectClassFile cf, int offset, int length, - ParseObserver observer) { - if (length != 0) { - return throwBadLength(0); - } - - return new AttDeprecated(); - } - - /** - * Parses an {@code EnclosingMethod} attribute. - */ - private Attribute enclosingMethod(DirectClassFile cf, int offset, - int length, ParseObserver observer) { - if (length != 4) { - throwBadLength(4); - } - - ByteArray bytes = cf.getBytes(); - ConstantPool pool = cf.getConstantPool(); - - int idx = bytes.getUnsignedShort(offset); - CstType type = (CstType) pool.get(idx); - - idx = bytes.getUnsignedShort(offset + 2); - CstNat method = (CstNat) pool.get0Ok(idx); - - Attribute result = new AttEnclosingMethod(type, method); - - if (observer != null) { - observer.parsed(bytes, offset, 2, "class: " + type); - observer.parsed(bytes, offset + 2, 2, "method: " + - DirectClassFile.stringOrNone(method)); - } - - return result; - } - - /** - * Parses an {@code Exceptions} attribute. - */ - private Attribute exceptions(DirectClassFile cf, int offset, int length, - ParseObserver observer) { - if (length < 2) { - return throwSeverelyTruncated(); - } - - ByteArray bytes = cf.getBytes(); - int count = bytes.getUnsignedShort(offset); // number_of_exceptions - - if (observer != null) { - observer.parsed(bytes, offset, 2, - "number_of_exceptions: " + Hex.u2(count)); - } - - offset += 2; - length -= 2; - - if (length != (count * 2)) { - throwBadLength((count * 2) + 2); - } - - TypeList list = cf.makeTypeList(offset, count); - return new AttExceptions(list); - } - - /** - * Parses an {@code InnerClasses} attribute. - */ - private Attribute innerClasses(DirectClassFile cf, int offset, int length, - ParseObserver observer) { - if (length < 2) { - return throwSeverelyTruncated(); - } - - ByteArray bytes = cf.getBytes(); - ConstantPool pool = cf.getConstantPool(); - int count = bytes.getUnsignedShort(offset); // number_of_classes - - if (observer != null) { - observer.parsed(bytes, offset, 2, - "number_of_classes: " + Hex.u2(count)); - } - - offset += 2; - length -= 2; - - if (length != (count * 8)) { - throwBadLength((count * 8) + 2); - } - - InnerClassList list = new InnerClassList(count); - - for (int i = 0; i < count; i++) { - int innerClassIdx = bytes.getUnsignedShort(offset); - int outerClassIdx = bytes.getUnsignedShort(offset + 2); - int nameIdx = bytes.getUnsignedShort(offset + 4); - int accessFlags = bytes.getUnsignedShort(offset + 6); - CstType innerClass = (CstType) pool.get(innerClassIdx); - CstType outerClass = (CstType) pool.get0Ok(outerClassIdx); - CstString name = (CstString) pool.get0Ok(nameIdx); - list.set(i, innerClass, outerClass, name, accessFlags); - if (observer != null) { - observer.parsed(bytes, offset, 2, - "inner_class: " + - DirectClassFile.stringOrNone(innerClass)); - observer.parsed(bytes, offset + 2, 2, - " outer_class: " + - DirectClassFile.stringOrNone(outerClass)); - observer.parsed(bytes, offset + 4, 2, - " name: " + - DirectClassFile.stringOrNone(name)); - observer.parsed(bytes, offset + 6, 2, - " access_flags: " + - AccessFlags.innerClassString(accessFlags)); - } - offset += 8; - } - - list.setImmutable(); - return new AttInnerClasses(list); - } - - /** - * Parses a {@code LineNumberTable} attribute. - */ - private Attribute lineNumberTable(DirectClassFile cf, int offset, - int length, ParseObserver observer) { - if (length < 2) { - return throwSeverelyTruncated(); - } - - ByteArray bytes = cf.getBytes(); - int count = bytes.getUnsignedShort(offset); // line_number_table_length - - if (observer != null) { - observer.parsed(bytes, offset, 2, - "line_number_table_length: " + Hex.u2(count)); - } - - offset += 2; - length -= 2; - - if (length != (count * 4)) { - throwBadLength((count * 4) + 2); - } - - LineNumberList list = new LineNumberList(count); - - for (int i = 0; i < count; i++) { - int startPc = bytes.getUnsignedShort(offset); - int lineNumber = bytes.getUnsignedShort(offset + 2); - list.set(i, startPc, lineNumber); - if (observer != null) { - observer.parsed(bytes, offset, 4, - Hex.u2(startPc) + " " + lineNumber); - } - offset += 4; - } - - list.setImmutable(); - return new AttLineNumberTable(list); - } - - /** - * Parses a {@code LocalVariableTable} attribute. - */ - private Attribute localVariableTable(DirectClassFile cf, int offset, - int length, ParseObserver observer) { - if (length < 2) { - return throwSeverelyTruncated(); - } - - ByteArray bytes = cf.getBytes(); - int count = bytes.getUnsignedShort(offset); - - if (observer != null) { - observer.parsed(bytes, offset, 2, - "local_variable_table_length: " + Hex.u2(count)); - } - - LocalVariableList list = parseLocalVariables( - bytes.slice(offset + 2, offset + length), cf.getConstantPool(), - observer, count, false); - return new AttLocalVariableTable(list); - } - - /** - * Parses a {@code LocalVariableTypeTable} attribute. - */ - private Attribute localVariableTypeTable(DirectClassFile cf, int offset, - int length, ParseObserver observer) { - if (length < 2) { - return throwSeverelyTruncated(); - } - - ByteArray bytes = cf.getBytes(); - int count = bytes.getUnsignedShort(offset); - - if (observer != null) { - observer.parsed(bytes, offset, 2, - "local_variable_type_table_length: " + Hex.u2(count)); - } - - LocalVariableList list = parseLocalVariables( - bytes.slice(offset + 2, offset + length), cf.getConstantPool(), - observer, count, true); - return new AttLocalVariableTypeTable(list); - } - - /** - * Parse the table part of either a {@code LocalVariableTable} - * or a {@code LocalVariableTypeTable}. - * - * @param bytes {@code non-null;} bytes to parse, which should only - * contain the table data (no header) - * @param pool {@code non-null;} constant pool to use - * @param count {@code >= 0;} the number of entries - * @param typeTable {@code true} iff this is for a type table - * @return {@code non-null;} the constructed list - */ - private LocalVariableList parseLocalVariables(ByteArray bytes, - ConstantPool pool, ParseObserver observer, int count, - boolean typeTable) { - if (bytes.size() != (count * 10)) { - // "+ 2" is for the count. - throwBadLength((count * 10) + 2); - } - - ByteArray.MyDataInputStream in = bytes.makeDataInputStream(); - LocalVariableList list = new LocalVariableList(count); - - try { - for (int i = 0; i < count; i++) { - int startPc = in.readUnsignedShort(); - int length = in.readUnsignedShort(); - int nameIdx = in.readUnsignedShort(); - int typeIdx = in.readUnsignedShort(); - int index = in.readUnsignedShort(); - CstString name = (CstString) pool.get(nameIdx); - CstString type = (CstString) pool.get(typeIdx); - CstString descriptor = null; - CstString signature = null; - - if (typeTable) { - signature = type; - } else { - descriptor = type; - } - - list.set(i, startPc, length, name, - descriptor, signature, index); - - if (observer != null) { - observer.parsed(bytes, i * 10, 10, Hex.u2(startPc) + - ".." + Hex.u2(startPc + length) + " " + - Hex.u2(index) + " " + name.toHuman() + " " + - type.toHuman()); - } - } - } catch (IOException ex) { - throw new RuntimeException("shouldn't happen", ex); - } - - list.setImmutable(); - return list; - } - - /** - * Parses a {@code RuntimeInvisibleAnnotations} attribute. - */ - private Attribute runtimeInvisibleAnnotations(DirectClassFile cf, - int offset, int length, ParseObserver observer) { - if (length < 2) { - throwSeverelyTruncated(); - } - - AnnotationParser ap = - new AnnotationParser(cf, offset, length, observer); - Annotations annotations = - ap.parseAnnotationAttribute(AnnotationVisibility.BUILD); - - return new AttRuntimeInvisibleAnnotations(annotations, length); - } - - /** - * Parses a {@code RuntimeVisibleAnnotations} attribute. - */ - private Attribute runtimeVisibleAnnotations(DirectClassFile cf, - int offset, int length, ParseObserver observer) { - if (length < 2) { - throwSeverelyTruncated(); - } - - AnnotationParser ap = - new AnnotationParser(cf, offset, length, observer); - Annotations annotations = - ap.parseAnnotationAttribute(AnnotationVisibility.RUNTIME); - - return new AttRuntimeVisibleAnnotations(annotations, length); - } - - /** - * Parses a {@code RuntimeInvisibleParameterAnnotations} attribute. - */ - private Attribute runtimeInvisibleParameterAnnotations(DirectClassFile cf, - int offset, int length, ParseObserver observer) { - if (length < 2) { - throwSeverelyTruncated(); - } - - AnnotationParser ap = - new AnnotationParser(cf, offset, length, observer); - AnnotationsList list = - ap.parseParameterAttribute(AnnotationVisibility.BUILD); - - return new AttRuntimeInvisibleParameterAnnotations(list, length); - } - - /** - * Parses a {@code RuntimeVisibleParameterAnnotations} attribute. - */ - private Attribute runtimeVisibleParameterAnnotations(DirectClassFile cf, - int offset, int length, ParseObserver observer) { - if (length < 2) { - throwSeverelyTruncated(); - } - - AnnotationParser ap = - new AnnotationParser(cf, offset, length, observer); - AnnotationsList list = - ap.parseParameterAttribute(AnnotationVisibility.RUNTIME); - - return new AttRuntimeVisibleParameterAnnotations(list, length); - } - - /** - * Parses a {@code Signature} attribute. - */ - private Attribute signature(DirectClassFile cf, int offset, int length, - ParseObserver observer) { - if (length != 2) { - throwBadLength(2); - } - - ByteArray bytes = cf.getBytes(); - ConstantPool pool = cf.getConstantPool(); - int idx = bytes.getUnsignedShort(offset); - CstString cst = (CstString) pool.get(idx); - Attribute result = new AttSignature(cst); - - if (observer != null) { - observer.parsed(bytes, offset, 2, "signature: " + cst); - } - - return result; - } - - /** - * Parses a {@code SourceFile} attribute. - */ - private Attribute sourceFile(DirectClassFile cf, int offset, int length, - ParseObserver observer) { - if (length != 2) { - throwBadLength(2); - } - - ByteArray bytes = cf.getBytes(); - ConstantPool pool = cf.getConstantPool(); - int idx = bytes.getUnsignedShort(offset); - CstString cst = (CstString) pool.get(idx); - Attribute result = new AttSourceFile(cst); - - if (observer != null) { - observer.parsed(bytes, offset, 2, "source: " + cst); - } - - return result; - } - - /** - * Parses a {@code Synthetic} attribute. - */ - private Attribute synthetic(DirectClassFile cf, int offset, int length, - ParseObserver observer) { - if (length != 0) { - return throwBadLength(0); - } - - return new AttSynthetic(); - } - - /** - * Throws the right exception when a known attribute has a way too short - * length. - * - * @return never - * @throws ParseException always thrown - */ - private static Attribute throwSeverelyTruncated() { - throw new ParseException("severely truncated attribute"); - } - - /** - * Throws the right exception when a known attribute has a too short - * length. - * - * @return never - * @throws ParseException always thrown - */ - private static Attribute throwTruncated() { - throw new ParseException("truncated attribute"); - } - - /** - * Throws the right exception when an attribute has an unexpected length - * (given its contents). - * - * @param expected expected length - * @return never - * @throws ParseException always thrown - */ - private static Attribute throwBadLength(int expected) { - throw new ParseException("bad attribute length; expected length " + - Hex.u4(expected)); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/package.html b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/package.html deleted file mode 100644 index 2a461984321..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/direct/package.html +++ /dev/null @@ -1,12 +0,0 @@ - -

Implementation of cf.iface.* based on a direct representation -of class files as byte[]s.

- -

PACKAGES USED: -

    -
  • com.android.dx.cf.attrib
  • -
  • com.android.dx.cf.iface
  • -
  • com.android.dx.rop.pool
  • -
  • com.android.dx.util
  • -
- diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/Attribute.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/Attribute.java deleted file mode 100644 index b075251db8a..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/Attribute.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.iface; - -/** - * Interface representing attributes of class files (directly or indirectly). - */ -public interface Attribute { - /** - * Get the name of the attribute. - * - * @return {@code non-null;} the name - */ - public String getName(); - - /** - * Get the total length of the attribute in bytes, including the - * header. Since the header is always six bytes, the result of - * this method is always at least {@code 6}. - * - * @return {@code >= 6;} the total length, in bytes - */ - public int byteLength(); -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/AttributeList.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/AttributeList.java deleted file mode 100644 index f7a1d270537..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/AttributeList.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.iface; - -/** - * Interface for lists of attributes. - */ -public interface AttributeList { - /** - * Get whether this instance is mutable. Note that the - * {@code AttributeList} interface itself doesn't provide any means - * of mutation, but that doesn't mean that there isn't a non-interface - * way of mutating an instance. - * - * @return {@code true} iff this instance is somehow mutable - */ - public boolean isMutable(); - - /** - * Get the number of attributes in the list. - * - * @return the size - */ - public int size(); - - /** - * Get the {@code n}th attribute. - * - * @param n {@code n >= 0, n < size();} which attribute - * @return {@code non-null;} the attribute in question - */ - public Attribute get(int n); - - /** - * Get the total length of this list in bytes, when part of a - * class file. The returned value includes the two bytes for the - * {@code attributes_count} length indicator. - * - * @return {@code >= 2;} the total length, in bytes - */ - public int byteLength(); - - /** - * Get the first attribute in the list with the given name, if any. - * - * @param name {@code non-null;} attribute name - * @return {@code null-ok;} first attribute in the list with the given name, - * or {@code null} if there is none - */ - public Attribute findFirst(String name); - - /** - * Get the next attribute in the list after the given one, with the same - * name, if any. - * - * @param attrib {@code non-null;} attribute to start looking after - * @return {@code null-ok;} next attribute after {@code attrib} with the - * same name as {@code attrib} - */ - public Attribute findNext(Attribute attrib); -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/ClassFile.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/ClassFile.java deleted file mode 100644 index cb5237a50cd..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/ClassFile.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.iface; - -import com.android.dx.rop.cst.ConstantPool; -import com.android.dx.rop.cst.CstString; -import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.type.TypeList; - -/** - * Interface for things which purport to be class files or reasonable - * facsimiles thereof. - * - *

Note: The fields referred to in this documentation are of the - * {@code ClassFile} structure defined in vmspec-2 sec4.1. - */ -public interface ClassFile { - /** - * Gets the field {@code magic}. - * - * @return the value in question - */ - public int getMagic(); - - /** - * Gets the field {@code minor_version}. - * - * @return the value in question - */ - public int getMinorVersion(); - - /** - * Gets the field {@code major_version}. - * - * @return the value in question - */ - public int getMajorVersion(); - - /** - * Gets the field {@code access_flags}. - * - * @return the value in question - */ - public int getAccessFlags(); - - /** - * Gets the field {@code this_class}, interpreted as a type constant. - * - * @return {@code non-null;} the value in question - */ - public CstType getThisClass(); - - /** - * Gets the field {@code super_class}, interpreted as a type constant - * if non-zero. - * - * @return {@code null-ok;} the value in question - */ - public CstType getSuperclass(); - - /** - * Gets the field {@code constant_pool} (along with - * {@code constant_pool_count}). - * - * @return {@code non-null;} the constant pool - */ - public ConstantPool getConstantPool(); - - /** - * Gets the field {@code interfaces} (along with - * {@code interfaces_count}). - * - * @return {@code non-null;} the list of interfaces - */ - public TypeList getInterfaces(); - - /** - * Gets the field {@code fields} (along with - * {@code fields_count}). - * - * @return {@code non-null;} the list of fields - */ - public FieldList getFields(); - - /** - * Gets the field {@code methods} (along with - * {@code methods_count}). - * - * @return {@code non-null;} the list of fields - */ - public MethodList getMethods(); - - /** - * Gets the field {@code attributes} (along with - * {@code attributes_count}). - * - * @return {@code non-null;} the list of attributes - */ - public AttributeList getAttributes(); - - /** - * Gets the name out of the {@code SourceFile} attribute of this - * file, if any. This is a convenient shorthand for scrounging around - * the class's attributes. - * - * @return {@code non-null;} the constant pool - */ - public CstString getSourceFile(); -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/Field.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/Field.java deleted file mode 100644 index e3002bcd08c..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/Field.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.iface; - -import com.android.dx.rop.cst.TypedConstant; - -/** - * Interface representing fields of class files. - */ -public interface Field - extends Member { - /** - * Get the constant value for this field, if any. This only returns - * non-{@code null} for a {@code static final} field which - * includes a {@code ConstantValue} attribute. - * - * @return {@code null-ok;} the constant value, or {@code null} if this - * field isn't a constant - */ - public TypedConstant getConstantValue(); -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/FieldList.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/FieldList.java deleted file mode 100644 index 9cd27a31138..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/FieldList.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.iface; - -/** - * Interface for lists of fields. - */ -public interface FieldList -{ - /** - * Get whether this instance is mutable. Note that the - * {@code FieldList} interface itself doesn't provide any means - * of mutation, but that doesn't mean that there isn't a non-interface - * way of mutating an instance. - * - * @return {@code true} iff this instance is somehow mutable - */ - public boolean isMutable(); - - /** - * Get the number of fields in the list. - * - * @return the size - */ - public int size(); - - /** - * Get the {@code n}th field. - * - * @param n {@code n >= 0, n < size();} which field - * @return {@code non-null;} the field in question - */ - public Field get(int n); -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/Member.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/Member.java deleted file mode 100644 index b346de4475d..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/Member.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.iface; - -import com.android.dx.rop.cst.CstNat; -import com.android.dx.rop.cst.CstString; -import com.android.dx.rop.cst.CstType; - -/** - * Interface representing members of class files (that is, fields and methods). - */ -public interface Member { - /** - * Get the defining class. - * - * @return {@code non-null;} the defining class - */ - public CstType getDefiningClass(); - - /** - * Get the field {@code access_flags}. - * - * @return the access flags - */ - public int getAccessFlags(); - - /** - * Get the field {@code name_index} of the member. This is - * just a convenient shorthand for {@code getNat().getName()}. - * - * @return {@code non-null;} the name - */ - public CstString getName(); - - /** - * Get the field {@code descriptor_index} of the member. This is - * just a convenient shorthand for {@code getNat().getDescriptor()}. - * - * @return {@code non-null;} the descriptor - */ - public CstString getDescriptor(); - - /** - * Get the name and type associated with this member. This is a - * combination of the fields {@code name_index} and - * {@code descriptor_index} in the original classfile, interpreted - * via the constant pool. - * - * @return {@code non-null;} the name and type - */ - public CstNat getNat(); - - /** - * Get the field {@code attributes} (along with - * {@code attributes_count}). - * - * @return {@code non-null;} the constant pool - */ - public AttributeList getAttributes(); -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/Method.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/Method.java deleted file mode 100644 index 18b9af64f85..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/Method.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.iface; - -import com.android.dx.rop.type.Prototype; - -/** - * Interface representing methods of class files. - */ -public interface Method - extends Member -{ - /** - * Get the effective method descriptor, which includes, if - * necessary, a first {@code this} parameter. - * - * @return {@code non-null;} the effective method descriptor - */ - public Prototype getEffectiveDescriptor(); -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/MethodList.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/MethodList.java deleted file mode 100644 index dfa6528a692..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/MethodList.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.iface; - -/** - * Interface for lists of methods. - */ -public interface MethodList { - /** - * Get whether this instance is mutable. Note that the - * {@code MethodList} interface itself doesn't provide any means - * of mutation, but that doesn't mean that there isn't a non-interface - * way of mutating an instance. - * - * @return {@code true} iff this instance is somehow mutable - */ - public boolean isMutable(); - - /** - * Get the number of methods in the list. - * - * @return the size - */ - public int size(); - - /** - * Get the {@code n}th method. - * - * @param n {@code n >= 0, n < size();} which method - * @return {@code non-null;} the method in question - */ - public Method get(int n); -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/ParseException.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/ParseException.java deleted file mode 100644 index 6ed6d3bbf1a..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/ParseException.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.iface; - -import com.android.dex.util.ExceptionWithContext; - -/** - * Exception from parsing. - */ -public class ParseException - extends ExceptionWithContext { - public ParseException(String message) { - super(message); - } - - public ParseException(Throwable cause) { - super(cause); - } - - public ParseException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/ParseObserver.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/ParseObserver.java deleted file mode 100644 index 98d5a75c2b9..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/ParseObserver.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.iface; - -import com.android.dx.util.ByteArray; - -/** - * Observer of parsing in action. This is used to supply feedback from - * the various things that parse particularly to the dumping utilities. - */ -public interface ParseObserver { - /** - * Indicate that the level of indentation for a dump should increase - * or decrease (positive or negative argument, respectively). - * - * @param indentDelta the amount to change indentation - */ - public void changeIndent(int indentDelta); - - /** - * Indicate that a particular member is now being parsed. - * - * @param bytes {@code non-null;} the source that is being parsed - * @param offset offset into {@code bytes} for the start of the - * member - * @param name {@code non-null;} name of the member - * @param descriptor {@code non-null;} descriptor of the member - */ - public void startParsingMember(ByteArray bytes, int offset, String name, - String descriptor); - - /** - * Indicate that a particular member is no longer being parsed. - * - * @param bytes {@code non-null;} the source that was parsed - * @param offset offset into {@code bytes} for the end of the - * member - * @param name {@code non-null;} name of the member - * @param descriptor {@code non-null;} descriptor of the member - * @param member {@code non-null;} the actual member that was parsed - */ - public void endParsingMember(ByteArray bytes, int offset, String name, - String descriptor, Member member); - - /** - * Indicate that some parsing happened. - * - * @param bytes {@code non-null;} the source that was parsed - * @param offset offset into {@code bytes} for what was parsed - * @param len number of bytes parsed - * @param human {@code non-null;} human form for what was parsed - */ - public void parsed(ByteArray bytes, int offset, int len, String human); -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/StdAttributeList.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/StdAttributeList.java deleted file mode 100644 index 287b8c7f303..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/StdAttributeList.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.iface; - -import com.android.dx.util.FixedSizeList; - -/** - * Standard implementation of {@link AttributeList}, which directly stores - * an array of {@link Attribute} objects and can be made immutable. - */ -public final class StdAttributeList extends FixedSizeList - implements AttributeList { - /** - * Constructs an instance. All indices initially contain {@code null}. - * - * @param size the size of the list - */ - public StdAttributeList(int size) { - super(size); - } - - /** {@inheritDoc} */ - public Attribute get(int n) { - return (Attribute) get0(n); - } - - /** {@inheritDoc} */ - public int byteLength() { - int sz = size(); - int result = 2; // u2 attributes_count - - for (int i = 0; i < sz; i++) { - result += get(i).byteLength(); - } - - return result; - } - - /** {@inheritDoc} */ - public Attribute findFirst(String name) { - int sz = size(); - - for (int i = 0; i < sz; i++) { - Attribute att = get(i); - if (att.getName().equals(name)) { - return att; - } - } - - return null; - } - - /** {@inheritDoc} */ - public Attribute findNext(Attribute attrib) { - int sz = size(); - int at; - - outer: { - for (at = 0; at < sz; at++) { - Attribute att = get(at); - if (att == attrib) { - break outer; - } - } - - return null; - } - - String name = attrib.getName(); - - for (at++; at < sz; at++) { - Attribute att = get(at); - if (att.getName().equals(name)) { - return att; - } - } - - return null; - } - - /** - * Sets the attribute at the given index. - * - * @param n {@code >= 0, < size();} which attribute - * @param attribute {@code null-ok;} the attribute object - */ - public void set(int n, Attribute attribute) { - set0(n, attribute); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/StdField.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/StdField.java deleted file mode 100644 index ef9873d6fc8..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/StdField.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.iface; - -import com.android.dx.cf.attrib.AttConstantValue; -import com.android.dx.rop.cst.CstNat; -import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.cst.TypedConstant; - -/** - * Standard implementation of {@link Field}, which directly stores - * all the associated data. - */ -public final class StdField extends StdMember implements Field { - /** - * Constructs an instance. - * - * @param definingClass {@code non-null;} the defining class - * @param accessFlags access flags - * @param nat {@code non-null;} member name and type (descriptor) - * @param attributes {@code non-null;} list of associated attributes - */ - public StdField(CstType definingClass, int accessFlags, CstNat nat, - AttributeList attributes) { - super(definingClass, accessFlags, nat, attributes); - } - - /** {@inheritDoc} */ - public TypedConstant getConstantValue() { - AttributeList attribs = getAttributes(); - AttConstantValue cval = (AttConstantValue) - attribs.findFirst(AttConstantValue.ATTRIBUTE_NAME); - - if (cval == null) { - return null; - } - - return cval.getConstantValue(); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/StdFieldList.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/StdFieldList.java deleted file mode 100644 index f27bd226129..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/StdFieldList.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.iface; - -import com.android.dx.util.FixedSizeList; - -/** - * Standard implementation of {@link FieldList}, which directly stores - * an array of {@link Field} objects and can be made immutable. - */ -public final class StdFieldList extends FixedSizeList implements FieldList { - /** - * Constructs an instance. All indices initially contain {@code null}. - * - * @param size the size of the list - */ - public StdFieldList(int size) { - super(size); - } - - /** {@inheritDoc} */ - public Field get(int n) { - return (Field) get0(n); - } - - /** - * Sets the field at the given index. - * - * @param n {@code >= 0, < size();} which field - * @param field {@code null-ok;} the field object - */ - public void set(int n, Field field) { - set0(n, field); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/StdMember.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/StdMember.java deleted file mode 100644 index e67b216ec39..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/StdMember.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.iface; - -import com.android.dx.rop.cst.CstNat; -import com.android.dx.rop.cst.CstString; -import com.android.dx.rop.cst.CstType; - -/** - * Standard implementation of {@link Member}, which directly stores - * all the associated data. - */ -public abstract class StdMember implements Member { - /** {@code non-null;} the defining class */ - private final CstType definingClass; - - /** access flags */ - private final int accessFlags; - - /** {@code non-null;} member name and type */ - private final CstNat nat; - - /** {@code non-null;} list of associated attributes */ - private final AttributeList attributes; - - /** - * Constructs an instance. - * - * @param definingClass {@code non-null;} the defining class - * @param accessFlags access flags - * @param nat {@code non-null;} member name and type (descriptor) - * @param attributes {@code non-null;} list of associated attributes - */ - public StdMember(CstType definingClass, int accessFlags, CstNat nat, - AttributeList attributes) { - if (definingClass == null) { - throw new NullPointerException("definingClass == null"); - } - - if (nat == null) { - throw new NullPointerException("nat == null"); - } - - if (attributes == null) { - throw new NullPointerException("attributes == null"); - } - - this.definingClass = definingClass; - this.accessFlags = accessFlags; - this.nat = nat; - this.attributes = attributes; - } - - /** {@inheritDoc} */ - @Override - public String toString() { - StringBuffer sb = new StringBuffer(100); - - sb.append(getClass().getName()); - sb.append('{'); - sb.append(nat.toHuman()); - sb.append('}'); - - return sb.toString(); - } - - /** {@inheritDoc} */ - public final CstType getDefiningClass() { - return definingClass; - } - - /** {@inheritDoc} */ - public final int getAccessFlags() { - return accessFlags; - } - - /** {@inheritDoc} */ - public final CstNat getNat() { - return nat; - } - - /** {@inheritDoc} */ - public final CstString getName() { - return nat.getName(); - } - - /** {@inheritDoc} */ - public final CstString getDescriptor() { - return nat.getDescriptor(); - } - - /** {@inheritDoc} */ - public final AttributeList getAttributes() { - return attributes; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/StdMethod.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/StdMethod.java deleted file mode 100644 index c511d7d0a50..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/StdMethod.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.iface; - -import com.android.dx.rop.code.AccessFlags; -import com.android.dx.rop.cst.CstNat; -import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.type.Prototype; - -/** - * Standard implementation of {@link Method}, which directly stores - * all the associated data. - */ -public final class StdMethod extends StdMember implements Method { - /** {@code non-null;} the effective method descriptor */ - private final Prototype effectiveDescriptor; - - /** - * Constructs an instance. - * - * @param definingClass {@code non-null;} the defining class - * @param accessFlags access flags - * @param nat {@code non-null;} member name and type (descriptor) - * @param attributes {@code non-null;} list of associated attributes - */ - public StdMethod(CstType definingClass, int accessFlags, CstNat nat, - AttributeList attributes) { - super(definingClass, accessFlags, nat, attributes); - - String descStr = getDescriptor().getString(); - effectiveDescriptor = - Prototype.intern(descStr, definingClass.getClassType(), - AccessFlags.isStatic(accessFlags), - nat.isInstanceInit()); - } - - /** {@inheritDoc} */ - public Prototype getEffectiveDescriptor() { - return effectiveDescriptor; - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/StdMethodList.java b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/StdMethodList.java deleted file mode 100644 index 417cdeee125..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/StdMethodList.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.cf.iface; - -import com.android.dx.util.FixedSizeList; - -/** - * Standard implementation of {@link MethodList}, which directly stores - * an array of {@link Method} objects and can be made immutable. - */ -public final class StdMethodList extends FixedSizeList implements MethodList { - /** - * Constructs an instance. All indices initially contain {@code null}. - * - * @param size the size of the list - */ - public StdMethodList(int size) { - super(size); - } - - /** {@inheritDoc} */ - public Method get(int n) { - return (Method) get0(n); - } - - /** - * Sets the method at the given index. - * - * @param n {@code >= 0, < size();} which method - * @param method {@code null-ok;} the method object - */ - public void set(int n, Method method) { - set0(n, method); - } -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/package.html b/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/package.html deleted file mode 100644 index c7345527dae..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/cf/iface/package.html +++ /dev/null @@ -1,10 +0,0 @@ - -

Interfaces and base classes for dealing with class files. This package -doesn't have any parsing but does have basic container implementations.

- -

PACKAGES USED: -

    -
  • com.android.dx.rop.pool
  • -
  • com.android.dx.util
  • -
- diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/command/DxConsole.java b/third-party/java/dx-from-kitkat/src/com/android/dx/command/DxConsole.java deleted file mode 100644 index 31901171e80..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/command/DxConsole.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.command; - -import java.io.PrintStream; - -/** - * Provides standard and error PrintStream object to output information.
- * By default the PrintStream objects link to {@code System.out} and - * {@code System.err} but they can be changed to link to other - * PrintStream. - */ -public class DxConsole { - /** - * Standard output stream. Links to {@code System.out} by default. - */ - public PrintStream out = System.out; - - /** - * Error output stream. Links to {@code System.err} by default. - */ - public PrintStream err = System.err; -} diff --git a/third-party/java/dx-from-kitkat/src/com/android/dx/command/Main.java b/third-party/java/dx-from-kitkat/src/com/android/dx/command/Main.java deleted file mode 100644 index c421b4ecfc6..00000000000 --- a/third-party/java/dx-from-kitkat/src/com/android/dx/command/Main.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.command; - -import com.android.dx.Version; - -/** - * Main class for dx. It recognizes enough options to be able to dispatch - * to the right "actual" main. - */ -public class Main { - private static final String USAGE_MESSAGE = - "usage:\n" + - " dx --dex [--debug] [--verbose] [--positions=