{
- 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 extends java.util.zip.ZipEntry> 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=