From aa92b8250ecf9bb0698a0844123b67a5f2ac5279 Mon Sep 17 00:00:00 2001 From: chiba Date: Mon, 19 Jul 2004 12:02:27 +0000 Subject: [PATCH] Bugs item #988787 has been fixed. git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@114 30ef5769-5b8d-40dd-aea6-55b5d6557bb3 --- Readme.html | 2 +- src/main/javassist/CtClassType.java | 8 +- src/main/javassist/bytecode/AccessFlag.java | 6 + .../javassist/bytecode/AttributeInfo.java | 10 +- .../javassist/bytecode/CodeAttribute.java | 8 +- src/main/javassist/bytecode/CodeIterator.java | 6 + .../bytecode/EnclosingMethodAttribute.java | 111 ++++++++++++++++++ src/main/javassist/bytecode/FieldInfo.java | 2 + .../bytecode/LocalVariableAttribute.java | 50 +++++++- src/main/javassist/bytecode/MethodInfo.java | 2 + .../bytecode/SignatureAttribute.java | 70 +++++++++++ tutorial/tutorial.html | 19 ++- tutorial/tutorial3.html | 8 +- 13 files changed, 284 insertions(+), 18 deletions(-) create mode 100644 src/main/javassist/bytecode/EnclosingMethodAttribute.java create mode 100644 src/main/javassist/bytecode/SignatureAttribute.java diff --git a/Readme.html b/Readme.html index 59b76998..1d89d316 100644 --- a/Readme.html +++ b/Readme.html @@ -556,7 +556,7 @@ Andreas Salathe, Dante Torres estrada, S. Pam, Nuno Santos, Denis Taye, Colin Sampaleanu, Robert Bialek, Asato Shimotaki, Howard Lewis Ship, Richard Jones, Marjan Sterjev, Bruce McDonald, Mark Brennan, Vlad Skarzhevskyy, -and Brett Randall +Brett Randall, and Tsuyoshi Murakami for their contributions.


