下面列出了org.objectweb.asm.Type#getSize ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
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 = remappedVariableIndices.length;
if (key >= size) {
int[] newRemappedVariableIndices = new int[Math.max(2 * size, key + 1)];
System.arraycopy(remappedVariableIndices, 0, newRemappedVariableIndices, 0, size);
remappedVariableIndices = newRemappedVariableIndices;
}
int value = remappedVariableIndices[key];
if (value == 0) {
value = newLocalMapping(type);
setLocalType(value, type);
remappedVariableIndices[key] = value + 1;
} else {
value--;
}
return value;
}
@Override
public Type load(Context ctx) {
GeneratorAdapter g = ctx.getGeneratorAdapter();
Type type = VOID_TYPE;
for (int i = 0; i < expressions.size(); i++) {
Expression expression = expressions.get(i);
type = expression.load(ctx);
if (i != expressions.size() - 1) {
if (type.getSize() == 1)
g.pop();
if (type.getSize() == 2)
g.pop2();
}
}
return type;
}
private void redirectStaticMethodProxytoGlobal(MethodVisitor mv, String name, String desc){
String globName = getGlobName(className);
//return new StaticMethodProxytoGlobal(mv);//+ $Globals$
mv.visitCode();
mv.visitLabel(new Label());
mv.visitMethodInsn(INVOKESTATIC, globName, "getInstance?", "()L"+globName+";", false);
int argSpace = 0;
for(Type arg : Type.getArgumentTypes(desc)){
mv.visitVarInsn(arg.getOpcode(Opcodes.ILOAD), argSpace);
argSpace += arg.getSize();
}
mv.visitMethodInsn(INVOKEVIRTUAL, globName, name, desc, false);
Type retType = Type.getReturnType(desc);
int opcode = retType.getOpcode(Opcodes.IRETURN); //Opcodes.ARETURN;
/*if(retType.getDimensions() == 1){
}*/
mv.visitInsn(opcode);
mv.visitMaxs(1, 0);
mv.visitEnd();
}
private Map<Integer, InsnList> createJunkArguments(Type[] argumentTypes, int offset) {
Map<Integer, InsnList> junkArguments = new HashMap<>();
for (int k = 0; k < getJunkArgumentCount(); k++) {
InsnList junkProxyArgumentFix = new InsnList();
int junkVariable = 0;
for (Type argumentType : argumentTypes) {
if (RandomUtils.getRandomBoolean()) {
junkProxyArgumentFix.add(ASMUtils.getRandomValue(argumentType));
junkProxyArgumentFix.add(new VarInsnNode(ASMUtils.getVarOpcode(argumentType, true), offset + junkVariable));
}
junkVariable += argumentType.getSize();
}
junkArguments.put(ejectorContext.getNextId(), junkProxyArgumentFix);
}
return junkArguments;
}
/**
* Generates the instructions to box the top stack value. This value is replaced by its boxed
* equivalent on top of the stack.
*
* @param type the type of the top stack value.
*/
public void box(final Type type) {
if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
return;
}
if (type == Type.VOID_TYPE) {
push((String) null);
} else {
Type boxedType = getBoxedType(type);
newInstance(boxedType);
if (type.getSize() == 2) {
// Pp -> Ppo -> oPpo -> ooPpo -> ooPp -> o
dupX2();
dupX2();
pop();
} else {
// p -> po -> opo -> oop -> o
dupX1();
swap();
}
invokeConstructor(boxedType, new Method("<init>", Type.VOID_TYPE, new Type[] {type}));
}
}
private void doVisitMethodInsn(final int opcode, final String descriptor) {
if (isConstructor && !superClassConstructorCalled) {
for (Type argumentType : Type.getArgumentTypes(descriptor)) {
popValue();
if (argumentType.getSize() == 2) {
popValue();
}
}
switch (opcode) {
case INVOKEINTERFACE:
case INVOKEVIRTUAL:
popValue();
break;
case INVOKESPECIAL:
Object value = popValue();
if (value == UNINITIALIZED_THIS && !superClassConstructorCalled) {
superClassConstructorCalled = true;
onMethodEnter();
}
break;
default:
break;
}
Type returnType = Type.getReturnType(descriptor);
if (returnType != Type.VOID_TYPE) {
pushValue(OTHER);
if (returnType.getSize() == 2) {
pushValue(OTHER);
}
}
}
}
@Override
public SourceValue newValue(final Type type) {
if (type == Type.VOID_TYPE) {
return null;
}
return new SourceValue(type == null ? 1 : type.getSize());
}
public static void processIndy(ClassNode classNode, String methodName, InvokeDynamicInsnNode indy) {
MethodNode indyWrapper = new MethodNode(Opcodes.ASM7,
Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_STATIC,
methodName, indy.desc, null, new String[0]);
int localVarsPosition = 0;
for (Type arg : Type.getArgumentTypes(indy.desc)) {
indyWrapper.instructions.add(new VarInsnNode(arg.getOpcode(Opcodes.ILOAD), localVarsPosition));
localVarsPosition += arg.getSize();
}
indyWrapper.instructions.add(new InvokeDynamicInsnNode(indy.name, indy.desc, indy.bsm, indy.bsmArgs));
indyWrapper.instructions.add(new InsnNode(Opcodes.ARETURN));
classNode.methods.add(indyWrapper);
}
/**
* Constructs a new {@link LocalVariablesSorter}.
*
* @param api the ASM API version implemented by this visitor. Must be one of {@link
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
* @param access access flags of the adapted method.
* @param descriptor the method's descriptor (see {@link Type}).
* @param methodVisitor the method visitor to which this adapter delegates calls.
*/
protected LocalVariablesSorter(
final int api, final int access, final String descriptor, final MethodVisitor methodVisitor) {
super(api, methodVisitor);
nextLocal = (Opcodes.ACC_STATIC & access) == 0 ? 1 : 0;
for (Type argumentType : Type.getArgumentTypes(descriptor)) {
nextLocal += argumentType.getSize();
}
firstLocal = nextLocal;
}
/**
* @param types Array containing the Type of each argument in the method
* @return combined size of the slots for the local variables for all the argument types
*/
public final int getParametersStackSize(final Type[] types) {
int tmpSize = 0;
if (types != null) {
for (final Type t : types) {
tmpSize += t.getSize();
}
}
return tmpSize;
}
/**
* Generates the instructions to load the given method arguments on the stack.
*
* @param arg the index of the first method argument to be loaded.
* @param count the number of method arguments to be loaded.
*/
public void loadArgs(final int arg, final int count) {
int index = getArgIndex(arg);
for (int i = 0; i < count; ++i) {
Type argumentType = argumentTypes[arg + i];
loadInsn(argumentType, index);
index += argumentType.getSize();
}
}
@Override
public SourceValue newValue(final Type type) {
if (type == Type.VOID_TYPE) {
return null;
}
return new SourceValue(type == null ? 1 : type.getSize());
}
/**
* Converts Types to LocalVariables, assuming they start from variable 0.
*/
static List<LocalVariable> toLocalVariables( List<Type> types) {
List<LocalVariable> variables = Lists.newArrayList();
int stack = 0;
for (int i = 0; i < types.size(); i++) {
Type type = types.get(i);
variables.add(new LocalVariable(type, stack));
stack += type.getSize();
}
return variables;
}
/**
* Constructs a new {@link LocalVariablesSorter}.
*
* @param api the ASM API version implemented by this visitor. Must be one of {@link
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
* @param access access flags of the adapted method.
* @param descriptor the method's descriptor (see {@link Type}).
* @param methodVisitor the method visitor to which this adapter delegates calls.
*/
protected LocalVariablesSorter(
final int api, final int access, final String descriptor, final MethodVisitor methodVisitor) {
super(api, methodVisitor);
nextLocal = (Opcodes.ACC_STATIC & access) == 0 ? 1 : 0;
for (Type argumentType : Type.getArgumentTypes(descriptor)) {
nextLocal += argumentType.getSize();
}
firstLocal = nextLocal;
}
/**
* Computes the initial execution stack frame of the given method.
*
* @param owner the internal name of the class to which 'method' belongs.
* @param method the method to be analyzed.
* @return the initial execution stack frame of the 'method'.
*/
private Frame<V> computeInitialFrame(final String owner, final MethodNode method) {
Frame<V> frame = newFrame(method.maxLocals, method.maxStack);
int currentLocal = 0;
boolean isInstanceMethod = (method.access & ACC_STATIC) == 0;
if (isInstanceMethod) {
Type ownerType = Type.getObjectType(owner);
frame.setLocal(
currentLocal, interpreter.newParameterValue(isInstanceMethod, currentLocal, ownerType));
currentLocal++;
}
Type[] argumentTypes = Type.getArgumentTypes(method.desc);
for (Type argumentType : argumentTypes) {
frame.setLocal(
currentLocal,
interpreter.newParameterValue(isInstanceMethod, currentLocal, argumentType));
currentLocal++;
if (argumentType.getSize() == 2) {
frame.setLocal(currentLocal, interpreter.newEmptyValue(currentLocal));
currentLocal++;
}
}
while (currentLocal < method.maxLocals) {
frame.setLocal(currentLocal, interpreter.newEmptyValue(currentLocal));
currentLocal++;
}
frame.setReturn(interpreter.newReturnTypeValue(Type.getReturnType(method.desc)));
return frame;
}
private void registerExisting(int var, Type type) {
if (var >= max) max = var + type.getSize();
}
protected int newLocalMapping(final Type type) {
int local = nextLocal;
nextLocal += type.getSize();
return local;
}
protected int newLocalMapping(final Type type) {
int local = nextLocal;
nextLocal += type.getSize();
return local;
}
protected void save_stack(boolean check) {
// System.out.println("Saving " + currentBlock.getId());
if (!currentBlock.isEmpty() && currentBlock.get(currentBlock.size() - 1).canChangeFlow()) {
throw new IllegalStateException("Flow instruction already added to block; cannot save stack: " + currentBlock.getDisplayName());
}
// System.out.println("\n Befor: " + currentStack);
// System.out.println(" With size: " + currentStack.size());
// System.out.println(" With height: " + currentStack.height());
ExpressionStack copy = currentStack.copy();
int len = currentStack.size();
currentStack.clear();
int height = 0;
for(int i=len-1; i >= 0; i--) {
// peek(0) = top
// peek(len-1) = btm
int index = height;
Expr expr = copy.peek(i);
if(expr.getParent() != null) {
expr = expr.copy();
}
// System.out.println(" Pop: " + expr + ":" + expr.getType());
// System.out.println(" Idx: " + index);
Type type = assign_stack(index, expr);
Expr e = load_stack(index, type);
// System.out.println(" Push " + e + ":" + e.getType());
// System.out.println(" tlen: " + type.getSize());
currentStack.push(e);
height += type.getSize();
}
if(check) {
saved = true;
}
//System.out.println(" After: " + currentStack + "\n");
}
/**
* Constructs a new {@link LocalVariablesSorter}.
*
* @param api the ASM API version implemented by this visitor. Must be one of {@link
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link
* Opcodes#ASM7_EXPERIMENTAL}.
* @param access access flags of the adapted method.
* @param descriptor the method's descriptor (see {@link Type}).
* @param methodVisitor the method visitor to which this adapter delegates calls.
*/
protected LocalVariablesSorter(
final int api, final int access, final String descriptor, final MethodVisitor methodVisitor) {
super(api, methodVisitor);
nextLocal = (Opcodes.ACC_STATIC & access) == 0 ? 1 : 0;
for (Type argumentType : Type.getArgumentTypes(descriptor)) {
nextLocal += argumentType.getSize();
}
firstLocal = nextLocal;
}