Add class remapper
This commit is contained in:
parent
c17ba25551
commit
3f868baf13
|
@ -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}. <i>Subclasses must not use
|
||||
* this constructor</i>. 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;
|
||||
}
|
||||
}
|
|
@ -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:
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@link #map(String)} - map type</li>
|
||||
* <li>{@link #mapFieldName(String, String, String)} - map field name</li>
|
||||
* <li>{@link #mapMethodName(String, String, String)} - map method name</li>
|
||||
* </ul>
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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<String, String> mapping;
|
||||
|
||||
public SimpleRemapper(Map<String, String> 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);
|
||||
}
|
||||
}
|
|
@ -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 <i>ClassSignature</i>, <i>MethodTypeSignature</i>, or
|
||||
* <i>FieldTypeSignature</i>.
|
||||
*/
|
||||
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 <i>ClassSignature</i> (such as the <code>signature</code>
|
||||
* parameter of the {@link org.objectweb.asm.ClassVisitor#visit
|
||||
* ClassVisitor.visit} method) or a <i>MethodTypeSignature</i> (such as the
|
||||
* <code>signature</code> 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 <i>FieldTypeSignature</i>, such as the
|
||||
* <code>signature</code> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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):
|
||||
* <ul>
|
||||
* <li><i>ClassSignature</i> = ( <tt>visitFormalTypeParameter</tt>
|
||||
* <tt>visitClassBound</tt>? <tt>visitInterfaceBound</tt>* )* (
|
||||
* <tt>visitSuperclass</tt> <tt>visitInterface</tt>* )</li>
|
||||
* <li><i>MethodSignature</i> = ( <tt>visitFormalTypeParameter</tt>
|
||||
* <tt>visitClassBound</tt>? <tt>visitInterfaceBound</tt>* )* (
|
||||
* <tt>visitParameterType</tt>* <tt>visitReturnType</tt>
|
||||
* <tt>visitExceptionType</tt>* )</li>
|
||||
* <li><i>TypeSignature</i> = <tt>visitBaseType</tt> |
|
||||
* <tt>visitTypeVariable</tt> | <tt>visitArrayType</tt> | (
|
||||
* <tt>visitClassType</tt> <tt>visitTypeArgument</tt>* (
|
||||
* <tt>visitInnerClassType</tt> <tt>visitTypeArgument</tt>* )* <tt>visitEnd</tt>
|
||||
* ) )</li>
|
||||
* </ul>
|
||||
*
|
||||
* @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 <tt>void</tt>
|
||||
* .
|
||||
*/
|
||||
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() {
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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());
|
||||
}
|
Loading…
Reference in New Issue