diff --git a/contrib/asm/src/org/objectweb/asm/commons/LocalVariablesSorter.java b/contrib/asm/src/org/objectweb/asm/commons/LocalVariablesSorter.java new file mode 100644 index 00000000..295c319b --- /dev/null +++ b/contrib/asm/src/org/objectweb/asm/commons/LocalVariablesSorter.java @@ -0,0 +1,381 @@ +/*** + * ASM: a very small and fast Java bytecode manipulation framework + * Copyright (c) 2000-2011 INRIA, France Telecom + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.objectweb.asm.commons; + +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; +import org.objectweb.asm.TypePath; + +/** + * A {@link MethodVisitor} that renumbers local variables in their order of + * appearance. This adapter allows one to easily add new local variables to a + * method. It may be used by inheriting from this class, but the preferred way + * of using it is via delegation: the next visitor in the chain can indeed add + * new locals when needed by calling {@link #newLocal} on this adapter (this + * requires a reference back to this {@link LocalVariablesSorter}). + * + * @author Chris Nokleberg + * @author Eugene Kuleshov + * @author Eric Bruneton + */ +public class LocalVariablesSorter extends MethodVisitor { + + private static final Type OBJECT_TYPE = Type + .getObjectType("java/lang/Object"); + + /** + * Mapping from old to new local variable indexes. A local variable at index + * i of size 1 is remapped to 'mapping[2*i]', while a local variable at + * index i of size 2 is remapped to 'mapping[2*i+1]'. + */ + private int[] mapping = new int[40]; + + /** + * Array used to store stack map local variable types after remapping. + */ + private Object[] newLocals = new Object[20]; + + /** + * Index of the first local variable, after formal parameters. + */ + protected final int firstLocal; + + /** + * Index of the next local variable to be created by {@link #newLocal}. + */ + protected int nextLocal; + + /** + * Indicates if at least one local variable has moved due to remapping. + */ + private boolean changed; + + /** + * Creates a new {@link LocalVariablesSorter}. Subclasses must not use + * this constructor. Instead, they must use the + * {@link #LocalVariablesSorter(int, int, String, MethodVisitor)} version. + * + * @param access + * access flags of the adapted method. + * @param desc + * the method's descriptor (see {@link Type Type}). + * @param mv + * the method visitor to which this adapter delegates calls. + * @throws IllegalStateException + * If a subclass calls this constructor. + */ + public LocalVariablesSorter(final int access, final String desc, + final MethodVisitor mv) { + this(Opcodes.ASM5, access, desc, mv); + if (getClass() != LocalVariablesSorter.class) { + throw new IllegalStateException(); + } + } + + /** + * Creates a new {@link LocalVariablesSorter}. + * + * @param api + * the ASM API version implemented by this visitor. Must be one + * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. + * @param access + * access flags of the adapted method. + * @param desc + * the method's descriptor (see {@link Type Type}). + * @param mv + * the method visitor to which this adapter delegates calls. + */ + protected LocalVariablesSorter(final int api, final int access, + final String desc, final MethodVisitor mv) { + super(api, mv); + Type[] args = Type.getArgumentTypes(desc); + nextLocal = (Opcodes.ACC_STATIC & access) == 0 ? 1 : 0; + for (int i = 0; i < args.length; i++) { + nextLocal += args[i].getSize(); + } + firstLocal = nextLocal; + } + + @Override + public void visitVarInsn(final int opcode, final int var) { + Type type; + switch (opcode) { + case Opcodes.LLOAD: + case Opcodes.LSTORE: + type = Type.LONG_TYPE; + break; + + case Opcodes.DLOAD: + case Opcodes.DSTORE: + type = Type.DOUBLE_TYPE; + break; + + case Opcodes.FLOAD: + case Opcodes.FSTORE: + type = Type.FLOAT_TYPE; + break; + + case Opcodes.ILOAD: + case Opcodes.ISTORE: + type = Type.INT_TYPE; + break; + + default: + // case Opcodes.ALOAD: + // case Opcodes.ASTORE: + // case RET: + type = OBJECT_TYPE; + break; + } + mv.visitVarInsn(opcode, remap(var, type)); + } + + @Override + public void visitIincInsn(final int var, final int increment) { + mv.visitIincInsn(remap(var, Type.INT_TYPE), increment); + } + + @Override + public void visitMaxs(final int maxStack, final int maxLocals) { + mv.visitMaxs(maxStack, nextLocal); + } + + @Override + public void visitLocalVariable(final String name, final String desc, + final String signature, final Label start, final Label end, + final int index) { + int newIndex = remap(index, Type.getType(desc)); + mv.visitLocalVariable(name, desc, signature, start, end, newIndex); + } + + @Override + public AnnotationVisitor visitLocalVariableAnnotation(int typeRef, + TypePath typePath, Label[] start, Label[] end, int[] index, + String desc, boolean visible) { + Type t = Type.getType(desc); + int[] newIndex = new int[index.length]; + for (int i = 0; i < newIndex.length; ++i) { + newIndex[i] = remap(index[i], t); + } + return mv.visitLocalVariableAnnotation(typeRef, typePath, start, end, + newIndex, desc, visible); + } + + @Override + public void visitFrame(final int type, final int nLocal, + final Object[] local, final int nStack, final Object[] stack) { + if (type != Opcodes.F_NEW) { // uncompressed frame + throw new IllegalStateException( + "ClassReader.accept() should be called with EXPAND_FRAMES flag"); + } + + if (!changed) { // optimization for the case where mapping = identity + mv.visitFrame(type, nLocal, local, nStack, stack); + return; + } + + // creates a copy of newLocals + Object[] oldLocals = new Object[newLocals.length]; + System.arraycopy(newLocals, 0, oldLocals, 0, oldLocals.length); + + updateNewLocals(newLocals); + + // copies types from 'local' to 'newLocals' + // 'newLocals' already contains the variables added with 'newLocal' + + int index = 0; // old local variable index + int number = 0; // old local variable number + for (; number < nLocal; ++number) { + Object t = local[number]; + int size = t == Opcodes.LONG || t == Opcodes.DOUBLE ? 2 : 1; + if (t != Opcodes.TOP) { + Type typ = OBJECT_TYPE; + if (t == Opcodes.INTEGER) { + typ = Type.INT_TYPE; + } else if (t == Opcodes.FLOAT) { + typ = Type.FLOAT_TYPE; + } else if (t == Opcodes.LONG) { + typ = Type.LONG_TYPE; + } else if (t == Opcodes.DOUBLE) { + typ = Type.DOUBLE_TYPE; + } else if (t instanceof String) { + typ = Type.getObjectType((String) t); + } + setFrameLocal(remap(index, typ), t); + } + index += size; + } + + // removes TOP after long and double types as well as trailing TOPs + + index = 0; + number = 0; + for (int i = 0; index < newLocals.length; ++i) { + Object t = newLocals[index++]; + if (t != null && t != Opcodes.TOP) { + newLocals[i] = t; + number = i + 1; + if (t == Opcodes.LONG || t == Opcodes.DOUBLE) { + index += 1; + } + } else { + newLocals[i] = Opcodes.TOP; + } + } + + // visits remapped frame + mv.visitFrame(type, number, newLocals, nStack, stack); + + // restores original value of 'newLocals' + newLocals = oldLocals; + } + + // ------------- + + /** + * Creates a new local variable of the given type. + * + * @param type + * the type of the local variable to be created. + * @return the identifier of the newly created local variable. + */ + public int newLocal(final Type type) { + Object t; + switch (type.getSort()) { + case Type.BOOLEAN: + case Type.CHAR: + case Type.BYTE: + case Type.SHORT: + case Type.INT: + t = Opcodes.INTEGER; + break; + case Type.FLOAT: + t = Opcodes.FLOAT; + break; + case Type.LONG: + t = Opcodes.LONG; + break; + case Type.DOUBLE: + t = Opcodes.DOUBLE; + break; + case Type.ARRAY: + t = type.getDescriptor(); + break; + // case Type.OBJECT: + default: + t = type.getInternalName(); + break; + } + int local = newLocalMapping(type); + setLocalType(local, type); + setFrameLocal(local, t); + changed = true; + return local; + } + + /** + * Notifies subclasses that a new stack map frame is being visited. The + * array argument contains the stack map frame types corresponding to the + * local variables added with {@link #newLocal}. This method can update + * these types in place for the stack map frame being visited. The default + * implementation of this method does nothing, i.e. a local variable added + * with {@link #newLocal} will have the same type in all stack map frames. + * But this behavior is not always the desired one, for instance if a local + * variable is added in the middle of a try/catch block: the frame for the + * exception handler should have a TOP type for this new local. + * + * @param newLocals + * the stack map frame types corresponding to the local variables + * added with {@link #newLocal} (and null for the others). The + * format of this array is the same as in + * {@link MethodVisitor#visitFrame}, except that long and double + * types use two slots. The types for the current stack map frame + * must be updated in place in this array. + */ + protected void updateNewLocals(Object[] newLocals) { + } + + /** + * Notifies subclasses that a local variable has been added or remapped. The + * default implementation of this method does nothing. + * + * @param local + * a local variable identifier, as returned by {@link #newLocal + * newLocal()}. + * @param type + * the type of the value being stored in the local variable. + */ + protected void setLocalType(final int local, final Type type) { + } + + private void setFrameLocal(final int local, final Object type) { + int l = newLocals.length; + if (local >= l) { + Object[] a = new Object[Math.max(2 * l, local + 1)]; + System.arraycopy(newLocals, 0, a, 0, l); + newLocals = a; + } + newLocals[local] = type; + } + + private int remap(final int var, final Type type) { + if (var + type.getSize() <= firstLocal) { + return var; + } + int key = 2 * var + type.getSize() - 1; + int size = mapping.length; + if (key >= size) { + int[] newMapping = new int[Math.max(2 * size, key + 1)]; + System.arraycopy(mapping, 0, newMapping, 0, size); + mapping = newMapping; + } + int value = mapping[key]; + if (value == 0) { + value = newLocalMapping(type); + setLocalType(value, type); + mapping[key] = value + 1; + } else { + value--; + } + if (value != var) { + changed = true; + } + return value; + } + + protected int newLocalMapping(final Type type) { + int local = nextLocal; + nextLocal += type.getSize(); + return local; + } +} diff --git a/contrib/asm/src/org/objectweb/asm/commons/Remapper.java b/contrib/asm/src/org/objectweb/asm/commons/Remapper.java new file mode 100644 index 00000000..121cf887 --- /dev/null +++ b/contrib/asm/src/org/objectweb/asm/commons/Remapper.java @@ -0,0 +1,223 @@ +/*** + * ASM: a very small and fast Java bytecode manipulation framework + * Copyright (c) 2000-2011 INRIA, France Telecom + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.objectweb.asm.commons; + +import org.objectweb.asm.Handle; +import org.objectweb.asm.Type; +import org.objectweb.asm.signature.SignatureReader; +import org.objectweb.asm.signature.SignatureVisitor; +import org.objectweb.asm.signature.SignatureWriter; + +/** + * A class responsible for remapping types and names. Subclasses can override + * the following methods: + * + * + * + * @author Eugene Kuleshov + */ +public abstract class Remapper { + + public String mapDesc(String desc) { + Type t = Type.getType(desc); + switch (t.getSort()) { + case Type.ARRAY: + String s = mapDesc(t.getElementType().getDescriptor()); + for (int i = 0; i < t.getDimensions(); ++i) { + s = '[' + s; + } + return s; + case Type.OBJECT: + String newType = map(t.getInternalName()); + if (newType != null) { + return 'L' + newType + ';'; + } + } + return desc; + } + + private Type mapType(Type t) { + switch (t.getSort()) { + case Type.ARRAY: + String s = mapDesc(t.getElementType().getDescriptor()); + for (int i = 0; i < t.getDimensions(); ++i) { + s = '[' + s; + } + return Type.getType(s); + case Type.OBJECT: + s = map(t.getInternalName()); + return s != null ? Type.getObjectType(s) : t; + case Type.METHOD: + return Type.getMethodType(mapMethodDesc(t.getDescriptor())); + } + return t; + } + + public String mapType(String type) { + if (type == null) { + return null; + } + return mapType(Type.getObjectType(type)).getInternalName(); + } + + public String[] mapTypes(String[] types) { + String[] newTypes = null; + boolean needMapping = false; + for (int i = 0; i < types.length; i++) { + String type = types[i]; + String newType = map(type); + if (newType != null && newTypes == null) { + newTypes = new String[types.length]; + if (i > 0) { + System.arraycopy(types, 0, newTypes, 0, i); + } + needMapping = true; + } + if (needMapping) { + newTypes[i] = newType == null ? type : newType; + } + } + return needMapping ? newTypes : types; + } + + public String mapMethodDesc(String desc) { + if ("()V".equals(desc)) { + return desc; + } + + Type[] args = Type.getArgumentTypes(desc); + StringBuilder sb = new StringBuilder("("); + for (int i = 0; i < args.length; i++) { + sb.append(mapDesc(args[i].getDescriptor())); + } + Type returnType = Type.getReturnType(desc); + if (returnType == Type.VOID_TYPE) { + sb.append(")V"); + return sb.toString(); + } + sb.append(')').append(mapDesc(returnType.getDescriptor())); + return sb.toString(); + } + + public Object mapValue(Object value) { + if (value instanceof Type) { + return mapType((Type) value); + } + if (value instanceof Handle) { + Handle h = (Handle) value; + return new Handle(h.getTag(), mapType(h.getOwner()), mapMethodName( + h.getOwner(), h.getName(), h.getDesc()), + mapMethodDesc(h.getDesc())); + } + return value; + } + + /** + * + * @param typeSignature + * true if signature is a FieldTypeSignature, such as the + * signature parameter of the ClassVisitor.visitField or + * MethodVisitor.visitLocalVariable methods + */ + public String mapSignature(String signature, boolean typeSignature) { + if (signature == null) { + return null; + } + SignatureReader r = new SignatureReader(signature); + SignatureWriter w = new SignatureWriter(); + SignatureVisitor a = createRemappingSignatureAdapter(w); + if (typeSignature) { + r.acceptType(a); + } else { + r.accept(a); + } + return w.toString(); + } + + protected SignatureVisitor createRemappingSignatureAdapter( + SignatureVisitor v) { + return new RemappingSignatureAdapter(v, this); + } + + /** + * Map method name to the new name. Subclasses can override. + * + * @param owner + * owner of the method. + * @param name + * name of the method. + * @param desc + * descriptor of the method. + * @return new name of the method + */ + public String mapMethodName(String owner, String name, String desc) { + return name; + } + + /** + * Map invokedynamic method name to the new name. Subclasses can override. + * + * @param name + * name of the invokedynamic. + * @param desc + * descriptor of the invokedynamic. + * @return new invokdynamic name. + */ + public String mapInvokeDynamicMethodName(String name, String desc) { + return name; + } + + /** + * Map field name to the new name. Subclasses can override. + * + * @param owner + * owner of the field. + * @param name + * name of the field + * @param desc + * descriptor of the field + * @return new name of the field. + */ + public String mapFieldName(String owner, String name, String desc) { + return name; + } + + /** + * Map type name to the new name. Subclasses can override. + */ + public String map(String typeName) { + return typeName; + } +} diff --git a/contrib/asm/src/org/objectweb/asm/commons/RemappingAnnotationAdapter.java b/contrib/asm/src/org/objectweb/asm/commons/RemappingAnnotationAdapter.java new file mode 100644 index 00000000..b9749fcf --- /dev/null +++ b/contrib/asm/src/org/objectweb/asm/commons/RemappingAnnotationAdapter.java @@ -0,0 +1,79 @@ +/*** + * ASM: a very small and fast Java bytecode manipulation framework + * Copyright (c) 2000-2011 INRIA, France Telecom + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.objectweb.asm.commons; + +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.Opcodes; + +/** + * An {@link AnnotationVisitor} adapter for type remapping. + * + * @author Eugene Kuleshov + */ +public class RemappingAnnotationAdapter extends AnnotationVisitor { + + protected final Remapper remapper; + + public RemappingAnnotationAdapter(final AnnotationVisitor av, + final Remapper remapper) { + this(Opcodes.ASM5, av, remapper); + } + + protected RemappingAnnotationAdapter(final int api, + final AnnotationVisitor av, final Remapper remapper) { + super(api, av); + this.remapper = remapper; + } + + @Override + public void visit(String name, Object value) { + av.visit(name, remapper.mapValue(value)); + } + + @Override + public void visitEnum(String name, String desc, String value) { + av.visitEnum(name, remapper.mapDesc(desc), value); + } + + @Override + public AnnotationVisitor visitAnnotation(String name, String desc) { + AnnotationVisitor v = av.visitAnnotation(name, remapper.mapDesc(desc)); + return v == null ? null : (v == av ? this + : new RemappingAnnotationAdapter(v, remapper)); + } + + @Override + public AnnotationVisitor visitArray(String name) { + AnnotationVisitor v = av.visitArray(name); + return v == null ? null : (v == av ? this + : new RemappingAnnotationAdapter(v, remapper)); + } +} diff --git a/contrib/asm/src/org/objectweb/asm/commons/RemappingClassAdapter.java b/contrib/asm/src/org/objectweb/asm/commons/RemappingClassAdapter.java new file mode 100644 index 00000000..c0b52cae --- /dev/null +++ b/contrib/asm/src/org/objectweb/asm/commons/RemappingClassAdapter.java @@ -0,0 +1,135 @@ +/*** + * ASM: a very small and fast Java bytecode manipulation framework + * Copyright (c) 2000-2011 INRIA, France Telecom + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.objectweb.asm.commons; + +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.FieldVisitor; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.TypePath; + +/** + * A {@link ClassVisitor} for type remapping. + * + * @author Eugene Kuleshov + */ +public class RemappingClassAdapter extends ClassVisitor { + + protected final Remapper remapper; + + protected String className; + + public RemappingClassAdapter(final ClassVisitor cv, final Remapper remapper) { + this(Opcodes.ASM5, cv, remapper); + } + + protected RemappingClassAdapter(final int api, final ClassVisitor cv, + final Remapper remapper) { + super(api, cv); + this.remapper = remapper; + } + + @Override + public void visit(int version, int access, String name, String signature, + String superName, String[] interfaces) { + this.className = name; + super.visit(version, access, remapper.mapType(name), remapper + .mapSignature(signature, false), remapper.mapType(superName), + interfaces == null ? null : remapper.mapTypes(interfaces)); + } + + @Override + public AnnotationVisitor visitAnnotation(String desc, boolean visible) { + AnnotationVisitor av = super.visitAnnotation(remapper.mapDesc(desc), + visible); + return av == null ? null : createRemappingAnnotationAdapter(av); + } + + @Override + public AnnotationVisitor visitTypeAnnotation(int typeRef, + TypePath typePath, String desc, boolean visible) { + AnnotationVisitor av = super.visitTypeAnnotation(typeRef, typePath, + remapper.mapDesc(desc), visible); + return av == null ? null : createRemappingAnnotationAdapter(av); + } + + @Override + public FieldVisitor visitField(int access, String name, String desc, + String signature, Object value) { + FieldVisitor fv = super.visitField(access, + remapper.mapFieldName(className, name, desc), + remapper.mapDesc(desc), remapper.mapSignature(signature, true), + remapper.mapValue(value)); + return fv == null ? null : createRemappingFieldAdapter(fv); + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, + String signature, String[] exceptions) { + String newDesc = remapper.mapMethodDesc(desc); + MethodVisitor mv = super.visitMethod(access, remapper.mapMethodName( + className, name, desc), newDesc, remapper.mapSignature( + signature, false), + exceptions == null ? null : remapper.mapTypes(exceptions)); + return mv == null ? null : createRemappingMethodAdapter(access, + newDesc, mv); + } + + @Override + public void visitInnerClass(String name, String outerName, + String innerName, int access) { + // TODO should innerName be changed? + super.visitInnerClass(remapper.mapType(name), outerName == null ? null + : remapper.mapType(outerName), innerName, access); + } + + @Override + public void visitOuterClass(String owner, String name, String desc) { + super.visitOuterClass(remapper.mapType(owner), name == null ? null + : remapper.mapMethodName(owner, name, desc), + desc == null ? null : remapper.mapMethodDesc(desc)); + } + + protected FieldVisitor createRemappingFieldAdapter(FieldVisitor fv) { + return new RemappingFieldAdapter(fv, remapper); + } + + protected MethodVisitor createRemappingMethodAdapter(int access, + String newDesc, MethodVisitor mv) { + return new RemappingMethodAdapter(access, newDesc, mv, remapper); + } + + protected AnnotationVisitor createRemappingAnnotationAdapter( + AnnotationVisitor av) { + return new RemappingAnnotationAdapter(av, remapper); + } +} diff --git a/contrib/asm/src/org/objectweb/asm/commons/RemappingFieldAdapter.java b/contrib/asm/src/org/objectweb/asm/commons/RemappingFieldAdapter.java new file mode 100644 index 00000000..3179abac --- /dev/null +++ b/contrib/asm/src/org/objectweb/asm/commons/RemappingFieldAdapter.java @@ -0,0 +1,71 @@ +/*** + * ASM: a very small and fast Java bytecode manipulation framework + * Copyright (c) 2000-2011 INRIA, France Telecom + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.objectweb.asm.commons; + +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.FieldVisitor; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.TypePath; + +/** + * A {@link FieldVisitor} adapter for type remapping. + * + * @author Eugene Kuleshov + */ +public class RemappingFieldAdapter extends FieldVisitor { + + private final Remapper remapper; + + public RemappingFieldAdapter(final FieldVisitor fv, final Remapper remapper) { + this(Opcodes.ASM5, fv, remapper); + } + + protected RemappingFieldAdapter(final int api, final FieldVisitor fv, + final Remapper remapper) { + super(api, fv); + this.remapper = remapper; + } + + @Override + public AnnotationVisitor visitAnnotation(String desc, boolean visible) { + AnnotationVisitor av = fv.visitAnnotation(remapper.mapDesc(desc), + visible); + return av == null ? null : new RemappingAnnotationAdapter(av, remapper); + } + + @Override + public AnnotationVisitor visitTypeAnnotation(int typeRef, + TypePath typePath, String desc, boolean visible) { + AnnotationVisitor av = super.visitTypeAnnotation(typeRef, typePath, + remapper.mapDesc(desc), visible); + return av == null ? null : new RemappingAnnotationAdapter(av, remapper); + } +} diff --git a/contrib/asm/src/org/objectweb/asm/commons/RemappingMethodAdapter.java b/contrib/asm/src/org/objectweb/asm/commons/RemappingMethodAdapter.java new file mode 100644 index 00000000..c9badc2a --- /dev/null +++ b/contrib/asm/src/org/objectweb/asm/commons/RemappingMethodAdapter.java @@ -0,0 +1,224 @@ +/*** + * ASM: a very small and fast Java bytecode manipulation framework + * Copyright (c) 2000-2011 INRIA, France Telecom + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.objectweb.asm.commons; + +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.Handle; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.TypePath; + +/** + * A {@link LocalVariablesSorter} for type mapping. + * + * @author Eugene Kuleshov + */ +public class RemappingMethodAdapter extends LocalVariablesSorter { + + protected final Remapper remapper; + + public RemappingMethodAdapter(final int access, final String desc, + final MethodVisitor mv, final Remapper remapper) { + this(Opcodes.ASM5, access, desc, mv, remapper); + } + + protected RemappingMethodAdapter(final int api, final int access, + final String desc, final MethodVisitor mv, final Remapper remapper) { + super(api, access, desc, mv); + this.remapper = remapper; + } + + @Override + public AnnotationVisitor visitAnnotationDefault() { + AnnotationVisitor av = super.visitAnnotationDefault(); + return av == null ? av : new RemappingAnnotationAdapter(av, remapper); + } + + @Override + public AnnotationVisitor visitAnnotation(String desc, boolean visible) { + AnnotationVisitor av = super.visitAnnotation(remapper.mapDesc(desc), + visible); + return av == null ? av : new RemappingAnnotationAdapter(av, remapper); + } + + @Override + public AnnotationVisitor visitTypeAnnotation(int typeRef, + TypePath typePath, String desc, boolean visible) { + AnnotationVisitor av = super.visitTypeAnnotation(typeRef, typePath, + remapper.mapDesc(desc), visible); + return av == null ? av : new RemappingAnnotationAdapter(av, remapper); + } + + @Override + public AnnotationVisitor visitParameterAnnotation(int parameter, + String desc, boolean visible) { + AnnotationVisitor av = super.visitParameterAnnotation(parameter, + remapper.mapDesc(desc), visible); + return av == null ? av : new RemappingAnnotationAdapter(av, remapper); + } + + @Override + public void visitFrame(int type, int nLocal, Object[] local, int nStack, + Object[] stack) { + super.visitFrame(type, nLocal, remapEntries(nLocal, local), nStack, + remapEntries(nStack, stack)); + } + + private Object[] remapEntries(int n, Object[] entries) { + for (int i = 0; i < n; i++) { + if (entries[i] instanceof String) { + Object[] newEntries = new Object[n]; + if (i > 0) { + System.arraycopy(entries, 0, newEntries, 0, i); + } + do { + Object t = entries[i]; + newEntries[i++] = t instanceof String ? remapper + .mapType((String) t) : t; + } while (i < n); + return newEntries; + } + } + return entries; + } + + @Override + public void visitFieldInsn(int opcode, String owner, String name, + String desc) { + super.visitFieldInsn(opcode, remapper.mapType(owner), + remapper.mapFieldName(owner, name, desc), + remapper.mapDesc(desc)); + } + + @Deprecated + @Override + public void visitMethodInsn(final int opcode, final String owner, + final String name, final String desc) { + if (api >= Opcodes.ASM5) { + super.visitMethodInsn(opcode, owner, name, desc); + return; + } + doVisitMethodInsn(opcode, owner, name, desc, + opcode == Opcodes.INVOKEINTERFACE); + } + + @Override + public void visitMethodInsn(final int opcode, final String owner, + final String name, final String desc, final boolean itf) { + if (api < Opcodes.ASM5) { + super.visitMethodInsn(opcode, owner, name, desc, itf); + return; + } + doVisitMethodInsn(opcode, owner, name, desc, itf); + } + + private void doVisitMethodInsn(int opcode, String owner, String name, + String desc, boolean itf) { + // Calling super.visitMethodInsn requires to call the correct version + // depending on this.api (otherwise infinite loops can occur). To + // simplify and to make it easier to automatically remove the backward + // compatibility code, we inline the code of the overridden method here. + // IMPORTANT: THIS ASSUMES THAT visitMethodInsn IS NOT OVERRIDDEN IN + // LocalVariableSorter. + if (mv != null) { + mv.visitMethodInsn(opcode, remapper.mapType(owner), + remapper.mapMethodName(owner, name, desc), + remapper.mapMethodDesc(desc), itf); + } + } + + @Override + public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, + Object... bsmArgs) { + for (int i = 0; i < bsmArgs.length; i++) { + bsmArgs[i] = remapper.mapValue(bsmArgs[i]); + } + super.visitInvokeDynamicInsn( + remapper.mapInvokeDynamicMethodName(name, desc), + remapper.mapMethodDesc(desc), (Handle) remapper.mapValue(bsm), + bsmArgs); + } + + @Override + public void visitTypeInsn(int opcode, String type) { + super.visitTypeInsn(opcode, remapper.mapType(type)); + } + + @Override + public void visitLdcInsn(Object cst) { + super.visitLdcInsn(remapper.mapValue(cst)); + } + + @Override + public void visitMultiANewArrayInsn(String desc, int dims) { + super.visitMultiANewArrayInsn(remapper.mapDesc(desc), dims); + } + + @Override + public AnnotationVisitor visitInsnAnnotation(int typeRef, + TypePath typePath, String desc, boolean visible) { + AnnotationVisitor av = super.visitInsnAnnotation(typeRef, typePath, + remapper.mapDesc(desc), visible); + return av == null ? av : new RemappingAnnotationAdapter(av, remapper); + } + + @Override + public void visitTryCatchBlock(Label start, Label end, Label handler, + String type) { + super.visitTryCatchBlock(start, end, handler, type == null ? null + : remapper.mapType(type)); + } + + @Override + public AnnotationVisitor visitTryCatchAnnotation(int typeRef, + TypePath typePath, String desc, boolean visible) { + AnnotationVisitor av = super.visitTryCatchAnnotation(typeRef, typePath, + remapper.mapDesc(desc), visible); + return av == null ? av : new RemappingAnnotationAdapter(av, remapper); + } + + @Override + public void visitLocalVariable(String name, String desc, String signature, + Label start, Label end, int index) { + super.visitLocalVariable(name, remapper.mapDesc(desc), + remapper.mapSignature(signature, true), start, end, index); + } + + @Override + public AnnotationVisitor visitLocalVariableAnnotation(int typeRef, + TypePath typePath, Label[] start, Label[] end, int[] index, + String desc, boolean visible) { + AnnotationVisitor av = super.visitLocalVariableAnnotation(typeRef, + typePath, start, end, index, remapper.mapDesc(desc), visible); + return av == null ? av : new RemappingAnnotationAdapter(av, remapper); + } +} diff --git a/contrib/asm/src/org/objectweb/asm/commons/RemappingSignatureAdapter.java b/contrib/asm/src/org/objectweb/asm/commons/RemappingSignatureAdapter.java new file mode 100644 index 00000000..5728034c --- /dev/null +++ b/contrib/asm/src/org/objectweb/asm/commons/RemappingSignatureAdapter.java @@ -0,0 +1,155 @@ +/*** + * ASM: a very small and fast Java bytecode manipulation framework + * Copyright (c) 2000-2011 INRIA, France Telecom + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.objectweb.asm.commons; + +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.signature.SignatureVisitor; + +/** + * A {@link SignatureVisitor} adapter for type mapping. + * + * @author Eugene Kuleshov + */ +public class RemappingSignatureAdapter extends SignatureVisitor { + + private final SignatureVisitor v; + + private final Remapper remapper; + + private String className; + + public RemappingSignatureAdapter(final SignatureVisitor v, + final Remapper remapper) { + this(Opcodes.ASM5, v, remapper); + } + + protected RemappingSignatureAdapter(final int api, + final SignatureVisitor v, final Remapper remapper) { + super(api); + this.v = v; + this.remapper = remapper; + } + + @Override + public void visitClassType(String name) { + className = name; + v.visitClassType(remapper.mapType(name)); + } + + @Override + public void visitInnerClassType(String name) { + String remappedOuter = remapper.mapType(className) + '$'; + className = className + '$' + name; + String remappedName = remapper.mapType(className); + int index = remappedName.startsWith(remappedOuter) ? remappedOuter + .length() : remappedName.lastIndexOf('$') + 1; + v.visitInnerClassType(remappedName.substring(index)); + } + + @Override + public void visitFormalTypeParameter(String name) { + v.visitFormalTypeParameter(name); + } + + @Override + public void visitTypeVariable(String name) { + v.visitTypeVariable(name); + } + + @Override + public SignatureVisitor visitArrayType() { + v.visitArrayType(); + return this; + } + + @Override + public void visitBaseType(char descriptor) { + v.visitBaseType(descriptor); + } + + @Override + public SignatureVisitor visitClassBound() { + v.visitClassBound(); + return this; + } + + @Override + public SignatureVisitor visitExceptionType() { + v.visitExceptionType(); + return this; + } + + @Override + public SignatureVisitor visitInterface() { + v.visitInterface(); + return this; + } + + @Override + public SignatureVisitor visitInterfaceBound() { + v.visitInterfaceBound(); + return this; + } + + @Override + public SignatureVisitor visitParameterType() { + v.visitParameterType(); + return this; + } + + @Override + public SignatureVisitor visitReturnType() { + v.visitReturnType(); + return this; + } + + @Override + public SignatureVisitor visitSuperclass() { + v.visitSuperclass(); + return this; + } + + @Override + public void visitTypeArgument() { + v.visitTypeArgument(); + } + + @Override + public SignatureVisitor visitTypeArgument(char wildcard) { + v.visitTypeArgument(wildcard); + return this; + } + + @Override + public void visitEnd() { + v.visitEnd(); + } +} diff --git a/contrib/asm/src/org/objectweb/asm/commons/SimpleRemapper.java b/contrib/asm/src/org/objectweb/asm/commons/SimpleRemapper.java new file mode 100644 index 00000000..7b42b9bc --- /dev/null +++ b/contrib/asm/src/org/objectweb/asm/commons/SimpleRemapper.java @@ -0,0 +1,75 @@ +/*** + * ASM: a very small and fast Java bytecode manipulation framework + * Copyright (c) 2000-2011 INRIA, France Telecom + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.objectweb.asm.commons; + +import java.util.Collections; +import java.util.Map; + +/** + * A {@link Remapper} using a {@link Map} to define its mapping. + * + * @author Eugene Kuleshov + */ +public class SimpleRemapper extends Remapper { + + private final Map mapping; + + public SimpleRemapper(Map mapping) { + this.mapping = mapping; + } + + public SimpleRemapper(String oldName, String newName) { + this.mapping = Collections.singletonMap(oldName, newName); + } + + @Override + public String mapMethodName(String owner, String name, String desc) { + String s = map(owner + '.' + name + desc); + return s == null ? name : s; + } + + @Override + public String mapInvokeDynamicMethodName(String name, String desc) { + String s = map('.' + name + desc); + return s == null ? name : s; + } + + @Override + public String mapFieldName(String owner, String name, String desc) { + String s = map(owner + '.' + name); + return s == null ? name : s; + } + + @Override + public String map(String key) { + return mapping.get(key); + } +} diff --git a/contrib/asm/src/org/objectweb/asm/signature/SignatureReader.java b/contrib/asm/src/org/objectweb/asm/signature/SignatureReader.java new file mode 100644 index 00000000..1083b3de --- /dev/null +++ b/contrib/asm/src/org/objectweb/asm/signature/SignatureReader.java @@ -0,0 +1,228 @@ +/*** + * ASM: a very small and fast Java bytecode manipulation framework + * Copyright (c) 2000-2011 INRIA, France Telecom + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.objectweb.asm.signature; + +/** + * A type signature parser to make a signature visitor visit an existing + * signature. + * + * @author Thomas Hallgren + * @author Eric Bruneton + */ +public class SignatureReader { + + /** + * The signature to be read. + */ + private final String signature; + + /** + * Constructs a {@link SignatureReader} for the given signature. + * + * @param signature + * A ClassSignature, MethodTypeSignature, or + * FieldTypeSignature. + */ + public SignatureReader(final String signature) { + this.signature = signature; + } + + /** + * Makes the given visitor visit the signature of this + * {@link SignatureReader}. This signature is the one specified in the + * constructor (see {@link #SignatureReader(String) SignatureReader}). This + * method is intended to be called on a {@link SignatureReader} that was + * created using a ClassSignature (such as the signature + * parameter of the {@link org.objectweb.asm.ClassVisitor#visit + * ClassVisitor.visit} method) or a MethodTypeSignature (such as the + * signature parameter of the + * {@link org.objectweb.asm.ClassVisitor#visitMethod + * ClassVisitor.visitMethod} method). + * + * @param v + * the visitor that must visit this signature. + */ + public void accept(final SignatureVisitor v) { + String signature = this.signature; + int len = signature.length(); + int pos; + char c; + + if (signature.charAt(0) == '<') { + pos = 2; + do { + int end = signature.indexOf(':', pos); + v.visitFormalTypeParameter(signature.substring(pos - 1, end)); + pos = end + 1; + + c = signature.charAt(pos); + if (c == 'L' || c == '[' || c == 'T') { + pos = parseType(signature, pos, v.visitClassBound()); + } + + while ((c = signature.charAt(pos++)) == ':') { + pos = parseType(signature, pos, v.visitInterfaceBound()); + } + } while (c != '>'); + } else { + pos = 0; + } + + if (signature.charAt(pos) == '(') { + pos++; + while (signature.charAt(pos) != ')') { + pos = parseType(signature, pos, v.visitParameterType()); + } + pos = parseType(signature, pos + 1, v.visitReturnType()); + while (pos < len) { + pos = parseType(signature, pos + 1, v.visitExceptionType()); + } + } else { + pos = parseType(signature, pos, v.visitSuperclass()); + while (pos < len) { + pos = parseType(signature, pos, v.visitInterface()); + } + } + } + + /** + * Makes the given visitor visit the signature of this + * {@link SignatureReader}. This signature is the one specified in the + * constructor (see {@link #SignatureReader(String) SignatureReader}). This + * method is intended to be called on a {@link SignatureReader} that was + * created using a FieldTypeSignature, such as the + * signature parameter of the + * {@link org.objectweb.asm.ClassVisitor#visitField ClassVisitor.visitField} + * or {@link org.objectweb.asm.MethodVisitor#visitLocalVariable + * MethodVisitor.visitLocalVariable} methods. + * + * @param v + * the visitor that must visit this signature. + */ + public void acceptType(final SignatureVisitor v) { + parseType(this.signature, 0, v); + } + + /** + * Parses a field type signature and makes the given visitor visit it. + * + * @param signature + * a string containing the signature that must be parsed. + * @param pos + * index of the first character of the signature to parsed. + * @param v + * the visitor that must visit this signature. + * @return the index of the first character after the parsed signature. + */ + private static int parseType(final String signature, int pos, + final SignatureVisitor v) { + char c; + int start, end; + boolean visited, inner; + String name; + + switch (c = signature.charAt(pos++)) { + case 'Z': + case 'C': + case 'B': + case 'S': + case 'I': + case 'F': + case 'J': + case 'D': + case 'V': + v.visitBaseType(c); + return pos; + + case '[': + return parseType(signature, pos, v.visitArrayType()); + + case 'T': + end = signature.indexOf(';', pos); + v.visitTypeVariable(signature.substring(pos, end)); + return end + 1; + + default: // case 'L': + start = pos; + visited = false; + inner = false; + for (;;) { + switch (c = signature.charAt(pos++)) { + case '.': + case ';': + if (!visited) { + name = signature.substring(start, pos - 1); + if (inner) { + v.visitInnerClassType(name); + } else { + v.visitClassType(name); + } + } + if (c == ';') { + v.visitEnd(); + return pos; + } + start = pos; + visited = false; + inner = true; + break; + + case '<': + name = signature.substring(start, pos - 1); + if (inner) { + v.visitInnerClassType(name); + } else { + v.visitClassType(name); + } + visited = true; + top: for (;;) { + switch (c = signature.charAt(pos)) { + case '>': + break top; + case '*': + ++pos; + v.visitTypeArgument(); + break; + case '+': + case '-': + pos = parseType(signature, pos + 1, + v.visitTypeArgument(c)); + break; + default: + pos = parseType(signature, pos, + v.visitTypeArgument('=')); + break; + } + } + } + } + } + } +} diff --git a/contrib/asm/src/org/objectweb/asm/signature/SignatureVisitor.java b/contrib/asm/src/org/objectweb/asm/signature/SignatureVisitor.java new file mode 100644 index 00000000..1dba32d5 --- /dev/null +++ b/contrib/asm/src/org/objectweb/asm/signature/SignatureVisitor.java @@ -0,0 +1,238 @@ +/*** + * ASM: a very small and fast Java bytecode manipulation framework + * Copyright (c) 2000-2011 INRIA, France Telecom + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.objectweb.asm.signature; + +import org.objectweb.asm.Opcodes; + +/** + * A visitor to visit a generic signature. The methods of this interface must be + * called in one of the three following orders (the last one is the only valid + * order for a {@link SignatureVisitor} that is returned by a method of this + * interface): + * + * + * @author Thomas Hallgren + * @author Eric Bruneton + */ +public abstract class SignatureVisitor { + + /** + * Wildcard for an "extends" type argument. + */ + public final static char EXTENDS = '+'; + + /** + * Wildcard for a "super" type argument. + */ + public final static char SUPER = '-'; + + /** + * Wildcard for a normal type argument. + */ + public final static char INSTANCEOF = '='; + + /** + * The ASM API version implemented by this visitor. The value of this field + * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. + */ + protected final int api; + + /** + * Constructs a new {@link SignatureVisitor}. + * + * @param api + * the ASM API version implemented by this visitor. Must be one + * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. + */ + public SignatureVisitor(final int api) { + if (api != Opcodes.ASM4 && api != Opcodes.ASM5) { + throw new IllegalArgumentException(); + } + this.api = api; + } + + /** + * Visits a formal type parameter. + * + * @param name + * the name of the formal parameter. + */ + public void visitFormalTypeParameter(String name) { + } + + /** + * Visits the class bound of the last visited formal type parameter. + * + * @return a non null visitor to visit the signature of the class bound. + */ + public SignatureVisitor visitClassBound() { + return this; + } + + /** + * Visits an interface bound of the last visited formal type parameter. + * + * @return a non null visitor to visit the signature of the interface bound. + */ + public SignatureVisitor visitInterfaceBound() { + return this; + } + + /** + * Visits the type of the super class. + * + * @return a non null visitor to visit the signature of the super class + * type. + */ + public SignatureVisitor visitSuperclass() { + return this; + } + + /** + * Visits the type of an interface implemented by the class. + * + * @return a non null visitor to visit the signature of the interface type. + */ + public SignatureVisitor visitInterface() { + return this; + } + + /** + * Visits the type of a method parameter. + * + * @return a non null visitor to visit the signature of the parameter type. + */ + public SignatureVisitor visitParameterType() { + return this; + } + + /** + * Visits the return type of the method. + * + * @return a non null visitor to visit the signature of the return type. + */ + public SignatureVisitor visitReturnType() { + return this; + } + + /** + * Visits the type of a method exception. + * + * @return a non null visitor to visit the signature of the exception type. + */ + public SignatureVisitor visitExceptionType() { + return this; + } + + /** + * Visits a signature corresponding to a primitive type. + * + * @param descriptor + * the descriptor of the primitive type, or 'V' for void + * . + */ + public void visitBaseType(char descriptor) { + } + + /** + * Visits a signature corresponding to a type variable. + * + * @param name + * the name of the type variable. + */ + public void visitTypeVariable(String name) { + } + + /** + * Visits a signature corresponding to an array type. + * + * @return a non null visitor to visit the signature of the array element + * type. + */ + public SignatureVisitor visitArrayType() { + return this; + } + + /** + * Starts the visit of a signature corresponding to a class or interface + * type. + * + * @param name + * the internal name of the class or interface. + */ + public void visitClassType(String name) { + } + + /** + * Visits an inner class. + * + * @param name + * the local name of the inner class in its enclosing class. + */ + public void visitInnerClassType(String name) { + } + + /** + * Visits an unbounded type argument of the last visited class or inner + * class type. + */ + public void visitTypeArgument() { + } + + /** + * Visits a type argument of the last visited class or inner class type. + * + * @param wildcard + * '+', '-' or '='. + * @return a non null visitor to visit the signature of the type argument. + */ + public SignatureVisitor visitTypeArgument(char wildcard) { + return this; + } + + /** + * Ends the visit of a signature corresponding to a class or interface type. + */ + public void visitEnd() { + } +} diff --git a/contrib/asm/src/org/objectweb/asm/signature/SignatureWriter.java b/contrib/asm/src/org/objectweb/asm/signature/SignatureWriter.java new file mode 100644 index 00000000..ec475dbf --- /dev/null +++ b/contrib/asm/src/org/objectweb/asm/signature/SignatureWriter.java @@ -0,0 +1,227 @@ +/*** + * ASM: a very small and fast Java bytecode manipulation framework + * Copyright (c) 2000-2011 INRIA, France Telecom + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.objectweb.asm.signature; + +import org.objectweb.asm.Opcodes; + +/** + * A signature visitor that generates signatures in string format. + * + * @author Thomas Hallgren + * @author Eric Bruneton + */ +public class SignatureWriter extends SignatureVisitor { + + /** + * Buffer used to construct the signature. + */ + private final StringBuffer buf = new StringBuffer(); + + /** + * Indicates if the signature contains formal type parameters. + */ + private boolean hasFormals; + + /** + * Indicates if the signature contains method parameter types. + */ + private boolean hasParameters; + + /** + * Stack used to keep track of class types that have arguments. Each element + * of this stack is a boolean encoded in one bit. The top of the stack is + * the lowest order bit. Pushing false = *2, pushing true = *2+1, popping = + * /2. + */ + private int argumentStack; + + /** + * Constructs a new {@link SignatureWriter} object. + */ + public SignatureWriter() { + super(Opcodes.ASM5); + } + + // ------------------------------------------------------------------------ + // Implementation of the SignatureVisitor interface + // ------------------------------------------------------------------------ + + @Override + public void visitFormalTypeParameter(final String name) { + if (!hasFormals) { + hasFormals = true; + buf.append('<'); + } + buf.append(name); + buf.append(':'); + } + + @Override + public SignatureVisitor visitClassBound() { + return this; + } + + @Override + public SignatureVisitor visitInterfaceBound() { + buf.append(':'); + return this; + } + + @Override + public SignatureVisitor visitSuperclass() { + endFormals(); + return this; + } + + @Override + public SignatureVisitor visitInterface() { + return this; + } + + @Override + public SignatureVisitor visitParameterType() { + endFormals(); + if (!hasParameters) { + hasParameters = true; + buf.append('('); + } + return this; + } + + @Override + public SignatureVisitor visitReturnType() { + endFormals(); + if (!hasParameters) { + buf.append('('); + } + buf.append(')'); + return this; + } + + @Override + public SignatureVisitor visitExceptionType() { + buf.append('^'); + return this; + } + + @Override + public void visitBaseType(final char descriptor) { + buf.append(descriptor); + } + + @Override + public void visitTypeVariable(final String name) { + buf.append('T'); + buf.append(name); + buf.append(';'); + } + + @Override + public SignatureVisitor visitArrayType() { + buf.append('['); + return this; + } + + @Override + public void visitClassType(final String name) { + buf.append('L'); + buf.append(name); + argumentStack *= 2; + } + + @Override + public void visitInnerClassType(final String name) { + endArguments(); + buf.append('.'); + buf.append(name); + argumentStack *= 2; + } + + @Override + public void visitTypeArgument() { + if (argumentStack % 2 == 0) { + ++argumentStack; + buf.append('<'); + } + buf.append('*'); + } + + @Override + public SignatureVisitor visitTypeArgument(final char wildcard) { + if (argumentStack % 2 == 0) { + ++argumentStack; + buf.append('<'); + } + if (wildcard != '=') { + buf.append(wildcard); + } + return this; + } + + @Override + public void visitEnd() { + endArguments(); + buf.append(';'); + } + + /** + * Returns the signature that was built by this signature writer. + * + * @return the signature that was built by this signature writer. + */ + @Override + public String toString() { + return buf.toString(); + } + + // ------------------------------------------------------------------------ + // Utility methods + // ------------------------------------------------------------------------ + + /** + * Ends the formal type parameters section of the signature. + */ + private void endFormals() { + if (hasFormals) { + hasFormals = false; + buf.append('>'); + } + } + + /** + * Ends the type arguments of a class or inner class type. + */ + private void endArguments() { + if (argumentStack % 2 != 0) { + buf.append('>'); + } + argumentStack /= 2; + } +} \ No newline at end of file diff --git a/src/libbluray/bdj/java/org/videolan/BDJClassFileTransformer.java b/src/libbluray/bdj/java/org/videolan/BDJClassFileTransformer.java index 71faae08..10ddecc8 100644 --- a/src/libbluray/bdj/java/org/videolan/BDJClassFileTransformer.java +++ b/src/libbluray/bdj/java/org/videolan/BDJClassFileTransformer.java @@ -32,15 +32,48 @@ package org.videolan; * in class file com/tcs/blr/bluray/pal/fox/controller/d */ +import java.util.Map; + import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Attribute; +import org.objectweb.asm.commons.SimpleRemapper; +import org.objectweb.asm.commons.RemappingClassAdapter; -class BDJClassFileTransformer +public class BDJClassFileTransformer { + public byte[] rename(byte[] b, int off, int len, Map mappings) + throws ClassFormatError + { + byte[] r = new byte[len]; + for (int i = 0; i < len; i++) + r[i] = b[i+off]; + + return rename(r, mappings); + } + + public byte[] rename(byte[] b, Map mappings) + throws ClassFormatError + { + logger.info("Trying to rename class (" + b.length + " bytes)"); + + try { + SimpleRemapper m = new SimpleRemapper(mappings); + ClassReader cr = new ClassReader(b); + ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES/* | ClassWriter.COMPUTE_MAXS*/); + ClassVisitor cv = new RemappingClassAdapter(cw, m); + cr.accept(cv, ClassReader.SKIP_DEBUG); + return cw.toByteArray(); + } catch (Exception e) { + logger.error("Failed renaming class: " + e); + } + + return null; + } + public byte[] strip(byte[] b, int off, int len) throws ClassFormatError { diff --git a/src/libbluray/bdj/java/org/videolan/mmbd/Adapter.java b/src/libbluray/bdj/java/org/videolan/mmbd/Adapter.java new file mode 100644 index 00000000..da862b40 --- /dev/null +++ b/src/libbluray/bdj/java/org/videolan/mmbd/Adapter.java @@ -0,0 +1,241 @@ +/* + * This file is part of libbluray + * Copyright (C) 2017 VideoLAN + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +/* + * BD-J support classes for libmmbd + */ + +package org.videolan.mmbd; + +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.HashMap; +import java.util.Map; +import java.security.AccessController; +import java.security.PrivilegedAction; + +import org.videolan.BDJClassFileTransformer; +import org.videolan.BDJClassLoaderAdapter; +import org.videolan.Logger; + +import javax.media.ClockStartedError; +import javax.media.Manager; +import javax.media.NoPlayerException; +import javax.media.Player; +import javax.tv.xlet.Xlet; +import javax.tv.xlet.XletContext; +import javax.tv.xlet.XletStateChangeException; +import org.bluray.bdplus.StatusListener; + +public class Adapter implements BDJClassLoaderAdapter { + + public Map getHideClasses() { + return null; + } + + public Map getBootClasses() { + return bootClasses; + } + + public Map getXletClasses() { + return xletClasses; + } + + public Adapter() throws ClassNotFoundException { + /* relocate classes to avoid runtime package collisions */ + + final String s1 = "org/videolan/mmbd/Adapter$Xlet"; + final String s2 = "org/videolan/mmbd/Adapter$If"; + Map m = new HashMap(); + String d1, d2; + m.put(s1, d1 = (new String(b0) + new String(b1))); + m.put(s2, d2 = (new String(b0) + new String(b2))); + + BDJClassFileTransformer t = new BDJClassFileTransformer(); + byte[] c1 = t.rename(loadBootClassCode(s1), m); + byte[] c2 = t.rename(loadBootClassCode(s2), m); + + if (c1 != null) { + bootClasses = new HashMap(); + bootClasses.put(d1.replace('/', '.'), c1); + } + if (c2 != null) { + xletClasses = new HashMap(); + xletClasses.put(d2.replace('/', '.'), c2); + } + } + + public static abstract class If { + protected If() {} + } + + public static class Xlet implements StatusListener { + private static Xlet instance = new Xlet(); + private javax.tv.xlet.Xlet xlet = null; + private XletContext ctx = null; + + static private void log(String s) { + System.out.println(s); + } + static private void error(String s) { + System.err.println(s); + } + + public static Xlet initXlet(javax.tv.xlet.Xlet xlet, XletContext ctx) throws XletStateChangeException { + if ((xlet == null) || (ctx == null)) { + error("initXlet: null argument"); + throw new XletStateChangeException(); + } + if ((instance.xlet == xlet) && (instance.ctx == ctx)) { + error("initXlet: invalid arguments"); + throw new XletStateChangeException(); + } + log("initXlet"); + instance.xlet = xlet; + instance.ctx = ctx; + return instance; + } + + public static Xlet lookup(XletContext ctx) { + return instance; + } + + public void startXlet() throws XletStateChangeException { + } + + public void pauseXlet() { + } + + public void destroyXlet(boolean a) { + this.instance.xlet = null; + this.instance.ctx = null; + } + + public boolean isAuthRequired() { + log("isAuthRequired"); + return false; + } + + public void doAuth() throws InterruptedException { + doAuth(null); + } + + public synchronized void doAuth(If a) throws InterruptedException, RuntimeException { + error("doAuth"); + } + + public void destroy() { + } + + public void receive(int i) { + } + + public byte[] getMMV() { + byte[] b = new byte[8]; + new java.util.Random().nextBytes(b); + log("getMMV"); + return b; + } + + public Player createPlayer(javax.media.protocol.DataSource s) throws IOException, NoPlayerException { + return Manager.createPlayer(s); + } + + public Player createPlayer(javax.media.MediaLocator l) throws IOException, NoPlayerException { + return Manager.createPlayer(l); + } + + public Player createPlayer(java.net.URL u) throws IOException, NoPlayerException { + return Manager.createPlayer(u); + } + + public void destroyPlayer(Player p) { + if (p == null) + return; + p.stop(); + try { + p.deallocate(); + } catch (ClockStartedError localClockStartedError) { + } + p.close(); + } + } + + /* + * class loader + */ + + private final byte[] b0 = {99,111,109,47,109,97,99,114,111,118,105,115,105,111,110,47,98,100,112,108,117,115,47}; + private final byte[] b1 = {77,86,67,111,109,109}; + private final byte[] b2 = {83,116,114,101,101,116,76,111,99,107,71,101,116,116,101,114}; + + private byte[] loadBootClassCode(String name) throws ClassNotFoundException { + final String path = name.replace('.', '/').concat(".class"); + InputStream is = null; + ByteArrayOutputStream os = new ByteArrayOutputStream(); + byte[] buffer = new byte[0xffff]; + try { + is = (InputStream) + AccessController.doPrivileged( + new PrivilegedAction() { + public Object run() { + return ClassLoader.getSystemResourceAsStream(path); + } + }); + + if (is == null) { + logger.error("loadBootClassCode(" + name + "): not found"); + throw new ClassNotFoundException(name); + } + + while (true) { + int r = is.read(buffer); + if (r == -1) { + break; + } + os.write(buffer, 0, r); + } + + return os.toByteArray(); + + } catch (Exception e) { + logger.error("loadBootClassCode(" + name + ") failed: " + e); + throw new ClassNotFoundException(name); + + } finally { + try { + if (is != null) + is.close(); + } catch (IOException ioe) { + } + try { + if (os != null) + os.close(); + } catch (IOException ioe) { + } + } + } + + private Map bootClasses = new HashMap(); + private Map xletClasses = new HashMap(); + + private static final Logger logger = Logger.getLogger(Adapter.class.getName()); +}