6982999: tools must support -target 7 bytecodes

Reviewed-by: jjg, jrose
This commit is contained in:
Kumar Srinivasan 2011-01-18 08:37:05 -08:00
parent 8efa2d97ed
commit 41aff425b6
10 changed files with 468 additions and 12 deletions

View File

@ -39,6 +39,7 @@ import java.util.Map;
public abstract class Attribute {
public static final String AnnotationDefault = "AnnotationDefault";
public static final String BootstrapMethods = "BootstrapMethods";
public static final String CharacterRangeTable = "CharacterRangeTable";
public static final String Code = "Code";
public static final String ConstantValue = "ConstantValue";
@ -99,6 +100,7 @@ public abstract class Attribute {
protected void init() {
standardAttributes = new HashMap<String,Class<? extends Attribute>>();
standardAttributes.put(AnnotationDefault, AnnotationDefault_attribute.class);
standardAttributes.put(BootstrapMethods, BootstrapMethods_attribute.class);
standardAttributes.put(CharacterRangeTable, CharacterRangeTable_attribute.class);
standardAttributes.put(Code, Code_attribute.class);
standardAttributes.put(ConstantValue, ConstantValue_attribute.class);
@ -155,6 +157,7 @@ public abstract class Attribute {
public interface Visitor<R,P> {
R visitBootstrapMethods(BootstrapMethods_attribute attr, P p);
R visitDefault(DefaultAttribute attr, P p);
R visitAnnotationDefault(AnnotationDefault_attribute attr, P p);
R visitCharacterRangeTable(CharacterRangeTable_attribute attr, P p);

View File

@ -0,0 +1,90 @@
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.classfile;
import java.io.IOException;
/**
* See JVMS3 <TBD>
* http://cr.openjdk.java.net/~jrose/pres/indy-javadoc-mlvm/
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public class BootstrapMethods_attribute extends Attribute {
public final BootstrapMethodSpecifier[] bootstrap_method_specifiers;
BootstrapMethods_attribute(ClassReader cr, int name_index, int length)
throws IOException, AttributeException {
super(name_index, length);
int bootstrap_method_count = cr.readUnsignedShort();
bootstrap_method_specifiers = new BootstrapMethodSpecifier[bootstrap_method_count];
for (int i = 0; i < bootstrap_method_specifiers.length; i++)
bootstrap_method_specifiers[i] = new BootstrapMethodSpecifier(cr);
}
public BootstrapMethods_attribute(int name_index, BootstrapMethodSpecifier[] bootstrap_method_specifiers) {
super(name_index, length(bootstrap_method_specifiers));
this.bootstrap_method_specifiers = bootstrap_method_specifiers;
}
public static int length(BootstrapMethodSpecifier[] bootstrap_method_specifiers) {
int n = 2;
for (BootstrapMethodSpecifier b : bootstrap_method_specifiers)
n += b.length();
return n;
}
@Override
public <R, P> R accept(Visitor<R, P> visitor, P p) {
return visitor.visitBootstrapMethods(this, p);
}
public static class BootstrapMethodSpecifier {
public int bootstrap_method_ref;
public int[] bootstrap_arguments;
public BootstrapMethodSpecifier(int bootstrap_method_ref, int[] bootstrap_arguments) {
this.bootstrap_method_ref = bootstrap_method_ref;
this.bootstrap_arguments = bootstrap_arguments;
}
BootstrapMethodSpecifier(ClassReader cr) throws IOException {
bootstrap_method_ref = cr.readUnsignedShort();
int method_count = cr.readUnsignedShort();
bootstrap_arguments = new int[method_count];
for (int i = 0; i < bootstrap_arguments.length; i++) {
bootstrap_arguments[i] = cr.readUnsignedShort();
}
}
int length() {
// u2 (method_ref) + u2 (argc) + u2 * argc
return 2 + 2 + (bootstrap_arguments.length * 2);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2011 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -31,7 +31,10 @@ import com.sun.tools.classfile.ConstantPool.CONSTANT_Fieldref_info;
import com.sun.tools.classfile.ConstantPool.CONSTANT_Float_info;
import com.sun.tools.classfile.ConstantPool.CONSTANT_Integer_info;
import com.sun.tools.classfile.ConstantPool.CONSTANT_InterfaceMethodref_info;
import com.sun.tools.classfile.ConstantPool.CONSTANT_InvokeDynamic_info;
import com.sun.tools.classfile.ConstantPool.CONSTANT_Long_info;
import com.sun.tools.classfile.ConstantPool.CONSTANT_MethodHandle_info;
import com.sun.tools.classfile.ConstantPool.CONSTANT_MethodType_info;
import com.sun.tools.classfile.ConstantPool.CONSTANT_Methodref_info;
import com.sun.tools.classfile.ConstantPool.CONSTANT_NameAndType_info;
import com.sun.tools.classfile.ConstantPool.CONSTANT_String_info;
@ -304,6 +307,20 @@ public class ClassTranslator
return info;
}
public CPInfo visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, Map<Object, Object> translations) {
CONSTANT_InvokeDynamic_info info2 = (CONSTANT_InvokeDynamic_info) translations.get(info);
if (info2 == null) {
ConstantPool cp2 = translate(info.cp, translations);
if (cp2 == info.cp) {
info2 = info;
} else {
info2 = new CONSTANT_InvokeDynamic_info(cp2, info.bootstrap_method_attr_index, info.name_and_type_index);
}
translations.put(info, info2);
}
return info;
}
public CPInfo visitLong(CONSTANT_Long_info info, Map<Object, Object> translations) {
CONSTANT_Long_info info2 = (CONSTANT_Long_info) translations.get(info);
if (info2 == null) {
@ -339,6 +356,34 @@ public class ClassTranslator
return info;
}
public CPInfo visitMethodHandle(CONSTANT_MethodHandle_info info, Map<Object, Object> translations) {
CONSTANT_MethodHandle_info info2 = (CONSTANT_MethodHandle_info) translations.get(info);
if (info2 == null) {
ConstantPool cp2 = translate(info.cp, translations);
if (cp2 == info.cp) {
info2 = info;
} else {
info2 = new CONSTANT_MethodHandle_info(cp2, info.reference_kind, info.reference_index);
}
translations.put(info, info2);
}
return info;
}
public CPInfo visitMethodType(CONSTANT_MethodType_info info, Map<Object, Object> translations) {
CONSTANT_MethodType_info info2 = (CONSTANT_MethodType_info) translations.get(info);
if (info2 == null) {
ConstantPool cp2 = translate(info.cp, translations);
if (cp2 == info.cp) {
info2 = info;
} else {
info2 = new CONSTANT_MethodType_info(cp2, info.descriptor_index);
}
translations.put(info, info2);
}
return info;
}
public CPInfo visitString(CONSTANT_String_info info, Map<Object, Object> translations) {
CONSTANT_String_info info2 = (CONSTANT_String_info) translations.get(info);
if (info2 == null) {

View File

@ -267,6 +267,12 @@ public class ClassWriter {
return 1;
}
public Integer visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, ClassOutputStream out) {
out.writeShort(info.bootstrap_method_attr_index);
out.writeShort(info.name_and_type_index);
return 1;
}
public Integer visitLong(CONSTANT_Long_info info, ClassOutputStream out) {
out.writeLong(info.value);
return 2;
@ -278,6 +284,17 @@ public class ClassWriter {
return 1;
}
public Integer visitMethodHandle(CONSTANT_MethodHandle_info info, ClassOutputStream out) {
out.writeByte(info.reference_kind.tag);
out.writeShort(info.reference_index);
return 1;
}
public Integer visitMethodType(CONSTANT_MethodType_info info, ClassOutputStream out) {
out.writeShort(info.descriptor_index);
return 1;
}
public Integer visitMethodref(CONSTANT_Methodref_info info, ClassOutputStream out) {
return writeRef(info, out);
}
@ -332,6 +349,19 @@ public class ClassWriter {
return null;
}
public Void visitBootstrapMethods(BootstrapMethods_attribute attr, ClassOutputStream out) {
out.writeShort(attr.bootstrap_method_specifiers.length);
for (BootstrapMethods_attribute.BootstrapMethodSpecifier bsm : attr.bootstrap_method_specifiers) {
out.writeShort(bsm.bootstrap_method_ref);
int bsm_args_count = bsm.bootstrap_arguments.length;
out.writeShort(bsm_args_count);
for (int i : bsm.bootstrap_arguments) {
out.writeShort(i);
}
}
return null;
}
public Void visitCharacterRangeTable(CharacterRangeTable_attribute attr, ClassOutputStream out) {
out.writeShort(attr.character_range_table.length);
for (CharacterRangeTable_attribute.Entry e: attr.character_range_table)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -114,6 +114,54 @@ public class ConstantPool {
public static final int CONSTANT_Methodref = 10;
public static final int CONSTANT_InterfaceMethodref = 11;
public static final int CONSTANT_NameAndType = 12;
public static final int CONSTANT_MethodHandle = 15;
public static final int CONSTANT_MethodType = 16;
public static final int CONSTANT_InvokeDynamic = 18;
public static enum RefKind {
REF_getField(1, "getfield"),
REF_getStatic(2, "getstatic"),
REF_putField(3, "putfield"),
REF_putStatic(4, "putstatic"),
REF_invokeVirtual(5, "invokevirtual"),
REF_invokeStatic(6, "invokestatic"),
REF_invokeSpecial(7, "invokespecial"),
REF_newInvokeSpecial(8, "newinvokespecial"),
REF_invokeInterface(9, "invokeinterface");
public final int tag;
public final String name;
RefKind(int tag, String name) {
this.tag = tag;
this.name = name;
}
static RefKind getRefkind(int tag) {
switch(tag) {
case 1:
return REF_getField;
case 2:
return REF_getStatic;
case 3:
return REF_putField;
case 4:
return REF_putStatic;
case 5:
return REF_invokeVirtual;
case 6:
return REF_invokeStatic;
case 7:
return REF_invokeSpecial;
case 8:
return REF_newInvokeSpecial;
case 9:
return REF_invokeInterface;
default:
return null;
}
}
}
ConstantPool(ClassReader cr) throws IOException, InvalidEntry {
int count = cr.readUnsignedShort();
@ -146,11 +194,23 @@ public class ConstantPool {
pool[i] = new CONSTANT_InterfaceMethodref_info(this, cr);
break;
case CONSTANT_InvokeDynamic:
pool[i] = new CONSTANT_InvokeDynamic_info(this, cr);
break;
case CONSTANT_Long:
pool[i] = new CONSTANT_Long_info(cr);
i++;
break;
case CONSTANT_MethodHandle:
pool[i] = new CONSTANT_MethodHandle_info(this, cr);
break;
case CONSTANT_MethodType:
pool[i] = new CONSTANT_MethodType_info(this, cr);
break;
case CONSTANT_Methodref:
pool[i] = new CONSTANT_Methodref_info(this, cr);
break;
@ -279,9 +339,12 @@ public class ConstantPool {
R visitFloat(CONSTANT_Float_info info, P p);
R visitInteger(CONSTANT_Integer_info info, P p);
R visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, P p);
R visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, P p);
R visitLong(CONSTANT_Long_info info, P p);
R visitNameAndType(CONSTANT_NameAndType_info info, P p);
R visitMethodref(CONSTANT_Methodref_info info, P p);
R visitMethodHandle(CONSTANT_MethodHandle_info info, P p);
R visitMethodType(CONSTANT_MethodType_info info, P p);
R visitString(CONSTANT_String_info info, P p);
R visitUtf8(CONSTANT_Utf8_info info, P p);
}
@ -548,6 +611,44 @@ public class ConstantPool {
}
}
public static class CONSTANT_InvokeDynamic_info extends CPInfo {
CONSTANT_InvokeDynamic_info(ConstantPool cp, ClassReader cr) throws IOException {
super(cp);
bootstrap_method_attr_index = cr.readUnsignedShort();
name_and_type_index = cr.readUnsignedShort();
}
public CONSTANT_InvokeDynamic_info(ConstantPool cp, int bootstrap_method_index, int name_and_type_index) {
super(cp);
this.bootstrap_method_attr_index = bootstrap_method_index;
this.name_and_type_index = name_and_type_index;
}
public int getTag() {
return CONSTANT_InvokeDynamic;
}
public int byteLength() {
return 5;
}
@Override
public String toString() {
return "CONSTANT_InvokeDynamic_info[bootstrap_method_index: " + bootstrap_method_attr_index + ", name_and_type_index: " + name_and_type_index + "]";
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitInvokeDynamic(this, data);
}
public CONSTANT_NameAndType_info getNameAndTypeInfo() throws ConstantPoolException {
return cp.getNameAndTypeInfo(name_and_type_index);
}
public final int bootstrap_method_attr_index;
public final int name_and_type_index;
}
public static class CONSTANT_Long_info extends CPInfo {
CONSTANT_Long_info(ClassReader cr) throws IOException {
value = cr.readLong();
@ -582,6 +683,87 @@ public class ConstantPool {
public final long value;
}
public static class CONSTANT_MethodHandle_info extends CPInfo {
CONSTANT_MethodHandle_info(ConstantPool cp, ClassReader cr) throws IOException {
super(cp);
reference_kind = RefKind.getRefkind(cr.readUnsignedByte());
reference_index = cr.readUnsignedShort();
}
public CONSTANT_MethodHandle_info(ConstantPool cp, RefKind ref_kind, int member_index) {
super(cp);
this.reference_kind = ref_kind;
this.reference_index = member_index;
}
public int getTag() {
return CONSTANT_MethodHandle;
}
public int byteLength() {
return 4;
}
@Override
public String toString() {
return "CONSTANT_MethodHandle_info[ref_kind: " + reference_kind + ", member_index: " + reference_index + "]";
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitMethodHandle(this, data);
}
public CPRefInfo getCPRefInfo() throws ConstantPoolException {
int expected = CONSTANT_Methodref;
int actual = cp.get(reference_index).getTag();
// allow these tag types also:
switch (actual) {
case CONSTANT_Fieldref:
case CONSTANT_InterfaceMethodref:
expected = actual;
}
return (CPRefInfo) cp.get(reference_index, expected);
}
public final RefKind reference_kind;
public final int reference_index;
}
public static class CONSTANT_MethodType_info extends CPInfo {
CONSTANT_MethodType_info(ConstantPool cp, ClassReader cr) throws IOException {
super(cp);
descriptor_index = cr.readUnsignedShort();
}
public CONSTANT_MethodType_info(ConstantPool cp, int signature_index) {
super(cp);
this.descriptor_index = signature_index;
}
public int getTag() {
return CONSTANT_MethodType;
}
public int byteLength() {
return 3;
}
@Override
public String toString() {
return "CONSTANT_MethodType_info[signature_index: " + descriptor_index + "]";
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitMethodType(this, data);
}
public String getType() throws ConstantPoolException {
return cp.getUTF8Value(descriptor_index);
}
public final int descriptor_index;
}
public static class CONSTANT_Methodref_info extends CPRefInfo {
CONSTANT_Methodref_info(ConstantPool cp, ClassReader cr) throws IOException {
super(cp, cr, CONSTANT_Methodref);
@ -729,5 +911,4 @@ public class ConstantPool {
public final String value;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -626,10 +626,26 @@ public class Dependencies {
return visitRef(info, p);
}
public Void visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, Void p) {
return null;
}
public Void visitLong(CONSTANT_Long_info info, Void p) {
return null;
}
public Void visitMethodHandle(CONSTANT_MethodHandle_info info, Void p) {
return null;
}
public Void visitMethodType(CONSTANT_MethodType_info info, Void p) {
return null;
}
public Void visitMethodref(CONSTANT_Methodref_info info, Void p) {
return visitRef(info, p);
}
public Void visitNameAndType(CONSTANT_NameAndType_info info, Void p) {
try {
new Signature(info.type_index).getType(constant_pool).accept(this, null);
@ -639,10 +655,6 @@ public class Dependencies {
}
}
public Void visitMethodref(CONSTANT_Methodref_info info, Void p) {
return visitRef(info, p);
}
public Void visitString(CONSTANT_String_info info, Void p) {
return null;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -80,6 +80,9 @@ public class ClassFile {
public final static int CONSTANT_Methodref = 10;
public final static int CONSTANT_InterfaceMethodref = 11;
public final static int CONSTANT_NameandType = 12;
public final static int CONSTANT_MethodHandle = 15;
public final static int CONSTANT_MethodType = 16;
public final static int CONSTANT_InvokeDynamic = 18;
public final static int MAX_PARAMETERS = 0xff;
public final static int MAX_DIMENSIONS = 0xff;

View File

@ -434,14 +434,19 @@ public class ClassReader implements Completer {
}
case CONSTANT_Class:
case CONSTANT_String:
case CONSTANT_MethodType:
bp = bp + 2;
break;
case CONSTANT_MethodHandle:
bp = bp + 3;
break;
case CONSTANT_Fieldref:
case CONSTANT_Methodref:
case CONSTANT_InterfaceMethodref:
case CONSTANT_NameandType:
case CONSTANT_Integer:
case CONSTANT_Float:
case CONSTANT_InvokeDynamic:
bp = bp + 4;
break;
case CONSTANT_Long:
@ -510,6 +515,15 @@ public class ClassReader implements Completer {
case CONSTANT_Double:
poolObj[i] = new Double(getDouble(index + 1));
break;
case CONSTANT_MethodHandle:
skipBytes(4);
break;
case CONSTANT_MethodType:
skipBytes(3);
break;
case CONSTANT_InvokeDynamic:
skipBytes(5);
break;
default:
throw badClassFile("bad.const.pool.tag", Byte.toString(tag));
}
@ -1821,6 +1835,13 @@ public class ClassReader implements Completer {
sym.savedParameterNames = paramNames.reverse();
}
/**
* skip n bytes
*/
void skipBytes(int n) {
bp = bp + n;
}
/** Skip a field or method
*/
void skipMember() {

View File

@ -31,6 +31,7 @@ import com.sun.tools.classfile.AccessFlags;
import com.sun.tools.classfile.AnnotationDefault_attribute;
import com.sun.tools.classfile.Attribute;
import com.sun.tools.classfile.Attributes;
import com.sun.tools.classfile.BootstrapMethods_attribute;
import com.sun.tools.classfile.CharacterRangeTable_attribute;
import com.sun.tools.classfile.Code_attribute;
import com.sun.tools.classfile.CompilationID_attribute;
@ -151,6 +152,25 @@ public class AttributeWriter extends BasicWriter
return null;
}
public Void visitBootstrapMethods(BootstrapMethods_attribute attr, Void p) {
println(Attribute.BootstrapMethods + ":");
for (int i = 0; i < attr.bootstrap_method_specifiers.length ; i++) {
BootstrapMethods_attribute.BootstrapMethodSpecifier bsm = attr.bootstrap_method_specifiers[i];
indent(+1);
print(i + ": #" + bsm.bootstrap_method_ref + " ");
println(constantWriter.stringValue(bsm.bootstrap_method_ref));
indent(+1);
println("Method arguments:");
indent(+1);
for (int j = 0; j < bsm.bootstrap_arguments.length; j++) {
print("#" + bsm.bootstrap_arguments[j] + " ");
println(constantWriter.stringValue(bsm.bootstrap_arguments[j]));
}
indent(-3);
}
return null;
}
public Void visitCharacterRangeTable(CharacterRangeTable_attribute attr, Void ignore) {
println("CharacterRangeTable:");
indent(+1);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -97,6 +97,13 @@ public class ConstantWriter extends BasicWriter {
return 1;
}
public Integer visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, Void p) {
print("#" + info.bootstrap_method_attr_index + ":#" + info.name_and_type_index);
tab();
println("// " + stringValue(info));
return 1;
}
public Integer visitLong(CONSTANT_Long_info info, Void p) {
println(stringValue(info));
return 2;
@ -116,6 +123,20 @@ public class ConstantWriter extends BasicWriter {
return 1;
}
public Integer visitMethodHandle(CONSTANT_MethodHandle_info info, Void p) {
print("#" + info.reference_kind.tag + ":#" + info.reference_index);
tab();
println("// " + stringValue(info));
return 1;
}
public Integer visitMethodType(CONSTANT_MethodType_info info, Void p) {
print("#" + info.descriptor_index);
tab();
println("// " + stringValue(info));
return 1;
}
public Integer visitString(CONSTANT_String_info info, Void p) {
print("#" + info.string_index);
tab();
@ -201,14 +222,20 @@ public class ConstantWriter extends BasicWriter {
return "String";
case CONSTANT_Fieldref:
return "Field";
case CONSTANT_MethodHandle:
return "MethodHandle";
case CONSTANT_MethodType:
return "MethodType";
case CONSTANT_Methodref:
return "Method";
case CONSTANT_InterfaceMethodref:
return "InterfaceMethod";
case CONSTANT_InvokeDynamic:
return "InvokeDynamic";
case CONSTANT_NameAndType:
return "NameAndType";
default:
return "(unknown tag)";
return "(unknown tag " + tag + ")";
}
}
@ -264,6 +291,15 @@ public class ConstantWriter extends BasicWriter {
return visitRef(info, p);
}
public String visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, Void p) {
try {
String callee = stringValue(info.getNameAndTypeInfo());
return "#" + info.bootstrap_method_attr_index + ":" + callee;
} catch (ConstantPoolException e) {
return report(e);
}
}
public String visitLong(CONSTANT_Long_info info, Void p) {
return info.value + "l";
}
@ -288,6 +324,22 @@ public class ConstantWriter extends BasicWriter {
}
}
public String visitMethodHandle(CONSTANT_MethodHandle_info info, Void p) {
try {
return info.reference_kind.name + " " + stringValue(info.getCPRefInfo());
} catch (ConstantPoolException e) {
return report(e);
}
}
public String visitMethodType(CONSTANT_MethodType_info info, Void p) {
try {
return info.getType();
} catch (ConstantPoolException e) {
return report(e);
}
}
public String visitMethodref(CONSTANT_Methodref_info info, Void p) {
return visitRef(info, p);
}
@ -347,7 +399,6 @@ public class ConstantWriter extends BasicWriter {
}
}
/* If name is a valid binary name, return it; otherwise quote it. */
private static String checkName(String name) {
if (name == null)