();
private final AnnotationsAttribute runtimeVisibleAnnotationsAttribute;
private final ClassLoader classLoader;
private final ClassFactory classFactory;
@Deprecated
public ClassFile(String name, String superclass, String... interfaces) {
this(name, AccessFlag.of(AccessFlag.SUPER, AccessFlag.PUBLIC), superclass, null, interfaces);
}
@Deprecated
public ClassFile(String name, int accessFlags, String superclass, String... interfaces) {
this(name, accessFlags, superclass, null, interfaces);
}
@Deprecated
public ClassFile(String name, String superclass, ClassLoader classLoader, String... interfaces) {
this(name, AccessFlag.of(AccessFlag.SUPER, AccessFlag.PUBLIC), superclass, classLoader, interfaces);
}
@Deprecated
public ClassFile(String name, int accessFlags, String superclass, ClassLoader classLoader, String... interfaces) {
this(name, accessFlags, superclass, JavaVersions.JAVA_6, classLoader, interfaces);
}
@Deprecated
public ClassFile(String name, int accessFlags, String superclass, int version, ClassLoader classLoader, String... interfaces) {
if(version > JavaVersions.JAVA_6 && classLoader == null) {
throw new IllegalArgumentException("ClassLoader must be specified if version is greater than Java 6");
}
this.version = version;
this.classLoader = classLoader;
this.classFactory = null; // allowed to be null for backward compatibility reasons
this.name = name.replace('/', '.'); // store the name in . form
this.superclass = superclass;
this.accessFlags = accessFlags;
this.interfaces.addAll(Arrays.asList(interfaces));
this.runtimeVisibleAnnotationsAttribute = new AnnotationsAttribute(AnnotationsAttribute.Type.RUNTIME_VISIBLE, constPool);
this.attributes.add(runtimeVisibleAnnotationsAttribute);
}
public ClassFile(String name, String superclass, ClassLoader classLoader, ClassFactory classFactory, String... interfaces) {
this(name, AccessFlag.of(AccessFlag.SUPER, AccessFlag.PUBLIC), superclass, classLoader, classFactory, interfaces);
}
public ClassFile(String name, int accessFlags, String superclass, ClassLoader classLoader, ClassFactory classFactory, String... interfaces) {
this(name, accessFlags, superclass, JavaVersions.JAVA_6, classLoader, classFactory, interfaces);
}
public ClassFile(String name, int accessFlags, String superclass, int version, ClassLoader classLoader, ClassFactory classFactory, String... interfaces) {
if(version > JavaVersions.JAVA_6 && classLoader == null) {
throw new IllegalArgumentException("ClassLoader must be specified if version is greater than Java 6");
}
if (classFactory == null) {
throw new IllegalArgumentException("ClassFactory must be specified");
}
this.version = version;
this.classLoader = classLoader;
this.classFactory = classFactory;
this.name = name.replace('/', '.'); // store the name in . form
this.superclass = superclass;
this.accessFlags = accessFlags;
this.interfaces.addAll(Arrays.asList(interfaces));
this.runtimeVisibleAnnotationsAttribute = new AnnotationsAttribute(AnnotationsAttribute.Type.RUNTIME_VISIBLE, constPool);
this.attributes.add(runtimeVisibleAnnotationsAttribute);
}
public void addInterface(String iface) {
this.interfaces.add(iface);
}
// fields
/**
* Adds a field with the given name and descriptor.
*
*/
public ClassField addField(int accessFlags, String name, String descriptor) {
return addField(accessFlags, name, descriptor, null);
}
public ClassField addField(int accessFlags, String name, String descriptor, String signature) {
ClassField field = new ClassField((short) accessFlags, name, descriptor, this, constPool);
if (fields.contains(field)) {
throw new DuplicateMemberException("Field already exists. Field: " + name + " Descriptor:" + signature);
}
fields.add(field);
field.setSignature(signature);
return field;
}
public ClassField addField(int accessFlags, String name, Class> type) {
return addField(accessFlags, name, DescriptorUtils.makeDescriptor(type));
}
public ClassField addField(int accessFlags, String name, Class> type, String genericSignature) {
return addField(accessFlags, name, DescriptorUtils.makeDescriptor(type), genericSignature);
}
public ClassField addField(Field field) {
ClassField classField = addField((short) field.getModifiers(), field.getName(), field.getType(), null);
for (Annotation annotation : field.getDeclaredAnnotations()) {
classField.getRuntimeVisibleAnnotationsAttribute().addAnnotation(
AnnotationBuilder.createAnnotation(constPool, annotation));
}
return classField;
}
// methods
public ClassMethod addMethod(int accessFlags, String name, String returnType, String... parameters) {
ClassMethod method = new ClassMethod(name, returnType, parameters, accessFlags, this);
if (methods.contains(method)) {
throw new DuplicateMemberException("Method already exists. Method: " + name + " Parameters:"
+ Arrays.toString(parameters) + " Return Type: " + returnType);
}
methods.add(method);
return method;
}
/**
* Adds a method with the same signiture as the given method, including exception types
*
* The new method will have the same modifier as the original method, except that the abstract and native flags will be
* stripped.
*
* TODO: annotations and signiture attribute
*/
public ClassMethod addMethod(Method method) {
ClassMethod classMethod = addMethod(method.getModifiers() & (~AccessFlag.ABSTRACT) & (~AccessFlag.NATIVE), method
.getName(), DescriptorUtils.makeDescriptor(method.getReturnType()), DescriptorUtils.parameterDescriptors(method
.getParameterTypes()));
for (Class> e : method.getExceptionTypes()) {
classMethod.addCheckedExceptions((Class extends Exception>) e);
}
for (Annotation annotation : method.getDeclaredAnnotations()) {
classMethod.getRuntimeVisibleAnnotationsAttribute().addAnnotation(
AnnotationBuilder.createAnnotation(constPool, annotation));
}
int count = 0;
for (Annotation[] parameterAnnotations : method.getParameterAnnotations()) {
for (Annotation annotation : parameterAnnotations) {
classMethod.getRuntimeVisibleParameterAnnotationsAttribute().addAnnotation(count,
AnnotationBuilder.createAnnotation(constPool, annotation));
}
count++;
}
return classMethod;
}
/**
* Adds a constructor with the same signiture as the given constrcutor, including exception types
*
* TODO: annotations and signiture attribute
*/
public ClassMethod addConstructor(Constructor> method) {
ClassMethod classMethod = addMethod(method.getModifiers(), "", "V", DescriptorUtils.parameterDescriptors(method
.getParameterTypes()));
for (Class> e : method.getExceptionTypes()) {
classMethod.addCheckedExceptions((Class extends Exception>) e);
}
for (Annotation annotation : method.getDeclaredAnnotations()) {
classMethod.getRuntimeVisibleAnnotationsAttribute().addAnnotation(
AnnotationBuilder.createAnnotation(constPool, annotation));
}
int count = 0;
for (Annotation[] parameterAnnotations : method.getParameterAnnotations()) {
for (Annotation annotation : parameterAnnotations) {
classMethod.getRuntimeVisibleParameterAnnotationsAttribute().addAnnotation(count,
AnnotationBuilder.createAnnotation(constPool, annotation));
}
count++;
}
return classMethod;
}
public void write(ByteArrayDataOutputStream stream) throws IOException {
// first make sure everything we need is in the const pool
int nameIndex = constPool.addClassEntry(name);
int superClassIndex = constPool.addClassEntry(superclass);
List interfaceIndexes = new ArrayList(interfaces.size());
for (String i : interfaces) {
interfaceIndexes.add(constPool.addClassEntry(i));
}
stream.writeInt(0xCAFEBABE);// magic
stream.writeInt(version);
constPool.write(stream);
stream.writeShort(accessFlags);
stream.writeShort(nameIndex);
stream.writeShort(superClassIndex);
stream.writeShort(interfaceIndexes.size()); // interface count
for (int i : interfaceIndexes) {
stream.writeShort(i);
}
stream.writeShort(fields.size()); // field count
for (ClassField field : fields) {
field.write(stream);
}
stream.writeShort(methods.size()); // method count
for (ClassMethod method : methods) {
method.write(stream);
}
stream.writeShort(attributes.size()); // attribute count
for (Attribute attribute : attributes) {
attribute.write(stream);
}
}
public Class> define() {
return defineInternal(classLoader, null);
}
@Deprecated
public Class> define(ClassLoader loader) {
return defineInternal(loader, null);
}
public Class> define(ProtectionDomain domain) {
return defineInternal(classLoader, domain);
}
/**
* Definines the class using the given ClassLoader and ProtectionDomain
*/
@Deprecated
public Class> define(ClassLoader loader, ProtectionDomain domain) {
return defineInternal(loader, domain);
}
private Class> defineInternal(ClassLoader loader, ProtectionDomain domain) {
byte[] b = toBytecode();
final ClassFactory classFactory = this.classFactory == null ? DefaultClassFactory.INSTANCE : this.classFactory;
return classFactory.defineClass(loader, name, b, 0, b.length, domain);
}
public byte[] toBytecode() {
// TODO: throw illegal state exception if the class file is modified after writing
if (bytecode == null) {
try {
ByteArrayDataOutputStream out = new ByteArrayDataOutputStream();
write(out);
bytecode = out.getBytes();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return bytecode;
}
public ClassLoader getClassLoader() {
return classLoader;
}
public ConstPool getConstPool() {
return constPool;
}
/**
* returns the type descriptor for the class
*
* @return
*/
public String getDescriptor() {
return DescriptorUtils.makeDescriptor(name);
}
public AnnotationsAttribute getRuntimeVisibleAnnotationsAttribute() {
return runtimeVisibleAnnotationsAttribute;
}
/**
* Returns the generated class name
*
* @return The generated class name
*/
public String getName() {
return name;
}
/**
*
* @return The generated superclass name
*/
public String getSuperclass() {
return superclass;
}
/**
*
* @return The interfaces implemented by this class
*/
public List getInterfaces() {
return Collections.unmodifiableList(interfaces);
}
/**
*
* @return This class's fields
*/
public Set getFields() {
return Collections.unmodifiableSet(fields);
}
/**
*
* @return This classes methods
*/
public Set getMethods() {
return Collections.unmodifiableSet(methods);
}
}
jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/ClassMethod.java 0000664 0000000 0000000 00000015637 14046606623 0031730 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter;
import java.io.IOException;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import org.jboss.classfilewriter.annotations.AnnotationsAttribute;
import org.jboss.classfilewriter.annotations.ParameterAnnotationsAttribute;
import org.jboss.classfilewriter.attributes.Attribute;
import org.jboss.classfilewriter.attributes.ExceptionsAttribute;
import org.jboss.classfilewriter.attributes.SignatureAttribute;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.constpool.ConstPool;
import org.jboss.classfilewriter.util.ByteArrayDataOutputStream;
import org.jboss.classfilewriter.util.DescriptorUtils;
public class ClassMethod implements WritableEntry {
private final String returnType;
private final String[] parameters;
private final String name;
private final String descriptor;
private final int accessFlags;
private final ClassFile classFile;
/**
* The index of the name into the const pool
*/
private final int nameIndex;
/**
* the index of the descriptor into the const pool
*/
private final int descriptorIndex;
private final List attributes = new ArrayList();
private final CodeAttribute codeAttribute;
private final ExceptionsAttribute exceptionsAttribute;
private final boolean constructor;
private final AnnotationsAttribute runtimeVisibleAnnotationsAttribute;
private final ParameterAnnotationsAttribute runtimeVisibleParameterAnnotationsAttribute;
private SignatureAttribute signatureAttribute;
private String signature;
ClassMethod(String name, String returnType, String[] parameters, int accessFlags, ClassFile classFile) {
ConstPool constPool = classFile.getConstPool();
this.classFile = classFile;
this.returnType = DescriptorUtils.validateDescriptor(returnType);
this.parameters = parameters;
this.name = name;
this.descriptor = DescriptorUtils.methodDescriptor(parameters, returnType);
this.accessFlags = accessFlags;
this.nameIndex = constPool.addUtf8Entry(name);
this.descriptorIndex = constPool.addUtf8Entry(descriptor);
this.constructor = name.equals("");
this.exceptionsAttribute = new ExceptionsAttribute(constPool);
this.attributes.add(exceptionsAttribute);
if (Modifier.isAbstract(accessFlags)) {
codeAttribute = null;
} else {
codeAttribute = new CodeAttribute(this, constPool);
attributes.add(codeAttribute);
}
for (String param : this.parameters) {
DescriptorUtils.validateDescriptor(param);
}
this.runtimeVisibleAnnotationsAttribute = new AnnotationsAttribute(AnnotationsAttribute.Type.RUNTIME_VISIBLE, constPool);
this.attributes.add(runtimeVisibleAnnotationsAttribute);
this.runtimeVisibleParameterAnnotationsAttribute = new ParameterAnnotationsAttribute(
ParameterAnnotationsAttribute.Type.RUNTIME_VISIBLE, constPool, parameters.length);
this.attributes.add(runtimeVisibleParameterAnnotationsAttribute);
}
public void addCheckedExceptions(Class extends Exception>... exceptions) {
for (Class extends Exception> exception : exceptions) {
exceptionsAttribute.addExceptionClass(exception.getName());
}
}
public void addCheckedExceptions(String... exceptions) {
for (String exception : exceptions) {
exceptionsAttribute.addExceptionClass(exception);
}
}
public void write(ByteArrayDataOutputStream stream) throws IOException {
if(signatureAttribute != null) {
attributes.add(signatureAttribute);
}
stream.writeShort(accessFlags);
stream.writeShort(nameIndex);
stream.writeShort(descriptorIndex);
stream.writeShort(attributes.size());
for (Attribute attribute : attributes) {
attribute.write(stream);
}
}
public CodeAttribute getCodeAttribute() {
return codeAttribute;
}
public int getAccessFlags() {
return accessFlags;
}
public String getReturnType() {
return returnType;
}
public String[] getParameters() {
return parameters;
}
public String getName() {
return name;
}
public String getDescriptor() {
return descriptor;
}
public boolean isConstructor() {
return constructor;
}
public boolean isStatic() {
return Modifier.isStatic(accessFlags);
}
public ClassFile getClassFile() {
return classFile;
}
public AnnotationsAttribute getRuntimeVisibleAnnotationsAttribute() {
return runtimeVisibleAnnotationsAttribute;
}
public ParameterAnnotationsAttribute getRuntimeVisibleParameterAnnotationsAttribute() {
return runtimeVisibleParameterAnnotationsAttribute;
}
public String getSignature() {
return signature;
}
public void setSignature(String signature) {
if(signature == null) {
signatureAttribute = null;
} else {
signatureAttribute = new SignatureAttribute(classFile.getConstPool(), signature);
}
this.signature = signature;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((descriptor == null) ? 0 : descriptor.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ClassMethod other = (ClassMethod) obj;
if (descriptor == null) {
if (other.descriptor != null)
return false;
} else if (!descriptor.equals(other.descriptor))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "ClassMethod: " + name + descriptor;
}
}
jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/DefaultClassFactory.java 0000664 0000000 0000000 00000011271 14046606623 0033412 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2019 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter;
import sun.misc.Unsafe;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.security.ProtectionDomain;
/**
* Default class definition factory. This factory maintains backward compatibility
* but it doesn't work on JDK 12 and above where ClassLoader reflection magic is forbidden.
*
* @author Richard Opalka
*/
final class DefaultClassFactory implements ClassFactory {
static final ClassFactory INSTANCE = new DefaultClassFactory();
private final java.lang.reflect.Method defineClass1, defineClass2;
private DefaultClassFactory() {
try {
Method[] defineClassMethods = AccessController.doPrivileged(new PrivilegedExceptionAction() {
public Method[] run() throws Exception {
final sun.misc.Unsafe UNSAFE;
final long overrideOffset;
// first we need to grab Unsafe
try {
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
UNSAFE = (Unsafe) theUnsafe.get(null);
overrideOffset = UNSAFE.objectFieldOffset(AccessibleObject.class.getDeclaredField("override"));
} catch (Exception e) {
throw new Error(e);
}
// now we gain access to CL.defineClass methods
Class> cl = ClassLoader.class;
Method defClass1 = cl.getDeclaredMethod("defineClass", new Class[] { String.class, byte[].class, int.class,
int.class });
Method defClass2 = cl.getDeclaredMethod("defineClass", new Class[] { String.class, byte[].class, int.class,
int.class, ProtectionDomain.class });
// use Unsafe to crack open both CL.defineClass() methods (instead of using setAccessible())
UNSAFE.putBoolean(defClass1, overrideOffset, true);
UNSAFE.putBoolean(defClass2, overrideOffset, true);
return new Method[]{defClass1, defClass2};
}
});
// set methods to volatile fields
defineClass1 = defineClassMethods[0];
defineClass2 = defineClassMethods[1];
} catch (PrivilegedActionException pae) {
throw new RuntimeException("Cannot initialize DefaultClassFactory", pae.getException());
}
}
@Override
public Class> defineClass(final ClassLoader loader, final String name,
final byte[] b, final int off, final int len,
final ProtectionDomain domain) throws ClassFormatError {
try {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
final int index = name.lastIndexOf('.');
final String packageName;
if(index == -1 ) {
packageName = "";
} else {
packageName = name.substring(0, index);
}
RuntimePermission permission = new RuntimePermission("defineClassInPackage." + packageName);
sm.checkPermission(permission);
}
java.lang.reflect.Method method;
Object[] args;
if (domain == null) {
method = defineClass1;
args = new Object[]{name, b, 0, b.length};
} else {
method = defineClass2;
args = new Object[]{name, b, 0, b.length, domain};
}
return (Class>) method.invoke(loader, args);
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
DuplicateMemberException.java 0000664 0000000 0000000 00000001650 14046606623 0034352 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter;
/**
* Exception thrown if the same field or method is added twice
*
* @author Stuart Douglas
*
*/
public class DuplicateMemberException extends RuntimeException {
public DuplicateMemberException(String message) {
super(message);
}
}
InvalidBytecodeException.java 0000664 0000000 0000000 00000001477 14046606623 0034364 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter;
public class InvalidBytecodeException extends RuntimeException {
public InvalidBytecodeException(String messge) {
super(messge);
}
}
jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/JavaVersions.java 0000664 0000000 0000000 00000003045 14046606623 0032122 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter;
public class JavaVersions {
/**
* The major version number of class files for JDK 1.1.
*/
public static final int JAVA_1 = 45;
/**
* The major version number of class files for JDK 1.2.
*/
public static final int JAVA_2 = 46;
/**
* The major version number of class files for JDK 1.3.
*/
public static final int JAVA_3 = 47;
/**
* The major version number of class files for JDK 1.4.
*/
public static final int JAVA_4 = 48;
/**
* The major version number of class files for JDK 1.5.
*/
public static final int JAVA_5 = 49;
/**
* The major version number of class files for JDK 1.6.
*/
public static final int JAVA_6 = 50;
/**
* The major version number of class files for JDK 1.7.
*/
public static final int JAVA_7 = 51;
private JavaVersions() {
}
}
jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/WritableEntry.java 0000664 0000000 0000000 00000002034 14046606623 0032300 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter;
import org.jboss.classfilewriter.util.ByteArrayDataOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
/**
* a part of the class file that knows hows to write itself to a {@link ByteArrayOutputStream}
*
* @author Stuart Douglas
*
*/
public interface WritableEntry {
void write(ByteArrayDataOutputStream stream) throws IOException;
}
jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/annotations/ 0000775 0000000 0000000 00000000000 14046606623 0031200 5 ustar 00root root 0000000 0000000 AnnotationAnnotationValue.java 0000664 0000000 0000000 00000002623 14046606623 0037131 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/annotations /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.annotations;
import java.io.DataOutputStream;
import java.io.IOException;
import org.jboss.classfilewriter.constpool.ConstPool;
import org.jboss.classfilewriter.util.ByteArrayDataOutputStream;
/**
* Represents a nestled annotation value
*
* @author Stuart Douglas
*
*/
public class AnnotationAnnotationValue extends AnnotationValue {
private final ClassAnnotation value;
public AnnotationAnnotationValue(ConstPool constPool, String name, ClassAnnotation value) {
super(constPool, name);
this.value = value;
}
@Override
public char getTag() {
return '@';
}
@Override
public void writeData(ByteArrayDataOutputStream stream) throws IOException {
value.write(stream);
}
}
AnnotationBuilder.java 0000664 0000000 0000000 00000011265 14046606623 0035412 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/annotations /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.annotations;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.List;
import org.jboss.classfilewriter.constpool.ConstPool;
/**
* Utility class that can be used to contruct annotations and annotation attributes from java {@link Annotation} instances
*
* @author Stuart Douglas
*/
public class AnnotationBuilder {
public static ClassAnnotation createAnnotation(ConstPool constPool, final Annotation annotation) {
Class extends Annotation> annotationType = annotation.annotationType();
List values = new ArrayList();
try {
for (final Method m : annotationType.getDeclaredMethods()) {
Object value = AccessController.doPrivileged(new PrivilegedExceptionAction() {
@Override
public Object run() throws InvocationTargetException, IllegalAccessException {
m.setAccessible(true);
return m.invoke(annotation);
}
});
values.add(createValue(constPool, m.getName(), value));
}
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (PrivilegedActionException e) {
throw new RuntimeException(e);
}
return new ClassAnnotation(constPool, annotationType.getName(), values);
}
public static AnnotationValue createValue(ConstPool constPool, String name, Object value) {
Class> type = value.getClass();
if (type == String.class) {
return new StringAnnotationValue(constPool, name, (String) value);
} else if (type == int.class || type == Integer.class) {
return new IntAnnotationValue(constPool, name, (Integer) value);
} else if (type == short.class || type == Short.class) {
return new ShortAnnotationValue(constPool, name, (Short) value);
} else if (type == byte.class || type == Byte.class) {
return new ByteAnnotationValue(constPool, name, (Byte) value);
} else if (type == boolean.class || type == Boolean.class) {
return new BooleanAnnotationValue(constPool, name, (Boolean) value);
} else if (type == char.class || type == Character.class) {
return new CharAnnotationValue(constPool, name, (Character) value);
} else if (type == long.class || type == Long.class) {
return new LongAnnotationValue(constPool, name, (Long) value);
} else if (type == float.class || type == Float.class) {
return new FloatAnnotationValue(constPool, name, (Float) value);
} else if (type == double.class || type == Double.class) {
return new DoubleAnnotationValue(constPool, name, (Double) value);
} else if (type == Class.class) {
return new ClassAnnotationValue(constPool, name, (Class>) value);
} else if (type.isEnum() || (type.getEnclosingClass() != null && type.getEnclosingClass().isEnum())) {
return new EnumAnnotationValue(constPool, name, (Enum>) value);
} else if (value instanceof Annotation) {
return new AnnotationAnnotationValue(constPool, name, createAnnotation(constPool, (Annotation) value));
} else if (type.isArray()) {
int length = Array.getLength(value);
List values = new ArrayList();
for (int i = 0; i < length; ++i) {
values.add(createValue(constPool, null, Array.get(value, i)));
}
return new ArrayAnnotationValue(constPool, name, values);
}
throw new RuntimeException("Invalid type for annotation value. Type: " + type + " Value: " + value);
}
private AnnotationBuilder() {
}
}
AnnotationValue.java 0000664 0000000 0000000 00000003514 14046606623 0035076 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/annotations /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.annotations;
import org.jboss.classfilewriter.WritableEntry;
import org.jboss.classfilewriter.constpool.ConstPool;
import org.jboss.classfilewriter.util.ByteArrayDataOutputStream;
import java.io.IOException;
/**
* Represents an annotation name/value pair. This class can also represent a value an an array valued annotation instance, if
* the name is null
*
* @author Stuart Douglas
*
*/
public abstract class AnnotationValue implements WritableEntry {
private final String name;
private final int nameIndex;
protected AnnotationValue(ConstPool constPool, String name) {
this.name = name;
if (name != null) {
this.nameIndex = constPool.addUtf8Entry(name);
} else {
this.nameIndex = -1;
}
}
public void write(ByteArrayDataOutputStream stream) throws IOException {
if (nameIndex != -1) {
stream.writeShort(nameIndex);
}
stream.writeByte(getTag());
writeData(stream);
}
public abstract void writeData(ByteArrayDataOutputStream stream) throws IOException;
public String getName() {
return name;
}
public abstract char getTag();
}
AnnotationsAttribute.java 0000664 0000000 0000000 00000004345 14046606623 0036153 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/annotations /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.annotations;
import org.jboss.classfilewriter.attributes.Attribute;
import org.jboss.classfilewriter.constpool.ConstPool;
import org.jboss.classfilewriter.util.ByteArrayDataOutputStream;
import org.jboss.classfilewriter.util.LazySize;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;
/**
* An annotations attribute
*
* @author Stuart Douglas
*
*/
public class AnnotationsAttribute extends Attribute {
public enum Type {
RUNTIME_VISIBLE("RuntimeVisibleAnnotations"), RUNTIME_INVISIBLE("RuntimeInvisibleAnnotations");
Type(String tag) {
this.tag = tag;
}
private final String tag;
public String getTag() {
return tag;
}
}
private final List annotations;
public AnnotationsAttribute(Type type, ConstPool constPool) {
super(type.getTag(), constPool);
this.annotations = new ArrayList();
}
@Override
public void writeData(ByteArrayDataOutputStream stream) throws IOException {
LazySize sizeMarker = stream.writeSize();
stream.writeShort(annotations.size());
for (ClassAnnotation annotation : annotations) {
annotation.write(stream);
}
sizeMarker.markEnd();
}
public void addAnnotation(Annotation annotation) {
annotations.add(AnnotationBuilder.createAnnotation(constPool, annotation));
}
public void addAnnotation(ClassAnnotation annotation) {
annotations.add(annotation);
}
}
ArrayAnnotationValue.java 0000664 0000000 0000000 00000002775 14046606623 0036105 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/annotations /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.annotations;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.List;
import org.jboss.classfilewriter.constpool.ConstPool;
import org.jboss.classfilewriter.util.ByteArrayDataOutputStream;
/**
* An array annotation value
*
* @author Stuart Douglas
*
*/
public class ArrayAnnotationValue extends AnnotationValue {
private final List value;
public ArrayAnnotationValue(ConstPool constPool, String name, List value) {
super(constPool, name);
this.value = value;
}
@Override
public char getTag() {
return '[';
}
@Override
public void writeData(ByteArrayDataOutputStream stream) throws IOException {
stream.writeShort(value.size());
for (AnnotationValue v : value) {
v.write(stream);
}
}
}
BooleanAnnotationValue.java 0000664 0000000 0000000 00000003040 14046606623 0036370 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/annotations /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.annotations;
import java.io.DataOutputStream;
import java.io.IOException;
import org.jboss.classfilewriter.constpool.ConstPool;
import org.jboss.classfilewriter.util.ByteArrayDataOutputStream;
/**
* A boolean annotation value
*
* @author Stuart Douglas
*
*/
public class BooleanAnnotationValue extends AnnotationValue {
private final int valueIndex;
private final boolean value;
public BooleanAnnotationValue(ConstPool constPool, String name, boolean value) {
super(constPool, name);
this.value = value;
this.valueIndex = constPool.addIntegerEntry(value ? 1 : 0);
}
@Override
public char getTag() {
return 'Z';
}
@Override
public void writeData(ByteArrayDataOutputStream stream) throws IOException {
stream.writeShort(valueIndex);
}
public boolean getValue() {
return value;
}
}
ByteAnnotationValue.java 0000664 0000000 0000000 00000003006 14046606623 0035716 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/annotations /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.annotations;
import java.io.DataOutputStream;
import java.io.IOException;
import org.jboss.classfilewriter.constpool.ConstPool;
import org.jboss.classfilewriter.util.ByteArrayDataOutputStream;
/**
* a byte annotation value
*
* @author Stuart Douglas
*
*/
public class ByteAnnotationValue extends AnnotationValue {
private final int valueIndex;
private final byte value;
public ByteAnnotationValue(ConstPool constPool, String name, byte value) {
super(constPool, name);
this.value = value;
this.valueIndex = constPool.addIntegerEntry(value);
}
@Override
public char getTag() {
return 'B';
}
@Override
public void writeData(ByteArrayDataOutputStream stream) throws IOException {
stream.writeShort(valueIndex);
}
public byte getValue() {
return value;
}
}
CharAnnotationValue.java 0000664 0000000 0000000 00000003006 14046606623 0035670 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/annotations /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.annotations;
import java.io.DataOutputStream;
import java.io.IOException;
import org.jboss.classfilewriter.constpool.ConstPool;
import org.jboss.classfilewriter.util.ByteArrayDataOutputStream;
/**
* A char annotation value
*
* @author Stuart Douglas
*
*/
public class CharAnnotationValue extends AnnotationValue {
private final int valueIndex;
private final char value;
public CharAnnotationValue(ConstPool constPool, String name, char value) {
super(constPool, name);
this.value = value;
this.valueIndex = constPool.addIntegerEntry(value);
}
@Override
public char getTag() {
return 'C';
}
@Override
public void writeData(ByteArrayDataOutputStream stream) throws IOException {
stream.writeShort(valueIndex);
}
public char getValue() {
return value;
}
}
ClassAnnotation.java 0000664 0000000 0000000 00000003633 14046606623 0035071 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/annotations /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.annotations;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.jboss.classfilewriter.WritableEntry;
import org.jboss.classfilewriter.constpool.ConstPool;
import org.jboss.classfilewriter.util.ByteArrayDataOutputStream;
/**
* A bytecode representation of a java annotation
*
*
* @author Stuart Douglas
*
*/
public class ClassAnnotation implements WritableEntry {
private final String type;
private final int typeIndex;
private final List annotationValues;
public ClassAnnotation(ConstPool constPool, String type, List annotationValues) {
this.type = type;
this.typeIndex = constPool.addUtf8Entry("L" + type.replace('.','/') + ";");
this.annotationValues = new ArrayList(annotationValues);
}
public void write(ByteArrayDataOutputStream stream) throws IOException {
stream.writeShort(typeIndex);
stream.writeShort(annotationValues.size());
for (AnnotationValue value : annotationValues) {
value.write(stream);
}
}
public String getType() {
return type;
}
public List getAnnotationValues() {
return annotationValues;
}
}
ClassAnnotationValue.java 0000664 0000000 0000000 00000003250 14046606623 0036061 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/annotations /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.annotations;
import java.io.DataOutputStream;
import java.io.IOException;
import org.jboss.classfilewriter.constpool.ConstPool;
import org.jboss.classfilewriter.util.ByteArrayDataOutputStream;
import org.jboss.classfilewriter.util.DescriptorUtils;
/**
* A class annotation value
*
* @author Stuart Douglas
*
*/
public class ClassAnnotationValue extends AnnotationValue {
private final int valueIndex;
public ClassAnnotationValue(ConstPool constPool, String name, Class> value) {
super(constPool, name);
this.valueIndex = constPool.addUtf8Entry(DescriptorUtils.makeDescriptor(value));
}
public ClassAnnotationValue(ConstPool constPool, String name, String descriptor) {
super(constPool, name);
this.valueIndex = constPool.addUtf8Entry(descriptor);
}
@Override
public char getTag() {
return 'c';
}
@Override
public void writeData(ByteArrayDataOutputStream stream) throws IOException {
stream.writeShort(valueIndex);
}
}
DoubleAnnotationValue.java 0000664 0000000 0000000 00000003021 14046606623 0036222 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/annotations /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.annotations;
import java.io.DataOutputStream;
import java.io.IOException;
import org.jboss.classfilewriter.constpool.ConstPool;
import org.jboss.classfilewriter.util.ByteArrayDataOutputStream;
/**
* a double annotation value
*
* @author Stuart Douglas
*
*/
public class DoubleAnnotationValue extends AnnotationValue {
private final int valueIndex;
private final double value;
public DoubleAnnotationValue(ConstPool constPool, String name, double value) {
super(constPool, name);
this.value = value;
this.valueIndex = constPool.addDoubleEntry(value);
}
@Override
public char getTag() {
return 'D';
}
@Override
public void writeData(ByteArrayDataOutputStream stream) throws IOException {
stream.writeShort(valueIndex);
}
public double getValue() {
return value;
}
}
EnumAnnotationValue.java 0000664 0000000 0000000 00000003623 14046606623 0035724 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/annotations /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.annotations;
import java.io.DataOutputStream;
import java.io.IOException;
import org.jboss.classfilewriter.constpool.ConstPool;
import org.jboss.classfilewriter.util.ByteArrayDataOutputStream;
import org.jboss.classfilewriter.util.DescriptorUtils;
/**
* An enum annotation value
*
* @author Stuart Douglas
*
*/
public class EnumAnnotationValue extends AnnotationValue {
private final int valueIndex;
private final int typeIndex;
public EnumAnnotationValue(ConstPool constPool, String name, Enum> value) {
super(constPool, name);
this.valueIndex = constPool.addUtf8Entry(value.name());
this.typeIndex = constPool.addUtf8Entry(DescriptorUtils.makeDescriptor(value.getDeclaringClass().getName()));
}
public EnumAnnotationValue(ConstPool constPool, String name, String enumType, String enumValue) {
super(constPool, name);
this.valueIndex = constPool.addUtf8Entry(enumValue);
this.typeIndex = constPool.addUtf8Entry(enumType);
}
@Override
public char getTag() {
return 'e';
}
@Override
public void writeData(ByteArrayDataOutputStream stream) throws IOException {
stream.writeShort(typeIndex);
stream.writeShort(valueIndex);
}
}
FloatAnnotationValue.java 0000664 0000000 0000000 00000003012 14046606623 0036055 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/annotations /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.annotations;
import java.io.DataOutputStream;
import java.io.IOException;
import org.jboss.classfilewriter.constpool.ConstPool;
import org.jboss.classfilewriter.util.ByteArrayDataOutputStream;
/**
* A float annotation value
*
* @author Stuart Douglas
*
*/
public class FloatAnnotationValue extends AnnotationValue {
private final int valueIndex;
private final float value;
public FloatAnnotationValue(ConstPool constPool, String name, float value) {
super(constPool, name);
this.value = value;
this.valueIndex = constPool.addFloatEntry(value);
}
@Override
public char getTag() {
return 'F';
}
@Override
public void writeData(ByteArrayDataOutputStream stream) throws IOException {
stream.writeShort(valueIndex);
}
public float getValue() {
return value;
}
}
IntAnnotationValue.java 0000664 0000000 0000000 00000003001 14046606623 0035540 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/annotations /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.annotations;
import java.io.DataOutputStream;
import java.io.IOException;
import org.jboss.classfilewriter.constpool.ConstPool;
import org.jboss.classfilewriter.util.ByteArrayDataOutputStream;
/**
* An int annotation value
*
* @author Stuart Douglas
*
*/
public class IntAnnotationValue extends AnnotationValue {
private final int valueIndex;
private final int value;
public IntAnnotationValue(ConstPool constPool, String name, int value) {
super(constPool, name);
this.value = value;
this.valueIndex = constPool.addIntegerEntry(value);
}
@Override
public char getTag() {
return 'I';
}
@Override
public void writeData(ByteArrayDataOutputStream stream) throws IOException {
stream.writeShort(valueIndex);
}
public int getValue() {
return value;
}
}
LongAnnotationValue.java 0000664 0000000 0000000 00000003003 14046606623 0035707 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/annotations /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.annotations;
import java.io.DataOutputStream;
import java.io.IOException;
import org.jboss.classfilewriter.constpool.ConstPool;
import org.jboss.classfilewriter.util.ByteArrayDataOutputStream;
/**
* A long annotation value
*
* @author Stuart Douglas
*
*/
public class LongAnnotationValue extends AnnotationValue {
private final int valueIndex;
private final long value;
public LongAnnotationValue(ConstPool constPool, String name, long value) {
super(constPool, name);
this.value = value;
this.valueIndex = constPool.addLongEntry(value);
}
@Override
public char getTag() {
return 'J';
}
@Override
public void writeData(ByteArrayDataOutputStream stream) throws IOException {
stream.writeShort(valueIndex);
}
public long getValue() {
return value;
}
}
ParameterAnnotationsAttribute.java 0000664 0000000 0000000 00000006061 14046606623 0040011 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/annotations /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.annotations;
import org.jboss.classfilewriter.attributes.Attribute;
import org.jboss.classfilewriter.constpool.ConstPool;
import org.jboss.classfilewriter.util.ByteArrayDataOutputStream;
import org.jboss.classfilewriter.util.LazySize;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* A parameter annotations attribute
*
* @author Stuart Douglas
*
*/
public class ParameterAnnotationsAttribute extends Attribute {
public enum Type {
RUNTIME_VISIBLE("RuntimeVisibleParameterAnnotations"), RUNTIME_INVISIBLE("RuntimeInvisibleParameterAnnotations");
Type(String tag) {
this.tag = tag;
}
private final String tag;
public String getTag() {
return tag;
}
}
private final Map> annotations;
private final int noParameters;
public ParameterAnnotationsAttribute(Type type, ConstPool constPool, int noParameters) {
super(type.getTag(), constPool);
this.annotations = new HashMap>();
this.noParameters = noParameters;
}
@Override
public void writeData(ByteArrayDataOutputStream stream) throws IOException {
LazySize sizeMarker = stream.writeSize();
stream.writeByte(noParameters);
for(int i = 0; i < noParameters; ++ i) {
if(!annotations.containsKey(i)) {
stream.writeShort(0);
} else {
List ans = annotations.get(i);
stream.writeShort(ans.size());
for (ClassAnnotation annotation : ans) {
annotation.write(stream);
}
}
}
sizeMarker.markEnd();
}
public void addAnnotation(int parameter, Annotation annotation) {
if (!annotations.containsKey(parameter)) {
annotations.put(parameter, new ArrayList());
}
annotations.get(parameter).add(AnnotationBuilder.createAnnotation(constPool, annotation));
}
public void addAnnotation(int parameter, ClassAnnotation annotation) {
if (!annotations.containsKey(parameter)) {
annotations.put(parameter, new ArrayList());
}
annotations.get(parameter).add(annotation);
}
}
ShortAnnotationValue.java 0000664 0000000 0000000 00000003012 14046606623 0036107 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/annotations /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.annotations;
import java.io.DataOutputStream;
import java.io.IOException;
import org.jboss.classfilewriter.constpool.ConstPool;
import org.jboss.classfilewriter.util.ByteArrayDataOutputStream;
/**
* short annotation value
*
* @author Stuart Douglas
*
*/
public class ShortAnnotationValue extends AnnotationValue {
private final int valueIndex;
private final short value;
public ShortAnnotationValue(ConstPool constPool, String name, short value) {
super(constPool, name);
this.value = value;
this.valueIndex = constPool.addIntegerEntry(value);
}
@Override
public char getTag() {
return 'S';
}
@Override
public void writeData(ByteArrayDataOutputStream stream) throws IOException {
stream.writeShort(valueIndex);
}
public short getValue() {
return value;
}
}
StringAnnotationValue.java 0000664 0000000 0000000 00000002716 14046606623 0036270 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/annotations /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.annotations;
import java.io.IOException;
import org.jboss.classfilewriter.constpool.ConstPool;
import org.jboss.classfilewriter.util.ByteArrayDataOutputStream;
/**
* A string annotation value
*/
public class StringAnnotationValue extends AnnotationValue {
private final int valueIndex;
private final String value;
public StringAnnotationValue(ConstPool constPool, String name, String value) {
super(constPool, name);
this.value = value;
this.valueIndex = constPool.addUtf8Entry(value);
}
@Override
public char getTag() {
return 's';
}
@Override
public void writeData(ByteArrayDataOutputStream stream) throws IOException {
stream.writeShort(valueIndex);
}
public String getValue() {
return value;
}
}
jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/attributes/ 0000775 0000000 0000000 00000000000 14046606623 0031031 5 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/attributes/Attribute.java 0000664 0000000 0000000 00000003127 14046606623 0033642 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.attributes;
import org.jboss.classfilewriter.WritableEntry;
import org.jboss.classfilewriter.constpool.ConstPool;
import org.jboss.classfilewriter.util.ByteArrayDataOutputStream;
import java.io.IOException;
/**
* Represents an attribute in a class file
*
* @author Stuart Douglas
*
*/
public abstract class Attribute implements WritableEntry {
private final String name;
private final int nameIndex;
protected final ConstPool constPool;
public Attribute(String name, final ConstPool constPool) {
this.name = name;
this.nameIndex = constPool.addUtf8Entry(name);
this.constPool = constPool;
}
public void write(ByteArrayDataOutputStream stream) throws IOException {
stream.writeShort(nameIndex);
writeData(stream);
}
public abstract void writeData(ByteArrayDataOutputStream stream) throws IOException;
public String getName() {
return name;
}
}
ExceptionsAttribute.java 0000664 0000000 0000000 00000003626 14046606623 0035631 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/attributes /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.attributes;
import org.jboss.classfilewriter.constpool.ConstPool;
import org.jboss.classfilewriter.util.ByteArrayDataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* The exceptions attribute, stores the checked exceptions a method is declared to throw
*
* @author Stuart Douglas
*
*/
public class ExceptionsAttribute extends Attribute {
public static final String NAME = "Exceptions";
private final List exceptionClasses = new ArrayList();
private final List exceptionClassIndexes = new ArrayList();
private final ConstPool constPool;
public ExceptionsAttribute(ConstPool constPool) {
super(NAME, constPool);
this.constPool = constPool;
}
public void addExceptionClass(String exception) {
exceptionClasses.add(exception);
exceptionClassIndexes.add(constPool.addClassEntry(exception));
}
@Override
public void writeData(ByteArrayDataOutputStream stream) throws IOException {
stream.writeInt(2 + exceptionClassIndexes.size() * 2);
stream.writeShort(exceptionClassIndexes.size());
for (int i : exceptionClassIndexes) {
stream.writeShort(i);
}
}
}
SignatureAttribute.java 0000664 0000000 0000000 00000002623 14046606623 0035445 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/attributes /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.attributes;
import java.io.IOException;
import org.jboss.classfilewriter.constpool.ConstPool;
import org.jboss.classfilewriter.util.ByteArrayDataOutputStream;
public class SignatureAttribute extends Attribute {
public static final String NAME = "Signature";
private final String signature;
private final int signatureIndex;
public SignatureAttribute(final ConstPool constPool, String signature) {
super(NAME, constPool);
this.signature = signature;
this.signatureIndex = constPool.addUtf8Entry(signature);
}
@Override
public void writeData(ByteArrayDataOutputStream stream) throws IOException {
stream.writeInt(2); // data length
stream.writeShort(signatureIndex);
}
}
StackMapTableAttribute.java 0000664 0000000 0000000 00000011634 14046606623 0036161 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/attributes /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.attributes;
import org.jboss.classfilewriter.ClassMethod;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.code.StackEntry;
import org.jboss.classfilewriter.code.StackEntryType;
import org.jboss.classfilewriter.code.StackFrame;
import org.jboss.classfilewriter.code.StackFrameType;
import org.jboss.classfilewriter.constpool.ConstPool;
import org.jboss.classfilewriter.util.ByteArrayDataOutputStream;
import org.jboss.classfilewriter.util.LazySize;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
/**
* A JDK 6 StackMap sttribute.
*
*TODO: this will currently fall over if the code length, max locals or max stack is above 65535
*
* @author Stuart Douglas
*
*/
public class StackMapTableAttribute extends Attribute {
private static final int FULL_FRAME = 255;
private static final int SAME_FRAME_EXTENDED = 251;
public static final String NAME = "StackMapTable";
private final ClassMethod method;
public StackMapTableAttribute(ClassMethod classMethod, ConstPool constPool) {
super(NAME, constPool);
method = classMethod;
}
@Override
public void writeData(ByteArrayDataOutputStream stream) throws IOException {
// as we don't know the size yet we write everything to a byte stream first
// TODO: make this better
final CodeAttribute ca = method.getCodeAttribute();
// now we need to write the stack frames.
// for now we are going to write all frames as full frames
// TODO: optimise the frame creation
// write to dstream
LazySize size = stream.writeSize();
stream.writeShort(ca.getStackFrames().size());
int lastPos = -1;
for (Entry entry : method.getCodeAttribute().getStackFrames().entrySet()) {
int offset = entry.getKey() - lastPos - 1;
lastPos = entry.getKey();
StackFrame frame = entry.getValue();
if (frame.getType() == StackFrameType.SAME_FRAME || frame.getType() == StackFrameType.SAME_FRAME_EXTENDED) {
writeSameFrame(stream, offset, lastPos, frame);
} else if (frame.getType() == StackFrameType.SAME_LOCALS_1_STACK && offset < (127 - 64)) {
writeSameLocals1Stack(stream, offset, lastPos, frame);
} else {
writeFullFrame(stream, offset, lastPos, entry.getValue());
}
}
size.markEnd();
}
private void writeSameLocals1Stack(DataOutputStream dstream, int offset, int lastPos, StackFrame frame) throws IOException {
dstream.writeByte(offset + 64);
frame.getStackState().getContents().get(0).write(dstream);
}
private void writeSameFrame(DataOutputStream dstream, int offset, int lastPos, StackFrame frame) throws IOException {
if (offset > 63) {
dstream.writeByte(SAME_FRAME_EXTENDED);
dstream.writeShort(offset);
} else {
dstream.writeByte(offset);
}
}
/**
* writes a full_frame to the stack map table
*/
private void writeFullFrame(DataOutputStream dstream, int offset, int position, StackFrame value) throws IOException {
dstream.writeByte(FULL_FRAME);
dstream.writeShort(offset);
List realLocalVars = new ArrayList(value.getLocalVariableState().getContents().size());
for (StackEntry i : value.getLocalVariableState().getContents()) {
if (i.getType() != StackEntryType.TOP) {
realLocalVars.add(i);
}
}
dstream.writeShort(realLocalVars.size());
for (StackEntry i : realLocalVars) {
i.write(dstream);
}
// TODO: this is inefficient, the stack should store the number of TOP values in each frame
List realStack = new ArrayList(value.getStackState().getContents().size());
for (StackEntry i : value.getStackState().getContents()) {
if (i.getType() != StackEntryType.TOP) {
realStack.add(i);
}
}
dstream.writeShort(realStack.size());
for (StackEntry i : realStack) {
i.write(dstream);
}
}
}
jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/code/ 0000775 0000000 0000000 00000000000 14046606623 0027555 5 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/code/BranchEnd.java 0000664 0000000 0000000 00000003435 14046606623 0032251 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.code;
/**
* Marker that is used to create the end of a branch instruction.
*
* @author Stuart Douglas
*
*/
public class BranchEnd {
private final int branchLocation;
private final int offsetLocation;
private final StackFrame stackFrame;
private final boolean jump32Bit;
BranchEnd(int branchLocation, StackFrame stackFrame, final int offsetLocation) {
this.branchLocation = branchLocation;
this.offsetLocation = offsetLocation;
this.stackFrame = stackFrame.createFull();
this.jump32Bit = false;
}
public BranchEnd(final int branchLocation, final StackFrame stackFrame, final boolean jump32Bit, final int offsetLocation) {
this.branchLocation = branchLocation;
this.stackFrame = stackFrame.createFull();
this.jump32Bit = jump32Bit;
this.offsetLocation = offsetLocation;
}
int getBranchLocation() {
return branchLocation;
}
StackFrame getStackFrame() {
return stackFrame;
}
boolean isJump32Bit() {
return jump32Bit;
}
int getOffsetLocation() {
return offsetLocation;
}
}
jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/code/CodeAttribute.java 0000664 0000000 0000000 00000263320 14046606623 0033164 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.code;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.jboss.classfilewriter.ClassMethod;
import org.jboss.classfilewriter.InvalidBytecodeException;
import org.jboss.classfilewriter.attributes.Attribute;
import org.jboss.classfilewriter.attributes.StackMapTableAttribute;
import org.jboss.classfilewriter.constpool.ConstPool;
import org.jboss.classfilewriter.util.ByteArrayDataOutputStream;
import org.jboss.classfilewriter.util.DescriptorUtils;
import org.jboss.classfilewriter.util.LazySize;
@SuppressWarnings("unused")
public class CodeAttribute extends Attribute {
public static final String NAME = "Code";
private final ClassMethod method;
private final ConstPool constPool;
private final ByteArrayOutputStream finalDataBytes;
private final DataOutputStream data;
private int maxLocals = 0;
private int maxStackDepth = 0;
private final LinkedHashMap stackFrames = new LinkedHashMap();
/**
* maps bytecode offsets to jump locations. As these jump locations where not known when the instruction was written they
* need to be overwritten when the final bytecode is written out
*/
private final Map jumpLocations = new HashMap();
/**
* maps bytecode offsets to jump locations. As these jump locations where not known when the instruction was written they
* need to be overwritten when the final bytecode is written out
*
* These jump locations are 32 bit offsets,
*/
private final Map jumpLocations32 = new HashMap();
private StackFrame currentFrame;
private int currentOffset;
private final List attributes = new ArrayList();
private final StackMapTableAttribute stackMapTableAttribute;
private final List exceptionTable = new ArrayList();
private StackFrameTypeResolver stackFrameTypeResolver;
public CodeAttribute(ClassMethod method, ConstPool constPool) {
super(NAME, constPool);
this.method = method;
this.constPool = constPool;
this.finalDataBytes = new ByteArrayOutputStream();
this.data = new DataOutputStream(finalDataBytes);
if (!Modifier.isStatic(method.getAccessFlags())) {
maxLocals++;
}
for (String param : method.getParameters()) {
if (DescriptorUtils.isWide(param)) {
maxLocals += 2;
} else {
maxLocals++;
}
}
// creates a new initial stack frame
currentFrame = new StackFrame(method);
stackFrames.put(0, currentFrame);
currentOffset = 0;
stackMapTableAttribute = new StackMapTableAttribute(method, constPool);
}
public StackFrameTypeResolver getStackFrameTypeResolver() {
return stackFrameTypeResolver;
}
public void setStackFrameTypeResolver(StackFrameTypeResolver stackFrameTypeResolver) {
this.stackFrameTypeResolver = stackFrameTypeResolver;
}
@Override
public void writeData(ByteArrayDataOutputStream stream) throws IOException {
// add the stack map table
if (method.getClassFile().getClassLoader() != null) {
//we don't generate the stack map if the class loader is null
attributes.add(stackMapTableAttribute);
}
if (finalDataBytes.size() == 0) {
throw new RuntimeException("Code attribute is empty for method " + method.getName() + " " + method.getDescriptor());
}
byte[] bytecode = finalDataBytes.toByteArray();
for (Entry e : jumpLocations.entrySet()) {
overwriteShort(bytecode, e.getKey(), e.getValue());
}
for (Entry e : jumpLocations32.entrySet()) {
overwriteInt(bytecode, e.getKey(), e.getValue());
}
LazySize size = stream.writeSize();
stream.writeShort(maxStackDepth);
stream.writeShort(maxLocals);
stream.writeInt(bytecode.length);
stream.write(bytecode);
stream.writeShort(exceptionTable.size()); // exception table length
for (ExceptionHandler exception : exceptionTable) {
stream.writeShort(exception.getStart());
stream.writeShort(exception.getEnd());
stream.writeShort(exception.getHandler());
stream.writeShort(exception.getExceptionIndex());
}
stream.writeShort(attributes.size()); // attributes count
for (Attribute attribute : attributes) {
attribute.write(stream);
}
size.markEnd();
}
// -------------------------------------------
// Instruction methods, in alphabetical order
public void aaload() {
assertTypeOnStack(StackEntryType.INT, "aaload requires int on top of stack");
if (!getStack().top_1().getDescriptor().startsWith("[")) {
throw new InvalidBytecodeException("aaload needs an array in position 2 on the stack");
}
writeByte(Opcode.AALOAD);
currentOffset++;
advanceFrame(currentFrame.pop2push1("Ljava/lang/Object;"));
}
public void aastore() {
assertTypeOnStack(StackEntryType.OBJECT, "aastore requires reference type on top of stack");
assertTypeOnStack(1, StackEntryType.INT, "aastore requires an int on position 2 stack");
if (!getStack().top_2().getDescriptor().startsWith("[")) {
throw new InvalidBytecodeException("aaload needs an array in position 3 on the stack");
}
writeByte(Opcode.AASTORE);
currentOffset++;
advanceFrame(currentFrame.pop3());
}
public void aconstNull() {
writeByte(Opcode.ACONST_NULL);
currentOffset++;
advanceFrame(currentFrame.aconstNull());
}
public void aload(int no) {
LocalVariableState locals = getLocalVars();
if (locals.size() <= no) {
throw new InvalidBytecodeException("Cannot load variable at " + no + ". Local Variables: " + locals.toString());
}
StackEntry entry = locals.get(no);
if (entry.getType() != StackEntryType.OBJECT && entry.getType() != StackEntryType.NULL
&& entry.getType() != StackEntryType.UNINITIALIZED_THIS
&& entry.getType() != StackEntryType.UNITITIALIZED_OBJECT) {
throw new InvalidBytecodeException("Invalid local variable at location " + no + " Local Variables "
+ locals.toString());
}
if (no > 0xFF) {
// wide version
writeByte(Opcode.WIDE);
writeByte(Opcode.ALOAD);
writeShort(no);
currentOffset += 4;
} else if (no >= 0 && no < 4) {
writeByte(Opcode.ALOAD_0 + no);
currentOffset++;
} else {
writeByte(Opcode.ALOAD);
writeByte(no);
currentOffset += 2;
}
advanceFrame(currentFrame.push(entry));
}
public void anewarray(String arrayType) {
assertTypeOnStack(StackEntryType.INT, "anewarray requires int on stack");
int index = constPool.addClassEntry(arrayType);
writeByte(Opcode.ANEWARRAY);
writeShort(index);
currentOffset += 3;
if (arrayType.startsWith("[")) {
advanceFrame(currentFrame.replace("[" + arrayType));
} else {
advanceFrame(currentFrame.replace("[L" + arrayType + ";"));
}
}
public void arraylength() {
assertTypeOnStack(StackEntryType.OBJECT, "arraylength requires array on stack");
writeByte(Opcode.ARRAYLENGTH);
currentOffset++;
advanceFrame(currentFrame.replace("I"));
}
public void astore(int no) {
assertTypeOnStack(StackEntryType.OBJECT, "aastore requires reference type on stack");
if (no > 0xFF) {
// wide version
writeByte(Opcode.WIDE);
writeByte(Opcode.ASTORE);
writeShort(no);
currentOffset += 4;
} else if (no >= 0 && no < 4) {
writeByte(Opcode.ASTORE_0 + no);
currentOffset++;
} else {
writeByte(Opcode.ASTORE);
writeByte(no);
currentOffset += 2;
}
advanceFrame(currentFrame.store(no));
}
public void athrow() {
assertTypeOnStack(StackEntryType.OBJECT, "athrow requires an object on the stack");
writeByte(Opcode.ATHROW);
currentOffset++;
currentFrame = null;
}
public void baload() {
assertTypeOnStack(StackEntryType.INT, "baload requires an int on top of the stack");
assertTypeOnStack(1, StackEntryType.OBJECT, "baload requires an array in position 2 on the stack");
writeByte(Opcode.BALOAD);
currentOffset++;
advanceFrame(currentFrame.pop2push1("I"));
}
public void bastore() {
assertTypeOnStack(StackEntryType.INT, "bastore requires an int on top of the stack");
assertTypeOnStack(1, StackEntryType.INT, "bastore requires an int in position 2 on the stack");
assertTypeOnStack(2, StackEntryType.OBJECT, "bastore requires an array reference in position 3 on the stack");
writeByte(Opcode.BASTORE);
currentOffset++;
advanceFrame(currentFrame.pop3());
}
public void caload() {
assertTypeOnStack(StackEntryType.INT, "caload requires an int on top of the stack");
assertTypeOnStack(1, StackEntryType.OBJECT, "caload requires an array in position 2 on the stack");
writeByte(Opcode.CALOAD);
currentOffset++;
advanceFrame(currentFrame.pop2push1("I"));
}
public void castore() {
assertTypeOnStack(StackEntryType.INT, "castore requires an int on top of the stack");
assertTypeOnStack(1, StackEntryType.INT, "castore requires an int in position 2 on the stack");
assertTypeOnStack(2, StackEntryType.OBJECT, "castore requires an array reference in position 3 on the stack");
writeByte(Opcode.CASTORE);
currentOffset++;
advanceFrame(currentFrame.pop3());
}
public void bipush(byte value) {
writeByte(Opcode.BIPUSH);
writeByte(value);
currentOffset += 2;
advanceFrame(currentFrame.push("B"));
}
/**
* marks the end of a branch. The current stack frame is checked for compatibility with the stack frame at the branch start
*/
public void branchEnd(BranchEnd end) {
mergeStackFrames(end.getStackFrame());
final int jump = currentOffset - end.getOffsetLocation();
if (end.isJump32Bit()) {
jumpLocations32.put(end.getBranchLocation(), jump);
} else {
if (jump > Short.MAX_VALUE) {
throw new RuntimeException(jump + " is to big to be written as a 16 bit value");
}
jumpLocations.put(end.getBranchLocation(), jump);
}
}
/**
* Do not use Descriptor format (e.g. Ljava/lang/Object;), the correct form is just java/lang/Object or java.lang.Object
*/
public void checkcast(String className) {
if (!className.startsWith("[") && className.endsWith(";")) {
throw new RuntimeException("Invalid cast format " + className);
}
className = className.replace('.', '/');
assertTypeOnStack(StackEntryType.OBJECT, "checkcast requires reference type on stack");
int classIndex = constPool.addClassEntry(className);
writeByte(Opcode.CHECKCAST);
writeShort(classIndex);
currentOffset += 3;
advanceFrame(currentFrame.replace(className));
}
public void checkcast(Class> clazz) {
checkcast(clazz.getName());
}
public void d2f() {
assertTypeOnStack(StackEntryType.DOUBLE, "d2f requires double on stack");
writeByte(Opcode.D2F);
currentOffset++;
advanceFrame(currentFrame.pop2push1("F"));
}
public void d2i() {
assertTypeOnStack(StackEntryType.DOUBLE, "d2i requires double on stack");
writeByte(Opcode.D2I);
currentOffset++;
advanceFrame(currentFrame.pop2push1("I"));
}
public void d2l() {
assertTypeOnStack(StackEntryType.DOUBLE, "d2l requires double on stack");
writeByte(Opcode.D2L);
currentOffset++;
advanceFrame(currentFrame.pop2push1("J"));
}
public void dadd() {
assertTypeOnStack(StackEntryType.DOUBLE, "dadd requires double on stack");
assertTypeOnStack(2, StackEntryType.DOUBLE, "dadd requires double on stack");
writeByte(Opcode.DADD);
currentOffset++;
advanceFrame(currentFrame.pop2());
}
public void daload() {
assertTypeOnStack(StackEntryType.INT, "daload requires an int on top of the stack");
assertTypeOnStack(1, StackEntryType.OBJECT, "daload requires an array in position 2 on the stack");
writeByte(Opcode.DALOAD);
currentOffset++;
advanceFrame(currentFrame.pop2push1("D"));
}
public void dastore() {
assertTypeOnStack(StackEntryType.DOUBLE, "dastore requires an int on top of the stack");
assertTypeOnStack(2, StackEntryType.INT, "dastore requires an int in position 2 on the stack");
assertTypeOnStack(3, StackEntryType.OBJECT, "dastore requires an array reference in position 3 on the stack");
writeByte(Opcode.DASTORE);
currentOffset++;
advanceFrame(currentFrame.pop4());
}
public void dcmpg() {
assertTypeOnStack(StackEntryType.DOUBLE, "dcmpg requires double on stack");
assertTypeOnStack(2, StackEntryType.DOUBLE, "dcmpg requires double on stack");
writeByte(Opcode.DCMPG);
currentOffset++;
advanceFrame(currentFrame.pop4push1("I"));
}
public void dcmpl() {
assertTypeOnStack(StackEntryType.DOUBLE, "dcmpl requires double on stack");
assertTypeOnStack(2, StackEntryType.DOUBLE, "dcmpl requires double in position 3 on stack");
writeByte(Opcode.DCMPL);
currentOffset++;
advanceFrame(currentFrame.pop4push1("I"));
}
/**
* Adds the appropriate dconst instruction.
*
* note, if the value is not 0 or 1 then ldc is used instead
*/
public void dconst(double value) {
if (value == 0.0) {
writeByte(Opcode.DCONST_0);
} else if (value == 1.0) {
writeByte(Opcode.DCONST_1);
} else {
ldc2(value);
return;
}
currentOffset++;
advanceFrame(currentFrame.push("D"));
}
public void ddiv() {
assertTypeOnStack(StackEntryType.DOUBLE, "ddiv requires double on stack");
assertTypeOnStack(2, StackEntryType.DOUBLE, "ddiv requires double in position 3 on stack");
writeByte(Opcode.DDIV);
currentOffset++;
advanceFrame(currentFrame.pop2());
}
public void dload(int no) {
LocalVariableState locals = getLocalVars();
if (locals.size() <= no) {
throw new InvalidBytecodeException("Cannot load variable at " + no + ". Local Variables: " + locals.toString());
}
StackEntry entry = locals.get(no);
if (entry.getType() != StackEntryType.DOUBLE) {
throw new InvalidBytecodeException("Invalid local variable at location " + no + " Local Variables "
+ locals.toString());
}
if (no > 0xFF) {
// wide version
writeByte(Opcode.WIDE);
writeByte(Opcode.DLOAD);
writeShort(no);
currentOffset += 4;
} else if (no >= 0 && no < 4) {
writeByte(Opcode.DLOAD_0 + no);
currentOffset++;
} else {
writeByte(Opcode.DLOAD);
writeByte(no);
currentOffset += 2;
}
advanceFrame(currentFrame.push(entry));
}
public void dmul() {
assertTypeOnStack(StackEntryType.DOUBLE, "dmul requires double on stack");
assertTypeOnStack(2, StackEntryType.DOUBLE, "dmul requires double in position 3 on stack");
writeByte(Opcode.DMUL);
currentOffset++;
advanceFrame(currentFrame.pop2());
}
public void dneg() {
assertTypeOnStack(StackEntryType.DOUBLE, "dneg requires double on stack");
writeByte(Opcode.DNEG);
currentOffset++;
duplicateFrame();
}
public void drem() {
assertTypeOnStack(StackEntryType.DOUBLE, "drem requires double on stack");
assertTypeOnStack(2, StackEntryType.DOUBLE, "drem requires double in position 3 on stack");
writeByte(Opcode.DREM);
currentOffset++;
advanceFrame(currentFrame.pop2());
}
public void dstore(int no) {
assertTypeOnStack(StackEntryType.DOUBLE, "dastore requires double on stack");
if (no > 0xFF) {
// wide version
writeByte(Opcode.WIDE);
writeByte(Opcode.DSTORE);
writeShort(no);
currentOffset += 4;
} else if (no >= 0 && no < 4) {
writeByte(Opcode.DSTORE_0 + no);
currentOffset++;
} else {
writeByte(Opcode.DSTORE);
writeByte(no);
currentOffset += 2;
}
advanceFrame(currentFrame.store(no));
}
public void dsub() {
assertTypeOnStack(StackEntryType.DOUBLE, "dsub requires double on stack");
assertTypeOnStack(2, StackEntryType.DOUBLE, "dsub requires double in position 3 on stack");
writeByte(Opcode.DSUB);
currentOffset++;
advanceFrame(currentFrame.pop2());
}
public void dup() {
assertNotWideOnStack("dup acnnot be used if double or long is on top of the stack");
writeByte(Opcode.DUP);
currentOffset++;
advanceFrame(currentFrame.dup());
}
public void dupX1() {
assertNotWideOnStack("dup_x1 cannot be used if double or long is on top of the stack");
assertNotWideOnStack(1, "dup_x1 cannot be used if double or long is in position 2 on the stack");
writeByte(Opcode.DUP_X1);
currentOffset++;
advanceFrame(currentFrame.dupX1());
}
public void dupX2() {
assertNotWideOnStack("dup_x2 acnnot be used if double or long is on top of the stack");
writeByte(Opcode.DUP_X2);
currentOffset++;
advanceFrame(currentFrame.dupX2());
}
public void dup2() {
writeByte(Opcode.DUP2);
currentOffset++;
advanceFrame(currentFrame.dup2());
}
public void dup2X1() {
assertNotWideOnStack(2, "dup2_x1 cannot be used if double or long is in position 3 on the stack");
writeByte(Opcode.DUP2_X1);
currentOffset++;
advanceFrame(currentFrame.dup2X1());
}
public void dup2X2() {
assertNotWideOnStack(3, "dup2_x2 cannot be used if double or long is in position 4 on the stack");
writeByte(Opcode.DUP2_X2);
currentOffset++;
advanceFrame(currentFrame.dup2X2());
}
/**
* Begin writing an exception handler block. The handler is not actually persisted until exceptionHandler is called.
*/
public ExceptionHandler exceptionBlockStart(String exceptionType) {
return new ExceptionHandler(currentOffset, constPool.addClassEntry(exceptionType), exceptionType,
currentFrame);
}
/**
* Mark the end of an exception handler block. The last instruction that was written will be the last instruction covered by
* the handler
*/
public void exceptionBlockEnd(ExceptionHandler handler) {
handler.setEnd(currentOffset);
}
/**
* Marks the current code location as the exception handler and adds the handler to the exception handler table;
*/
public void exceptionHandlerStart(ExceptionHandler handler) {
if (handler.getEnd() == 0) {
throw new InvalidBytecodeException(
"handler end location must be initialised via exceptionHandlerEnd before calling exceptionHandlerAdd");
}
handler.setHandler(currentOffset);
exceptionTable.add(handler);
mergeStackFrames(new StackFrame(new StackState(handler.getExceptionType(), constPool), handler.getFrame()
.getLocalVariableState(), StackFrameType.FULL_FRAME));
}
public void f2d() {
assertTypeOnStack(StackEntryType.FLOAT, "f2s requires float on stack");
writeByte(Opcode.F2D);
currentOffset++;
advanceFrame(currentFrame.replace("D"));
}
public void f2i() {
assertTypeOnStack(StackEntryType.FLOAT, "f2i requires float on stack");
writeByte(Opcode.F2I);
currentOffset++;
advanceFrame(currentFrame.replace("I"));
}
public void f2l() {
assertTypeOnStack(StackEntryType.FLOAT, "f2l requires float on stack");
writeByte(Opcode.F2L);
currentOffset++;
advanceFrame(currentFrame.replace("J"));
}
public void fadd() {
assertTypeOnStack(StackEntryType.FLOAT, "fadd requires float on stack");
assertTypeOnStack(1, StackEntryType.FLOAT, "fadd requires float on stack");
writeByte(Opcode.FADD);
currentOffset++;
advanceFrame(currentFrame.pop());
}
public void faload() {
assertTypeOnStack(StackEntryType.INT, "faload requires an int on top of the stack");
assertTypeOnStack(1, StackEntryType.OBJECT, "faload requires an array in position 2 on the stack");
writeByte(Opcode.FALOAD);
currentOffset++;
advanceFrame(currentFrame.pop2push1("F"));
}
public void fastore() {
assertTypeOnStack(StackEntryType.FLOAT, "fastore requires an int on top of the stack");
assertTypeOnStack(1, StackEntryType.INT, "fastore requires an int in position 2 on the stack");
assertTypeOnStack(2, StackEntryType.OBJECT, "fastore requires an array reference in position 3 on the stack");
writeByte(Opcode.FASTORE);
currentOffset++;
advanceFrame(currentFrame.pop3());
}
public void fcmpg() {
assertTypeOnStack(StackEntryType.FLOAT, "fcmpg requires float on stack");
assertTypeOnStack(1, StackEntryType.FLOAT, "fcmpg requires float on stack");
writeByte(Opcode.FCMPG);
currentOffset++;
advanceFrame(currentFrame.pop2push1("I"));
}
public void fcmpl() {
assertTypeOnStack(StackEntryType.FLOAT, "fcmpl requires float on stack");
assertTypeOnStack(1, StackEntryType.FLOAT, "fcmpl requires float in position 2 on stack");
writeByte(Opcode.FCMPL);
currentOffset++;
advanceFrame(currentFrame.pop2push1("I"));
}
/**
* Adds the appropriate fconst instruction.
*
* note, if the value is not 0, 1, 2 then ldc is used instead
*/
public void fconst(float value) {
if (value == 0) {
writeByte(Opcode.FCONST_0);
} else if (value == 1) {
writeByte(Opcode.FCONST_1);
} else if (value == 2) {
writeByte(Opcode.FCONST_2);
} else {
ldc(value);
return;
}
currentOffset++;
advanceFrame(currentFrame.push("F"));
}
public void fdiv() {
assertTypeOnStack(StackEntryType.FLOAT, "fdiv requires float on stack");
assertTypeOnStack(1, StackEntryType.FLOAT, "fdiv requires float in position 2 on stack");
writeByte(Opcode.FDIV);
currentOffset++;
advanceFrame(currentFrame.pop());
}
public void fload(int no) {
LocalVariableState locals = getLocalVars();
if (locals.size() <= no) {
throw new InvalidBytecodeException("Cannot load variable at " + no + ". Local Variables: " + locals.toString());
}
StackEntry entry = locals.get(no);
if (entry.getType() != StackEntryType.FLOAT) {
throw new InvalidBytecodeException("Invalid local variable at location " + no + " Local Variables "
+ locals.toString());
}
if (no > 0xFF) {
// wide version
writeByte(Opcode.WIDE);
writeByte(Opcode.FLOAD);
writeShort(no);
currentOffset += 4;
} else if (no >= 0 && no < 4) {
writeByte(Opcode.FLOAD_0 + no);
currentOffset++;
} else {
writeByte(Opcode.FLOAD);
writeByte(no);
currentOffset += 2;
}
advanceFrame(currentFrame.push(entry));
}
public void fmul() {
assertTypeOnStack(StackEntryType.FLOAT, "fmul requires float on stack");
assertTypeOnStack(1, StackEntryType.FLOAT, "fmul requires float in position 2 on stack");
writeByte(Opcode.FMUL);
currentOffset++;
advanceFrame(currentFrame.pop());
}
public void fneg() {
assertTypeOnStack(StackEntryType.FLOAT, "fneg requires float on stack");
writeByte(Opcode.FNEG);
currentOffset++;
duplicateFrame();
}
public void frem() {
assertTypeOnStack(StackEntryType.FLOAT, "frem requires float on stack");
assertTypeOnStack(1, StackEntryType.FLOAT, "frem requires float in position 2 on stack");
writeByte(Opcode.FREM);
currentOffset++;
advanceFrame(currentFrame.pop());
}
public void fstore(int no) {
assertTypeOnStack(StackEntryType.FLOAT, "fstore requires float on stack");
if (no > 0xFF) {
// wide version
writeByte(Opcode.WIDE);
writeByte(Opcode.FSTORE);
writeShort(no);
currentOffset += 4;
} else if (no >= 0 && no < 4) {
writeByte(Opcode.FSTORE_0 + no);
currentOffset++;
} else {
writeByte(Opcode.FSTORE);
writeByte(no);
currentOffset += 2;
}
advanceFrame(currentFrame.store(no));
}
public void fsub() {
assertTypeOnStack(StackEntryType.FLOAT, "fsub requires float on stack");
assertTypeOnStack(1, StackEntryType.FLOAT, "fsub requires float in position 2 on stack");
writeByte(Opcode.FSUB);
currentOffset++;
advanceFrame(currentFrame.pop());
}
public void getfield(String className, String field, Class> fieldType) {
getfield(className, field, DescriptorUtils.makeDescriptor(fieldType));
}
public void getfield(String className, String field, String descriptor) {
assertTypeOnStack(StackEntryType.OBJECT, "getfield requires object on stack");
int index = constPool.addFieldEntry(className, field, descriptor);
writeByte(Opcode.GETFIELD);
writeShort(index);
currentOffset += 3;
advanceFrame(currentFrame.replace(descriptor));
}
public void getstatic(String className, String field, Class> fieldType) {
getstatic(className, field, DescriptorUtils.makeDescriptor(fieldType));
}
public void getstatic(String className, String field, String descriptor) {
int index = constPool.addFieldEntry(className, field, descriptor);
writeByte(Opcode.GETSTATIC);
writeShort(index);
currentOffset += 3;
advanceFrame(currentFrame.push(descriptor));
}
/**
* writes a goto instruction.
*
* TODO: implemented goto_w
*/
public void gotoInstruction(CodeLocation location) {
writeByte(Opcode.GOTO);
writeShort(location.getLocation() - currentOffset);
mergeStackFrames(location.getStackFrame());
currentOffset += 3;
currentFrame = null;
}
/**
* writes a goto instruction.
*
* TODO: implemented goto_w
*/
public BranchEnd gotoInstruction() {
writeByte(Opcode.GOTO);
writeShort(0);
currentOffset += 3;
BranchEnd ret = new BranchEnd(currentOffset - 2, currentFrame, currentOffset - 3);
currentFrame = null;
return ret;
}
public void i2b() {
assertTypeOnStack(StackEntryType.INT, "i2b requires int on stack");
writeByte(Opcode.I2B);
currentOffset++;
advanceFrame(currentFrame.replace("B"));
}
public void i2c() {
assertTypeOnStack(StackEntryType.INT, "i2c requires int on stack");
writeByte(Opcode.I2C);
currentOffset++;
advanceFrame(currentFrame.replace("C"));
}
public void i2d() {
assertTypeOnStack(StackEntryType.INT, "i2d requires int on stack");
writeByte(Opcode.I2D);
currentOffset++;
advanceFrame(currentFrame.replace("D"));
}
public void i2f() {
assertTypeOnStack(StackEntryType.INT, "i2f requires int on stack");
writeByte(Opcode.I2F);
currentOffset++;
advanceFrame(currentFrame.replace("F"));
}
public void i2l() {
assertTypeOnStack(StackEntryType.INT, "i2l requires int on stack");
writeByte(Opcode.I2L);
currentOffset++;
advanceFrame(currentFrame.replace("J"));
}
public void i2s() {
assertTypeOnStack(StackEntryType.INT, "i2s requires int on stack");
writeByte(Opcode.I2S);
currentOffset++;
advanceFrame(currentFrame.replace("S"));
}
public void iadd() {
assertTypeOnStack(StackEntryType.INT, "iadd requires int on stack");
assertTypeOnStack(1, StackEntryType.INT, "iadd requires int on stack");
writeByte(Opcode.IADD);
currentOffset++;
advanceFrame(currentFrame.pop());
}
public void iaload() {
assertTypeOnStack(StackEntryType.INT, "iaload requires an int on top of the stack");
assertTypeOnStack(1, StackEntryType.OBJECT, "iaload requires an array in position 2 on the stack");
writeByte(Opcode.IALOAD);
currentOffset++;
advanceFrame(currentFrame.pop2push1("I"));
}
public void iand() {
assertTypeOnStack(StackEntryType.INT, "iand requires int on stack");
assertTypeOnStack(1, StackEntryType.INT, "iand requires int on stack");
writeByte(Opcode.IAND);
currentOffset++;
advanceFrame(currentFrame.pop());
}
public void iastore() {
assertTypeOnStack(StackEntryType.INT, "iastore requires an int on top of the stack");
assertTypeOnStack(1, StackEntryType.INT, "iastore requires an int in position 2 on the stack");
assertTypeOnStack(2, StackEntryType.OBJECT, "iastore requires an array reference in position 3 on the stack");
writeByte(Opcode.IASTORE);
currentOffset++;
advanceFrame(currentFrame.pop3());
}
/**
* Adds the appropriate iconst instruction.
*
* note, if the value is not in the range -1 to 5 ldc is written instead
*
* @param value
*/
public void iconst(int value) {
if (value < -1 || value > 5) {
if (value < -128 || value > 127) {
ldc(value);
} else {
writeByte(Opcode.BIPUSH);
writeByte(value);
currentOffset += 2;
advanceFrame(currentFrame.push("I"));
}
return;
}
writeByte(Opcode.ICONST_0 + value);
currentOffset++;
advanceFrame(currentFrame.push("I"));
}
public void idiv() {
assertTypeOnStack(StackEntryType.INT, "idiv requires int on stack");
assertTypeOnStack(1, StackEntryType.INT, "idiv requires int in position 2 on stack");
writeByte(Opcode.IDIV);
currentOffset++;
advanceFrame(currentFrame.pop());
}
public void ifAcmpeq(CodeLocation location) {
assertTypeOnStack(StackEntryType.OBJECT, "ifAcmpeq requires reference type on stack");
assertTypeOnStack(1, StackEntryType.OBJECT, "ifAcmpeq requires reference type in position 2 on stack");
writeByte(Opcode.IF_ACMPEQ);
writeShort(location.getLocation() - currentOffset);
mergeStackFrames(location.getStackFrame());
currentOffset += 3;
advanceFrame(currentFrame.pop2());
}
public BranchEnd ifAcmpeq() {
assertTypeOnStack(StackEntryType.OBJECT, "ifAcmpeq requires reference type on stack");
assertTypeOnStack(1, StackEntryType.OBJECT, "ifAcmpeq requires reference type int position 2 on stack");
writeByte(Opcode.IF_ACMPEQ);
writeShort(0);
currentOffset += 3;
advanceFrame(currentFrame.pop2());
return new BranchEnd(currentOffset - 2, currentFrame, currentOffset - 3);
}
public void ifAcmpne(CodeLocation location) {
assertTypeOnStack(StackEntryType.OBJECT, "ifAcmpne requires reference type on stack");
assertTypeOnStack(1, StackEntryType.OBJECT, "ifAcmpne requires reference type in position 2 on stack");
writeByte(Opcode.IF_ACMPNE);
writeShort(location.getLocation() - currentOffset);
mergeStackFrames(location.getStackFrame());
currentOffset += 3;
advanceFrame(currentFrame.pop2());
}
public BranchEnd ifAcmpne() {
assertTypeOnStack(StackEntryType.OBJECT, "ifAcmpne requires reference type on stack");
assertTypeOnStack(1, StackEntryType.OBJECT, "ifAcmpne requires reference type int position 2 on stack");
writeByte(Opcode.IF_ACMPNE);
writeShort(0);
currentOffset += 3;
advanceFrame(currentFrame.pop2());
BranchEnd ret = new BranchEnd(currentOffset - 2, currentFrame, currentOffset - 3);
return ret;
}
public void ifIcmpeq(CodeLocation location) {
addIfIcmp(location, Opcode.IF_ICMPEQ, "ifIcmpeq");
}
public BranchEnd ifIcmpeq() {
return addIfIcmp(Opcode.IF_ICMPEQ, "ifIcmpeq");
}
public void ifIcmpne(CodeLocation location) {
addIfIcmp(location, Opcode.IF_ICMPNE, "ifIcmpne");
}
public BranchEnd ifIcmpne() {
return addIfIcmp(Opcode.IF_ICMPNE, "ifIcmpne");
}
public void ifIcmplt(CodeLocation location) {
addIfIcmp(location, Opcode.IF_ICMPLT, "ifIcmplt");
}
public BranchEnd ifIcmplt() {
return addIfIcmp(Opcode.IF_ICMPLT, "ifIcmplt");
}
public void ifIcmple(CodeLocation location) {
addIfIcmp(location, Opcode.IF_ICMPLE, "ifIcmple");
}
public BranchEnd ifIcmple() {
return addIfIcmp(Opcode.IF_ICMPLE, "ifIcmple");
}
public void ifIcmpgt(CodeLocation location) {
addIfIcmp(location, Opcode.IF_ICMPGT, "ifIcmpgt");
}
public BranchEnd ifIcmpgt() {
return addIfIcmp(Opcode.IF_ICMPGT, "ifIcmpgt");
}
public void ifIcmpge(CodeLocation location) {
addIfIcmp(location, Opcode.IF_ICMPGE, "ifIcmpge");
}
public BranchEnd ifIcmpge() {
return addIfIcmp(Opcode.IF_ICMPGE, "ifIcmpge");
}
public void ifEq(CodeLocation location) {
addIf(location, Opcode.IFEQ, "ifeq");
}
public BranchEnd ifeq() {
return addIf(Opcode.IFEQ, "ifeq");
}
public void ifne(CodeLocation location) {
addIf(location, Opcode.IFNE, "ifne");
}
public BranchEnd ifne() {
return addIf(Opcode.IFNE, "ifne");
}
public void iflt(CodeLocation location) {
addIf(location, Opcode.IFLT, "iflt");
}
public BranchEnd iflt() {
return addIf(Opcode.IFLT, "iflt");
}
public void ifle(CodeLocation location) {
addIf(location, Opcode.IFLE, "ifle");
}
public BranchEnd ifle() {
return addIf(Opcode.IFLE, "ifle");
}
public void ifgt(CodeLocation location) {
addIf(location, Opcode.IFGT, "ifgt");
}
public BranchEnd ifgt() {
return addIf(Opcode.IFGT, "ifgt");
}
public void ifge(CodeLocation location) {
addIf(location, Opcode.IFGE, "ifge");
}
public BranchEnd ifge() {
return addIf(Opcode.IFGE, "ifge");
}
public void ifnotnull(CodeLocation location) {
addNullComparison(location, Opcode.IFNONNULL, "ifnotnull");
}
public BranchEnd ifnotnull() {
return addNullComparison(Opcode.IFNONNULL, "ifnotnull");
}
/**
* Jump to the given location if the reference type on the top of the stack is null
*/
public void ifnull(CodeLocation location) {
addNullComparison(location, Opcode.IFNULL, "ifnull");
}
/**
* Jump to the given location if the reference type on the top of the stack is null.
*
* The {@link BranchEnd} returned from this method is used to set the end point to a future point in the bytecode stream
*/
public BranchEnd ifnull() {
return addNullComparison(Opcode.IFNULL, "ifnull");
}
public void iinc(int local, int amount) {
if (getLocalVars().get(local).getType() != StackEntryType.INT) {
throw new InvalidBytecodeException("iinc requires int at local variable position " + local + " "
+ getLocalVars().toString());
}
if (local > 0xFF || amount > 0xFF) {
writeByte(Opcode.WIDE);
writeByte(Opcode.IINC);
writeShort(local);
writeShort(amount);
currentOffset += 6;
} else {
writeByte(Opcode.IINC);
writeByte(local);
writeByte(amount);
currentOffset += 3;
}
duplicateFrame();
}
public void iload(int no) {
LocalVariableState locals = getLocalVars();
if (locals.size() <= no) {
throw new InvalidBytecodeException("Cannot load variable at " + no + ". Local Variables: " + locals.toString());
}
StackEntry entry = locals.get(no);
if (entry.getType() != StackEntryType.INT) {
throw new InvalidBytecodeException("Invalid local variable at location " + no + " Local Variables "
+ locals.toString());
}
if (no > 0xFF) {
// wide version
writeByte(Opcode.WIDE);
writeByte(Opcode.ILOAD);
writeShort(no);
currentOffset += 4;
} else if (no >= 0 && no < 4) {
writeByte(Opcode.ILOAD_0 + no);
currentOffset++;
} else {
writeByte(Opcode.ILOAD);
writeByte(no);
currentOffset += 2;
}
advanceFrame(currentFrame.push(entry));
}
public void imul() {
assertTypeOnStack(StackEntryType.INT, "imul requires int on stack");
assertTypeOnStack(1, StackEntryType.INT, "imul requires int in position 2 on stack");
writeByte(Opcode.IMUL);
currentOffset++;
advanceFrame(currentFrame.pop());
}
public void ineg() {
assertTypeOnStack(StackEntryType.INT, "ineg requires int on stack");
writeByte(Opcode.INEG);
currentOffset++;
duplicateFrame();
}
public void instanceofInstruction(String className) {
assertTypeOnStack(StackEntryType.OBJECT, "instanceof requires an object reference on the stack");
int classIndex = constPool.addClassEntry(className);
writeByte(Opcode.INSTANCEOF);
writeShort(classIndex);
currentOffset += 3;
advanceFrame(currentFrame.replace("I"));
}
public void invokespecial(String className, String methodName, String descriptor) {
String[] params = DescriptorUtils.parameterDescriptors(descriptor);
String returnType = DescriptorUtils.returnType(descriptor);
invokespecial(className, methodName, descriptor, returnType, params);
}
public void invokespecial(String className, String methodName, String returnType, String[] parameterTypes) {
String descriptor = DescriptorUtils.methodDescriptor(parameterTypes, returnType);
invokespecial(className, methodName, descriptor, returnType, parameterTypes);
}
public void invokespecial(Constructor> constructor) {
invokespecial(constructor.getDeclaringClass().getName(), "", DescriptorUtils
.makeDescriptor(constructor), "V", DescriptorUtils.parameterDescriptors(constructor.getParameterTypes()));
}
public void invokespecial(Method method) {
if (Modifier.isStatic(method.getModifiers())) {
throw new InvalidBytecodeException("Cannot use invokespacial to invoke a static method");
}
invokespecial(method.getDeclaringClass().getName(), method.getName(), DescriptorUtils.methodDescriptor(method),
DescriptorUtils.makeDescriptor(method.getReturnType()), DescriptorUtils.parameterDescriptors(method
.getParameterTypes()));
}
private void invokespecial(String className, String methodName, String descriptor, String returnType,
String[] parameterTypes) {
// TODO: validate stack
int method = constPool.addMethodEntry(className, methodName, descriptor);
writeByte(Opcode.INVOKESPECIAL);
writeShort(method);
currentOffset += 3;
int pop = 1 + parameterTypes.length;
for (String argument : parameterTypes) {
if (argument.equals("D") || argument.equals("J")) {
pop++;
}
}
if (methodName.equals("")) {
advanceFrame(currentFrame.constructorCall(pop - 1));
} else if (returnType.equals("V")) {
advanceFrame(currentFrame.pop(pop));
} else {
advanceFrame(currentFrame.pop(pop).push(returnType));
}
}
public void invokestatic(String className, String methodName, String descriptor) {
String[] params = DescriptorUtils.parameterDescriptors(descriptor);
String returnType = DescriptorUtils.returnType(descriptor);
invokestatic(className, methodName, descriptor, returnType, params);
}
public void invokestatic(String className, String methodName, String returnType, String[] parameterTypes) {
String descriptor = DescriptorUtils.methodDescriptor(parameterTypes, returnType);
invokestatic(className, methodName, descriptor, returnType, parameterTypes);
}
public void invokestatic(Method method) {
if (!Modifier.isStatic(method.getModifiers())) {
throw new InvalidBytecodeException("Cannot use invokestatic to invoke a non static method");
}
invokestatic(method.getDeclaringClass().getName(), method.getName(), DescriptorUtils.methodDescriptor(method),
DescriptorUtils.makeDescriptor(method.getReturnType()), DescriptorUtils.parameterDescriptors(method
.getParameterTypes()));
}
private void invokestatic(String className, String methodName, String descriptor, String returnType, String[] parameterTypes) {
// TODO: validate stack
int method = constPool.addMethodEntry(className, methodName, descriptor);
writeByte(Opcode.INVOKESTATIC);
writeShort(method);
currentOffset += 3;
int pop = parameterTypes.length;
for (String argument : parameterTypes) {
if (argument.equals("D") || argument.equals("J")) {
pop++;
}
}
if (returnType.equals("V")) {
advanceFrame(currentFrame.pop(pop));
} else {
advanceFrame(currentFrame.pop(pop).push(returnType));
}
}
public void invokevirtual(String className, String methodName, String descriptor) {
String[] params = DescriptorUtils.parameterDescriptors(descriptor);
String returnType = DescriptorUtils.returnType(descriptor);
invokevirtual(className, methodName, descriptor, returnType, params);
}
public void invokevirtual(String className, String methodName, String returnType, String[] parameterTypes) {
String descriptor = DescriptorUtils.methodDescriptor(parameterTypes, returnType);
invokevirtual(className, methodName, descriptor, returnType, parameterTypes);
}
public void invokevirtual(Method method) {
if (Modifier.isStatic(method.getModifiers())) {
throw new InvalidBytecodeException("Cannot use invokevirtual to invoke a static method");
} else if (Modifier.isPrivate(method.getModifiers())) {
throw new InvalidBytecodeException("Cannot use invokevirtual to invoke a private method");
} else if (method.getDeclaringClass().isInterface()) {
throw new InvalidBytecodeException("Cannot use invokevirtual to invoke an interface method");
}
invokevirtual(method.getDeclaringClass().getName(), method.getName(), DescriptorUtils.methodDescriptor(method),
DescriptorUtils.makeDescriptor(method.getReturnType()), DescriptorUtils.parameterDescriptors(method
.getParameterTypes()));
}
private void invokevirtual(String className, String methodName, String descriptor, String returnType,
String[] parameterTypes) {
// TODO: validate stack
int method = constPool.addMethodEntry(className, methodName, descriptor);
writeByte(Opcode.INVOKEVIRTUAL);
writeShort(method);
currentOffset += 3;
int pop = 1 + parameterTypes.length;
for (String argument : parameterTypes) {
if (argument.equals("D") || argument.equals("J")) {
pop++;
}
}
if (returnType.equals("V")) {
advanceFrame(currentFrame.pop(pop));
} else {
advanceFrame(currentFrame.pop(pop).push(returnType));
}
}
public void invokeinterface(String className, String methodName, String descriptor) {
String[] params = DescriptorUtils.parameterDescriptors(descriptor);
String returnType = DescriptorUtils.returnType(descriptor);
invokeinterface(className, methodName, descriptor, returnType, params);
}
public void invokeinterface(String className, String methodName, String returnType, String[] parameterTypes) {
String descriptor = DescriptorUtils.methodDescriptor(parameterTypes, returnType);
invokeinterface(className, methodName, descriptor, returnType, parameterTypes);
}
public void invokeinterface(Method method) {
if (Modifier.isStatic(method.getModifiers())) {
throw new InvalidBytecodeException("Cannot use invokeinterface to invoke a static method");
} else if (Modifier.isPrivate(method.getModifiers())) {
throw new InvalidBytecodeException("Cannot use invokeinterface to invoke a private method");
} else if (!method.getDeclaringClass().isInterface()) {
throw new InvalidBytecodeException("Cannot use invokeinterface to invoke a non interface method");
}
invokeinterface(method.getDeclaringClass().getName(), method.getName(), DescriptorUtils.methodDescriptor(method),
DescriptorUtils.makeDescriptor(method.getReturnType()), DescriptorUtils.parameterDescriptors(method
.getParameterTypes()));
}
private void invokeinterface(String className, String methodName, String descriptor, String returnType,
String[] parameterTypes) {
// TODO: validate stack
int pop = 1 + parameterTypes.length;
for (String argument : parameterTypes) {
if (argument.equals("D") || argument.equals("J")) {
pop++;
}
}
int method = constPool.addInterfaceMethodEntry(className, methodName, descriptor);
writeByte(Opcode.INVOKEINTERFACE);
writeShort(method);
writeByte(pop);
writeByte(0);
currentOffset += 5;
if (returnType.equals("V")) {
advanceFrame(currentFrame.pop(pop));
} else {
advanceFrame(currentFrame.pop(pop).push(returnType));
}
}
public void ior() {
assertTypeOnStack(StackEntryType.INT, "ior requires int on stack");
assertTypeOnStack(1, StackEntryType.INT, "ior requires int on stack");
writeByte(Opcode.IOR);
currentOffset++;
advanceFrame(currentFrame.pop());
}
public void irem() {
assertTypeOnStack(StackEntryType.INT, "irem requires int on stack");
assertTypeOnStack(1, StackEntryType.INT, "irem requires int on stack");
writeByte(Opcode.IREM);
currentOffset++;
advanceFrame(currentFrame.pop());
}
public void ishl() {
assertTypeOnStack(StackEntryType.INT, "ishl requires int on stack");
assertTypeOnStack(1, StackEntryType.INT, "ishl requires int on stack");
writeByte(Opcode.ISHL);
currentOffset++;
advanceFrame(currentFrame.pop());
}
public void ishr() {
assertTypeOnStack(StackEntryType.INT, "ishr requires int on stack");
assertTypeOnStack(1, StackEntryType.INT, "ishr requires int on stack");
writeByte(Opcode.ISHR);
currentOffset++;
advanceFrame(currentFrame.pop());
}
public void istore(int no) {
assertTypeOnStack(StackEntryType.INT, "istore requires int on stack");
if (no > 0xFF) {
// wide version
writeByte(Opcode.WIDE);
writeByte(Opcode.ISTORE);
writeShort(no);
currentOffset += 4;
} else if (no >= 0 && no < 4) {
writeByte(Opcode.ISTORE_0 + no);
currentOffset++;
} else {
writeByte(Opcode.ISTORE);
writeByte(no);
currentOffset += 2;
}
advanceFrame(currentFrame.store(no));
}
public void isub() {
assertTypeOnStack(StackEntryType.INT, "isub requires int on stack");
assertTypeOnStack(1, StackEntryType.INT, "isub requires int on stack");
writeByte(Opcode.ISUB);
currentOffset++;
advanceFrame(currentFrame.pop());
}
public void iushr() {
assertTypeOnStack(StackEntryType.INT, "iushr requires int on stack");
assertTypeOnStack(1, StackEntryType.INT, "iushr requires int on stack");
writeByte(Opcode.IUSHR);
currentOffset++;
advanceFrame(currentFrame.pop());
}
public void ixor() {
assertTypeOnStack(StackEntryType.INT, "ixor requires int on stack");
assertTypeOnStack(1, StackEntryType.INT, "ixor requires int on stack");
writeByte(Opcode.IXOR);
currentOffset++;
advanceFrame(currentFrame.pop());
}
public void l2d() {
assertTypeOnStack(StackEntryType.LONG, "l2d requires long on stack");
writeByte(Opcode.L2D);
currentOffset++;
advanceFrame(currentFrame.pop2push1("D"));
}
public void l2f() {
assertTypeOnStack(StackEntryType.LONG, "l2f requires long on stack");
writeByte(Opcode.L2F);
currentOffset++;
advanceFrame(currentFrame.pop2push1("F"));
}
public void l2i() {
assertTypeOnStack(StackEntryType.LONG, "l2i requires long on stack");
writeByte(Opcode.L2I);
currentOffset++;
advanceFrame(currentFrame.pop2push1("I"));
}
public void ladd() {
assertTypeOnStack(StackEntryType.LONG, "ladd requires long on stack");
assertTypeOnStack(2, StackEntryType.LONG, "ladd requires long on stack");
writeByte(Opcode.LADD);
currentOffset++;
advanceFrame(currentFrame.pop2());
}
public void laload() {
assertTypeOnStack(StackEntryType.INT, "laload requires an int on top of the stack");
assertTypeOnStack(1, StackEntryType.OBJECT, "laload requires an array in position 2 on the stack");
writeByte(Opcode.LALOAD);
currentOffset++;
advanceFrame(currentFrame.pop2push1("J"));
}
public void land() {
assertTypeOnStack(StackEntryType.LONG, "land requires long on stack");
assertTypeOnStack(2, StackEntryType.LONG, "land requires long on stack");
writeByte(Opcode.LAND);
currentOffset++;
advanceFrame(currentFrame.pop2());
}
public void lastore() {
assertTypeOnStack(StackEntryType.LONG, "lastore requires an long on top of the stack");
assertTypeOnStack(2, StackEntryType.INT, "lastore requires an int in position 2 on the stack");
assertTypeOnStack(3, StackEntryType.OBJECT, "lastore requires an array reference in position 3 on the stack");
writeByte(Opcode.LASTORE);
currentOffset++;
advanceFrame(currentFrame.pop4());
}
public void lcmp() {
assertTypeOnStack(StackEntryType.LONG, "lcmp requires long on stack");
assertTypeOnStack(2, StackEntryType.LONG, "lcmp requires long on stack");
writeByte(Opcode.LCMP);
currentOffset++;
advanceFrame(currentFrame.pop4push1("I"));
}
/**
* Adds the appropriate lconst instruction.
*
* note, if the value is not 0 or 1 then ldc is used instead
*/
public void lconst(long value) {
if (value == 0) {
writeByte(Opcode.LCONST_0);
} else if (value == 1) {
writeByte(Opcode.LCONST_1);
} else {
ldc2(value);
return;
}
currentOffset++;
advanceFrame(currentFrame.push("J"));
}
/**
* Adds an ldc instruction for an int.
*
* @param value The value to load
*/
public void ldc(int value) {
if (value > -2 && value < 6) {
iconst(value);
return;
}
int index = constPool.addIntegerEntry(value);
ldcInternal(index);
advanceFrame(currentFrame.push("I"));
}
/**
* Adds an ldc instruction for float
*/
public void ldc(float value) {
int index = constPool.addFloatEntry(value);
ldcInternal(index);
advanceFrame(currentFrame.push("F"));
}
/**
* Adds an ldc instruction for a String
*
* To load a class literal using ldc use the @{link #loadType(String)} method.
*/
public void ldc(String value) {
int index = constPool.addStringEntry(value);
ldcInternal(index);
advanceFrame(currentFrame.push("Ljava/lang/String;"));
}
/**
* Adds an ldc instruction for an int.
*/
private void ldcInternal(int index) {
if (index > 0xFF) {
writeByte(Opcode.LDC_W);
writeShort(index);
currentOffset += 3;
} else {
writeByte(Opcode.LDC);
writeByte(index);
currentOffset += 2;
}
}
/**
* Adds an ldc2_w instruction for double
*/
public void ldc2(double value) {
int index = constPool.addDoubleEntry(value);
writeByte(Opcode.LDC2_W);
writeShort(index);
currentOffset += 3;
advanceFrame(currentFrame.push("D"));
}
/**
* Adds an ldc2_w instruction for long
*/
public void ldc2(long value) {
int index = constPool.addLongEntry(value);
writeByte(Opcode.LDC2_W);
writeShort(index);
currentOffset += 3;
advanceFrame(currentFrame.push("J"));
}
public void ldiv() {
assertTypeOnStack(StackEntryType.LONG, "ldiv requires long on stack");
assertTypeOnStack(2, StackEntryType.LONG, "ldiv requires long in position 3 on stack");
writeByte(Opcode.LDIV);
currentOffset++;
advanceFrame(currentFrame.pop2());
}
public void lload(int no) {
LocalVariableState locals = getLocalVars();
if (locals.size() <= no) {
throw new InvalidBytecodeException("Cannot load variable at " + no + ". Local Variables: " + locals.toString());
}
StackEntry entry = locals.get(no);
if (entry.getType() != StackEntryType.LONG) {
throw new InvalidBytecodeException("Invalid local variable at location " + no + " Local Variables "
+ locals.toString());
}
if (no > 0xFF) {
// wide version
writeByte(Opcode.WIDE);
writeByte(Opcode.LLOAD);
writeShort(no);
currentOffset += 4;
} else if (no >= 0 && no < 4) {
writeByte(Opcode.LLOAD_0 + no);
currentOffset++;
} else {
writeByte(Opcode.LLOAD);
writeByte(no);
currentOffset += 2;
}
advanceFrame(currentFrame.push(entry));
}
public void lmul() {
assertTypeOnStack(StackEntryType.LONG, "lmul requires long on stack");
assertTypeOnStack(2, StackEntryType.LONG, "lmul requires long in position 3 on stack");
writeByte(Opcode.LMUL);
currentOffset++;
advanceFrame(currentFrame.pop2());
}
public void lneg() {
assertTypeOnStack(StackEntryType.LONG, "lneg requires long on stack");
writeByte(Opcode.LNEG);
currentOffset++;
duplicateFrame();
}
/**
* Generates the apprpriate load instruction for the given type
*
* @param type The type of variable
* @param no local variable number
*/
public void load(Class> type, int no) {
load(DescriptorUtils.makeDescriptor(type), no);
}
/**
* Generates the apprpriate load instruction for the given type
*
* @param descriptor The descriptor of the variable
* @param no local variable number
*/
public void load(String descriptor, int no) {
if (descriptor.length() != 1) {
aload(no);
} else {
char type = descriptor.charAt(0);
switch (type) {
case 'F':
fload(no);
break;
case 'J':
lload(no);
break;
case 'D':
dload(no);
break;
case 'I':
case 'S':
case 'B':
case 'C':
case 'Z':
iload(no);
break;
default:
throw new InvalidBytecodeException("Could not load primitive type: " + type);
}
}
}
public void loadClass(String className) {
int index = constPool.addClassEntry(className);
ldcInternal(index);
advanceFrame(currentFrame.push("Ljava/lang/Class;"));
}
/**
* Loads a java.lang.Class for the given descriptor into the stack.
*/
public void loadType(String descriptor) {
if (descriptor.length() != 1) {
if (descriptor.startsWith("L") && descriptor.endsWith(";")) {
descriptor = descriptor.substring(1, descriptor.length() - 1);
}
loadClass(descriptor);
} else {
char type = descriptor.charAt(0);
switch (type) {
case 'I':
getstatic(Integer.class.getName(), "TYPE", "Ljava/lang/Class;");
break;
case 'J':
getstatic(Long.class.getName(), "TYPE", "Ljava/lang/Class;");
break;
case 'S':
getstatic(Short.class.getName(), "TYPE", "Ljava/lang/Class;");
break;
case 'F':
getstatic(Float.class.getName(), "TYPE", "Ljava/lang/Class;");
break;
case 'D':
getstatic(Double.class.getName(), "TYPE", "Ljava/lang/Class;");
break;
case 'B':
getstatic(Byte.class.getName(), "TYPE", "Ljava/lang/Class;");
break;
case 'C':
getstatic(Character.class.getName(), "TYPE", "Ljava/lang/Class;");
break;
case 'Z':
getstatic(Boolean.class.getName(), "TYPE", "Ljava/lang/Class;");
break;
case 'V':
getstatic(Void.class.getName(), "TYPE", "Ljava/lang/Class;");
break;
default:
throw new InvalidBytecodeException("Unkown primitive type: " + type);
}
}
}
/**
* Adds a lookup switch statement
*
* @param lookupSwitchBuilder
* @return
*/
public void lookupswitch(final LookupSwitchBuilder lookupSwitchBuilder) {
assertTypeOnStack(StackEntryType.INT, "lookupswitch requires an int on the stack");
writeByte(Opcode.LOOKUPSWITCH);
final int startOffset = currentOffset;
currentOffset++;
while (currentOffset % 4 != 0) {
writeByte(0);
currentOffset++;
}
StackFrame frame = currentFrame.pop();
final List values = new ArrayList(lookupSwitchBuilder.getValues());
if (lookupSwitchBuilder.getDefaultLocation() != null) {
writeInt(lookupSwitchBuilder.getDefaultLocation().getLocation() - currentOffset);
} else {
writeInt(0);
final BranchEnd ret = new BranchEnd(currentOffset, frame, true, startOffset);
lookupSwitchBuilder.getDefaultBranchEnd().set(ret);
}
writeInt(values.size());
currentOffset += 8;
Collections.sort(values);
for (final LookupSwitchBuilder.ValuePair value : values) {
writeInt(value.getValue());
currentOffset += 4;
if (value.getLocation() != null) {
writeInt(value.getLocation().getLocation());
currentOffset += 4;
} else {
writeInt(0);
final BranchEnd ret = new BranchEnd(currentOffset, frame, true, startOffset);
value.getBranchEnd().set(ret);
currentOffset += 4;
}
}
currentFrame = null;
}
public void lor() {
assertTypeOnStack(StackEntryType.LONG, "lor requires long on stack");
assertTypeOnStack(2, StackEntryType.LONG, "lor requires long in position 3 on stack");
writeByte(Opcode.LOR);
currentOffset++;
advanceFrame(currentFrame.pop2());
}
public void lrem() {
assertTypeOnStack(StackEntryType.LONG, "lrem requires long on stack");
assertTypeOnStack(2, StackEntryType.LONG, "lrem requires long in position 3 on stack");
writeByte(Opcode.LREM);
currentOffset++;
advanceFrame(currentFrame.pop2());
}
public void lshl() {
assertTypeOnStack(StackEntryType.INT, "lshl requires int on stack");
assertTypeOnStack(1, StackEntryType.LONG, "lshl requires long in position 2 on stack");
writeByte(Opcode.LSHL);
currentOffset++;
advanceFrame(currentFrame.pop());
}
public void lshr() {
assertTypeOnStack(StackEntryType.INT, "lshr requires int on stack");
assertTypeOnStack(1, StackEntryType.LONG, "lshr requires long in position 2 on stack");
writeByte(Opcode.LSHR);
currentOffset++;
advanceFrame(currentFrame.pop());
}
public void lstore(int no) {
assertTypeOnStack(StackEntryType.LONG, "lstore requires long on stack");
if (no > 0xFF) {
// wide version
writeByte(Opcode.WIDE);
writeByte(Opcode.LSTORE);
writeShort(no);
currentOffset += 4;
} else if (no >= 0 && no < 4) {
writeByte(Opcode.LSTORE_0 + no);
currentOffset++;
} else {
writeByte(Opcode.LSTORE);
writeByte(no);
currentOffset += 2;
}
advanceFrame(currentFrame.store(no));
}
public void lsub() {
assertTypeOnStack(StackEntryType.LONG, "lsub requires long on stack");
assertTypeOnStack(2, StackEntryType.LONG, "lsub requires long in position 3 on stack");
writeByte(Opcode.LSUB);
currentOffset++;
advanceFrame(currentFrame.pop2());
}
public void lushr() {
assertTypeOnStack(StackEntryType.INT, "lushr requires int on stack");
assertTypeOnStack(1, StackEntryType.LONG, "lushr requires long in position 2 on stack");
writeByte(Opcode.LUSHR);
currentOffset++;
advanceFrame(currentFrame.pop());
}
public void lxor() {
assertTypeOnStack(StackEntryType.LONG, "lxor requires long on stack");
assertTypeOnStack(2, StackEntryType.LONG, "lxor requires long in position 3 on stack");
writeByte(Opcode.LXOR);
currentOffset++;
advanceFrame(currentFrame.pop2());
}
/**
* Gets the location object for the current location in the bytecode. Jumps to this location will begin executing the next
* instruction that is written to the bytecode stream
*/
public CodeLocation mark() {
return new CodeLocation(currentOffset, currentFrame);
}
public void monitorenter() {
assertTypeOnStack(StackEntryType.OBJECT, "monitorenter requires object reference on stack");
writeByte(Opcode.MONITORENTER);
currentOffset++;
advanceFrame(currentFrame.pop());
}
public void monitorexit() {
assertTypeOnStack(StackEntryType.OBJECT, "monitorexit requires object reference on stack");
writeByte(Opcode.MONITOREXIT);
currentOffset++;
advanceFrame(currentFrame.pop());
}
public void multianewarray(String arrayType, int dimensions) {
StringBuilder newType = new StringBuilder();
for (int i = 0; i < dimensions; ++i) {
assertTypeOnStack(i, StackEntryType.INT, "multianewarray requires int on stack in position " + i);
newType.append('[');
}
if (!arrayType.startsWith("[")) {
newType.append('L');
newType.append(arrayType.replace('.', '/'));
newType.append(";");
} else {
newType.append(arrayType);
}
int classIndex = constPool.addClassEntry(newType.toString());
writeByte(Opcode.MULTIANEWARRAY);
writeShort(classIndex);
writeByte(dimensions);
currentOffset += 4;
advanceFrame(currentFrame.pop(dimensions).push(newType.toString()));
}
public void newInstruction(String classname) {
int classIndex = constPool.addClassEntry(classname);
writeByte(Opcode.NEW);
writeShort(classIndex);
StackEntry entry = new StackEntry(StackEntryType.UNITITIALIZED_OBJECT, DescriptorUtils.makeDescriptor(classname), currentOffset);
currentOffset += 3;
advanceFrame(currentFrame.push(entry));
}
public void newInstruction(Class> clazz) {
newInstruction(clazz.getName());
}
/**
* arrayType must be a {@link Class} object that represents a primitive type
*/
public void newarray(Class> arrayType) {
assertTypeOnStack(StackEntryType.INT, "newarray requires int on stack");
int type;
String desc;
if (arrayType == boolean.class) {
type = Opcode.T_BOOLEAN;
desc = "[Z";
} else if (arrayType == char.class) {
type = Opcode.T_CHAR;
desc = "[C";
} else if (arrayType == float.class) {
type = Opcode.T_FLOAT;
desc = "[F";
} else if (arrayType == double.class) {
type = Opcode.T_DOUBLE;
desc = "[D";
} else if (arrayType == byte.class) {
type = Opcode.T_BYTE;
desc = "[B";
} else if (arrayType == short.class) {
type = Opcode.T_SHORT;
desc = "[S";
} else if (arrayType == int.class) {
type = Opcode.T_INT;
desc = "[I";
} else if (arrayType == long.class) {
type = Opcode.T_LONG;
desc = "[J";
} else {
throw new InvalidBytecodeException("Class " + arrayType + " is not a primitive type");
}
writeByte(Opcode.NEWARRAY);
writeByte(type);
currentOffset += 2;
advanceFrame(currentFrame.replace(desc));
}
public void nop() {
writeByte(Opcode.NOP);
currentOffset++;
duplicateFrame();
}
public void pop() {
writeByte(Opcode.POP);
currentOffset++;
advanceFrame(currentFrame.pop());
}
public void pop2() {
writeByte(Opcode.POP2);
currentOffset++;
advanceFrame(currentFrame.pop2());
}
public void putfield(String className, String field, Class> fieldType) {
putfield(className, field, DescriptorUtils.makeDescriptor(fieldType));
}
public void putfield(String className, String field, String descriptor) {
if (!getStack().isOnTop(descriptor)) {
throw new InvalidBytecodeException("Attempting to put wrong type into field. Field:" + className + "."
+ field + " (" + descriptor + "). Stack State: " + getStack().toString());
}
if (getStack().top_1().getType() != StackEntryType.UNINITIALIZED_THIS) {
assertTypeOnStack(1, StackEntryType.OBJECT, "expected object in position 2 on stack");
}
int index = constPool.addFieldEntry(className, field, descriptor);
writeByte(Opcode.PUTFIELD);
writeShort(index);
currentOffset += 3;
advanceFrame(currentFrame.pop2());
}
public void putstatic(String className, String field, Class> fieldType) {
putstatic(className, field, DescriptorUtils.makeDescriptor(fieldType));
}
public void putstatic(String className, String field, String descriptor) {
if (!getStack().isOnTop(descriptor)) {
throw new InvalidBytecodeException("Attempting to put wrong type into static field. Field:" + className + "."
+ field + " (" + descriptor + "). Stack State: " + getStack().toString());
}
int index = constPool.addFieldEntry(className, field, descriptor);
writeByte(Opcode.PUTSTATIC);
writeShort(index);
currentOffset += 3;
advanceFrame(currentFrame.pop());
}
/**
* Adds the appropriate return instruction for the methods return type.
*/
public void returnInstruction() {
String returnType = method.getReturnType();
if (!returnType.equals("V")) {
if (!getStack().isOnTop(returnType)) {
throw new InvalidBytecodeException(returnType + " is not on top of stack. " + getStack().toString());
}
}
// all these instructions are one byte
currentOffset++;
// return instructions do not create stack map entries
if (returnType.length() > 1) {
writeByte(Opcode.ARETURN);
} else {
char ret = method.getReturnType().charAt(0);
switch (ret) {
case 'V':
writeByte(Opcode.RETURN);
break;
case 'I':
case 'Z':
case 'S':
case 'B':
case 'C':
writeByte(Opcode.IRETURN);
break;
case 'F':
writeByte(Opcode.FRETURN);
break;
case 'D':
writeByte(Opcode.DRETURN);
break;
case 'J':
writeByte(Opcode.LRETURN);
}
}
currentFrame = null;
}
public void saload() {
assertTypeOnStack(StackEntryType.INT, "saload requires an int on top of the stack");
assertTypeOnStack(1, StackEntryType.OBJECT, "saload requires an array in position 2 on the stack");
writeByte(Opcode.SALOAD);
currentOffset++;
advanceFrame(currentFrame.pop2push1("I"));
}
public void sastore() {
assertTypeOnStack(StackEntryType.INT, "sastore requires an int on top of the stack");
assertTypeOnStack(1, StackEntryType.INT, "sastore requires an int in position 2 on the stack");
assertTypeOnStack(2, StackEntryType.OBJECT, "sastore requires an array reference in position 3 on the stack");
writeByte(Opcode.SASTORE);
currentOffset++;
advanceFrame(currentFrame.pop3());
}
public void sipush(short value) {
writeByte(Opcode.SIPUSH);
writeShort(value);
currentOffset += 3;
advanceFrame(currentFrame.push("S"));
}
public void swap() {
assertNotWideOnStack("swap cannot be used when wide type is on top of stack");
assertNotWideOnStack(1, "swap cannot be used when wide type is on position 1 of the stack");
writeByte(Opcode.SWAP);
currentOffset++;
advanceFrame(currentFrame.swap());
}
public void tableswitch(final TableSwitchBuilder builder) {
assertTypeOnStack(StackEntryType.INT, "lookupswitch requires an int on the stack");
writeByte(Opcode.TABLESWITCH);
final int startOffset = currentOffset;
currentOffset++;
while (currentOffset % 4 != 0) {
writeByte(0);
currentOffset++;
}
if (builder.getHigh() - builder.getLow() + 1 != builder.getValues().size()) {
throw new RuntimeException("high - low + 1 != the number of values in the table");
}
StackFrame frame = currentFrame.pop();
if (builder.getDefaultLocation() != null) {
writeInt(builder.getDefaultLocation().getLocation() - currentOffset);
} else {
writeInt(0);
final BranchEnd ret = new BranchEnd(currentOffset, frame, true, startOffset);
builder.getDefaultBranchEnd().set(ret);
}
writeInt(builder.getLow());
writeInt(builder.getHigh());
currentOffset += 12;
for (final TableSwitchBuilder.ValuePair value : builder.getValues()) {
if (value.getLocation() != null) {
writeInt(value.getLocation().getLocation());
currentOffset += 4;
} else {
writeInt(0);
final BranchEnd ret = new BranchEnd(currentOffset, frame, true, startOffset);
value.getBranchEnd().set(ret);
currentOffset += 4;
}
}
currentFrame = null;
}
/**
* loads all parameters onto the stack.
*
* If this method is non-static then the parameter at location 0 (i.e. this object) is not pushed.
*/
public void loadMethodParameters() {
int index = method.isStatic() ? 0 : 1;
for (String type : method.getParameters()) {
if (type.length() > 1) {
// object or array
aload(index);
} else if (type.equals("D")) {
dload(index);
index++;
} else if (type.equals("J")) {
lload(index);
index++;
} else if (type.equals("F")) {
fload(index);
} else {
iload(index);
}
index++;
}
}
private void writeByte(int n) {
try {
data.writeByte(n);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private void writeShort(int n) {
try {
if (n > Short.MAX_VALUE * 2) {
throw new RuntimeException(n + " is to big to be written as a 16 bit value");
}
data.writeShort(n);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private void writeInt(int n) {
try {
data.writeInt(n);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* overwrites a 16 bit value in the already written bytecode data
*/
private void overwriteShort(byte[] bytecode, int offset, int value) {
bytecode[offset] = (byte) (value >> 8);
bytecode[offset + 1] = (byte) (value);
}
/**
* overwrites a 32 bit value in the already written bytecode data
*/
private void overwriteInt(byte[] bytecode, int offset, int value) {
bytecode[offset] = (byte) (value >> 24);
bytecode[offset + 1] = (byte) (value >> 16);
bytecode[offset + 2] = (byte) (value >> 8);
bytecode[offset + 3] = (byte) (value);
}
public LinkedHashMap getStackFrames() {
return new LinkedHashMap(stackFrames);
}
public void setupFrame(String... types) {
final LocalVariableState localVariableState = new LocalVariableState(constPool, types);
final StackFrame f = new StackFrame(new StackState(constPool), localVariableState, StackFrameType.FULL_FRAME);
mergeStackFrames(f);
}
public ConstPool getConstPool() {
return constPool;
}
/**
* Adds a duplicate of the current frame to the current position.
*
* currently this just puts the same frame into a different position
*/
private void duplicateFrame() {
stackFrames.put(currentOffset, currentFrame);
updateMaxValues();
}
private void advanceFrame(StackFrame frame) {
stackFrames.put(currentOffset, frame);
currentFrame = frame;
updateMaxValues();
}
private void updateMaxValues() {
if (getStack().getContents().size() > maxStackDepth) {
maxStackDepth = getStack().getContents().size();
}
if (getLocalVars().getContents().size() > maxLocals) {
maxLocals = getLocalVars().getContents().size();
}
}
private LocalVariableState getLocalVars() {
if (currentFrame == null) {
throw new RuntimeException("No local variable information available, call setupFrame first");
}
return currentFrame.getLocalVariableState();
}
private StackState getStack() {
return currentFrame.getStackState();
}
public void assertTypeOnStack(int position, StackEntryType type, String message) {
if (getStack().size() <= position) {
throw new InvalidBytecodeException(message + " Stack State: " + getStack().toString());
}
int index = getStack().getContents().size() - 1 - position;
if (type == StackEntryType.DOUBLE || type == StackEntryType.LONG) {
index -= 1;
}
StackEntryType stype = getStack().getContents().get(index).getType();
if (stype != type) {
if (!(type == StackEntryType.OBJECT && stype == StackEntryType.NULL)) {
throw new InvalidBytecodeException(message + " Stack State: " + getStack().toString());
}
}
}
public void assertTypeOnStack(StackEntryType type, String message) {
assertTypeOnStack(0, type, message);
}
public void assertNotWideOnStack(int position, String message) {
if (getStack().size() <= position) {
throw new InvalidBytecodeException(message + " Stack State: " + getStack().toString());
}
int index = getStack().getContents().size() - 1 - position;
StackEntryType stype = getStack().getContents().get(index).getType();
if (stype == StackEntryType.TOP) {
throw new InvalidBytecodeException(message + " Stack State: " + getStack().toString());
}
}
public void assertNotWideOnStack(String message) {
assertNotWideOnStack(0, message);
}
/**
* Merge the stack frames.
*
* If the frames are incompatible then an {@link InvalidBytecodeException} is thrown. If the frames cannot be properly
* merged then the stack map is marked as invalid
*/
private void mergeStackFrames(StackFrame stackFrame) {
if (currentFrame == null) {
currentFrame = stackFrame;
stackFrames.put(currentOffset, currentFrame);
return;
}
StackState currentStackState = getStack();
StackState mergeStackState = stackFrame.getStackState();
if (currentStackState.size() != mergeStackState.size()) {
throw new InvalidBytecodeException("Cannot merge stack frames, different stack sizes " + currentFrame + " " + stackFrame);
}
for (int i = 0; i < mergeStackState.size(); ++i) {
StackEntry currentEntry = currentStackState.getContents().get(i);
StackEntry mergeEntry = mergeStackState.getContents().get(i);
if (mergeEntry.getType() == currentEntry.getType()) {
if (mergeEntry.getType() == StackEntryType.OBJECT) {
if (!mergeEntry.getDescriptor().equals(currentEntry.getDescriptor())) {
if (method.getClassFile().getClassLoader() != null) {
String superType = findSuperType(mergeEntry.getDescriptor(), currentEntry.getDescriptor());
if (superType == null) {
throw new InvalidBytecodeException("Could not find common supertype for " + mergeEntry.getDescriptor() + " and " + currentEntry.getDescriptor() + " " + currentFrame + " " + stackFrame);
} else if (!superType.equals(currentEntry.getDescriptor())) {
stackFrames.put(currentOffset, currentFrame = currentFrame.mergeStack(i, new StackEntry(StackEntryType.OBJECT, DescriptorUtils.makeDescriptor(superType), constPool)));
}
}
}
}
} else if (!((mergeEntry.getType() == StackEntryType.NULL && currentEntry.getType() == StackEntryType.OBJECT) || (mergeEntry
.getType() == StackEntryType.OBJECT && currentEntry.getType() == StackEntryType.NULL))) {
throw new InvalidBytecodeException("Cannot merge stack frame " + currentStackState + " with frame "
+ mergeStackState + " stack entry " + i + " is invalid " + currentFrame + " " + stackFrame);
}
}
LocalVariableState currentLocalVariableState = getLocalVars();
LocalVariableState mergeLocalVariableState = stackFrame.getLocalVariableState();
if (currentLocalVariableState.size() < mergeLocalVariableState.size()) {
throw new InvalidBytecodeException(
"Cannot merge stack frames, merge location has less locals than current location " + currentFrame + " " + stackFrame);
}
for (int i = 0; i < mergeLocalVariableState.size(); ++i) {
StackEntry currentEntry = currentLocalVariableState.getContents().get(i);
StackEntry mergeEntry = mergeLocalVariableState.getContents().get(i);
if (mergeEntry.getType() == currentEntry.getType()) {
if (mergeEntry.getType() == StackEntryType.OBJECT) {
if (!mergeEntry.getDescriptor().equals(currentEntry.getDescriptor())) {
if (!mergeEntry.getDescriptor().equals(currentEntry.getDescriptor())) {
if (method.getClassFile().getClassLoader() != null) {
String superType = findSuperType(mergeEntry.getDescriptor(), currentEntry.getDescriptor());
if (superType == null) {
throw new InvalidBytecodeException("Could not find common supertype for " + mergeEntry.getDescriptor() + " and " + currentEntry.getDescriptor() + " " + currentFrame + " " + stackFrame);
} else if (!superType.equals(currentEntry.getDescriptor())) {
stackFrames.put(currentOffset, currentFrame = currentFrame.mergeLocals(i, new StackEntry(StackEntryType.OBJECT, DescriptorUtils.makeDescriptor(superType), constPool)));
}
}
}
}
}
} else if (!((mergeEntry.getType() == StackEntryType.NULL && currentEntry.getType() == StackEntryType.OBJECT) || (mergeEntry
.getType() == StackEntryType.OBJECT && currentEntry.getType() == StackEntryType.NULL))) {
throw new InvalidBytecodeException("Cannot merge stack frame " + currentLocalVariableState + " with frame "
+ currentLocalVariableState + " local variable entry " + i + " is invalid " + currentFrame + " " + stackFrame);
}
}
}
private String findSuperType(String ds1, String ds2) {
String d1 = ds1;
if (ds1.endsWith(";")) {
d1 = ds1.substring(1, ds1.length() - 1).replace("/", ".");
}
String d2 = ds2;
if (ds2.endsWith(";")) {
d2 = ds2.substring(1, ds2.length() - 1).replace("/", ".");
}
if (stackFrameTypeResolver != null) {
return stackFrameTypeResolver.resolve(method.getClassFile().getClassLoader(), d1, d2);
}
//just load the classes for now
ClassLoader cl = method.getClassFile().getClassLoader();
try {
Class> c1 = cl.loadClass(d1);
Class> c2 = cl.loadClass(d2);
if (c1.isAssignableFrom(c2)) {
return c1.getName();
} else if (c2.isAssignableFrom(c1)) {
return c2.getName();
} else {
Class> p = c1;
while (p != Object.class) {
if (p.isAssignableFrom(c2)) {
return p.getName();
}
p = p.getSuperclass();
}
p = c2;
while (p != Object.class) {
if (p.isAssignableFrom(c1)) {
return p.getName();
}
p = p.getSuperclass();
}
Set> s1 = getAllSuperclassesAndInterface(c1, new HashSet>());
Set> s2 = getAllSuperclassesAndInterface(c2, new HashSet>());
leavesOnly(s1);
leavesOnly(s2);
Set> interfaces = new HashSet>();
interfaces.addAll(s1);
interfaces.addAll(s2);
interfaces.remove(c1);
interfaces.remove(c2);
if (interfaces.size() == 1) {
return interfaces.iterator().next().getName();
} else if (interfaces.size() > 1) {
throw new RuntimeException("Could not resolve common superclass for " + d1 + " and " + d2);
} else {
return Object.class.getName();
}
}
} catch (ClassNotFoundException e) {
return null;
}
}
private void leavesOnly(Set> s2) {
List> keys = new ArrayList>(s2);
for (Class> key : keys) {
for (Class> content : s2) {
if (key == content) {
continue;
}
if (key.isAssignableFrom(content)) {
s2.remove(key);
break;
}
}
}
}
private Set> getAllSuperclassesAndInterface(Class> c, Set> set) {
set.addAll(Arrays.asList(c.getInterfaces()));
set.add(c);
if (c.getSuperclass() != null) {
getAllSuperclassesAndInterface(c.getSuperclass(), set);
}
return set;
}
private void addIfIcmp(CodeLocation location, int opcode, String name) {
assertTypeOnStack(StackEntryType.INT, name + " requires int on stack");
assertTypeOnStack(1, StackEntryType.INT, name + " requires int in position 2 on stack");
writeByte(opcode);
writeShort(location.getLocation() - currentOffset);
currentOffset += 3;
advanceFrame(currentFrame.pop2());
mergeStackFrames(location.getStackFrame());
}
private BranchEnd addIfIcmp(int opcode, String name) {
assertTypeOnStack(StackEntryType.INT, name + " requires int on stack");
assertTypeOnStack(1, StackEntryType.INT, name + " requires int int position 2 on stack");
writeByte(opcode);
writeShort(0);
currentOffset += 3;
advanceFrame(currentFrame.pop2());
BranchEnd ret = new BranchEnd(currentOffset - 2, currentFrame, currentOffset - 3);
return ret;
}
private void addIf(CodeLocation location, int opcode, String name) {
assertTypeOnStack(StackEntryType.INT, name + " requires int on stack");
writeByte(opcode);
writeShort(location.getLocation() - currentOffset);
currentOffset += 3;
advanceFrame(currentFrame.pop());
mergeStackFrames(location.getStackFrame());
}
private BranchEnd addIf(int opcode, String name) {
assertTypeOnStack(StackEntryType.INT, name + " requires int on stack");
writeByte(opcode);
writeShort(0);
currentOffset += 3;
advanceFrame(currentFrame.pop());
return new BranchEnd(currentOffset - 2, currentFrame, currentOffset - 3);
}
private void addNullComparison(CodeLocation location, int opcode, String name) {
assertTypeOnStack(StackEntryType.OBJECT, name + " requires reference type on stack");
writeByte(opcode);
writeShort(location.getLocation() - currentOffset);
currentOffset += 3;
advanceFrame(currentFrame.pop());
mergeStackFrames(location.getStackFrame());
}
private BranchEnd addNullComparison(int opcode, String name) {
assertTypeOnStack(StackEntryType.OBJECT, name + " requires reference type on stack");
writeByte(opcode);
writeShort(0);
currentOffset += 3;
advanceFrame(currentFrame.pop());
return new BranchEnd(currentOffset - 2, currentFrame, currentOffset - 3);
}
/**
* Interface that can be used to override the type merging process when merging stack frames
*/
public interface StackFrameTypeResolver {
String resolve(ClassLoader classLoader, String type1, String type2);
}
}
jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/code/CodeLocation.java 0000664 0000000 0000000 00000002450 14046606623 0032764 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.code;
/**
* Represents a location in the bytecode.
*
* @author Stuart Douglas
*
*/
public class CodeLocation {
/**
* The absolution location in the bytecode stream. This will always point to a valid jump location
*/
private final int location;
/**
* The stack frame at the given bytecode location
*/
private final StackFrame stackFrame;
CodeLocation(int location, StackFrame stackFrame) {
this.location = location;
this.stackFrame = stackFrame;
}
int getLocation() {
return location;
}
StackFrame getStackFrame() {
return stackFrame;
}
}
jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/code/ExceptionHandler.java0000664 0000000 0000000 00000003217 14046606623 0033657 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.code;
/**
*
* @author Stuart Douglas
*
*/
public class ExceptionHandler {
private final int start;
private final int exceptionIndex;
private final String exceptionType;
private final StackFrame frame;
private int end;
private int handler;
ExceptionHandler(int start, int exceptionIndex, String exceptionType, StackFrame frame) {
this.start = start;
this.exceptionIndex = exceptionIndex;
this.exceptionType = exceptionType;
this.frame = frame;
}
int getEnd() {
return end;
}
void setEnd(int end) {
this.end = end;
}
int getHandler() {
return handler;
}
void setHandler(int handler) {
this.handler = handler;
}
int getStart() {
return start;
}
int getExceptionIndex() {
return exceptionIndex;
}
StackFrame getFrame() {
return frame;
}
public String getExceptionType() {
return exceptionType;
}
}
LocalVariableState.java 0000664 0000000 0000000 00000014400 14046606623 0034041 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/code /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.code;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.jboss.classfilewriter.ClassMethod;
import org.jboss.classfilewriter.InvalidBytecodeException;
import org.jboss.classfilewriter.constpool.ConstPool;
/**
* In immutable local variable state
*
* @author Stuart Douglas
*
*/
public class LocalVariableState {
/**
* The contents, null is used to represent the additional spot taken up by a wide variable.
*
* This list may be shared between frames, so it must never be modified
*
* The very first element represents the first local variable (this for non static methods)
*/
private final List contents;
private final ConstPool constPool;
/**
* construct the initial local variable state for a method
*/
public LocalVariableState(ClassMethod method) {
this.constPool = method.getClassFile().getConstPool();
contents = new ArrayList();
if (!method.isStatic()) {
if (method.isConstructor()) {
contents.add(new StackEntry(StackEntryType.UNINITIALIZED_THIS, method.getClassFile().getDescriptor()));
} else {
contents.add(StackEntry.of(method.getClassFile().getDescriptor(), method.getClassFile().getConstPool()));
}
}
for (String param : method.getParameters()) {
StackEntry entry = StackEntry.of(param, method.getClassFile().getConstPool());
contents.add(entry);
if (entry.isWide()) {
contents.add(new StackEntry(StackEntryType.TOP, param));
}
}
}
public LocalVariableState(final ConstPool pool, final String ... entries) {
this.constPool = pool;
contents = new ArrayList();
for(String c : entries) {
final StackEntry entry = StackEntry.of(c, constPool);
contents.add(entry);
}
}
private LocalVariableState(final List contents, ConstPool constPool) {
this.contents = contents;
this.constPool = constPool;
}
public List getContents() {
return Collections.unmodifiableList(contents);
}
public StackEntry get(int index) {
return contents.get(index);
}
public LocalVariableState storeWide(int index, StackEntry entry) {
ArrayList newContents = new ArrayList(contents.size());
for (int i = 0; i <= index || i < contents.size(); ++i) {
if (index == i) {
newContents.add(entry);
newContents.add(new StackEntry(StackEntryType.TOP, entry.getDescriptor()));
++i;
} else if (i >= contents.size()) {
// write a null in unitialised slots
// not sure if this is correct
newContents.add(new StackEntry(StackEntryType.NULL, null));
} else {
newContents.add(contents.get(i));
}
}
return new LocalVariableState(newContents, constPool);
}
public LocalVariableState store(int index, StackEntry entry) {
ArrayList newContents = new ArrayList(contents.size());
for (int i = 0; i <= index || i < contents.size(); ++i) {
if (index == i) {
newContents.add(entry);
} else if (i >= contents.size()) {
// write a null in unitialised slots
// not sure if this is correct
newContents.add(new StackEntry(StackEntryType.NULL, null));
} else {
newContents.add(contents.get(i));
}
}
return new LocalVariableState(newContents, constPool);
}
public int size() {
return contents.size();
}
@Override
public String toString() {
return "Local Variables: " + contents.toString();
}
public LocalVariableState constructorCall(StackEntry entry) {
List newContents = new ArrayList(contents.size());
if (entry.getType() == StackEntryType.UNINITIALIZED_THIS) {
for (int i = 0; i < contents.size(); ++i) {
StackEntry stackEntry = contents.get(i);
if (stackEntry.getType() == StackEntryType.UNINITIALIZED_THIS) {
newContents.add(StackEntry.of(stackEntry.getDescriptor(), constPool));
} else {
newContents.add(stackEntry);
}
}
return new LocalVariableState(newContents, constPool);
} else if (entry.getType() == StackEntryType.UNITITIALIZED_OBJECT) {
for (int i = 0; i < contents.size(); ++i) {
StackEntry stackEntry = contents.get(i);
if (stackEntry.getType() == StackEntryType.UNITITIALIZED_OBJECT
&& stackEntry.getNewInstructionLocation() == entry.getNewInstructionLocation()) {
newContents.add(StackEntry.of(stackEntry.getDescriptor(), constPool));
} else {
newContents.add(stackEntry);
}
}
return new LocalVariableState(newContents, constPool);
} else {
throw new InvalidBytecodeException("entry is not an unitialized object. " + toString());
}
}
public LocalVariableState updateMerged(int pos, StackEntry frame) {
List newContents = new ArrayList(contents);
newContents.remove(pos);
newContents.add(pos, frame);
return new LocalVariableState(newContents, constPool);
}
}
LookupSwitchBuilder.java 0000664 0000000 0000000 00000007611 14046606623 0034310 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/code /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.code;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
/**
* builder class used to build a lookupswitch statement.
*
* @author Stuart Douglas
*/
public class LookupSwitchBuilder {
private final CodeLocation defaultLocation;
private final AtomicReference defaultBranchEnd;
private final List values = new ArrayList();
/**
* Builds a lookup switch statement with no specified default location.
*
* When the lookup switch is added to the code attribute a {@link BranchEnd} will be returned that can be used to
* set the location.
*/
public LookupSwitchBuilder() {
defaultBranchEnd = new AtomicReference();
defaultLocation = null;
}
/**
* Builds a lookup switch statement, specifying the default location
* @param defaultLocation The default location
*/
public LookupSwitchBuilder(final CodeLocation defaultLocation) {
this.defaultLocation = defaultLocation;
defaultBranchEnd = null;
}
/**
* Adds a value to the table that is at a location yet to be written.
*
* After this lookup switch has been written then the BranchEnd can be retrieved
* from the returned reference.
*
* @param value The value to add to the lookup table
* @return A reference to the BranchEnd that will be created.
*/
public AtomicReference add(int value) {
final AtomicReference end = new AtomicReference();
ValuePair vp = new ValuePair(value, end);
values.add(vp);
return end;
}
/**
* Adds a value to the table
*
*
* @param value The value to add to the lookup table
*/
public LookupSwitchBuilder add(int value, final CodeLocation location) {
values.add(new ValuePair(value, location));
return this;
}
public CodeLocation getDefaultLocation() {
return defaultLocation;
}
public AtomicReference getDefaultBranchEnd() {
return defaultBranchEnd;
}
public List getValues() {
return Collections.unmodifiableList(values);
}
public static class ValuePair implements Comparable {
private final int value;
private final CodeLocation location;
private final AtomicReference branchEnd;
public ValuePair(final int value, final AtomicReference branchEnd) {
this.value = value;
this.location = null;
this.branchEnd = branchEnd;
}
public ValuePair(final int value, final CodeLocation location) {
this.value = value;
this.location = location;
this.branchEnd = null;
}
@Override
public int compareTo(final ValuePair o) {
return Integer.valueOf(value).compareTo(Integer.valueOf(o.value));
}
public int getValue() {
return value;
}
public CodeLocation getLocation() {
return location;
}
public AtomicReference getBranchEnd() {
return branchEnd;
}
}
}
jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/code/Opcode.java 0000664 0000000 0000000 00000027223 14046606623 0031637 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.code;
/**
* JVM Instruction Set.
*
*
* This interface defines opcodes and array types for the NEWARRAY instruction.
*
* This has been shamelessly borrowed from javassist
*
*/
public interface Opcode {
/* Opcodes */
int AALOAD = 50;
int AASTORE = 83;
int ACONST_NULL = 1;
int ALOAD = 25;
int ALOAD_0 = 42;
int ALOAD_1 = 43;
int ALOAD_2 = 44;
int ALOAD_3 = 45;
int ANEWARRAY = 189;
int ARETURN = 176;
int ARRAYLENGTH = 190;
int ASTORE = 58;
int ASTORE_0 = 75;
int ASTORE_1 = 76;
int ASTORE_2 = 77;
int ASTORE_3 = 78;
int ATHROW = 191;
int BALOAD = 51;
int BASTORE = 84;
int BIPUSH = 16;
int CALOAD = 52;
int CASTORE = 85;
int CHECKCAST = 192;
int D2F = 144;
int D2I = 142;
int D2L = 143;
int DADD = 99;
int DALOAD = 49;
int DASTORE = 82;
int DCMPG = 152;
int DCMPL = 151;
int DCONST_0 = 14;
int DCONST_1 = 15;
int DDIV = 111;
int DLOAD = 24;
int DLOAD_0 = 38;
int DLOAD_1 = 39;
int DLOAD_2 = 40;
int DLOAD_3 = 41;
int DMUL = 107;
int DNEG = 119;
int DREM = 115;
int DRETURN = 175;
int DSTORE = 57;
int DSTORE_0 = 71;
int DSTORE_1 = 72;
int DSTORE_2 = 73;
int DSTORE_3 = 74;
int DSUB = 103;
int DUP = 89;
int DUP2 = 92;
int DUP2_X1 = 93;
int DUP2_X2 = 94;
int DUP_X1 = 90;
int DUP_X2 = 91;
int F2D = 141;
int F2I = 139;
int F2L = 140;
int FADD = 98;
int FALOAD = 48;
int FASTORE = 81;
int FCMPG = 150;
int FCMPL = 149;
int FCONST_0 = 11;
int FCONST_1 = 12;
int FCONST_2 = 13;
int FDIV = 110;
int FLOAD = 23;
int FLOAD_0 = 34;
int FLOAD_1 = 35;
int FLOAD_2 = 36;
int FLOAD_3 = 37;
int FMUL = 106;
int FNEG = 118;
int FREM = 114;
int FRETURN = 174;
int FSTORE = 56;
int FSTORE_0 = 67;
int FSTORE_1 = 68;
int FSTORE_2 = 69;
int FSTORE_3 = 70;
int FSUB = 102;
int GETFIELD = 180;
int GETSTATIC = 178;
int GOTO = 167;
int GOTO_W = 200;
int I2B = 145;
int I2C = 146;
int I2D = 135;
int I2F = 134;
int I2L = 133;
int I2S = 147;
int IADD = 96;
int IALOAD = 46;
int IAND = 126;
int IASTORE = 79;
int ICONST_0 = 3;
int ICONST_1 = 4;
int ICONST_2 = 5;
int ICONST_3 = 6;
int ICONST_4 = 7;
int ICONST_5 = 8;
int ICONST_M1 = 2;
int IDIV = 108;
int IFEQ = 153;
int IFGE = 156;
int IFGT = 157;
int IFLE = 158;
int IFLT = 155;
int IFNE = 154;
int IFNONNULL = 199;
int IFNULL = 198;
int IF_ACMPEQ = 165;
int IF_ACMPNE = 166;
int IF_ICMPEQ = 159;
int IF_ICMPGE = 162;
int IF_ICMPGT = 163;
int IF_ICMPLE = 164;
int IF_ICMPLT = 161;
int IF_ICMPNE = 160;
int IINC = 132;
int ILOAD = 21;
int ILOAD_0 = 26;
int ILOAD_1 = 27;
int ILOAD_2 = 28;
int ILOAD_3 = 29;
int IMUL = 104;
int INEG = 116;
int INSTANCEOF = 193;
int INVOKEINTERFACE = 185;
int INVOKESPECIAL = 183;
int INVOKESTATIC = 184;
int INVOKEVIRTUAL = 182;
int IOR = 128;
int IREM = 112;
int IRETURN = 172;
int ISHL = 120;
int ISHR = 122;
int ISTORE = 54;
int ISTORE_0 = 59;
int ISTORE_1 = 60;
int ISTORE_2 = 61;
int ISTORE_3 = 62;
int ISUB = 100;
int IUSHR = 124;
int IXOR = 130;
int JSR = 168;
int JSR_W = 201;
int L2D = 138;
int L2F = 137;
int L2I = 136;
int LADD = 97;
int LALOAD = 47;
int LAND = 127;
int LASTORE = 80;
int LCMP = 148;
int LCONST_0 = 9;
int LCONST_1 = 10;
int LDC = 18;
int LDC2_W = 20;
int LDC_W = 19;
int LDIV = 109;
int LLOAD = 22;
int LLOAD_0 = 30;
int LLOAD_1 = 31;
int LLOAD_2 = 32;
int LLOAD_3 = 33;
int LMUL = 105;
int LNEG = 117;
int LOOKUPSWITCH = 171;
int LOR = 129;
int LREM = 113;
int LRETURN = 173;
int LSHL = 121;
int LSHR = 123;
int LSTORE = 55;
int LSTORE_0 = 63;
int LSTORE_1 = 64;
int LSTORE_2 = 65;
int LSTORE_3 = 66;
int LSUB = 101;
int LUSHR = 125;
int LXOR = 131;
int MONITORENTER = 194;
int MONITOREXIT = 195;
int MULTIANEWARRAY = 197;
int NEW = 187;
int NEWARRAY = 188;
int NOP = 0;
int POP = 87;
int POP2 = 88;
int PUTFIELD = 181;
int PUTSTATIC = 179;
int RET = 169;
int RETURN = 177;
int SALOAD = 53;
int SASTORE = 86;
int SIPUSH = 17;
int SWAP = 95;
int TABLESWITCH = 170;
int WIDE = 196;
/* array-type code for the newarray instruction */
int T_BOOLEAN = 4;
int T_CHAR = 5;
int T_FLOAT = 6;
int T_DOUBLE = 7;
int T_BYTE = 8;
int T_SHORT = 9;
int T_INT = 10;
int T_LONG = 11;
/* how many values are pushed on the operand stack. */
int[] STACK_GROW = { 0, // nop, 0
1, // aconst_null, 1
1, // iconst_m1, 2
1, // iconst_0, 3
1, // iconst_1, 4
1, // iconst_2, 5
1, // iconst_3, 6
1, // iconst_4, 7
1, // iconst_5, 8
2, // lconst_0, 9
2, // lconst_1, 10
1, // fconst_0, 11
1, // fconst_1, 12
1, // fconst_2, 13
2, // dconst_0, 14
2, // dconst_1, 15
1, // bipush, 16
1, // sipush, 17
1, // ldc, 18
1, // ldc_w, 19
2, // ldc2_w, 20
1, // iload, 21
2, // lload, 22
1, // fload, 23
2, // dload, 24
1, // aload, 25
1, // iload_0, 26
1, // iload_1, 27
1, // iload_2, 28
1, // iload_3, 29
2, // lload_0, 30
2, // lload_1, 31
2, // lload_2, 32
2, // lload_3, 33
1, // fload_0, 34
1, // fload_1, 35
1, // fload_2, 36
1, // fload_3, 37
2, // dload_0, 38
2, // dload_1, 39
2, // dload_2, 40
2, // dload_3, 41
1, // aload_0, 42
1, // aload_1, 43
1, // aload_2, 44
1, // aload_3, 45
-1, // iaload, 46
0, // laload, 47
-1, // faload, 48
0, // daload, 49
-1, // aaload, 50
-1, // baload, 51
-1, // caload, 52
-1, // saload, 53
-1, // istore, 54
-2, // lstore, 55
-1, // fstore, 56
-2, // dstore, 57
-1, // astore, 58
-1, // istore_0, 59
-1, // istore_1, 60
-1, // istore_2, 61
-1, // istore_3, 62
-2, // lstore_0, 63
-2, // lstore_1, 64
-2, // lstore_2, 65
-2, // lstore_3, 66
-1, // fstore_0, 67
-1, // fstore_1, 68
-1, // fstore_2, 69
-1, // fstore_3, 70
-2, // dstore_0, 71
-2, // dstore_1, 72
-2, // dstore_2, 73
-2, // dstore_3, 74
-1, // astore_0, 75
-1, // astore_1, 76
-1, // astore_2, 77
-1, // astore_3, 78
-3, // iastore, 79
-4, // lastore, 80
-3, // fastore, 81
-4, // dastore, 82
-3, // aastore, 83
-3, // bastore, 84
-3, // castore, 85
-3, // sastore, 86
-1, // pop, 87
-2, // pop2, 88
1, // dup, 89
1, // dup_x1, 90
1, // dup_x2, 91
2, // dup2, 92
2, // dup2_x1, 93
2, // dup2_x2, 94
0, // swap, 95
-1, // iadd, 96
-2, // ladd, 97
-1, // fadd, 98
-2, // dadd, 99
-1, // isub, 100
-2, // lsub, 101
-1, // fsub, 102
-2, // dsub, 103
-1, // imul, 104
-2, // lmul, 105
-1, // fmul, 106
-2, // dmul, 107
-1, // idiv, 108
-2, // ldiv, 109
-1, // fdiv, 110
-2, // ddiv, 111
-1, // irem, 112
-2, // lrem, 113
-1, // frem, 114
-2, // drem, 115
0, // ineg, 116
0, // lneg, 117
0, // fneg, 118
0, // dneg, 119
-1, // ishl, 120
-1, // lshl, 121
-1, // ishr, 122
-1, // lshr, 123
-1, // iushr, 124
-1, // lushr, 125
-1, // iand, 126
-2, // land, 127
-1, // ior, 128
-2, // lor, 129
-1, // ixor, 130
-2, // lxor, 131
0, // iinc, 132
1, // i2l, 133
0, // i2f, 134
1, // i2d, 135
-1, // l2i, 136
-1, // l2f, 137
0, // l2d, 138
0, // f2i, 139
1, // f2l, 140
1, // f2d, 141
-1, // d2i, 142
0, // d2l, 143
-1, // d2f, 144
0, // i2b, 145
0, // i2c, 146
0, // i2s, 147
-3, // lcmp, 148
-1, // fcmpl, 149
-1, // fcmpg, 150
-3, // dcmpl, 151
-3, // dcmpg, 152
-1, // ifeq, 153
-1, // ifne, 154
-1, // iflt, 155
-1, // ifge, 156
-1, // ifgt, 157
-1, // ifle, 158
-2, // if_icmpeq, 159
-2, // if_icmpne, 160
-2, // if_icmplt, 161
-2, // if_icmpge, 162
-2, // if_icmpgt, 163
-2, // if_icmple, 164
-2, // if_acmpeq, 165
-2, // if_acmpne, 166
0, // goto, 167
1, // jsr, 168
0, // ret, 169
-1, // tableswitch, 170
-1, // lookupswitch, 171
-1, // ireturn, 172
-2, // lreturn, 173
-1, // freturn, 174
-2, // dreturn, 175
-1, // areturn, 176
0, // return, 177
0, // getstatic, 178 depends on the type
0, // putstatic, 179 depends on the type
0, // getfield, 180 depends on the type
0, // putfield, 181 depends on the type
0, // invokevirtual, 182 depends on the type
0, // invokespecial, 183 depends on the type
0, // invokestatic, 184 depends on the type
0, // invokeinterface, 185 depends on the type
0, // undefined, 186
1, // new, 187
0, // newarray, 188
0, // anewarray, 189
0, // arraylength, 190
-1, // athrow, 191 stack is cleared
0, // checkcast, 192
0, // instanceof, 193
-1, // monitorenter, 194
-1, // monitorexit, 195
0, // wide, 196 depends on the following opcode
0, // multianewarray, 197 depends on the dimensions
-1, // ifnull, 198
-1, // ifnonnull, 199
0, // goto_w, 200
1 // jsr_w, 201
};
}
jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/code/StackEntry.java 0000664 0000000 0000000 00000011601 14046606623 0032506 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.code;
import java.io.DataOutputStream;
import java.io.IOException;
import org.jboss.classfilewriter.constpool.ConstPool;
import org.jboss.classfilewriter.util.DescriptorUtils;
/**
* represents the state of the stack or the local variable array.
*
* This is written out as part of the StackMap attribute
*
* @author Stuart Douglas
*
*/
public class StackEntry {
private final StackEntryType type;
private final String descriptor;
/**
* if this is OBJECT then this holds the const pool index
*/
private final int descriptorIndex;
/**
* if this is an unititialized bytecode then this holds the absolute position of the new instruction that created it
*/
private final int newInstructionLocation;
public StackEntry(StackEntryType type, String descriptor) {
if (type == StackEntryType.OBJECT) {
throw new RuntimeException("OBJECT stack entries must provide a const pool index for the class");
}
this.type = type;
if(descriptor != null && descriptor.contains(".")) {
throw new RuntimeException("invalid descriptor "+ descriptor);
}
this.descriptor = descriptor;
this.newInstructionLocation = -1;
this.descriptorIndex = -1;
}
public StackEntry(StackEntryType type, String descriptor, ConstPool pool) {
this.type = type;
this.descriptor = descriptor;
this.newInstructionLocation = -1;
if(descriptor.contains(".")) {
throw new RuntimeException("invalid descriptor " + descriptor);
}
if(type == StackEntryType.OBJECT) {
if (descriptor.charAt(0) == 'L') {
descriptorIndex = pool.addClassEntry(descriptor.substring(1, descriptor.length() - 1)); // strip the L and the ;
} else {
descriptorIndex = pool.addClassEntry(descriptor); // strip the L and the ;
}
} else {
descriptorIndex = -1;
}
}
public StackEntry(StackEntryType type, String descriptor, int newInstructionLocation) {
this.type = type;
this.descriptor = descriptor;
this.newInstructionLocation = newInstructionLocation;
this.descriptorIndex = -1;
if(descriptor != null && descriptor.contains(".")) {
throw new RuntimeException("invalid descriptor " + descriptor);
}
}
public String getDescriptor() {
return descriptor;
}
public int getNewInstructionLocation() {
return newInstructionLocation;
}
public StackEntryType getType() {
return type;
}
@Override
public String toString() {
if (type == StackEntryType.OBJECT) {
return "StackEntry [descriptor=" + descriptor + ", type=" + type
+ "]";
}
return "StackEntry [type=" + type + "]";
}
public static StackEntry of(String descriptor, ConstPool pool) {
String desc = descriptor.replace('.', '/');
if(!DescriptorUtils.isPrimitive(desc)) {
return new StackEntry(StackEntryType.OBJECT, desc, pool);
}else {
char ret = desc.charAt(0);
switch (ret) {
case 'I':
case 'Z':
case 'S':
case 'B':
case 'C':
return new StackEntry(StackEntryType.INT, desc);
case 'F':
return new StackEntry(StackEntryType.FLOAT, desc);
case 'D':
return new StackEntry(StackEntryType.DOUBLE, desc);
case 'J':
return new StackEntry(StackEntryType.LONG, desc);
}
}
throw new RuntimeException("Unknown descriptor: " + desc);
}
public boolean isWide() {
return type == StackEntryType.DOUBLE || type == StackEntryType.LONG;
}
/**
* writes the entry to the stream
*/
public void write(DataOutputStream dstream) throws IOException {
dstream.writeByte(type.ordinal());
if (type == StackEntryType.OBJECT) {
dstream.writeShort(descriptorIndex);
} else if (type == StackEntryType.UNITITIALIZED_OBJECT) {
dstream.writeShort(newInstructionLocation);
}
}
}
jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/code/StackEntryType.java 0000664 0000000 0000000 00000001446 14046606623 0033356 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.code;
public enum StackEntryType {
TOP, INT, FLOAT, DOUBLE, LONG, NULL, UNINITIALIZED_THIS, OBJECT, UNITITIALIZED_OBJECT
}
jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/code/StackFrame.java 0000664 0000000 0000000 00000020312 14046606623 0032436 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.code;
import org.jboss.classfilewriter.ClassMethod;
/**
* Represents a stack frame in the virtual machine. Holds the state of the local variable array and the stack
*
* @author Stuart Douglas
*
*/
public class StackFrame {
/**
* The current state of the stack
*/
private final StackState stackState;
/**
* The local variable state
*/
private final LocalVariableState localVariableState;
private final StackFrameType type;
/**
* Creates the initial stack frame
*/
public StackFrame(ClassMethod method) {
this.stackState = new StackState(method.getClassFile().getConstPool());
this.localVariableState = new LocalVariableState(method);
this.type = StackFrameType.FULL_FRAME;
}
public StackFrame(StackState stackState, LocalVariableState localVariableState, StackFrameType type) {
this.stackState = stackState;
this.localVariableState = localVariableState;
this.type = type;
}
public StackState getStackState() {
return stackState;
}
public LocalVariableState getLocalVariableState() {
return localVariableState;
}
/**
* push an operand of the given type onto the stack
*
* If the entry is wide then a corresponding TOP type will be created
*/
public StackFrame push(String type) {
StackState ns = stackState.push(type);
return new StackFrame(ns, localVariableState, typeNoLocalChange(ns));
}
/**
* push an operand of the given type onto the stack.
*
* If the entry is wide then a corresponding TOP type will be created
*/
public StackFrame push(StackEntry entry) {
StackState ns = stackState.push(entry);
return new StackFrame(ns, localVariableState, typeNoLocalChange(ns));
}
/**
* pushes a null type onto the stack
*
* @return
*/
public StackFrame aconstNull() {
StackState ns = stackState.aconstNull();
return new StackFrame(ns, localVariableState, typeNoLocalChange(ns));
}
public StackFrame pop(int no) {
StackState ns = stackState.pop(no);
return new StackFrame(ns, localVariableState, typeNoLocalChange(ns));
}
/**
* pops an operand from the stack
*/
public StackFrame pop() {
StackState ns = stackState.pop(1);
return new StackFrame(ns, localVariableState, typeNoLocalChange(ns));
}
/**
* pops 2 operands from the stack
*/
public StackFrame pop2() {
StackState ns = stackState.pop(2);
return new StackFrame(ns, localVariableState, typeNoLocalChange(ns));
}
/**
* pops 3 operands from the stack
*/
public StackFrame pop3() {
StackState ns = stackState.pop(3);
return new StackFrame(ns, localVariableState, typeNoLocalChange(ns));
}
/**
* pops 4 operands from the stack
*/
public StackFrame pop4() {
StackState ns = stackState.pop(4);
return new StackFrame(ns, localVariableState, typeNoLocalChange(ns));
}
/**
* replace the operand at the top of the stack with the given operand
*/
public StackFrame replace(String type) {
// TODO: inefficinet
StackState ns = stackState.pop(1).push(type);
return new StackFrame(ns, localVariableState, typeNoLocalChange(ns));
}
public StackFrame dup() {
StackState ns = stackState.dup();
return new StackFrame(ns, localVariableState, StackFrameType.FULL_FRAME);
}
public StackFrame dupX1() {
StackState ns = stackState.dupX1();
return new StackFrame(ns, localVariableState, StackFrameType.FULL_FRAME);
}
public StackFrame dupX2() {
StackState ns = stackState.dupX2();
return new StackFrame(ns, localVariableState, StackFrameType.FULL_FRAME);
}
public StackFrame dup2() {
StackState ns = stackState.dup2();
return new StackFrame(ns, localVariableState, StackFrameType.FULL_FRAME);
}
public StackFrame dup2X1() {
StackState ns = stackState.dup2X1();
return new StackFrame(ns, localVariableState, StackFrameType.FULL_FRAME);
}
public StackFrame dup2X2() {
StackState ns = stackState.dup2X2();
return new StackFrame(ns, localVariableState, StackFrameType.FULL_FRAME);
}
/**
* Store the variable on top of the stack into a local variable, poping the variable from the stack. Wide types are handled
* automatically
*/
public StackFrame store(int no) {
StackEntry top = stackState.top();
StackState ns;
LocalVariableState ls;
if(top.getType() == StackEntryType.TOP) { //wide type
StackEntry type = stackState.top_1();
ns = stackState.pop(2);
ls = localVariableState.storeWide(no, type);
} else {
StackEntry type = stackState.top();
ns = stackState.pop(1);
ls = localVariableState.store(no, type);
}
return new StackFrame(ns, ls, StackFrameType.FULL_FRAME);
}
/**
* remote the top two operands and replace them with an different operand
*
*/
public StackFrame pop2push1(String type) {
StackState ns = stackState.pop(2).push(type);
return new StackFrame(ns, localVariableState, typeNoLocalChange(ns));
}
/**
* remote the top two operands and replace them with an different operand
*
*/
public StackFrame pop4push1(String type) {
StackState ns = stackState.pop(4).push(type);
return new StackFrame(ns, localVariableState, typeNoLocalChange(ns));
}
@Override
public String toString() {
return "StackFrame [localVariableState=" + localVariableState + ", stackState=" + stackState + "]";
}
/**
* marks the value in potition initializedValueStackPosition as initialized. This also pops this value and everything above
* it
*/
public StackFrame constructorCall(int initializedValueStackPosition) {
StackEntry entry = stackState.getContents().get(stackState.getContents().size() - 1 - initializedValueStackPosition);
StackState ns = stackState.constructorCall(initializedValueStackPosition, entry);
LocalVariableState locals = localVariableState.constructorCall(entry);
return new StackFrame(ns, locals, StackFrameType.FULL_FRAME);
}
public StackFrame swap() {
StackState ns = stackState.swap();
return new StackFrame(ns, localVariableState, StackFrameType.FULL_FRAME);
}
/**
* determins the type of stack frame this is when no local variables have changed
*/
private StackFrameType typeNoLocalChange(StackState ns) {
int size = ns.getContents().size();
if (size == 0) {
return StackFrameType.SAME_FRAME;
} else if (size == 1) {
return StackFrameType.SAME_LOCALS_1_STACK;
}
return StackFrameType.FULL_FRAME;
}
public StackFrame mergeStack(int pos, StackEntry frame) {
StackState stack = stackState.updateMerged(pos, frame);
return new StackFrame(stack, localVariableState, StackFrameType.FULL_FRAME);
}
public StackFrame mergeLocals(int pos, StackEntry frame) {
LocalVariableState locals = localVariableState.updateMerged(pos, frame);
return new StackFrame(stackState, locals, StackFrameType.FULL_FRAME);
}
public StackFrameType getType() {
return type;
}
public StackFrame createFull() {
return new StackFrame(stackState, localVariableState, StackFrameType.FULL_FRAME);
}
}
jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/code/StackFrameType.java 0000664 0000000 0000000 00000001573 14046606623 0033310 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.code;
/**
* The frame type for the StackMapTable
*
* @author Stuart Douglas
*
*/
public enum StackFrameType {
SAME_FRAME, SAME_LOCALS_1_STACK, CHOP_FRAME, SAME_FRAME_EXTENDED, APPEND_FRAME, FULL_FRAME
}
jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/code/StackState.java 0000664 0000000 0000000 00000026531 14046606623 0032475 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.code;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.jboss.classfilewriter.InvalidBytecodeException;
import org.jboss.classfilewriter.constpool.ConstPool;
import org.jboss.classfilewriter.util.DescriptorUtils;
/**
* In immutable stack state, which may be shared between frames
*
* @author Stuart Douglas
*
*/
public class StackState {
/**
* The contents of the stack
*
* This list may be shared between frames, so it must never be modified
*
* The very first element represents the bottom of the stack, with the last element representing the top. Wide elements are
* stored as Wide, Top, with the {@link StackEntryType#TOP} on the top of the stack
*/
private final List contents;
private final ConstPool constPool;
public StackState(ConstPool constPool) {
this.contents = new ArrayList(0);
this.constPool = constPool;
}
public StackState(String exceptionType, ConstPool constPool) {
this.contents = new ArrayList(1);
this.contents.add(new StackEntry(StackEntryType.OBJECT, DescriptorUtils.makeDescriptor(exceptionType), constPool));
this.constPool = constPool;
}
private StackState(final List contents, ConstPool constPool) {
this.contents = contents;
this.constPool = constPool;
}
/**
* checks that the appropriate object type is on top of the stack
*/
public boolean isOnTop(String descriptor) {
if (contents.isEmpty()) {
return false;
}
StackEntry entry = StackEntry.of(descriptor, constPool);
StackEntry top = top();
if (entry.isWide()) {
if (contents.size() == 1) {
return false;
}
return top_1().getType() == entry.getType();
}
if (top.getType() == StackEntryType.NULL && entry.getType() == StackEntryType.OBJECT) {
return true;
}
return top.getType() == entry.getType();
}
public int size() {
return contents.size();
}
/**
* push a type on to the top of the stack
*/
public StackState push(String type) {
StackEntry entry = StackEntry.of(type, constPool);
if (entry.getType() == StackEntryType.DOUBLE || entry.getType() == StackEntryType.LONG) {
return newStack(entry, new StackEntry(StackEntryType.TOP, type));
}
return newStack(entry);
}
/**
* push a type on to the top of the stack
*/
public StackState push(StackEntry entry) {
if (entry.getType() == StackEntryType.DOUBLE || entry.getType() == StackEntryType.LONG) {
return newStack(entry, new StackEntry(StackEntryType.TOP, entry.getDescriptor()));
}
return newStack(entry);
}
public StackState aconstNull() {
StackEntry entry = new StackEntry(StackEntryType.NULL, null);
return newStack(entry);
}
/**
* pop a non-wide type from the top of the stack
*/
public StackState pop(int no) {
if (no == 0) {
return this;
}
if (contents.size() < no) {
throw new InvalidBytecodeException("cannot pop" + no + ", only " + contents.size() + " on stack " + toString());
}
StackEntry type = contents.get(contents.size() - no);
if (type.getType() == StackEntryType.TOP) {
throw new InvalidBytecodeException("Pop" + no + " would split wide type " + toString());
}
return new StackState(contents.subList(0, contents.size() - no), constPool);
}
public StackState dup() {
if (contents.isEmpty()) {
throw new InvalidBytecodeException("cannot dup empty stack");
}
StackEntry type = top();
if (type.getType() == StackEntryType.TOP) {
throw new InvalidBytecodeException("Cannot dup wide type");
}
return newStack(type);
}
public StackState dupX1() {
if (contents.size() < 2) {
throw new InvalidBytecodeException("cannot dup_x1, stack does not have enough items");
}
StackEntry type = top();
if (type.getType() == StackEntryType.TOP) {
throw new InvalidBytecodeException("Cannot dup_x1 wide type");
}
ArrayList ret = new ArrayList(1 + contents.size());
for (int i = 0; i < contents.size(); ++i) {
if (i == contents.size() - 2) {
ret.add(top());
}
ret.add(contents.get(i));
}
return new StackState(ret, constPool);
}
public StackState dupX2() {
if (contents.size() < 3) {
throw new InvalidBytecodeException("cannot dup_x1, stack does not have enough items");
}
StackEntry type = top();
if (type.getType() == StackEntryType.TOP) {
throw new InvalidBytecodeException("Cannot dup_x1 wide type");
}
ArrayList ret = new ArrayList(1 + contents.size());
for (int i = 0; i < contents.size(); ++i) {
if (i == contents.size() - 3) {
ret.add(top());
}
ret.add(contents.get(i));
}
return new StackState(ret, constPool);
}
public StackState dup2() {
if (contents.size() <2) {
throw new InvalidBytecodeException("cannot dup2, stack size is " + contents.size() + " " + toString());
}
StackEntry t1 = top();
StackEntry t2 = top_1();
if (t2.getType() == StackEntryType.TOP) {
throw new InvalidBytecodeException("Cannot dup2 when second type on stack is wide: " + toString());
}
return newStack(t2, t1);
}
public StackState dup2X1() {
if (contents.size() < 3) {
throw new InvalidBytecodeException("cannot dup2X1, stack size is " + contents.size() + " " + toString());
}
StackEntry t1 = top();
StackEntry t2 = top_1();
StackEntry t3 = top_2();
if (t2.getType() == StackEntryType.TOP) {
throw new InvalidBytecodeException("Cannot dup2X1 when second type on stack is wide: " + toString());
}
if (t3.getType() == StackEntryType.TOP) {
throw new InvalidBytecodeException("Cannot dup2X2 when third type on stack is wide: " + toString());
}
ArrayList ret = new ArrayList(2 + contents.size());
for (int i = 0; i < contents.size(); ++i) {
if (i == contents.size() - 3) {
ret.add(t2);
ret.add(t1);
}
ret.add(contents.get(i));
}
return new StackState(ret, constPool);
}
public StackState dup2X2() {
if (contents.size() < 4) {
throw new InvalidBytecodeException("cannot dup2X2, stack size is " + contents.size() + " " + toString());
}
StackEntry t1 = top();
StackEntry t2 = top_1();
StackEntry t4 = top_3();
if (t2.getType() == StackEntryType.TOP) {
throw new InvalidBytecodeException("Cannot dup2X2 when second type on stack is wide: " + toString());
}
if (t4.getType() == StackEntryType.TOP) {
throw new InvalidBytecodeException("Cannot dup2X2 when fourth type on stack is wide: " + toString());
}
ArrayList ret = new ArrayList(2 + contents.size());
for (int i = 0; i < contents.size(); ++i) {
if (i == contents.size() - 4) {
ret.add(t2);
ret.add(t1);
}
ret.add(contents.get(i));
}
return new StackState(ret, constPool);
}
private StackState newStack(StackEntry... pushValues) {
ArrayList ret = new ArrayList(pushValues.length + contents.size());
ret.addAll(contents);
for (StackEntry s : pushValues) {
ret.add(s);
}
return new StackState(ret, constPool);
}
public StackEntry top() {
return contents.get(contents.size() - 1);
}
public StackEntry top_1() {
return contents.get(contents.size() - 2);
}
public StackEntry top_2() {
return contents.get(contents.size() - 3);
}
public StackEntry top_3() {
return contents.get(contents.size() - 4);
}
@Override
public String toString() {
return "Stack: " + contents.toString();
}
public List getContents() {
return Collections.unmodifiableList(contents);
}
public StackState constructorCall(int initializedValueStackPosition, StackEntry entry) {
List newContents = new ArrayList(contents.size());
if (entry.getType() == StackEntryType.UNINITIALIZED_THIS) {
for (int i = 0; i < contents.size() - 1 - initializedValueStackPosition; ++i) {
StackEntry stackEntry = contents.get(i);
if (stackEntry.getType() == StackEntryType.UNINITIALIZED_THIS) {
newContents.add(StackEntry.of(stackEntry.getDescriptor(), constPool));
} else {
newContents.add(stackEntry);
}
}
return new StackState(newContents, constPool);
} else if (entry.getType() == StackEntryType.UNITITIALIZED_OBJECT) {
for (int i = 0; i < contents.size() - 1 - initializedValueStackPosition; ++i) {
StackEntry stackEntry = contents.get(i);
if (stackEntry.getType() == StackEntryType.UNITITIALIZED_OBJECT
&& stackEntry.getNewInstructionLocation() == entry.getNewInstructionLocation()) {
newContents.add(StackEntry.of(stackEntry.getDescriptor(), constPool));
} else {
newContents.add(stackEntry);
}
}
return new StackState(newContents, constPool);
} else {
throw new InvalidBytecodeException("Object at position " + initializedValueStackPosition
+ " is not an unitialized object. " + toString());
}
}
public StackState updateMerged(int pos, StackEntry frame) {
List newContents = new ArrayList(contents);
newContents.remove(pos);
newContents.add(pos, frame);
return new StackState(newContents, constPool);
}
public StackState swap() {
int size = contents.size();
List newContents = new ArrayList(contents.subList(0, size - 2));
newContents.add(contents.get(size - 1));
newContents.add(contents.get(size - 2));
return new StackState(newContents, constPool);
}
}
TableSwitchBuilder.java 0000664 0000000 0000000 00000007426 14046606623 0034072 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/code /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.code;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
/**
* builder class used to build a tableswitch statement.
*
* @author Stuart Douglas
*/
public class TableSwitchBuilder {
private final CodeLocation defaultLocation;
private final AtomicReference defaultBranchEnd;
private final List values = new ArrayList();
private final int low;
private final int high;
/**
* Builds a lookup switch statement with no specified default location.
*
* When the lookup switch is added to the code attribute a {@link org.jboss.classfilewriter.code.BranchEnd} will be returned that can be used to
* set the location.
* @param low
* @param high
*/
public TableSwitchBuilder(final int low, final int high) {
this.low = low;
this.high = high;
defaultBranchEnd = new AtomicReference();
defaultLocation = null;
}
/**
* Builds a lookup switch statement, specifying the default location
* @param defaultLocation The default location
* @param low
* @param high
*/
public TableSwitchBuilder(final CodeLocation defaultLocation, final int low, final int high) {
this.defaultLocation = defaultLocation;
this.low = low;
this.high = high;
defaultBranchEnd = null;
}
/**
* Adds a value to the table that is at a location yet to be written.
*
* After this lookup switch has been written then the BranchEnd can be retrieved
* from the returned reference.
*
* @return A reference to the BranchEnd that will be created.
*/
public AtomicReference add() {
final AtomicReference end = new AtomicReference();
ValuePair vp = new ValuePair(end);
values.add(vp);
return end;
}
/**
* Adds a value to the table
*
*
*/
public TableSwitchBuilder add( final CodeLocation location) {
values.add(new ValuePair(location));
return this;
}
public CodeLocation getDefaultLocation() {
return defaultLocation;
}
public AtomicReference getDefaultBranchEnd() {
return defaultBranchEnd;
}
public List getValues() {
return Collections.unmodifiableList(values);
}
public int getLow() {
return low;
}
public int getHigh() {
return high;
}
public static class ValuePair {
private final CodeLocation location;
private final AtomicReference branchEnd;
public ValuePair(final AtomicReference branchEnd) {
this.location = null;
this.branchEnd = branchEnd;
}
public ValuePair(final CodeLocation location) {
this.location = location;
this.branchEnd = null;
}
public CodeLocation getLocation() {
return location;
}
public AtomicReference getBranchEnd() {
return branchEnd;
}
}
}
jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/constpool/ 0000775 0000000 0000000 00000000000 14046606623 0030663 5 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/constpool/ClassEntry.java 0000664 0000000 0000000 00000002203 14046606623 0033612 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.constpool;
import java.io.DataOutputStream;
import java.io.IOException;
public class ClassEntry extends ConstPoolEntry {
private final int utf8Location;
public ClassEntry(int utf8Location) {
this.utf8Location = utf8Location;
}
@Override
public ConstPoolEntryType getType() {
return ConstPoolEntryType.CLASS;
}
public void writeData(DataOutputStream stream) throws IOException {
stream.writeShort(utf8Location);
}
}
jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/constpool/ConstPool.java 0000664 0000000 0000000 00000024761 14046606623 0033460 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.constpool;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.jboss.classfilewriter.WritableEntry;
import org.jboss.classfilewriter.util.ByteArrayDataOutputStream;
public class ConstPool implements WritableEntry {
private final LinkedHashMap entries = new LinkedHashMap();
private final Map utf8Locations = new HashMap();
private final Map classLocations = new HashMap();
private final Map stringLocations = new HashMap();
private final Map nameAndTypeLocations = new HashMap();
private final Map fieldLocations = new HashMap();
private final Map methodLocations = new HashMap();
private final Map interfaceMethodLocations = new HashMap();
private final Map integerLocations = new HashMap();
private final Map floatLocations = new HashMap();
private final Map longLocations = new HashMap();
private final Map doubleLocations = new HashMap();
private int count = 1;
/**
* The constant_pool_count field of the class file format
*/
private Integer constPoolSize = 1;
public Integer addUtf8Entry(String entry) {
if (utf8Locations.containsKey(entry)) {
return utf8Locations.get(entry);
}
final int index = count++;
constPoolSize++;
entries.put(index, new Utf8Entry(entry));
utf8Locations.put(entry, index);
return index;
}
/**
* Adds a CONSTANT_Class_info to the const pool. This must be in internal form
*/
public Integer addClassEntry(String className) {
className = className.replace('.', '/');
if (classLocations.containsKey(className)) {
return classLocations.get(className);
}
final Integer utf8Location = addUtf8Entry(className);
final Integer index = count++;
constPoolSize++;
entries.put(index, new ClassEntry(utf8Location));
classLocations.put(className, index);
return index;
}
/**
* Adds a CONSTANT_String_info to the const pool.
*/
public Integer addStringEntry(String string) {
if (stringLocations.containsKey(string)) {
return stringLocations.get(string);
}
final Integer utf8Location = addUtf8Entry(string);
final Integer index = count++;
constPoolSize++;
entries.put(index, new StringEntry(utf8Location));
stringLocations.put(string, index);
return index;
}
public Integer addIntegerEntry(int entry) {
if (integerLocations.containsKey(entry)) {
return integerLocations.get(entry);
}
final Integer index = count++;
constPoolSize++;
entries.put(index, new IntegerEntry(entry));
integerLocations.put(entry, index);
return index;
}
public Integer addFloatEntry(float entry) {
if (floatLocations.containsKey(entry)) {
return floatLocations.get(entry);
}
final Integer index = count++;
constPoolSize++;
entries.put(index, new FloatEntry(entry));
floatLocations.put(entry, index);
return index;
}
public Integer addLongEntry(long entry) {
if (longLocations.containsKey(entry)) {
return longLocations.get(entry);
}
final Integer index = count++;
count++;
constPoolSize += 2;
entries.put(index, new LongEntry(entry));
longLocations.put(entry, index);
return index;
}
public Integer addDoubleEntry(double entry) {
if (doubleLocations.containsKey(entry)) {
return doubleLocations.get(entry);
}
final Integer index = count++;
count++;
constPoolSize += 2;
entries.put(index, new DoubleEntry(entry));
doubleLocations.put(entry, index);
return index;
}
public Integer addNameAndTypeEntry(String name, String type) {
final NameAndType typeInfo = new NameAndType(name, type);
if(nameAndTypeLocations.containsKey(typeInfo)) {
return nameAndTypeLocations.get(typeInfo);
}
final Integer nameIndex = addUtf8Entry(name);
final Integer typeIndex = addUtf8Entry(type);
final Integer index = count++;
constPoolSize++;
entries.put(index,new NameAndTypeEntry(nameIndex, typeIndex));
nameAndTypeLocations.put(typeInfo, index);
return index;
}
public Integer addFieldEntry(String className, String fieldName, String fieldType) {
final NameAndType nameAndType = new NameAndType(fieldName, fieldType);
final MemberInfo field = new MemberInfo(className, nameAndType);
if (fieldLocations.containsKey(field)) {
return fieldLocations.get(field);
}
final Integer nameAndTypeIndex = addNameAndTypeEntry(fieldName, fieldType);
final Integer classIndex = addClassEntry(className);
final Integer index = count++;
constPoolSize++;
entries.put(index, new FieldRefEntry(classIndex, nameAndTypeIndex));
fieldLocations.put(field, index);
return index;
}
public Integer addMethodEntry(String className, String methodName, String descriptor) {
final NameAndType nameAndType = new NameAndType(methodName, descriptor);
final MemberInfo method = new MemberInfo(className, nameAndType);
if (methodLocations.containsKey(method)) {
return methodLocations.get(method);
}
final Integer nameAndTypeIndex = addNameAndTypeEntry(methodName, descriptor);
final Integer classIndex = addClassEntry(className);
final Integer index = count++;
constPoolSize++;
entries.put(index, new MethodRefEntry(classIndex, nameAndTypeIndex));
methodLocations.put(method, index);
return index;
}
public Integer addInterfaceMethodEntry(String className, String methodName, String descriptor) {
final NameAndType nameAndType = new NameAndType(methodName, descriptor);
final MemberInfo method = new MemberInfo(className, nameAndType);
if (interfaceMethodLocations.containsKey(method)) {
return interfaceMethodLocations.get(method);
}
final Integer nameAndTypeIndex = addNameAndTypeEntry(methodName, descriptor);
final Integer classIndex = addClassEntry(className);
final Integer index = count++;
constPoolSize++;
entries.put(index, new InterfaceMethodRefEntry(classIndex, nameAndTypeIndex));
interfaceMethodLocations.put(method, index);
return index;
}
public void write(ByteArrayDataOutputStream stream) throws IOException {
stream.writeShort(constPoolSize);
for (Entry entry : entries.entrySet()) {
entry.getValue().write(stream);
}
}
private static final class NameAndType {
private final String name, type;
public NameAndType(String name, String type) {
this.name = name;
this.type = type;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((type == null) ? 0 : type.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
NameAndType other = (NameAndType) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (type == null) {
if (other.type != null)
return false;
} else if (!type.equals(other.type))
return false;
return true;
}
}
private static class MemberInfo {
private final String className;
private final NameAndType nameAndType;
public MemberInfo(String className,NameAndType nameAndType) {
this.className = className;
this.nameAndType = nameAndType;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((className == null) ? 0 : className.hashCode());
result = prime * result + ((nameAndType == null) ? 0 : nameAndType.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
MemberInfo other = (MemberInfo) obj;
if (className == null) {
if (other.className != null)
return false;
} else if (!className.equals(other.className))
return false;
if (nameAndType == null) {
if (other.nameAndType != null)
return false;
} else if (!nameAndType.equals(other.nameAndType))
return false;
return true;
}
}
}
ConstPoolEntry.java 0000664 0000000 0000000 00000002314 14046606623 0034411 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/constpool /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.constpool;
import org.jboss.classfilewriter.WritableEntry;
import org.jboss.classfilewriter.util.ByteArrayDataOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public abstract class ConstPoolEntry implements WritableEntry {
public final void write(ByteArrayDataOutputStream stream) throws IOException {
stream.writeByte(getType().getTag());
writeData(stream);
}
public abstract void writeData(DataOutputStream stream) throws IOException;
public abstract ConstPoolEntryType getType();
}
ConstPoolEntryType.java 0000664 0000000 0000000 00000002402 14046606623 0035251 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/constpool /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.constpool;
public enum ConstPoolEntryType {
CLASS(7,1),
FIELDREF(9,1),
METHODREF(10,1),
INTERFACE_METHODREF(11,1),
STRING(8,1),
INTEGER(3,1),
FLOAT(4,1),
LONG(5,2),
DOUBLE(6,2),
NAME_AND_TYPE(12,1),
UTF8(1,1);
private final int tag;
private final int slots;
ConstPoolEntryType(int tag, int slots) {
this.tag = tag;
this.slots = slots;
}
public int getTag() {
return tag;
}
/**
* The number of spaces this takes up in the const pool
*/
public int getSlots() {
return slots;
}
}
jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/constpool/DoubleEntry.java0000664 0000000 0000000 00000002171 14046606623 0033763 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.constpool;
import java.io.DataOutputStream;
import java.io.IOException;
public class DoubleEntry extends ConstPoolEntry {
private final double value;
public DoubleEntry(double value) {
this.value = value;
}
@Override
public ConstPoolEntryType getType() {
return ConstPoolEntryType.DOUBLE;
}
@Override
public void writeData(DataOutputStream stream) throws IOException {
stream.writeDouble(value);
}
}
FieldRefEntry.java 0000664 0000000 0000000 00000002456 14046606623 0034160 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/constpool /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.constpool;
import java.io.DataOutputStream;
import java.io.IOException;
public class FieldRefEntry extends ConstPoolEntry {
private final int classIndex;
private final int nameAndTypeIndex;
public FieldRefEntry(int classIndex, int nameAndTypeIndex) {
this.classIndex = classIndex;
this.nameAndTypeIndex = nameAndTypeIndex;
}
@Override
public ConstPoolEntryType getType() {
return ConstPoolEntryType.FIELDREF;
}
@Override
public void writeData(DataOutputStream stream) throws IOException {
stream.writeShort(classIndex);
stream.writeShort(nameAndTypeIndex);
}
}
jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/constpool/FloatEntry.java 0000664 0000000 0000000 00000002163 14046606623 0033617 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.constpool;
import java.io.DataOutputStream;
import java.io.IOException;
public class FloatEntry extends ConstPoolEntry {
private final float value;
public FloatEntry(float value) {
this.value = value;
}
@Override
public ConstPoolEntryType getType() {
return ConstPoolEntryType.FLOAT;
}
@Override
public void writeData(DataOutputStream stream) throws IOException {
stream.writeFloat(value);
}
}
IntegerEntry.java 0000664 0000000 0000000 00000002163 14046606623 0034070 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/constpool /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.constpool;
import java.io.DataOutputStream;
import java.io.IOException;
public class IntegerEntry extends ConstPoolEntry {
private final int value;
public IntegerEntry(int value) {
this.value = value;
}
@Override
public ConstPoolEntryType getType() {
return ConstPoolEntryType.INTEGER;
}
@Override
public void writeData(DataOutputStream stream) throws IOException {
stream.writeInt(value);
}
}
InterfaceMethodRefEntry.java 0000664 0000000 0000000 00000002515 14046606623 0036172 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/constpool /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.constpool;
import java.io.DataOutputStream;
import java.io.IOException;
public class InterfaceMethodRefEntry extends ConstPoolEntry {
private final int classIndex;
private final int nameAndTypeIndex;
public InterfaceMethodRefEntry(int classIndex, int nameAndTypeIndex) {
this.classIndex = classIndex;
this.nameAndTypeIndex = nameAndTypeIndex;
}
@Override
public ConstPoolEntryType getType() {
return ConstPoolEntryType.INTERFACE_METHODREF;
}
@Override
public void writeData(DataOutputStream stream) throws IOException {
stream.writeShort(classIndex);
stream.writeShort(nameAndTypeIndex);
}
}
jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/constpool/LongEntry.java 0000664 0000000 0000000 00000002155 14046606623 0033452 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.constpool;
import java.io.DataOutputStream;
import java.io.IOException;
public class LongEntry extends ConstPoolEntry {
private final long value;
public LongEntry(long value) {
this.value = value;
}
@Override
public ConstPoolEntryType getType() {
return ConstPoolEntryType.LONG;
}
@Override
public void writeData(DataOutputStream stream) throws IOException {
stream.writeLong(value);
}
}
MethodRefEntry.java 0000664 0000000 0000000 00000002461 14046606623 0034351 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/constpool /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.constpool;
import java.io.DataOutputStream;
import java.io.IOException;
public class MethodRefEntry extends ConstPoolEntry {
private final int classIndex;
private final int nameAndTypeIndex;
public MethodRefEntry(int classIndex, int nameAndTypeIndex) {
this.classIndex = classIndex;
this.nameAndTypeIndex = nameAndTypeIndex;
}
@Override
public ConstPoolEntryType getType() {
return ConstPoolEntryType.METHODREF;
}
@Override
public void writeData(DataOutputStream stream) throws IOException {
stream.writeShort(classIndex);
stream.writeShort(nameAndTypeIndex);
}
}
NameAndTypeEntry.java 0000664 0000000 0000000 00000002457 14046606623 0034646 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/constpool /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.constpool;
import java.io.DataOutputStream;
import java.io.IOException;
public class NameAndTypeEntry extends ConstPoolEntry {
private final int nameIndex;
private final int descriptorIndex;
public NameAndTypeEntry(int nameIndex, int descriptorIndex) {
this.nameIndex = nameIndex;
this.descriptorIndex = descriptorIndex;
}
@Override
public ConstPoolEntryType getType() {
return ConstPoolEntryType.NAME_AND_TYPE;
}
@Override
public void writeData(DataOutputStream stream) throws IOException {
stream.writeShort(nameIndex);
stream.writeShort(descriptorIndex);
}
}
jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/constpool/StringEntry.java0000664 0000000 0000000 00000002206 14046606623 0034016 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.constpool;
import java.io.DataOutputStream;
import java.io.IOException;
public class StringEntry extends ConstPoolEntry {
private final int utf8Index;
public StringEntry(int utf8Index) {
this.utf8Index = utf8Index;
}
@Override
public ConstPoolEntryType getType() {
return ConstPoolEntryType.STRING;
}
@Override
public void writeData(DataOutputStream stream) throws IOException {
stream.writeShort(utf8Index);
}
}
jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/constpool/Utf8Entry.java 0000664 0000000 0000000 00000002227 14046606623 0033401 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.constpool;
import java.io.DataOutputStream;
import java.io.IOException;
public class Utf8Entry extends ConstPoolEntry {
private final String data;
public Utf8Entry(String data) {
this.data = data;
}
@Override
public ConstPoolEntryType getType() {
return ConstPoolEntryType.UTF8;
}
public void writeData(DataOutputStream stream) throws IOException {
stream.writeUTF(data);
}
public String getData() {
return data;
}
}
jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/util/ 0000775 0000000 0000000 00000000000 14046606623 0027620 5 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/util/Boxing.java 0000664 0000000 0000000 00000012546 14046606623 0031721 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.util;
import org.jboss.classfilewriter.code.CodeAttribute;
/**
* This class is responsible for generating bytecode fragments to box/unbox whatever happens to be on the top of the stack.
*
* It is the calling codes responsibility to make sure that the correct type is on the stack
*
* @author Stuart Douglas
*
*/
public class Boxing {
static public void boxIfNessesary(CodeAttribute ca, String desc) {
if (desc.length() == 1) {
char type = desc.charAt(0);
switch (type) {
case 'I':
boxInt(ca);
break;
case 'J':
boxLong(ca);
break;
case 'S':
boxShort(ca);
break;
case 'F':
boxFloat(ca);
break;
case 'D':
boxDouble(ca);
break;
case 'B':
boxByte(ca);
break;
case 'C':
boxChar(ca);
break;
case 'Z':
boxBoolean(ca);
break;
default:
throw new RuntimeException("Cannot box unkown primitive type: " + type);
}
}
}
static public CodeAttribute unbox(CodeAttribute ca, String desc) {
char type = desc.charAt(0);
switch (type) {
case 'I':
return unboxInt(ca);
case 'J':
return unboxLong(ca);
case 'S':
return unboxShort(ca);
case 'F':
return unboxFloat(ca);
case 'D':
return unboxDouble(ca);
case 'B':
return unboxByte(ca);
case 'C':
return unboxChar(ca);
case 'Z':
return unboxBoolean(ca);
}
throw new RuntimeException("Cannot unbox unkown primitive type: " + type);
}
static public void boxInt(CodeAttribute bc) {
bc.invokestatic("java.lang.Integer", "valueOf", "(I)Ljava/lang/Integer;");
}
static public void boxLong(CodeAttribute bc) {
bc.invokestatic("java.lang.Long", "valueOf", "(J)Ljava/lang/Long;");
}
static public void boxShort(CodeAttribute bc) {
bc.invokestatic("java.lang.Short", "valueOf", "(S)Ljava/lang/Short;");
}
static public void boxByte(CodeAttribute bc) {
bc.invokestatic("java.lang.Byte", "valueOf", "(B)Ljava/lang/Byte;");
}
static public void boxFloat(CodeAttribute bc) {
bc.invokestatic("java.lang.Float", "valueOf", "(F)Ljava/lang/Float;");
}
static public void boxDouble(CodeAttribute bc) {
bc.invokestatic("java.lang.Double", "valueOf", "(D)Ljava/lang/Double;");
}
static public void boxChar(CodeAttribute bc) {
bc.invokestatic("java.lang.Character", "valueOf", "(C)Ljava/lang/Character;");
}
static public void boxBoolean(CodeAttribute bc) {
bc.invokestatic("java.lang.Boolean", "valueOf", "(Z)Ljava/lang/Boolean;");
}
// unboxing
static public CodeAttribute unboxInt(CodeAttribute bc) {
bc.checkcast("java.lang.Number");
bc.invokevirtual("java.lang.Number", "intValue", "()I");
return bc;
}
static public CodeAttribute unboxLong(CodeAttribute bc) {
bc.checkcast("java.lang.Number");
bc.invokevirtual("java.lang.Number", "longValue", "()J");
return bc;
}
static public CodeAttribute unboxShort(CodeAttribute bc) {
bc.checkcast("java.lang.Number");
bc.invokevirtual("java.lang.Number", "shortValue", "()S");
return bc;
}
static public CodeAttribute unboxByte(CodeAttribute bc) {
bc.checkcast("java.lang.Number");
bc.invokevirtual("java.lang.Number", "byteValue", "()B");
return bc;
}
static public CodeAttribute unboxFloat(CodeAttribute bc) {
bc.checkcast("java.lang.Number");
bc.invokevirtual("java.lang.Number", "floatValue", "()F");
return bc;
}
static public CodeAttribute unboxDouble(CodeAttribute bc) {
bc.checkcast("java.lang.Number");
bc.invokevirtual("java.lang.Number", "doubleValue", "()D");
return bc;
}
static public CodeAttribute unboxChar(CodeAttribute bc) {
bc.checkcast("java.lang.Character");
bc.invokevirtual("java.lang.Character", "charValue", "()C");
return bc;
}
static public CodeAttribute unboxBoolean(CodeAttribute bc) {
bc.checkcast("java.lang.Boolean");
bc.invokevirtual("java.lang.Boolean", "booleanValue", "()Z");
return bc;
}
}
ByteArrayDataOutputStream.java 0000664 0000000 0000000 00000004745 14046606623 0035507 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/util /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.util;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* DataOutputStream sub class that allows for the lazy writing of length values.
*
* These length values are inserted into the bytes when then final bytes are read.
* @author Stuart Douglas
*/
public class ByteArrayDataOutputStream extends DataOutputStream {
private final ByteArrayOutputStream bytes;
private final List sizes = new ArrayList();
public ByteArrayDataOutputStream(ByteArrayOutputStream bytes) {
super(bytes);
this.bytes = bytes;
}
public ByteArrayDataOutputStream() {
this(new ByteArrayOutputStream());
}
public LazySize writeSize() throws IOException {
LazySizeImpl sv = new LazySizeImpl(this.written);
sizes.add(sv);
writeInt(0);
return sv;
}
public byte[] getBytes() {
byte[] data = bytes.toByteArray();
for (final LazySizeImpl i : sizes) {
overwriteInt(data, i.position, i.value);
}
return data;
}
/**
* overwrites a 32 bit value in the already written bytecode data
*/
private void overwriteInt(byte[] bytecode, int offset, int value) {
bytecode[offset] = (byte) (value >> 24);
bytecode[offset + 1] = (byte) (value >> 16);
bytecode[offset + 2] = (byte) (value >> 8);
bytecode[offset + 3] = (byte) (value);
}
private class LazySizeImpl implements LazySize {
private final int position;
private int value;
public LazySizeImpl(int position) {
this.position = position;
}
@Override
public void markEnd() {
value = written - position - 4;
}
}
}
jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/util/DescriptorUtils.java 0000664 0000000 0000000 00000017544 14046606623 0033635 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.util;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
/**
* Utility class for working with method descriptors
*
* @author Stuart Douglas
*/
public class DescriptorUtils {
static final String VOID_CLASS_DESCRIPTOR = "V";
static final String BYTE_CLASS_DESCRIPTOR = "B";
static final String CHAR_CLASS_DESCRIPTOR = "C";
static final String DOUBLE_CLASS_DESCRIPTOR = "D";
static final String FLOAT_CLASS_DESCRIPTOR = "F";
static final String INT_CLASS_DESCRIPTOR = "I";
static final String LONG_CLASS_DESCRIPTOR = "J";
static final String SHORT_CLASS_DESCRIPTOR = "S";
static final String BOOLEAN_CLASS_DESCRIPTOR = "Z";
/**
* Changes a class name to the internal form suitable for use in a descriptor string.
*
* e.g. java.lang.String => Ljava/lang/String;
*/
public static String makeDescriptor(String className) {
String repl = className.replace('.', '/');
return 'L' + repl + ';';
}
public static String makeDescriptor(Class> c) {
if (void.class.equals(c)) {
return VOID_CLASS_DESCRIPTOR;
} else if (byte.class.equals(c)) {
return BYTE_CLASS_DESCRIPTOR;
} else if (char.class.equals(c)) {
return CHAR_CLASS_DESCRIPTOR;
} else if (double.class.equals(c)) {
return DOUBLE_CLASS_DESCRIPTOR;
} else if (float.class.equals(c)) {
return FLOAT_CLASS_DESCRIPTOR;
} else if (int.class.equals(c)) {
return INT_CLASS_DESCRIPTOR;
} else if (long.class.equals(c)) {
return LONG_CLASS_DESCRIPTOR;
} else if (short.class.equals(c)) {
return SHORT_CLASS_DESCRIPTOR;
} else if (boolean.class.equals(c)) {
return BOOLEAN_CLASS_DESCRIPTOR;
} else if (c.isArray()) {
return c.getName().replace('.', '/');
} else
// normal object
{
return makeDescriptor(c.getName());
}
}
public static String makeDescriptor(Constructor> c) {
StringBuilder desc = new StringBuilder("(");
for (Class> p : c.getParameterTypes()) {
desc.append(DescriptorUtils.makeDescriptor(p));
}
desc.append(")");
desc.append("V");
return desc.toString();
}
/**
* returns an array of String representations of the parameter types. Primitives are returned as their native
* representations, while clases are returned in the internal descriptor form e.g. Ljava/lang/Integer;
*/
public static String[] parameterDescriptors(String methodDescriptor) {
int i = 1; // char 0 is a '('
List ret = new ArrayList();
int arraystart = -1;
while (methodDescriptor.charAt(i) != ')') {
String type = null;
if (methodDescriptor.charAt(i) == '[') {
if (arraystart == -1) {
arraystart = i;
}
} else {
if (methodDescriptor.charAt(i) == 'L') {
int start = i;
i++;
while (methodDescriptor.charAt(i) != ';') {
++i;
}
if (arraystart == -1) {
type = methodDescriptor.substring(start, i + 1);
} else {
type = methodDescriptor.substring(arraystart, i + 1);
}
} else {
if (arraystart == -1) {
type = methodDescriptor.charAt(i) + "";
} else {
type = methodDescriptor.substring(arraystart, i + 1);
}
}
arraystart = -1;
ret.add(type);
}
++i;
}
String[] r = new String[ret.size()];
for (int j = 0; j < ret.size(); ++j) {
r[j] = ret.get(j);
}
return r;
}
public static String[] parameterDescriptors(Method m) {
return parameterDescriptors(m.getParameterTypes());
}
public static String[] parameterDescriptors(Class>[] parameters) {
String[] ret = new String[parameters.length];
for (int i = 0; i < ret.length; ++i) {
ret[i] = DescriptorUtils.makeDescriptor(parameters[i]);
}
return ret;
}
public static String returnType(String methodDescriptor) {
return methodDescriptor.substring(methodDescriptor.lastIndexOf(')') + 1, methodDescriptor.length());
}
/**
* returns true if the descriptor represents a primitive type
*/
public static boolean isPrimitive(String descriptor) {
if (descriptor.length() == 1) {
return true;
}
return false;
}
/**
* returns true if the descriptor represents a long or a double
*/
public static boolean isWide(String descriptor) {
if (!isPrimitive(descriptor)) {
return false;
}
char c = descriptor.charAt(0);
if (c == 'D' || c == 'J') {
return true;
}
return false;
}
/**
* returns true if the class represents a long or a double
*/
public static boolean isWide(Class> cls) {
return cls == double.class || cls == long.class;
}
public static String methodDescriptor(Method m) {
StringBuilder desc = new StringBuilder("(");
for (Class> p : m.getParameterTypes()) {
desc.append(DescriptorUtils.makeDescriptor(p));
}
desc.append(")");
desc.append(DescriptorUtils.makeDescriptor(m.getReturnType()));
return desc.toString();
}
public static String methodDescriptor(String[] parameters, String returnType) {
StringBuilder desc = new StringBuilder("(");
for (String p : parameters) {
desc.append(p);
}
desc.append(")");
desc.append(returnType);
return desc.toString();
}
/**
* performs basic validation on a descriptor
*/
public static String validateDescriptor(String descriptor) {
if (descriptor.length() == 0) {
throw new RuntimeException("descriptors may not be empty");
}
if (descriptor.length() > 1) {
if (descriptor.startsWith("L")) {
if (!descriptor.endsWith(";")) {
throw new RuntimeException(descriptor + " is not a valid descriptor");
}
} else if (descriptor.startsWith("[")) {
} else {
throw new RuntimeException(descriptor + " is not a valid descriptor");
}
} else {
char type = descriptor.charAt(0);
switch (type) {
case 'I':
case 'Z':
case 'S':
case 'B':
case 'F':
case 'D':
case 'V':
case 'J':
case 'C':
break;
default:
throw new RuntimeException(descriptor + " is not a valid descriptor");
}
}
return descriptor;
}
}
jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/util/LazySize.java 0000664 0000000 0000000 00000001541 14046606623 0032236 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.util;
/**
* Represents a place holder for a size value in a byte array that can be written to later.
*
* @author Stuart Douglas
*/
public interface LazySize {
void markEnd();
}
jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/util/SignatureBuilder.java0000664 0000000 0000000 00000005501 14046606623 0033734 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.util;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
/**
* Generates the contents of a Signature attribute from a java type.
*
* TODO: this is all wrong, I'm to tired to read the pathetic excuse for a spec properly
*
* @author Stuart Douglas
*
*/
public class SignatureBuilder {
/**
* Generates the field signiture for a field of the given type
*
* @param type
* @return the signiture, or null if no signure is required (e.g. for Class types)
*/
public static String fieldAttribute(Type type) {
StringBuilder builder = new StringBuilder();
fieldAttribute(type, builder);
return builder.toString();
}
private static void fieldAttribute(Type type, StringBuilder builder) {
if (type instanceof Class>) {
classType((Class>) type, builder);
} else if (type instanceof ParameterizedType) {
ParameterizedType ptype = (ParameterizedType) type;
parametizedType(ptype, builder);
} else if (type instanceof WildcardType) {
WildcardType ptype = (WildcardType) type;
wildcardType(ptype, builder);
}
}
private static void wildcardType(WildcardType type, StringBuilder builder) {
// WRONG
builder.append('*');
}
public static void parametizedType(ParameterizedType type, StringBuilder builder) {
fieldAttribute(type.getRawType(), builder); //write the owner type
//now write the type arguments
builder.append('<');
for(Type t : type.getActualTypeArguments()) {
fieldAttribute(t, builder);
builder.append(';');
}
builder.append(">;");
}
private static void classType(Class> clazz, StringBuilder builder) {
if (clazz.isMemberClass()) {
classType(clazz.getDeclaringClass(), builder);
builder.append('.');
builder.append(clazz.getSimpleName());
} else {
builder.append("L");
builder.append(clazz.getName().replace('.', '/'));
}
}
private SignatureBuilder() {
}
}
jboss-classfilewriter-1.2.5.Final/src/main/java/org/jboss/classfilewriter/util/Signatures.java 0000664 0000000 0000000 00000024611 14046606623 0032613 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source
* Copyright 2015, Red Hat, Inc., and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* 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 org.jboss.classfilewriter.util;
import static org.jboss.classfilewriter.util.DescriptorUtils.BOOLEAN_CLASS_DESCRIPTOR;
import static org.jboss.classfilewriter.util.DescriptorUtils.BYTE_CLASS_DESCRIPTOR;
import static org.jboss.classfilewriter.util.DescriptorUtils.CHAR_CLASS_DESCRIPTOR;
import static org.jboss.classfilewriter.util.DescriptorUtils.DOUBLE_CLASS_DESCRIPTOR;
import static org.jboss.classfilewriter.util.DescriptorUtils.FLOAT_CLASS_DESCRIPTOR;
import static org.jboss.classfilewriter.util.DescriptorUtils.INT_CLASS_DESCRIPTOR;
import static org.jboss.classfilewriter.util.DescriptorUtils.LONG_CLASS_DESCRIPTOR;
import static org.jboss.classfilewriter.util.DescriptorUtils.SHORT_CLASS_DESCRIPTOR;
import static org.jboss.classfilewriter.util.DescriptorUtils.VOID_CLASS_DESCRIPTOR;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
/**
* Encode signatures that use types outside the type system of the Java Virtual Machine. See also the JVM spec, section "4.7.9.1. Signatures".
*
* If anything goes wrong during encoding a {@link RuntimeException} is thrown.
*
* @author Martin Kouba
*/
public final class Signatures {
static final char WILDCARD_UPPER_BOUND = '+';
static final char WILDCARD_LOWER_BOUND = '-';
static final char WILDCARD_NO_BOUND = '*';
static final char TYPE_PARAM_DEL_START = '<';
static final char TYPE_PARAM_DEL_END = '>';
static final char SEMICOLON = ';';
static final char COLON = ':';
private Signatures() {
}
/**
*
*
* @param method
* @return the JVM method signature
*/
public static String methodSignature(Method method) {
StringBuilder builder = new StringBuilder();
// Type parameters
TypeVariable>[] typeParams = method.getTypeParameters();
if (typeParams.length > 0) {
builder.append(TYPE_PARAM_DEL_START);
for (TypeVariable> typeParam : typeParams) {
typeParameter(typeParam, builder);
}
builder.append(TYPE_PARAM_DEL_END);
}
// Formal parameters
Type[] params = method.getGenericParameterTypes();
builder.append('(');
if (params.length > 0) {
for (Type paramType : params) {
javaType(paramType, builder);
}
}
builder.append(')');
// Return type
javaType(method.getGenericReturnType(), builder);
// Throws
Type[] exceptions = method.getGenericExceptionTypes();
if (exceptions.length > 0) {
// "If the throws clause of a method or constructor declaration does not involve type variables, then a compiler may treat the declaration as having no throws clause for the purpose of emitting a method signature."
// Note that it's only possible to use a type parameter in a throws clause
for (Type exceptionType : exceptions) {
builder.append('^');
javaType(exceptionType, builder);
}
}
return builder.toString();
}
/**
* TypeParameter
*
* @param typeVariable
* @param builder
*/
private static void typeParameter(TypeVariable> typeVariable, StringBuilder builder) {
builder.append(typeVariable.getName());
Type[] bounds = typeVariable.getBounds();
if (bounds.length > 0) {
for (int i = 0; i < bounds.length; i++) {
// If the first bound is an interface, add additional colon to comply with the spec (ClassBound is not optional)
if (i == 0 && getTypeParamBoundRawType(bounds[i]).isInterface()) {
builder.append(COLON);
}
builder.append(COLON);
javaType(bounds[i], builder);
}
} else {
// If no upper bound is declared, the upper bound is java.lang.Object
builder.append(COLON);
javaType(Object.class, builder);
}
}
/**
* JavaTypeSignature
*
* @param type
* @param builder
*/
private static void javaType(Type type, StringBuilder builder) {
if (type instanceof Class) {
nonGenericType((Class>) type, builder);
} else if (type instanceof ParameterizedType) {
parameterizedType((ParameterizedType) type, builder);
} else if (type instanceof GenericArrayType) {
GenericArrayType genericArrayType = (GenericArrayType) type;
builder.append('[');
javaType(genericArrayType.getGenericComponentType(), builder);
} else if (type instanceof WildcardType) {
wildcardType((WildcardType) type, builder);
} else if (type instanceof TypeVariable) {
typeVariable((TypeVariable>) type, builder);
} else {
throw new IllegalArgumentException("Signature encoding error - unsupported type: " + type);
}
}
/**
* Note that Java language does not support more than one upper/lower bound.
*
* @param wildcard
* @param builder
*/
private static void wildcardType(WildcardType wildcard, StringBuilder builder) {
if (wildcard.getLowerBounds().length > 0) {
for (Type lowerBound : wildcard.getLowerBounds()) {
builder.append(WILDCARD_LOWER_BOUND);
javaType(lowerBound, builder);
}
} else {
if (wildcard.getUpperBounds().length == 0 || (wildcard.getUpperBounds().length == 1 && Object.class.equals(wildcard.getUpperBounds()[0]))) {
// If no upper bound is explicitly declared, the upper bound is java.lang.Object
// It's not clear whether an empty array may be returned
builder.append(WILDCARD_NO_BOUND);
} else {
for (Type upperBound : wildcard.getUpperBounds()) {
builder.append(WILDCARD_UPPER_BOUND);
javaType(upperBound, builder);
}
}
}
}
private static void typeVariable(TypeVariable> typeVariable, StringBuilder builder) {
builder.append('T');
builder.append(typeVariable.getName());
builder.append(SEMICOLON);
}
private static void parameterizedType(ParameterizedType parameterizedType, StringBuilder builder) {
Type rawType = parameterizedType.getRawType();
if (rawType instanceof Class) {
builder.append(classTypeBase(((Class>) rawType).getName()));
} else {
throw new IllegalStateException(String.format("Signature encoding error - unsupported raw type: %s of parameterized type: %s", parameterizedType,
rawType));
}
builder.append(TYPE_PARAM_DEL_START);
for (Type actualTypeArgument : parameterizedType.getActualTypeArguments()) {
javaType(actualTypeArgument, builder);
}
builder.append(TYPE_PARAM_DEL_END);
builder.append(SEMICOLON);
}
/**
* BaseType, ClassTypeSignature or ArrayTypeSignature
*
* @param clazz
*/
private static void nonGenericType(Class> clazz, StringBuilder builder) {
if (void.class.equals(clazz)) {
builder.append(VOID_CLASS_DESCRIPTOR);
} else if (byte.class.equals(clazz)) {
builder.append(BYTE_CLASS_DESCRIPTOR);
} else if (char.class.equals(clazz)) {
builder.append(CHAR_CLASS_DESCRIPTOR);
} else if (double.class.equals(clazz)) {
builder.append(DOUBLE_CLASS_DESCRIPTOR);
} else if (float.class.equals(clazz)) {
builder.append(FLOAT_CLASS_DESCRIPTOR);
} else if (int.class.equals(clazz)) {
builder.append(INT_CLASS_DESCRIPTOR);
} else if (long.class.equals(clazz)) {
builder.append(LONG_CLASS_DESCRIPTOR);
} else if (short.class.equals(clazz)) {
builder.append(SHORT_CLASS_DESCRIPTOR);
} else if (boolean.class.equals(clazz)) {
builder.append(BOOLEAN_CLASS_DESCRIPTOR);
} else if (clazz.isArray()) {
builder.append(encodeClassName(clazz.getName()));
} else {
builder.append(classTypeBase(clazz.getName()) + SEMICOLON);
}
}
/**
* ClassTypeSignature base
*
* @param clazz
* @param builder
*/
private static String classTypeBase(String className) {
return 'L' + encodeClassName(className);
}
private static String encodeClassName(String className) {
return className.replace('.', '/');
}
@SuppressWarnings("unchecked")
private static Class getTypeParamBoundRawType(Type type) {
if (type instanceof Class>) {
return (Class) type;
}
if (type instanceof ParameterizedType) {
if (((ParameterizedType) type).getRawType() instanceof Class>) {
return (Class) ((ParameterizedType) type).getRawType();
}
}
if (type instanceof TypeVariable>) {
TypeVariable> variable = (TypeVariable>) type;
Type[] bounds = variable.getBounds();
return getBound(bounds);
}
throw new IllegalStateException("Signature encoding error - unexpected type parameter bound type: " + type);
}
@SuppressWarnings("unchecked")
private static Class getBound(Type[] bounds) {
if (bounds.length == 0) {
return (Class) Object.class;
} else {
return getTypeParamBoundRawType(bounds[0]);
}
}
}
jboss-classfilewriter-1.2.5.Final/src/test/ 0000775 0000000 0000000 00000000000 14046606623 0020644 5 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/ 0000775 0000000 0000000 00000000000 14046606623 0021565 5 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/ 0000775 0000000 0000000 00000000000 14046606623 0022354 5 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/ 0000775 0000000 0000000 00000000000 14046606623 0023474 5 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/ 0000775 0000000 0000000 00000000000 14046606623 0026676 5 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/ 0000775 0000000 0000000 00000000000 14046606623 0027655 5 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/annotation/ 0000775 0000000 0000000 00000000000 14046606623 0032027 5 ustar 00root root 0000000 0000000 AnnotationArrayValuedAnnotation.java 0000664 0000000 0000000 00000001612 14046606623 0041120 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/annotation /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnotationArrayValuedAnnotation {
IntValuedAnnotation[] value();
}
AnnotationTester.java 0000664 0000000 0000000 00000004212 14046606623 0036113 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/annotation /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.jboss.classfilewriter.ClassFile;
import org.jboss.classfilewriter.ClassMethod;
/**
* Utility class for testing annotation bytecode
*
* @author Stuart Douglas
*
*/
public class AnnotationTester {
private static int count = 0;
private static final String NAME = "com.test.AnnotationTest";
public static Field testFieldAnnotations(Class> clazz, String name) {
try {
ClassFile file = new ClassFile(NAME + count++, Object.class.getName(), AnnotationTester.class.getClassLoader());
Field field = clazz.getDeclaredField(name);
file.addField(field);
Class> newClass = file.define();
return newClass.getDeclaredField(name);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static Method testMethodAnnotations(Class> clazz, String name) {
try {
ClassFile file = new ClassFile(NAME + count++, Object.class.getName(), AnnotationTester.class.getClassLoader());
Method method = clazz.getDeclaredMethod(name, String.class);
ClassMethod cmeth = file.addMethod(method);
cmeth.getCodeAttribute().returnInstruction();
Class> newClass = file.define();
return newClass.getDeclaredMethod(name, String.class);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
AnnotationValuedAnnotation.java 0000664 0000000 0000000 00000001603 14046606623 0040121 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/annotation /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnotationValuedAnnotation {
IntValuedAnnotation value();
}
ClassArrayValuedAnnotation.java 0000664 0000000 0000000 00000001572 14046606623 0040060 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/annotation /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface ClassArrayValuedAnnotation {
Class>[] value();
}
ClassValuedAnnotation.java 0000664 0000000 0000000 00000001563 14046606623 0037061 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/annotation /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface ClassValuedAnnotation {
Class> value();
}
EnumValuedAnnotation.java 0000664 0000000 0000000 00000001645 14046606623 0036721 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/annotation /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface EnumValuedAnnotation {
SimpleEnum value();
enum SimpleEnum {
A, B, C, D
}
}
FieldAnnotationClass.java 0000664 0000000 0000000 00000002551 14046606623 0036662 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/annotation /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.annotation;
import java.util.concurrent.TimeUnit;
public class FieldAnnotationClass {
@IntValuedAnnotation(value = 10)
public String intField;
@ClassValuedAnnotation(String.class)
public String classField;
@EnumValuedAnnotation(EnumValuedAnnotation.SimpleEnum.C)
public String enumField;
@TimeUnitValuedAnnotation(TimeUnit.SECONDS)
public String timeUnitField;
@AnnotationValuedAnnotation(@IntValuedAnnotation(20))
public String annotationField;
@IntArrayAnnotation( { 1, 2, 3 })
public String intArrayField;
@AnnotationArrayValuedAnnotation( { @IntValuedAnnotation(10), @IntValuedAnnotation(20) })
public String annotationArrayField;
}
FieldAnnotationTest.java 0000664 0000000 0000000 00000007275 14046606623 0036544 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/annotation /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.annotation;
import java.lang.reflect.Field;
import java.util.concurrent.TimeUnit;
import org.junit.Assert;
import org.junit.Test;
public class FieldAnnotationTest {
@Test
public void testIntFieldAnnotation() {
Field field = AnnotationTester.testFieldAnnotations(FieldAnnotationClass.class, "intField");
Assert.assertEquals(1, field.getDeclaredAnnotations().length);
Assert.assertEquals(10, ((IntValuedAnnotation) field.getDeclaredAnnotations()[0]).value());
}
@Test
public void testClassFieldAnnotation() {
Field field = AnnotationTester.testFieldAnnotations(FieldAnnotationClass.class, "classField");
Assert.assertEquals(1, field.getDeclaredAnnotations().length);
Assert.assertEquals(String.class, ((ClassValuedAnnotation) field.getDeclaredAnnotations()[0]).value());
}
@Test
public void testEnumFieldAnnotation() {
Field field = AnnotationTester.testFieldAnnotations(FieldAnnotationClass.class, "enumField");
Assert.assertEquals(1, field.getDeclaredAnnotations().length);
Assert.assertEquals(EnumValuedAnnotation.SimpleEnum.C, ((EnumValuedAnnotation) field.getDeclaredAnnotations()[0]).value());
}
/**
* the members of TimeUnit are actually inner classes, and isEnum returns false
*/
@Test
public void testTimeUnitEnumFieldAnnotation() {
Field field = AnnotationTester.testFieldAnnotations(FieldAnnotationClass.class, "timeUnitField");
Assert.assertEquals(1, field.getDeclaredAnnotations().length);
Assert.assertEquals(TimeUnit.SECONDS, ((TimeUnitValuedAnnotation) field.getDeclaredAnnotations()[0]).value());
}
@Test
public void testAnnotationFieldAnnotation() {
Field field = AnnotationTester.testFieldAnnotations(FieldAnnotationClass.class, "annotationField");
Assert.assertEquals(1, field.getDeclaredAnnotations().length);
Assert.assertEquals(20, ((AnnotationValuedAnnotation) field.getDeclaredAnnotations()[0]).value().value());
}
@Test
public void testIntArrayFieldAnnotation() {
Field field = AnnotationTester.testFieldAnnotations(FieldAnnotationClass.class, "intArrayField");
Assert.assertEquals(1, field.getDeclaredAnnotations().length);
Assert.assertEquals(1, ((IntArrayAnnotation) field.getDeclaredAnnotations()[0]).value()[0]);
Assert.assertEquals(2, ((IntArrayAnnotation) field.getDeclaredAnnotations()[0]).value()[1]);
Assert.assertEquals(3, ((IntArrayAnnotation) field.getDeclaredAnnotations()[0]).value()[2]);
}
@Test
public void testAnnotationArrayFieldAnnotation() {
Field field = AnnotationTester.testFieldAnnotations(FieldAnnotationClass.class, "annotationArrayField");
Assert.assertEquals(1, field.getDeclaredAnnotations().length);
Assert.assertEquals(10, ((AnnotationArrayValuedAnnotation) field.getDeclaredAnnotations()[0]).value()[0].value());
Assert.assertEquals(20, ((AnnotationArrayValuedAnnotation) field.getDeclaredAnnotations()[0]).value()[1].value());
}
}
IntArrayAnnotation.java 0000664 0000000 0000000 00000001555 14046606623 0036405 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/annotation /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface IntArrayAnnotation {
int[] value();
}
IntValuedAnnotation.java 0000664 0000000 0000000 00000001554 14046606623 0036546 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/annotation /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface IntValuedAnnotation {
int value();
}
MethodAnnotationClass.java 0000664 0000000 0000000 00000003741 14046606623 0037061 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/annotation /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.annotation;
public class MethodAnnotationClass {
@IntValuedAnnotation(value = 10)
public void intMethod(@IntValuedAnnotation(value = 10) String p) {
}
@ClassValuedAnnotation(void.class)
public void classMethod(@ClassValuedAnnotation(void.class) String p) {
}
@EnumValuedAnnotation(EnumValuedAnnotation.SimpleEnum.C)
public void enumMethod(@EnumValuedAnnotation(EnumValuedAnnotation.SimpleEnum.C) String p) {
}
@AnnotationValuedAnnotation(@IntValuedAnnotation(20))
public void annotationMethod(@AnnotationValuedAnnotation(@IntValuedAnnotation(20)) String p) {
}
@IntArrayAnnotation( { 1, 2, 3 })
public void intArrayMethod(@IntArrayAnnotation( { 1, 2, 3 }) String p) {
}
@AnnotationArrayValuedAnnotation( { @IntValuedAnnotation(10), @IntValuedAnnotation(20) })
public void annotationArrayMethod(
@AnnotationArrayValuedAnnotation( { @IntValuedAnnotation(10), @IntValuedAnnotation(20) }) String p) {
}
@ClassArrayValuedAnnotation( { String.class, int.class, Object.class })
public void classArrayMethod(@ClassArrayValuedAnnotation( { String.class, int.class, Object.class }) String p) {
}
@StringValuedAnnotation(comment = "string")
public void stringMethod(@StringValuedAnnotation(comment = "string") String p ) {
}
}
MethodAnnotationTest.java 0000664 0000000 0000000 00000014057 14046606623 0036735 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/annotation /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.annotation;
import java.lang.reflect.Method;
import org.junit.Assert;
import org.junit.Test;
public class MethodAnnotationTest {
@Test
public void testIntMethodAnnotation() {
Method method = AnnotationTester.testMethodAnnotations(MethodAnnotationClass.class, "intMethod");
Assert.assertEquals(1, method.getDeclaredAnnotations().length);
Assert.assertEquals(10, ((IntValuedAnnotation) method.getDeclaredAnnotations()[0]).value());
Assert.assertEquals(1, method.getParameterAnnotations()[0].length);
Assert.assertEquals(10, ((IntValuedAnnotation) method.getParameterAnnotations()[0][0]).value());
}
@Test
public void testStringMethodAnnotation() {
Method method = AnnotationTester.testMethodAnnotations(MethodAnnotationClass.class, "stringMethod");
Assert.assertEquals(1, method.getDeclaredAnnotations().length);
Assert.assertEquals("string", ((StringValuedAnnotation) method.getDeclaredAnnotations()[0]).comment());
Assert.assertEquals(1, method.getParameterAnnotations()[0].length);
Assert.assertEquals("string", ((StringValuedAnnotation) method.getParameterAnnotations()[0][0]).comment());
}
@Test
public void testClassMethodAnnotation() {
Method method = AnnotationTester.testMethodAnnotations(MethodAnnotationClass.class, "classMethod");
Assert.assertEquals(1, method.getDeclaredAnnotations().length);
Assert.assertEquals(void.class, ((ClassValuedAnnotation) method.getDeclaredAnnotations()[0]).value());
Assert.assertEquals(1, method.getParameterAnnotations()[0].length);
Assert.assertEquals(void.class, ((ClassValuedAnnotation) method.getParameterAnnotations()[0][0]).value());
}
@Test
public void testEnumMethodAnnotation() {
Method method = AnnotationTester.testMethodAnnotations(MethodAnnotationClass.class, "enumMethod");
Assert.assertEquals(1, method.getDeclaredAnnotations().length);
Assert.assertEquals(EnumValuedAnnotation.SimpleEnum.C, ((EnumValuedAnnotation) method.getDeclaredAnnotations()[0]).value());
Assert.assertEquals(1, method.getParameterAnnotations()[0].length);
Assert.assertEquals(EnumValuedAnnotation.SimpleEnum.C, ((EnumValuedAnnotation) method.getParameterAnnotations()[0][0]).value());
}
@Test
public void testAnnotationMethodAnnotation() {
Method method = AnnotationTester.testMethodAnnotations(MethodAnnotationClass.class, "annotationMethod");
Assert.assertEquals(1, method.getDeclaredAnnotations().length);
Assert.assertEquals(20, ((AnnotationValuedAnnotation) method.getDeclaredAnnotations()[0]).value().value());
Assert.assertEquals(1, method.getParameterAnnotations()[0].length);
Assert.assertEquals(20, ((AnnotationValuedAnnotation) method.getParameterAnnotations()[0][0]).value().value());
}
@Test
public void testIntArrayMethodAnnotation() {
Method method = AnnotationTester.testMethodAnnotations(MethodAnnotationClass.class, "intArrayMethod");
Assert.assertEquals(1, method.getDeclaredAnnotations().length);
Assert.assertEquals(1, ((IntArrayAnnotation) method.getDeclaredAnnotations()[0]).value()[0]);
Assert.assertEquals(2, ((IntArrayAnnotation) method.getDeclaredAnnotations()[0]).value()[1]);
Assert.assertEquals(3, ((IntArrayAnnotation) method.getDeclaredAnnotations()[0]).value()[2]);
Assert.assertEquals(1, method.getParameterAnnotations()[0].length);
Assert.assertEquals(1, ((IntArrayAnnotation) method.getParameterAnnotations()[0][0]).value()[0]);
Assert.assertEquals(2, ((IntArrayAnnotation) method.getParameterAnnotations()[0][0]).value()[1]);
Assert.assertEquals(3, ((IntArrayAnnotation) method.getParameterAnnotations()[0][0]).value()[2]);
}
@Test
public void testAnnotationArrayMethodAnnotation() {
Method method = AnnotationTester.testMethodAnnotations(MethodAnnotationClass.class, "annotationArrayMethod");
Assert.assertEquals(1, method.getDeclaredAnnotations().length);
Assert.assertEquals(10, ((AnnotationArrayValuedAnnotation) method.getDeclaredAnnotations()[0]).value()[0].value());
Assert.assertEquals(20, ((AnnotationArrayValuedAnnotation) method.getDeclaredAnnotations()[0]).value()[1].value());
Assert.assertEquals(1, method.getParameterAnnotations()[0].length);
Assert.assertEquals(10, ((AnnotationArrayValuedAnnotation) method.getParameterAnnotations()[0][0]).value()[0].value());
Assert.assertEquals(20, ((AnnotationArrayValuedAnnotation) method.getParameterAnnotations()[0][0]).value()[1].value());
}
@Test
public void testClassArrayMethodAnnotation() {
Method method = AnnotationTester.testMethodAnnotations(MethodAnnotationClass.class, "classArrayMethod");
Assert.assertEquals(1, method.getDeclaredAnnotations().length);
Assert.assertEquals(String.class, ((ClassArrayValuedAnnotation) method.getDeclaredAnnotations()[0]).value()[0]);
Assert.assertEquals(int.class, ((ClassArrayValuedAnnotation) method.getDeclaredAnnotations()[0]).value()[1]);
Assert.assertEquals(1, method.getParameterAnnotations()[0].length);
Assert.assertEquals(String.class, ((ClassArrayValuedAnnotation) method.getParameterAnnotations()[0][0]).value()[0]);
Assert.assertEquals(int.class, ((ClassArrayValuedAnnotation) method.getParameterAnnotations()[0][0]).value()[1]);
}
}
StringValuedAnnotation.java 0000664 0000000 0000000 00000001627 14046606623 0037263 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/annotation /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* @author Stuart Douglas
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface StringValuedAnnotation {
String comment();
}
TimeUnitValuedAnnotation.java 0000664 0000000 0000000 00000001634 14046606623 0037551 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/annotation /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.concurrent.TimeUnit;
@Retention(RetentionPolicy.RUNTIME)
public @interface TimeUnitValuedAnnotation {
TimeUnit value();
}
jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/ 0000775 0000000 0000000 00000000000 14046606623 0031453 5 ustar 00root root 0000000 0000000 MethodTester.java 0000664 0000000 0000000 00000006447 14046606623 0034661 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode;
import java.io.FileOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.jboss.classfilewriter.AccessFlag;
import org.jboss.classfilewriter.ClassFile;
import org.jboss.classfilewriter.ClassMethod;
import org.jboss.classfilewriter.JavaVersions;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.util.DescriptorUtils;
/**
* Utility class for testing method bytecode
*
* @author Stuart Douglas
*
*/
public class MethodTester {
private static int methodNo;
private final ClassMethod method;
private boolean created = false;
private Method createdMethod;
public MethodTester(Class returnType, Class>... params) {
ClassFile file = new ClassFile("org.jboss.classwriter.test.GeneratedClass" + methodNo++, AccessFlag.PUBLIC, "java.lang.Object", JavaVersions.JAVA_7, getClass().getClassLoader());
String[] nparams = new String[params.length];
for(int i = 0; i < params.length;++i){
nparams[i] = DescriptorUtils.makeDescriptor(params[i]);
}
method = file.addMethod(AccessFlag.of(AccessFlag.PUBLIC, AccessFlag.STATIC), "method", DescriptorUtils
.makeDescriptor(returnType), nparams);
}
public CodeAttribute getCodeAttribute() {
return method.getCodeAttribute();
}
public T invoke(Object... params) {
if (!created) {
create();
}
try {
return (T) createdMethod.invoke(null, params);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
public Method getMethod() {
if (!created) {
create();
}
return createdMethod;
}
private void create() {
created = true;
Class> clazz = method.getClassFile().define();
for (Method i : clazz.getDeclaredMethods()) {
if (i.getName().equals("method")) {
createdMethod = i;
break;
}
}
if (createdMethod == null) {
throw new RuntimeException("Created method not found on class");
}
}
public void dump() {
try {
FileOutputStream st = new FileOutputStream("/tmp/dump.class");
st.write(this.method.getClassFile().toBytecode());
st.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
SomeInterface.java 0000664 0000000 0000000 00000001432 14046606623 0034763 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode;
public interface SomeInterface {
void setInt(int value);
long incrementLong(long value);
}
jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/a/ 0000775 0000000 0000000 00000000000 14046606623 0031673 5 ustar 00root root 0000000 0000000 AaloadTest.java 0000664 0000000 0000000 00000002525 14046606623 0034504 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/a /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.a;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class AaloadTest {
public static final Integer[] VALUE = { 2, 3, 4 };
@Test
public void testAaload() {
MethodTester mt = new MethodTester(Integer.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.getstatic(getClass().getName(), "VALUE", "[Ljava/lang/Integer;");
ca.iconst(1);
ca.aaload();
ca.checkcast("java.lang.Integer");
ca.returnInstruction();
Assert.assertEquals(3, (int) mt.invoke());
}
}
AastoreTest.java 0000664 0000000 0000000 00000002561 14046606623 0034721 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/a /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.a;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class AastoreTest {
public static final Class>[] VALUE = { null, null, null };
@Test
public void testAastore() {
MethodTester mt = new MethodTester(void.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.getstatic(getClass().getName(), "VALUE", "[Ljava/lang/Class;");
ca.iconst(1);
ca.loadType("Ljava/lang/Integer;");
ca.aastore();
ca.returnInstruction();
mt.invoke();
Assert.assertEquals(Integer.class, VALUE[1]);
}
}
AconstNullTest.java 0000664 0000000 0000000 00000002225 14046606623 0035402 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/a /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.a;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class AconstNullTest {
@Test
public void testAaload() {
MethodTester mt = new MethodTester(Integer.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.aconstNull();
ca.returnInstruction();
Assert.assertEquals(null, mt.invoke());
}
}
AloadTest.java 0000664 0000000 0000000 00000002435 14046606623 0034343 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/a /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.a;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class AloadTest {
public static final Integer VALUE = 10;
@Test
public void testAload() {
MethodTester mt = new MethodTester(Integer.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.getstatic(getClass().getName(), "VALUE", "Ljava/lang/Integer;");
ca.astore(0);
ca.aload(0);
ca.returnInstruction();
Assert.assertEquals(10, (int) mt.invoke());
}
}
AnewarrayTest.java 0000664 0000000 0000000 00000002571 14046606623 0035255 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/a /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.a;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class AnewarrayTest {
public static Integer[] VALUE;
@Test
public void testAnewarray() {
MethodTester mt = new MethodTester(Void.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.iconst(10);
ca.anewarray("java.lang.Integer");
ca.putstatic(getClass().getName(), "VALUE", "[Ljava/lang/Integer;");
ca.aconstNull();
ca.returnInstruction();
mt.invoke();
Assert.assertNotNull(VALUE);
Assert.assertEquals(10, VALUE.length);
}
}
ArraylengthTest.java 0000664 0000000 0000000 00000002431 14046606623 0035577 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/a /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.a;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class ArraylengthTest {
public static Integer[] VALUE = { 1, 2, 3 };
@Test
public void testArraylength() {
MethodTester mt = new MethodTester(int.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.getstatic(getClass().getName(), "VALUE", "[Ljava/lang/Integer;");
ca.arraylength();
ca.returnInstruction();
Assert.assertEquals(3, (int) mt.invoke());
}
}
AthrowTest.java 0000664 0000000 0000000 00000003117 14046606623 0034565 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/a /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.a;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class AthrowTest {
public static final Integer[] VALUE = { 2, 3, 4 };
@Test
public void testAthrow() {
try {
MethodTester mt = new MethodTester(Integer.class, TestException.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.aload(0);
ca.athrow();
mt.invoke(new TestException());
Assert.fail();
} catch (RuntimeException e) {
// runtime error wrapping IvocationTargetException wrapping TestException
if (e.getCause().getCause().getClass() != TestException.class) {
Assert.fail();
}
}
}
private static class TestException extends RuntimeException {
}
}
jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/b/ 0000775 0000000 0000000 00000000000 14046606623 0031674 5 ustar 00root root 0000000 0000000 BaloadTest.java 0000664 0000000 0000000 00000002421 14046606623 0034501 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/b /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.b;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class BaloadTest {
public static final byte[] VALUE = { 2, 3, 4 };
@Test
public void testBaload() {
MethodTester mt = new MethodTester(int.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.getstatic(getClass().getName(), "VALUE", "[B");
ca.iconst(1);
ca.baload();
ca.returnInstruction();
Assert.assertEquals(3, (int) mt.invoke());
}
}
BastoreTest.java 0000664 0000000 0000000 00000002464 14046606623 0034725 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/b /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.b;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class BastoreTest {
public static final byte[] VALUE = { 0, 0, 0 };
@Test
public void testBastore() {
MethodTester mt = new MethodTester(void.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.getstatic(getClass().getName(), "VALUE", "[B");
ca.iconst(1);
ca.iconst(30);
ca.bastore();
ca.returnInstruction();
mt.invoke();
Assert.assertEquals(30, VALUE[1]);
}
}
BipushTest.java 0000664 0000000 0000000 00000002220 14046606623 0034546 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/b /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.b;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class BipushTest {
@Test
public void testBipush() {
MethodTester mt = new MethodTester(byte.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.bipush((byte) 2);
ca.returnInstruction();
Assert.assertEquals(2, (int) mt.invoke());
}
}
jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/c/ 0000775 0000000 0000000 00000000000 14046606623 0031675 5 ustar 00root root 0000000 0000000 CaloadTest.java 0000664 0000000 0000000 00000002421 14046606623 0034503 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/c /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.c;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class CaloadTest {
public static final char[] VALUE = { 2, 3, 4 };
@Test
public void testCaload() {
MethodTester mt = new MethodTester(int.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.getstatic(getClass().getName(), "VALUE", "[C");
ca.iconst(1);
ca.caload();
ca.returnInstruction();
Assert.assertEquals(3, (int) mt.invoke());
}
}
CastoreTest.java 0000664 0000000 0000000 00000002464 14046606623 0034727 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/c /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.c;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class CastoreTest {
public static final char[] VALUE = { 0, 0, 0 };
@Test
public void testCastore() {
MethodTester mt = new MethodTester(void.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.getstatic(getClass().getName(), "VALUE", "[C");
ca.iconst(1);
ca.iconst(30);
ca.castore();
ca.returnInstruction();
mt.invoke();
Assert.assertEquals(30, VALUE[1]);
}
}
CheckcastTest.java 0000664 0000000 0000000 00000002460 14046606623 0035213 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/c /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.c;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class CheckcastTest {
public static final Number VALUE = new Integer(10);
@Test
public void testCheckcast() {
MethodTester mt = new MethodTester(Integer.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.getstatic(getClass().getName(), "VALUE", "Ljava/lang/Number;");
ca.checkcast("java.lang.Integer");
ca.returnInstruction();
Assert.assertEquals(10, (int) mt.invoke());
}
}
jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/d/ 0000775 0000000 0000000 00000000000 14046606623 0031676 5 ustar 00root root 0000000 0000000 D2fTest.java 0000664 0000000 0000000 00000002247 14046606623 0033742 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/d /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.d;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class D2fTest {
@Test
public void d2fTest() {
MethodTester mt = new MethodTester(float.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.ldc2((double) 0);
ca.d2f();
ca.returnInstruction();
Assert.assertEquals(0.0f, (double)mt.invoke(), 0);
}
}
D2iTest.java 0000664 0000000 0000000 00000002241 14046606623 0033737 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/d /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.d;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class D2iTest {
@Test
public void d2fTest() {
MethodTester mt = new MethodTester(int.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.ldc2((double) 0);
ca.d2i();
ca.returnInstruction();
Assert.assertEquals(0, (int) mt.invoke());
}
}
D2lTest.java 0000664 0000000 0000000 00000002235 14046606623 0033745 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/d /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.d;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class D2lTest {
@Test
public void d2lTest() {
MethodTester mt = new MethodTester(long.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.ldc2((double) 0);
ca.d2l();
ca.returnInstruction();
Assert.assertEquals(0, (long) mt.invoke());
}
}
DaddTest.java 0000664 0000000 0000000 00000002325 14046606623 0034160 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/d /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.d;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class DaddTest {
@Test
public void daddTest() {
MethodTester mt = new MethodTester(double.class, double.class, double.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.dload(0);
ca.dload(2);
ca.dadd();
ca.returnInstruction();
Assert.assertEquals(2.0, mt.invoke(1.0, 1.0), 0);
}
}
DaloadTest.java 0000664 0000000 0000000 00000002431 14046606623 0034506 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/d /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.d;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class DaloadTest {
public static final double[] VALUE = { 2.0, 3.0, 4.0 };
@Test
public void testDaload() {
MethodTester mt = new MethodTester(double.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.getstatic(getClass().getName(), "VALUE", "[D");
ca.iconst(1);
ca.daload();
ca.returnInstruction();
Assert.assertEquals(3.0, mt.invoke(), 0);
}
}
DastoreTest.java 0000664 0000000 0000000 00000002471 14046606623 0034727 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/d /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.d;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class DastoreTest {
public static final double[] VALUE = { 0, 0, 0 };
@Test
public void testDastore() {
MethodTester mt = new MethodTester(void.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.getstatic(getClass().getName(), "VALUE", "[D");
ca.iconst(1);
ca.ldc2(1.0);
ca.dastore();
ca.returnInstruction();
mt.invoke();
Assert.assertEquals(1.0, VALUE[1], 0);
}
}
DcmpgTest.java 0000664 0000000 0000000 00000002621 14046606623 0034355 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/d /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.d;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class DcmpgTest {
@Test
public void dcmpgTest() {
MethodTester mt = new MethodTester(int.class, double.class, double.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.dload(0);
ca.dload(2);
ca.dcmpg();
ca.returnInstruction();
Assert.assertEquals(0, (int) mt.invoke(1.0, 1.0));
Assert.assertEquals(1, (int) mt.invoke(1.0, 0.0));
Assert.assertEquals(-1, (int) mt.invoke(0.0, 1.0));
Assert.assertEquals(1, (int) mt.invoke(Double.NaN, 1.0));
}
}
DcmplTest.java 0000664 0000000 0000000 00000002622 14046606623 0034363 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/d /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.d;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class DcmplTest {
@Test
public void dcmplTest() {
MethodTester mt = new MethodTester(int.class, double.class, double.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.dload(0);
ca.dload(2);
ca.dcmpl();
ca.returnInstruction();
Assert.assertEquals(0, (int) mt.invoke(1.0, 1.0));
Assert.assertEquals(1, (int) mt.invoke(1.0, 0.0));
Assert.assertEquals(-1, (int) mt.invoke(0.0, 1.0));
Assert.assertEquals(-1, (int) mt.invoke(Double.NaN, 1.0));
}
}
DconstTest.java 0000664 0000000 0000000 00000002214 14046606623 0034553 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/d /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.d;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class DconstTest {
@Test
public void testDconst() {
MethodTester mt = new MethodTester(double.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.dconst(1);
ca.returnInstruction();
Assert.assertEquals(1.0, mt.invoke(), 0);
}
}
DdivTest.java 0000664 0000000 0000000 00000002437 14046606623 0034216 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/d /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.d;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class DdivTest {
@Test
public void ddivTest() {
MethodTester mt = new MethodTester(double.class, double.class, double.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.dload(0);
ca.dload(2);
ca.ddiv();
ca.returnInstruction();
Assert.assertEquals(10.0 / 5.0, mt.invoke(10.0, 5.0), 0);
Assert.assertEquals(12.0 / 2.0, mt.invoke(12.0, 2.0), 0);
}
}
DloadTest.java 0000664 0000000 0000000 00000002234 14046606623 0034346 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/d /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.d;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class DloadTest {
@Test
public void testDload() {
MethodTester mt = new MethodTester(double.class, double.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.dload(0);
ca.returnInstruction();
Assert.assertEquals(10.0, mt.invoke(10.0), 0);
}
}
DmulTest.java 0000664 0000000 0000000 00000002440 14046606623 0034223 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/d /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.d;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class DmulTest {
@Test
public void dmnulTest() {
MethodTester mt = new MethodTester(double.class, double.class, double.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.dload(0);
ca.dload(2);
ca.dmul();
ca.returnInstruction();
Assert.assertEquals(10.0 * 5.0, mt.invoke(10.0, 5.0), 0);
Assert.assertEquals(12.0 * 2.0, mt.invoke(12.0, 2.0), 0);
}
}
DnegTest.java 0000664 0000000 0000000 00000002254 14046606623 0034202 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/d /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.d;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class DnegTest {
@Test
public void dnegTest() {
MethodTester mt = new MethodTester(double.class, double.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.dload(0);
ca.dneg();
ca.returnInstruction();
Assert.assertEquals(-1.0, mt.invoke(1), 0);
}
}
DremTest.java 0000664 0000000 0000000 00000002437 14046606623 0034217 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/d /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.d;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class DremTest {
@Test
public void ddivTest() {
MethodTester mt = new MethodTester(double.class, double.class, double.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.dload(0);
ca.dload(2);
ca.drem();
ca.returnInstruction();
Assert.assertEquals(10.0 % 5.0, mt.invoke(10.0, 5.0), 0);
Assert.assertEquals(13.0 % 2.0, mt.invoke(13.0, 2.0), 0);
}
}
DstoreTest.java 0000664 0000000 0000000 00000002270 14046606623 0034563 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/d /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.d;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class DstoreTest {
@Test
public void testDtore() {
MethodTester mt = new MethodTester(double.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.dconst(1.0);
ca.dstore(0);
ca.dload(0);
ca.returnInstruction();
Assert.assertEquals(1.0, mt.invoke(), 0);
}
}
DsubTest.java 0000664 0000000 0000000 00000002437 14046606623 0034225 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/d /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.d;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class DsubTest {
@Test
public void dsubTest() {
MethodTester mt = new MethodTester(double.class, double.class, double.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.dload(0);
ca.dload(2);
ca.dsub();
ca.returnInstruction();
Assert.assertEquals(10.0 - 5.0, mt.invoke(10.0, 5.0), 0);
Assert.assertEquals(12.0 - 2.0, mt.invoke(12.0, 2.0), 0);
}
}
Dup2Test.java 0000664 0000000 0000000 00000003001 14046606623 0034126 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/d /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.d;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class Dup2Test {
@Test
public void dup2Test() {
MethodTester mt = new MethodTester(int.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.iconst(1);
ca.iconst(2);
ca.dup2();
ca.pop2();
ca.returnInstruction();
Assert.assertEquals(2, (int) mt.invoke());
}
@Test
public void dup2WideTest() {
MethodTester mt = new MethodTester(double.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.dconst(0);
ca.dup2();
ca.pop2();
ca.returnInstruction();
Assert.assertEquals(0.0, mt.invoke(), 0);
}
}
Dup2X1Test.java 0000664 0000000 0000000 00000003133 14046606623 0034345 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/d /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.d;
import org.junit.Assert;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class Dup2X1Test {
@Test
public void dup2X1Test() {
MethodTester mt = new MethodTester(int.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.iconst(2);
ca.iconst(1);
ca.iconst(2);
ca.dup2X1();
ca.pop2();
ca.pop();
ca.returnInstruction();
Assert.assertEquals(2, (int) mt.invoke());
}
@Test
public void dup2X1WideTest() {
MethodTester mt = new MethodTester(double.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.iconst(0);
ca.dconst(0);
ca.dup2X1();
ca.pop2();
ca.pop();
ca.returnInstruction();
Assert.assertEquals(0.0, mt.invoke(), 0);
}
}
Dup2X2Test.java 0000664 0000000 0000000 00000006425 14046606623 0034355 0 ustar 00root root 0000000 0000000 jboss-classfilewriter-1.2.5.Final/src/test/java/org/jboss/classfilewriter/test/bytecode/d /*
* JBoss, Home of Professional Open Source.
*
* Copyright 2012 Red Hat, Inc.
*
* 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 org.jboss.classfilewriter.test.bytecode.d;
import org.junit.Assert;
import org.jboss.classfilewriter.InvalidBytecodeException;
import org.jboss.classfilewriter.code.CodeAttribute;
import org.jboss.classfilewriter.test.bytecode.MethodTester;
import org.junit.Test;
public class Dup2X2Test {
@Test
public void dup2X2Test() {
MethodTester mt = new MethodTester(int.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.iconst(0);
ca.iconst(0);
ca.iconst(1);
ca.iconst(2);
ca.dup2X2();
ca.pop2();
ca.pop2();
ca.returnInstruction();
Assert.assertEquals(2, (int) mt.invoke());
}
@Test
public void dup2X2WideTest() {
MethodTester mt = new MethodTester(double.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.dconst(0);
ca.dconst(0);
ca.dup2X2();
ca.pop2();
ca.pop2();
ca.returnInstruction();
Assert.assertEquals(0.0, mt.invoke(), 0);
}
@Test
public void dup2X2Wide2Test() {
MethodTester mt = new MethodTester(double.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.iconst(0);
ca.iconst(0);
ca.dconst(0);
ca.dup2X2();
ca.pop2();
ca.pop2();
ca.returnInstruction();
Assert.assertEquals(0.0, mt.invoke(), 0);
}
@Test
public void dup2X2Wide3Test() {
MethodTester mt = new MethodTester(int.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.dconst(0);
ca.iconst(0);
ca.iconst(1);
ca.dup2X2();
ca.pop2();
ca.pop2();
ca.returnInstruction();
Assert.assertEquals(1, (int) mt.invoke());
}
@Test(expected = InvalidBytecodeException.class)
public void dup2X2Wide4Test() {
MethodTester mt = new MethodTester(double.class);
CodeAttribute ca = mt.getCodeAttribute();
ca.dconst(0);
ca.dconst(0);
ca.iconst(1);
ca.dup2X2();
ca.pop2();
ca.pop2();
ca.returnInstruction();
Assert.assertEquals(0, mt.invoke(), 0);
}
@Test(expected = InvalidBytecodeException.class)
public void dup2X2Wide5Test() {
MethodTester mt = new MethodTester