diff options
author | Jean-Philippe Lesot <jplesot@google.com> | 2013-05-17 07:26:19 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2013-05-17 07:26:20 +0000 |
commit | 97208a0be35a4b9583172dc853150a32bb138f15 (patch) | |
tree | 82ad444684cec09d06af862d40d051249a61ab81 | |
parent | 467f7e3aaf8aafe324744bfd825fe9941862b7b7 (diff) | |
parent | 5ca383d7373cf7c54706b8e70d534deee8d2e3ad (diff) | |
download | android_dalvik-97208a0be35a4b9583172dc853150a32bb138f15.tar.gz android_dalvik-97208a0be35a4b9583172dc853150a32bb138f15.tar.bz2 android_dalvik-97208a0be35a4b9583172dc853150a32bb138f15.zip |
Merge "Added support for version 51 class files in dx"
19 files changed, 275 insertions, 99 deletions
diff --git a/dx/src/com/android/dx/cf/code/ByteOps.java b/dx/src/com/android/dx/cf/code/ByteOps.java index 13760088c..850346a94 100644 --- a/dx/src/com/android/dx/cf/code/ByteOps.java +++ b/dx/src/com/android/dx/cf/code/ByteOps.java @@ -210,6 +210,7 @@ public class ByteOps { 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; diff --git a/dx/src/com/android/dx/cf/code/BytecodeArray.java b/dx/src/com/android/dx/cf/code/BytecodeArray.java index f4ea007b9..424b971a8 100644 --- a/dx/src/com/android/dx/cf/code/BytecodeArray.java +++ b/dx/src/com/android/dx/cf/code/BytecodeArray.java @@ -16,6 +16,7 @@ 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; @@ -772,6 +773,9 @@ public final class BytecodeArray { count | (expectZero << 8)); return 5; } + case ByteOps.INVOKEDYNAMIC: { + throw new ParseException("invokedynamic not supported"); + } case ByteOps.NEWARRAY: { return parseNewarray(offset, visitor); } diff --git a/dx/src/com/android/dx/cf/cst/ConstantPoolParser.java b/dx/src/com/android/dx/cf/cst/ConstantPoolParser.java index 7ec2fbac0..036c8802a 100644 --- a/dx/src/com/android/dx/cf/cst/ConstantPoolParser.java +++ b/dx/src/com/android/dx/cf/cst/ConstantPoolParser.java @@ -27,6 +27,9 @@ 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; @@ -184,41 +187,51 @@ public final class ConstantPoolParser { for (int i = 1; i < offsets.length; i += lastCategory) { offsets[i] = at; int tag = bytes.getUnsignedByte(at); - 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; - } - default: { - ParseException ex = - new ParseException("unknown tag byte: " + Hex.u1(tag)); - ex.addContext("...while preparsing cst " + Hex.u2(i) + - " at offset " + Hex.u4(at)); - throw ex; + 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; } } @@ -313,6 +326,18 @@ public final class ConstantPoolParser { 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) + diff --git a/dx/src/com/android/dx/cf/cst/ConstantTags.java b/dx/src/com/android/dx/cf/cst/ConstantTags.java index 9febbdf5e..56ef4d75f 100644 --- a/dx/src/com/android/dx/cf/cst/ConstantTags.java +++ b/dx/src/com/android/dx/cf/cst/ConstantTags.java @@ -52,4 +52,13 @@ public interface ConstantTags { /** 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/dx/src/com/android/dx/cf/direct/DirectClassFile.java b/dx/src/com/android/dx/cf/direct/DirectClassFile.java index a7bb073a6..2af2efe68 100644 --- a/dx/src/com/android/dx/cf/direct/DirectClassFile.java +++ b/dx/src/com/android/dx/cf/direct/DirectClassFile.java @@ -50,6 +50,7 @@ public class DirectClassFile implements ClassFile { * 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), @@ -68,7 +69,7 @@ public class DirectClassFile implements ClassFile { * * Note: if you change this, please change "java.class.version" in System.java. */ - private static final int CLASS_FILE_MAX_MAJOR_VERSION = 50; + 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; diff --git a/dx/tests/003-magic-version-access/class-version-49.0.txt b/dx/tests/003-magic-version-access/class-version-49.0.txt index 0b30fcdbe..9b9a27f0b 100644 --- a/dx/tests/003-magic-version-access/class-version-49.0.txt +++ b/dx/tests/003-magic-version-access/class-version-49.0.txt @@ -1,5 +1,5 @@ # -# classfile with the highest valid version, 49.0 (0x31.0x00) +# classfile with the valid version 49.0 (0x31.0x00) # cafe babe # magic diff --git a/dx/tests/003-magic-version-access/class-version-49.1.txt b/dx/tests/003-magic-version-access/class-version-49.1.txt index 9eb477c98..69c0ab17a 100644 --- a/dx/tests/003-magic-version-access/class-version-49.1.txt +++ b/dx/tests/003-magic-version-access/class-version-49.1.txt @@ -1,6 +1,5 @@ # -# classfile with a minor version 1 higher than the highest valid -# version. 49.1 (0x31.0x01) +# classfile with the valid version 49.1 (0x31.0x01) # cafe babe # magic diff --git a/dx/tests/003-magic-version-access/class-version-49.65535.txt b/dx/tests/003-magic-version-access/class-version-49.65535.txt index 668631b34..42970aaba 100644 --- a/dx/tests/003-magic-version-access/class-version-49.65535.txt +++ b/dx/tests/003-magic-version-access/class-version-49.65535.txt @@ -1,6 +1,5 @@ # -# classfile with an invalid version, with the same major version -# as the highest valid version. 49.65535 (0x31.0xffff) +# classfile with the valid version 49.65535 (0x31.0xffff) # cafe babe # magic diff --git a/dx/tests/003-magic-version-access/class-version-50.0.txt b/dx/tests/003-magic-version-access/class-version-50.0.txt index fa670775a..dac631dd5 100644 --- a/dx/tests/003-magic-version-access/class-version-50.0.txt +++ b/dx/tests/003-magic-version-access/class-version-50.0.txt @@ -1,6 +1,5 @@ # -# classfile with an invalid version, with a higher major version -# than the highest valid version. 50.0 (0x32.0x00) +# classfile with the valid version 50.0 (0x30.0x00) # cafe babe # magic diff --git a/dx/tests/003-magic-version-access/class-version-50.1.txt b/dx/tests/003-magic-version-access/class-version-50.1.txt index 9543be144..2b0d547bb 100644 --- a/dx/tests/003-magic-version-access/class-version-50.1.txt +++ b/dx/tests/003-magic-version-access/class-version-50.1.txt @@ -1,6 +1,5 @@ # -# classfile with an invalid version, with a higher major version -# than the highest valid version. 50.0 (0x32.0x00) +# classfile with the valid version 50.1 (0x32.0x01) # cafe babe # magic diff --git a/dx/tests/003-magic-version-access/class-version-50.65535.txt b/dx/tests/003-magic-version-access/class-version-50.65535.txt index 9db1958fc..b74f326f4 100644 --- a/dx/tests/003-magic-version-access/class-version-50.65535.txt +++ b/dx/tests/003-magic-version-access/class-version-50.65535.txt @@ -1,6 +1,5 @@ # -# classfile with an invalid version, with a higher major version -# than the highest valid version. 50.0 (0x32.0x00) +# classfile with the valid version 50.65535 (0x32.0xffff) # cafe babe # magic diff --git a/dx/tests/003-magic-version-access/class-version-51.0.txt b/dx/tests/003-magic-version-access/class-version-51.0.txt index 2ffb4cd16..22c28afe4 100644 --- a/dx/tests/003-magic-version-access/class-version-51.0.txt +++ b/dx/tests/003-magic-version-access/class-version-51.0.txt @@ -1,6 +1,5 @@ # -# classfile with an invalid version, with a higher major version -# than the highest valid version. 50.0 (0x32.0x00) +# classfile with the highest valid version 51.0 (0x33.0x00) # cafe babe # magic diff --git a/dx/tests/003-magic-version-access/class-version-51.1.txt b/dx/tests/003-magic-version-access/class-version-51.1.txt new file mode 100644 index 000000000..e4632a320 --- /dev/null +++ b/dx/tests/003-magic-version-access/class-version-51.1.txt @@ -0,0 +1,26 @@ +# +# classfile with a minor version 1 higher than the highest valid +# version. 51.0 (0x33.0x00) +# + +cafe babe # magic +0001 # minor_version +0033 # major_version +0005 # constant_pool_count + +# +# constant_pool +# +01 0005 "Small" # 0001: utf8["Small"] +01 0010 "java/lang/Object" # 0002: utf8["java/lang/Object"] +07 0001 # 0003: class[Small] +07 0002 # 0004: class[java/lang/Object] + +ffff # access_flags +0003 # this_class +0004 # super_class +0000 # interfaces_count +0000 # fields_count +0000 # methods_count + +0000 # attributes_count diff --git a/dx/tests/003-magic-version-access/class-version-51.65535.txt b/dx/tests/003-magic-version-access/class-version-51.65535.txt new file mode 100644 index 000000000..cab1e6412 --- /dev/null +++ b/dx/tests/003-magic-version-access/class-version-51.65535.txt @@ -0,0 +1,26 @@ +# +# classfile with an invalid version, with the same major version +# as the highest valid version. 51.65535 (0x33.0xffff) +# + +cafe babe # magic +ffff # minor_version +0033 # major_version +0005 # constant_pool_count + +# +# constant_pool +# +01 0005 "Small" # 0001: utf8["Small"] +01 0010 "java/lang/Object" # 0002: utf8["java/lang/Object"] +07 0001 # 0003: class[Small] +07 0002 # 0004: class[java/lang/Object] + +ffff # access_flags +0003 # this_class +0004 # super_class +0000 # interfaces_count +0000 # fields_count +0000 # methods_count + +0000 # attributes_count diff --git a/dx/tests/003-magic-version-access/class-version-52.0.txt b/dx/tests/003-magic-version-access/class-version-52.0.txt new file mode 100644 index 000000000..fe79f5e1d --- /dev/null +++ b/dx/tests/003-magic-version-access/class-version-52.0.txt @@ -0,0 +1,26 @@ +# +# classfile with an invalid version, with a higher major version +# than the highest valid version. 51.0 (0x33.0x00) +# + +cafe babe # magic +0000 # minor_version +0034 # major_version +0005 # constant_pool_count + +# +# constant_pool +# +01 0005 "Small" # 0001: utf8["Small"] +01 0010 "java/lang/Object" # 0002: utf8["java/lang/Object"] +07 0001 # 0003: class[Small] +07 0002 # 0004: class[java/lang/Object] + +ffff # access_flags +0003 # this_class +0004 # super_class +0000 # interfaces_count +0000 # fields_count +0000 # methods_count + +0000 # attributes_count diff --git a/dx/tests/003-magic-version-access/expected.txt b/dx/tests/003-magic-version-access/expected.txt index a63292224..24f73653f 100644 --- a/dx/tests/003-magic-version-access/expected.txt +++ b/dx/tests/003-magic-version-access/expected.txt @@ -198,28 +198,91 @@ begin classfile magic: cafebabe minor_version: 0001 major_version: 0032 +constant_pool_count: 0005 -trouble parsing: -bad class file magic (cafebabe) or version (0032.0001) -...while parsing class-version-50.1.txt +constant_pool: + 0001: utf8{"Small"} + 0002: utf8{"java/lang/Object"} + 0003: type{Small} + 0004: type{java.lang.Object} +end constant_pool +access_flags: public|final|super|interface|abstract|synthetic|annotation|enum|89ce +this_class: type{Small} +super_class: type{java.lang.Object} +interfaces_count: 0000 +fields_count: 0000 +methods_count: 0000 +attributes_count: 0000 +end classfile reading class-version-50.65535.txt... begin classfile magic: cafebabe minor_version: ffff major_version: 0032 +constant_pool_count: 0005 -trouble parsing: -bad class file magic (cafebabe) or version (0032.ffff) -...while parsing class-version-50.65535.txt +constant_pool: + 0001: utf8{"Small"} + 0002: utf8{"java/lang/Object"} + 0003: type{Small} + 0004: type{java.lang.Object} +end constant_pool +access_flags: public|final|super|interface|abstract|synthetic|annotation|enum|89ce +this_class: type{Small} +super_class: type{java.lang.Object} +interfaces_count: 0000 +fields_count: 0000 +methods_count: 0000 +attributes_count: 0000 +end classfile reading class-version-51.0.txt... begin classfile magic: cafebabe minor_version: 0000 major_version: 0033 +constant_pool_count: 0005 + +constant_pool: + 0001: utf8{"Small"} + 0002: utf8{"java/lang/Object"} + 0003: type{Small} + 0004: type{java.lang.Object} +end constant_pool +access_flags: public|final|super|interface|abstract|synthetic|annotation|enum|89ce +this_class: type{Small} +super_class: type{java.lang.Object} +interfaces_count: 0000 +fields_count: 0000 +methods_count: 0000 +attributes_count: 0000 +end classfile +reading class-version-51.1.txt... +begin classfile +magic: cafebabe +minor_version: 0001 +major_version: 0033 + +trouble parsing: +bad class file magic (cafebabe) or version (0033.0001) +...while parsing class-version-51.1.txt +reading class-version-51.65535.txt... +begin classfile +magic: cafebabe +minor_version: ffff +major_version: 0033 + +trouble parsing: +bad class file magic (cafebabe) or version (0033.ffff) +...while parsing class-version-51.65535.txt +reading class-version-52.0.txt... +begin classfile +magic: cafebabe +minor_version: 0000 +major_version: 0034 trouble parsing: -bad class file magic (cafebabe) or version (0033.0000) -...while parsing class-version-51.0.txt +bad class file magic (cafebabe) or version (0034.0000) +...while parsing class-version-52.0.txt reading small-class.txt... begin classfile magic: cafebabe diff --git a/dx/tests/003-magic-version-access/run b/dx/tests/003-magic-version-access/run index 24de48e8e..3af61188a 100644 --- a/dx/tests/003-magic-version-access/run +++ b/dx/tests/003-magic-version-access/run @@ -35,11 +35,14 @@ dx --debug --dump --width=100 class-version-49.0.txt dx --debug --dump --width=100 class-version-49.1.txt dx --debug --dump --width=100 class-version-49.65535.txt dx --debug --dump --width=100 class-version-50.0.txt +dx --debug --dump --width=100 class-version-50.1.txt +dx --debug --dump --width=100 class-version-50.65535.txt +dx --debug --dump --width=100 class-version-51.0.txt # Too big (throws an exception) -dx --dump --strict class-version-50.1.txt -dx --dump --strict class-version-50.65535.txt -dx --dump --strict class-version-51.0.txt +dx --dump --strict class-version-51.1.txt +dx --dump --strict class-version-51.65535.txt +dx --dump --strict class-version-52.0.txt # Show that we can dump the access flags even when they # don't make any sense. diff --git a/dx/tests/024-code-bytecode/expected.txt b/dx/tests/024-code-bytecode/expected.txt index 4637474b6..26d58bdb5 100644 --- a/dx/tests/024-code-bytecode/expected.txt +++ b/dx/tests/024-code-bytecode/expected.txt @@ -42,10 +42,10 @@ methods[0]: attributes[0]: name: Code - length: 000001dc + length: 000001db max_stack: 0001 max_locals: 0001 - code_length: 000001d0 + code_length: 000001cf 0000: nop 0001: aconst_null 0002: iconst_m1 // #-01 @@ -251,41 +251,40 @@ methods[0]: 015d: invokespecial method{Small.blort:()V} 0160: invokestatic method{Small.blort:()V} 0163: invokeinterface ifaceMethod{Small.blort:()V}, 0001 - 0168: unused_ba - 0169: new type{Small} - 016c: newarray boolean - 016e: newarray char - 0170: newarray float - 0172: newarray double - 0174: newarray byte - 0176: newarray short - 0178: newarray int - 017a: newarray long - 017c: anewarray type{Small} - 017f: arraylength - 0180: athrow - 0181: checkcast type{java.lang.Object} - 0184: instanceof type{java.lang.Object} - 0187: monitorenter - 0188: monitorexit - 0189: wide iload 0123 - 018d: wide lload 0124 // category-2 - 0191: wide fload 0125 - 0195: wide dload 0126 // category-2 - 0199: wide aload 0127 - 019d: wide istore 20f0 - 01a1: wide lstore 20f1 // category-2 - 01a5: wide fstore 20f2 - 01a9: wide dstore 20f3 // category-2 - 01ad: wide astore 20f4 - 01b1: wide ret ffff - 01b5: wide iinc 0002, #+1000 - 01bb: multianewarray type{java.lang.Object}, 04 - 01bf: ifnull 0000 - 01c2: ifnonnull 01c2 - 01c5: goto_w 700001c5 - 01ca: jsr_w 000001c5 - 01cf: unused_ca + 0168: new type{Small} + 016b: newarray boolean + 016d: newarray char + 016f: newarray float + 0171: newarray double + 0173: newarray byte + 0175: newarray short + 0177: newarray int + 0179: newarray long + 017b: anewarray type{Small} + 017e: arraylength + 017f: athrow + 0180: checkcast type{java.lang.Object} + 0183: instanceof type{java.lang.Object} + 0186: monitorenter + 0187: monitorexit + 0188: wide iload 0123 + 018c: wide lload 0124 // category-2 + 0190: wide fload 0125 + 0194: wide dload 0126 // category-2 + 0198: wide aload 0127 + 019c: wide istore 20f0 + 01a0: wide lstore 20f1 // category-2 + 01a4: wide fstore 20f2 + 01a8: wide dstore 20f3 // category-2 + 01ac: wide astore 20f4 + 01b0: wide ret ffff + 01b4: wide iinc 0002, #+1000 + 01ba: multianewarray type{java.lang.Object}, 04 + 01be: ifnull ffff + 01c1: ifnonnull 01c1 + 01c4: goto_w 700001c4 + 01c9: jsr_w 000001c4 + 01ce: unused_ca exception_table_length: 0000 attributes_count: 0000 end attributes[0] diff --git a/dx/tests/024-code-bytecode/small-class.txt b/dx/tests/024-code-bytecode/small-class.txt index 2526cf2b2..7d1ff3700 100644 --- a/dx/tests/024-code-bytecode/small-class.txt +++ b/dx/tests/024-code-bytecode/small-class.txt @@ -45,10 +45,10 @@ cafe babe # magic 0001 # attributes_count # attributes[0] 0007 # name -000001dc # length (note: == code_length + 0x0c) +000001db # length (note: == code_length + 0x0c) 0001 # max_stack 0001 # max_locals -000001d0 # code_length +000001cf # code_length 00 # 0000: nop 01 # 0001: aconst_null @@ -262,7 +262,6 @@ b6 0015 # 015a: invokevirtual 0015 b7 0015 # 015d: invokespecial 0015 b8 0015 # 0160: invokestatic 0015 b9 0016 01 00 # 0163: invokeinterface 0016 -ba # 0168: <unused> bb 0001 # 0169: new 0001 bc 04 # 016c: newarray boolean bc 05 # 016e: newarray char |