diff --git a/src/main/javassist/CtClassType.java b/src/main/javassist/CtClassType.java index 4834ae8a..2949bcba 100644 --- a/src/main/javassist/CtClassType.java +++ b/src/main/javassist/CtClassType.java @@ -830,6 +830,7 @@ class CtClassType extends CtClass { modifyConstructors(cf); cf.write(out); out.flush(); + fieldInitializers = null; } else classPool.writeClassfile(getName(), out); @@ -844,9 +845,12 @@ class CtClassType extends CtClass { } } - protected void modifyClassConstructor(ClassFile cf) + private void modifyClassConstructor(ClassFile cf) throws CannotCompileException, NotFoundException { + if (fieldInitializers == null) + return; + Bytecode code = new Bytecode(cf.getConstPool(), 0, 0); Javac jv = new Javac(code, this); int stacksize = 0; @@ -903,7 +907,7 @@ class CtClassType extends CtClass { } } - protected void modifyConstructors(ClassFile cf) + private void modifyConstructors(ClassFile cf) throws CannotCompileException, NotFoundException { if (fieldInitializers == null) diff --git a/src/main/javassist/bytecode/AccessFlag.java b/src/main/javassist/bytecode/AccessFlag.java index 79e75cdf..6f18e096 100644 --- a/src/main/javassist/bytecode/AccessFlag.java +++ b/src/main/javassist/bytecode/AccessFlag.java @@ -27,11 +27,17 @@ public class AccessFlag { public static final int FINAL = 0x0010; public static final int SYNCHRONIZED = 0x0020; public static final int VOLATILE = 0x0040; + public static final int BRIDGE = 0x0040; // for method_info public static final int TRANSIENT = 0x0080; + public static final int VARARGS = 0x0080; // for method_info public static final int NATIVE = 0x0100; public static final int INTERFACE = 0x0200; public static final int ABSTRACT = 0x0400; public static final int STRICT = 0x0800; + public static final int SYNTHETIC = 0x1000; + public static final int ANNOTATION = 0x2000; + public static final int ENUM = 0x4000; + public static final int SUPER = 0x0020; // Note: 0x0020 is assigned to both ACC_SUPER and ACC_SYNCHRONIZED diff --git a/src/main/javassist/bytecode/AttributeInfo.java b/src/main/javassist/bytecode/AttributeInfo.java index 12ac5c75..28b01846 100644 --- a/src/main/javassist/bytecode/AttributeInfo.java +++ b/src/main/javassist/bytecode/AttributeInfo.java @@ -67,7 +67,8 @@ public class AttributeInfo { } static AttributeInfo read(ConstPool cp, DataInputStream in) - throws IOException { + throws IOException + { int name = in.readUnsignedShort(); String nameStr = cp.getUtf8Info(name); if (nameStr.charAt(0) < 'L') { @@ -77,6 +78,8 @@ public class AttributeInfo { return new ConstantAttribute(cp, name, in); else if (nameStr.equals(DeprecatedAttribute.tag)) return new DeprecatedAttribute(cp, name, in); + else if (nameStr.equals(EnclosingMethodAttribute.tag)) + return new EnclosingMethodAttribute(cp, name, in); else if (nameStr.equals(ExceptionsAttribute.tag)) return new ExceptionsAttribute(cp, name, in); else if (nameStr.equals(InnerClassesAttribute.tag)) @@ -87,7 +90,8 @@ public class AttributeInfo { */ if (nameStr.equals(LineNumberAttribute.tag)) return new LineNumberAttribute(cp, name, in); - else if (nameStr.equals(LocalVariableAttribute.tag)) + else if (nameStr.equals(LocalVariableAttribute.tag) + || nameStr.equals(LocalVariableAttribute.typeTag)) return new LocalVariableAttribute(cp, name, in); else if (nameStr.equals(AnnotationsAttribute.visibleTag) || nameStr.equals(AnnotationsAttribute.invisibleTag)) @@ -95,6 +99,8 @@ public class AttributeInfo { else if (nameStr.equals(ParameterAnnotationsAttribute.visibleTag) || nameStr.equals(ParameterAnnotationsAttribute.invisibleTag)) return new ParameterAnnotationsAttribute(cp, name, in); + else if (nameStr.equals(SignatureAttribute.tag)) + return new SignatureAttribute(cp, name, in); else if (nameStr.equals(SourceFileAttribute.tag)) return new SourceFileAttribute(cp, name, in); else if (nameStr.equals(SyntheticAttribute.tag)) diff --git a/src/main/javassist/bytecode/CodeAttribute.java b/src/main/javassist/bytecode/CodeAttribute.java index ec1f9a58..4c7e27bb 100644 --- a/src/main/javassist/bytecode/CodeAttribute.java +++ b/src/main/javassist/bytecode/CodeAttribute.java @@ -81,7 +81,7 @@ public class CodeAttribute extends AttributeInfo implements Opcode { maxStack = src.getMaxStack(); maxLocals = src.getMaxLocals(); exceptions = src.getExceptionTable().copy(cp, classnames); - info = src.copyCode(cp, classnames, exceptions); + info = src.copyCode(cp, classnames, exceptions, this); attributes = new LinkedList(); /* Since an index into the source constant pool table may not @@ -279,6 +279,8 @@ public class CodeAttribute extends AttributeInfo implements Opcode { /** * Returns attributes[]. * It returns a list of AttributeInfo. + * A new element can be added to the returned list + * and an existing element can be removed from the list. * * @see AttributeInfo */ @@ -299,7 +301,7 @@ public class CodeAttribute extends AttributeInfo implements Opcode { * Copies code. */ private byte[] copyCode(ConstPool destCp, Map classnames, - ExceptionTable etable) + ExceptionTable etable, CodeAttribute destCa) throws BadBytecode { int len = getCodeLength(); @@ -307,7 +309,7 @@ public class CodeAttribute extends AttributeInfo implements Opcode { LdcEntry ldc = copyCode(this.info, 0, len, this.getConstPool(), newCode, destCp, classnames); - return LdcEntry.doit(newCode, ldc, etable, this); + return LdcEntry.doit(newCode, ldc, etable, destCa); } private static LdcEntry copyCode(byte[] code, int beginPos, int endPos, diff --git a/src/main/javassist/bytecode/CodeIterator.java b/src/main/javassist/bytecode/CodeIterator.java index 90c2308b..03da568e 100644 --- a/src/main/javassist/bytecode/CodeIterator.java +++ b/src/main/javassist/bytecode/CodeIterator.java @@ -638,6 +638,12 @@ public class CodeIterator implements Opcode { if (va != null) va.shiftPc(where, gapLength, exclusive); + LocalVariableAttribute vta + = (LocalVariableAttribute)ca.getAttribute( + LocalVariableAttribute.typeTag); + if (vta != null) + vta.shiftPc(where, gapLength, exclusive); + return newcode; } diff --git a/src/main/javassist/bytecode/EnclosingMethodAttribute.java b/src/main/javassist/bytecode/EnclosingMethodAttribute.java new file mode 100644 index 00000000..5ad92862 --- /dev/null +++ b/src/main/javassist/bytecode/EnclosingMethodAttribute.java @@ -0,0 +1,111 @@ +/* + * Javassist, a Java-bytecode translator toolkit. + * Copyright (C) 1999-2004 Shigeru Chiba. All Rights Reserved. + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. Alternatively, the contents of this file may be used under + * the terms of the GNU Lesser General Public License Version 2.1 or later. + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + */ + +package javassist.bytecode; + +import java.io.DataInputStream; +import java.io.IOException; +import java.util.Map; + +/** + * EnclosingMethod_attribute. + */ +public class EnclosingMethodAttribute extends AttributeInfo { + /** + * The name of this attribute "EnclosingMethod". + */ + public static final String tag = "EnclosingMethod"; + + EnclosingMethodAttribute(ConstPool cp, int n, DataInputStream in) + throws IOException + { + super(cp, n, in); + } + + /** + * Constructs an EnclosingMethod attribute. + * + * @param cp a constant pool table. + * @param className the name of the innermost enclosing class. + * @param methodName the name of the enclosing method. + * @param methodDesc the descriptor of the enclosing method. + */ + public EnclosingMethodAttribute(ConstPool cp, String className, + String methodName, String methodDesc) { + super(cp, tag); + int ci = cp.addClassInfo(className); + int ni = cp.addNameAndTypeInfo(methodName, methodDesc); + byte[] bvalue = new byte[4]; + bvalue[0] = (byte)(ci >>> 8); + bvalue[1] = (byte)ci; + bvalue[2] = (byte)(ni >>> 8); + bvalue[3] = (byte)ni; + set(bvalue); + } + + /** + * Returns the value of class_index. + */ + public int classIndex() { + return ByteArray.readU16bit(get(), 0); + } + + /** + * Returns the value of method_index. + */ + public int methodIndex() { + return ByteArray.readU16bit(get(), 2); + } + + /** + * Returns the name of the class specified by class_index. + */ + public String className() { + return getConstPool().getClassInfo(classIndex()); + } + + /** + * Returns the method name specified by method_index. + */ + public String methodName() { + ConstPool cp = getConstPool(); + int mi = methodIndex(); + int ni = cp.getNameAndTypeName(mi); + return cp.getUtf8Info(ni); + } + + /** + * Returns the method descriptor specified by method_index. + */ + public String methodDescriptor() { + ConstPool cp = getConstPool(); + int mi = methodIndex(); + int ti = cp.getNameAndTypeDescriptor(mi); + return cp.getUtf8Info(ti); + } + + /** + * Makes a copy. Class names are replaced according to the + * given Map object. + * + * @param newCp the constant pool table used by the new copy. + * @param classnames pairs of replaced and substituted + * class names. + */ + public AttributeInfo copy(ConstPool newCp, Map classnames) { + return new EnclosingMethodAttribute(newCp, className(), + methodName(), methodDescriptor()); + } +} diff --git a/src/main/javassist/bytecode/FieldInfo.java b/src/main/javassist/bytecode/FieldInfo.java index ba267fc9..8cdb1ae3 100644 --- a/src/main/javassist/bytecode/FieldInfo.java +++ b/src/main/javassist/bytecode/FieldInfo.java @@ -120,6 +120,8 @@ public final class FieldInfo { /** * Returns all the attributes. + * A new element can be added to the returned list + * and an existing element can be removed from the list. * * @return a list of AttributeInfo objects. * @see AttributeInfo diff --git a/src/main/javassist/bytecode/LocalVariableAttribute.java b/src/main/javassist/bytecode/LocalVariableAttribute.java index 735d609f..a88dfac7 100644 --- a/src/main/javassist/bytecode/LocalVariableAttribute.java +++ b/src/main/javassist/bytecode/LocalVariableAttribute.java @@ -20,7 +20,8 @@ import java.io.IOException; import java.util.Map; /** - * LocalVariableTable_attribute. + * LocalVariableTable_attribute or + * LocalVariableTypeTable_attribute. */ public class LocalVariableAttribute extends AttributeInfo { /** @@ -28,6 +29,11 @@ public class LocalVariableAttribute extends AttributeInfo { */ public static final String tag = "LocalVariableTable"; + /** + * The name of the attribute "LocalVariableTypeTable". + */ + public static final String typeTag = "LocalVariableTypeTable"; + LocalVariableAttribute(ConstPool cp, int n, DataInputStream in) throws IOException { @@ -85,7 +91,7 @@ public class LocalVariableAttribute extends AttributeInfo { } /** - * Returns local_variable_table[i].name_index. + * Returns the value of local_variable_table[i].name_index. * This represents the name of the local variable. * * @param i the i-th entry. @@ -105,8 +111,14 @@ public class LocalVariableAttribute extends AttributeInfo { } /** - * Returns local_variable_table[i].descriptor_index. + * Returns the value of + * local_variable_table[i].descriptor_index. * This represents the type descriptor of the local variable. + *

+ * If this attribute represents a LocalVariableTypeTable attribute, + * this method returns the value of + * local_variable_type_table[i].signature_index. + * It represents the type of the local variable. * * @param i the i-th entry. */ @@ -114,16 +126,46 @@ public class LocalVariableAttribute extends AttributeInfo { return ByteArray.readU16bit(info, i * 10 + 8); } + /** + * This method is equivalent to descriptorIndex(). + * If this attribute represents a LocalVariableTypeTable attribute, + * this method should be used instead of descriptorIndex() + * since the method name is more appropriate. + * + * @param i the i-th entry. + * @see #descriptorIndex(int) + */ + public int signatureIndex(int i) { + return descriptorIndex(i); + } + /** * Returns the type descriptor of the local variable * specified by local_variable_table[i].descriptor_index. - * + *

+ * If this attribute represents a LocalVariableTypeTable attribute, + * this method returns the type signature of the local variable + * specified by local_variable_type_table[i].signature_index. + * * @param i the i-th entry. */ public String descriptor(int i) { return getConstPool().getUtf8Info(descriptorIndex(i)); } + /** + * This method is equivalent to descriptor(). + * If this attribute represents a LocalVariableTypeTable attribute, + * this method should be used instead of descriptor() + * since the method name is more appropriate. + * + * @param i the i-th entry. + * @see #descriptor(int) + */ + public String signature(int i) { + return descriptor(i); + } + /** * Returns local_variable_table[i].index. * This represents the index of the local variable. diff --git a/src/main/javassist/bytecode/MethodInfo.java b/src/main/javassist/bytecode/MethodInfo.java index 6b265073..b3d33213 100644 --- a/src/main/javassist/bytecode/MethodInfo.java +++ b/src/main/javassist/bytecode/MethodInfo.java @@ -178,6 +178,8 @@ public final class MethodInfo { /** * Returns all the attributes. + * A new element can be added to the returned list + * and an existing element can be removed from the list. * * @return a list of AttributeInfo objects. * @see AttributeInfo diff --git a/src/main/javassist/bytecode/SignatureAttribute.java b/src/main/javassist/bytecode/SignatureAttribute.java new file mode 100644 index 00000000..b6518ebf --- /dev/null +++ b/src/main/javassist/bytecode/SignatureAttribute.java @@ -0,0 +1,70 @@ +/* + * Javassist, a Java-bytecode translator toolkit. + * Copyright (C) 1999-2004 Shigeru Chiba. All Rights Reserved. + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. Alternatively, the contents of this file may be used under + * the terms of the GNU Lesser General Public License Version 2.1 or later. + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + */ + +package javassist.bytecode; + +import java.io.DataInputStream; +import java.io.IOException; +import java.util.Map; + +/** + * Signature_attribute. + */ +public class SignatureAttribute extends AttributeInfo { + /** + * The name of this attribute "Signature". + */ + public static final String tag = "Signature"; + + SignatureAttribute(ConstPool cp, int n, DataInputStream in) + throws IOException + { + super(cp, n, in); + } + + /** + * Constructs a Signature attribute. + * + * @param cp a constant pool table. + * @param signature the signature represented by this attribute. + */ + public SignatureAttribute(ConstPool cp, String signature) { + super(cp, tag); + int index = cp.addUtf8Info(signature); + byte[] bvalue = new byte[2]; + bvalue[0] = (byte)(index >>> 8); + bvalue[1] = (byte)index; + set(bvalue); + } + + /** + * Returns the signature indicated by signature_index. + */ + public String getSignature() { + return getConstPool().getUtf8Info(ByteArray.readU16bit(get(), 0)); + } + + /** + * Makes a copy. Class names are replaced according to the + * given Map object. + * + * @param newCp the constant pool table used by the new copy. + * @param classnames pairs of replaced and substituted + * class names. + */ + public AttributeInfo copy(ConstPool newCp, Map classnames) { + return new SignatureAttribute(newCp, getSignature()); + } +} diff --git a/tutorial/tutorial.html b/tutorial/tutorial.html index 0598f60b..52a68e1c 100644 --- a/tutorial/tutorial.html +++ b/tutorial/tutorial.html @@ -400,6 +400,15 @@ program by a user-defined class loader. The latter one, as well as the program of the user-defined class loader, should be loaded by the system class loader. +

+


4.1 Class loading in Java

@@ -589,15 +598,15 @@ The event-listener class must implement the following interface:

The method start() is called when this event listener is added to a javassist.Loader object by addTranslator() in javassist.Loader. The -method onWrite() is called before -javassist.Loader loads a class. onWrite() +method onLoad() is called before +javassist.Loader loads a class. onLoad() can modify the definition of the loaded class.

For example, the following event listener changes all classes @@ -606,7 +615,7 @@ to public classes just before they are loaded.

-

Note that onWrite() does not have to call +

Note that onLoad() does not have to call toBytecode() or writeFile() since javassist.Loader calls these methods to obtain a class file. diff --git a/tutorial/tutorial3.html b/tutorial/tutorial3.html index 4b732978..c965a64c 100644 --- a/tutorial/tutorial3.html +++ b/tutorial/tutorial3.html @@ -84,10 +84,16 @@ In other words, a FieldInfo (or MethodInfo etc.) objec must not be shared among different ClassFile objects.

-To remove a field or a method, you must first obtain a java.util.List +To remove a field or a method, +you must first obtain a java.util.List object containing all the fields of the class. getFields() and getMethods() return the lists. A field or a method can be removed by calling remove() on the List object. +An attribute can be removed in a similar way. +Call getAttributes() in FieldInfo or +MethodInfo to obtain the list of attributes, +and remove one from the list. +


-- 2.39.5