gpt4 book ai didi

java - 操作从 ASM 生成的字节码

转载 作者:行者123 更新时间:2023-12-01 11:19:27 25 4
gpt4 key购买 nike

我只想为带有公共(public)或 protected 字段、构造函数和方法的 java 类生成字节码。

我正在尝试使用以下代码,但我不知道 这是正确的方法吗?

Client code:


String sourceFileName = file.getName();
ClassReader reader = new ClassReader(file.getContents());
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
JavaStubClassAdapter adapter = new JavaStubClassAdapter(writer, sourceFileName);
reader.accept(adapter, 0);
byte[] content = writer.toByteArray();
// we can use content to print in .class file

Adapator code:


private class JavaStubClassAdapter extends ClassVisitor {
private final String sourceFileName;

/**
* @param writer
* @param sourceFileName
*/
public JavaStubClassAdapter(ClassWriter writer, String sourceFileName) {
super(Opcodes.ASM7, writer);
this.sourceFileName = sourceFileName;
}

@Override
public void visitSource(String source, String debug) {
super.visitSource(this.sourceFileName, null);
}

@Override
public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) {
if (access == Opcodes.ACC_PUBLIC || access == Opcodes.ACC_PROTECTED) {
return super.visitField(access, name, descriptor, signature, value);
}
return null;
}

@Override
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature,
String[] exceptions) {
if (access == Opcodes.ACC_PUBLIC || access == Opcodes.ACC_PROTECTED) {
return super.visitMethod(access, name, descriptor, signature, exceptions);
}
return null;
}
}

最佳答案

下面的代码对我有用

Client code this method has org.eclipse.core.resources.IFile

        ClassReader reader = new ClassReader(file.getContents());
if (!isAccessPermited(reader.getAccess())) {
return new byte[0];
}
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
JavaStubClassAdapter adapter = new JavaStubClassAdapter(writer, sourceFileName);
reader.accept(adapter, 0);
return writer.toByteArray();

Helper methods

    private static boolean isAccessPermited(final int access) {
boolean isEnumAcc = (access & Opcodes.ACC_ENUM) == 0 ? false : true;
boolean isPublicAcc = (access & Opcodes.ACC_PUBLIC) == 0 ? false : true;
boolean isProtectedAcc = (access & Opcodes.ACC_PROTECTED) == 0 ? false : true;
if (isPublicAcc || isProtectedAcc || isEnumAcc) {
return true;
}
return false;
}

private static boolean isFinalAccess(final int access) {
return (access & Opcodes.ACC_FINAL) != 0;
}

Adapator code

    private static class JavaStubClassAdapter extends ClassVisitor {
private final String sourceFileName;

/**
* @param writer
* ClassVisitor
* @param sourceFileName
* String
*/
public JavaStubClassAdapter(ClassVisitor writer, String sourceFileName) {
super(Opcodes.ASM7, writer);
this.sourceFileName = sourceFileName;
}

@Override
public void visitSource(String source, String debug) {
super.visitSource(this.sourceFileName, null);
}

@Override
public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) {
if (isAccessPermited(access)) {
switch (descriptor) {
case "Ljava/lang/String;": //$NON-NLS-1$
if (isFinalAccess(access)) {
return super.visitField(access, name, descriptor, signature, "");
}
return super.visitField(access, name, descriptor, signature, null);
case "Z": //$NON-NLS-1$
return super.visitField(access, name, descriptor, signature, Boolean.FALSE);
case "C": //$NON-NLS-1$
case "B": //$NON-NLS-1$
case "S": //$NON-NLS-1$
case "I": //$NON-NLS-1$
case "J": //$NON-NLS-1$
case "D": //$NON-NLS-1$
case "F": //$NON-NLS-1$
if (isFinalAccess(access)) {
return super.visitField(access, name, descriptor, signature, Integer.valueOf(0));
}
return super.visitField(access, name, descriptor, signature, null);
case "Ljava/lang/Object": //$NON-NLS-1$
return super.visitField(access, name, descriptor, signature, null);

default:
return super.visitField(access, name, descriptor, signature, null);
}
}
return null;
}

@Override
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature,
String[] exceptions) {
if (isAccessPermited(access)) {
MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions);
return new JavaClassEmptyMethodVistor(mv, Type.getReturnType(descriptor));
}
return null;
}

@Override
public void visitInnerClass(String name, String outerName, String innerName, int access) {
if (isAccessPermited(access)) {
super.visitInnerClass(name, outerName, innerName, access);
}
}
}

private static class JavaClassEmptyMethodVistor extends MethodVisitor {
private final MethodVisitor visitor;

private final Type returnType;

public JavaClassEmptyMethodVistor(MethodVisitor methodVisitor, Type type) {
super(Opcodes.ASM7, methodVisitor);
this.visitor = methodVisitor;
this.returnType = type;
}

@Override
public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) {
// Do nothing
}

@Override
public void visitFieldInsn(int opcode, String owner, String name, String descriptor) {
// Do nothing
}

@Override
public void visitInsn(int opcode) {
if (returnType == Type.INT_TYPE || returnType == Type.FLOAT_TYPE
|| returnType == Type.LONG_TYPE || returnType == Type.DOUBLE_TYPE
|| returnType == Type.CHAR_TYPE || returnType == Type.BYTE_TYPE ) {
visitor.visitIntInsn(Opcodes.BIPUSH, 0);
visitor.visitInsn(Opcodes.IRETURN);
} else if (returnType == Type.BOOLEAN_TYPE) {
visitor.visitInsn(Opcodes.ICONST_0);
visitor.visitInsn(Opcodes.IRETURN);
} else if (returnType == Type.VOID_TYPE) {
visitor.visitInsn(Opcodes.RETURN);
} else {
visitor.visitInsn(Opcodes.ACONST_NULL);
visitor.visitInsn(Opcodes.ARETURN);
}
}

@Override
public void visitIincInsn(int var, int increment) {
// Do nothing
}

@Override
public void visitLineNumber(int line, Label start) {
// Do nothing
}

@Override
public void visitLabel(Label label) {
// Do nothing
}

@Override
public void visitTypeInsn(int opcode, String type) {
// Do nothing
}

@Override
public void visitJumpInsn(int opcode, Label label) {
// Do nothing
}

@Override
public void visitLdcInsn(Object value) {
// Do nothing
}

@Override
public void visitVarInsn(int opcode, int var) {
// Do nothing
}

@Override
public void visitMaxs(int maxStack, int maxLocals) {
visitor.visitMaxs(0, 0);
}

@Override
public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
// Do nothing
}

@Override
public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
// Do nothing
}

@Override
public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
// Do nothing
}

@Override
public void visitFrame(int type, int numLocal, Object[] local, int numStack, Object[] stack) {
// Do nothing
}
}

关于java - 操作从 ASM 生成的字节码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62464896/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com