下面列出了怎么用org.objectweb.asm.Opcodes的API类实例代码及写法,或者点击链接到github查看源代码。
public void visitEnd() {
if(bNeedBIDField) {
// Add a static field containing the bundle id to the processed class.
// This files is used by the wrapper methods to find the bundle owning
// the class.
// The field has the magic/long name defined by FIELD_BID
// hopefully no-one else uses this
super.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_STATIC,
FIELD_BID,
"J",
null,
new Long(bid));
}
super.visitEnd();
if(Activator.debugEnabled()) {
cp.dumpInfo();
}
}
@Override
public FieldVisitor visitField(final int access, final String name, final String desc, final String signature, final Object value) {
String s = remapper.mapFieldName(className, name, desc);
if ("-".equals(s)) {
return null;
}
if ((access & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED)) == 0) {
if ((access & Opcodes.ACC_FINAL) != 0 && (access & Opcodes.ACC_STATIC) != 0 && desc.length() == 1) {
}
super.visitField(access, name, desc, null, value);
} else {
if (!s.equals(name)) {
throw new RuntimeException("The public or protected field " + className + '.' + name + " must not be renamed.");
}
super.visitField(access, name, desc, null, value);
}
return null; // remove debug info
}
private static void defineDeltaSpikeProxyFields(ClassWriter cw)
{
// generates
// private DeltaSpikeProxyInvocationHandler invocationHandler;
cw.visitField(Opcodes.ACC_PRIVATE, FIELDNAME_INVOCATION_HANDLER,
TYPE_DELTA_SPIKE_PROXY_INVOCATION_HANDLER.getDescriptor(), null, null).visitEnd();
// generates
// private MyInvocationHandler delegateInvocationHandler;
cw.visitField(Opcodes.ACC_PRIVATE, FIELDNAME_DELEGATE_INVOCATION_HANDLER,
TYPE_INVOCATION_HANDLER.getDescriptor(), null, null).visitEnd();
// generates
// private Method[] delegateMethods;
cw.visitField(Opcodes.ACC_PRIVATE, FIELDNAME_DELEGATE_METHODS,
TYPE_METHOD_ARRAY.getDescriptor(), null, null).visitEnd();
}
private static SequenceQuery<AbstractInsnNode> conditionalAtStart() {
final Slot<Integer> counterVariable = Slot.create(Integer.class);
final Slot<LabelNode> loopStart = Slot.create(LabelNode.class);
final Slot<LabelNode> loopEnd = Slot.create(LabelNode.class);
return QueryStart
.any(AbstractInsnNode.class)
// .then(anIntegerConstant().and(debug("constant"))) // skip this?
.then(anIStore(counterVariable.write()).and(debug("store")))
.then(aLabelNode(loopStart.write()).and(debug("label")))
.then(anILoadOf(counterVariable.read()).and(debug("load")))
.zeroOrMore(QueryStart.match(opCode(Opcodes.ALOAD))) // optionally put object on stack
.then(loadsAnIntegerToCompareTo().and(debug("push")))
.then(jumpsTo(loopEnd.write()).and(aConditionalJump()))
.then(isA(LabelNode.class))
.zeroOrMore(anything())
.then(targetInstruction(counterVariable).and(debug("target")))
.then(jumpsTo(loopStart.read()).and(debug("jump")))
.then(labelNode(loopEnd.read()))
.zeroOrMore(anything());
}
/**
* {@inheritDoc}
*
* @see org.objectweb.asm.MethodVisitor#visitFieldInsn(int, java.lang.String, java.lang.String, java.lang.String)
*/
@Override
public void visitFieldInsn ( int opcode, String owner, String name, String desc ) {
JVMStackState s = this.stack;
if ( opcode == Opcodes.PUTSTATIC ) {
Object v = s.pop();
if ( ! ( v instanceof BaseType ) || ( (BaseType) v ).isTainted() ) {
// generated static cached, let's assume they are safe
if ( name.indexOf('$') < 0 && this.ref.getMethod().indexOf('$') < 0 ) {
this.parent.getAnalyzer().putstatic(this.ref);
}
}
}
else {
JVMImpl.handleFieldInsn(opcode, owner, name, desc, s);
}
if ( ( opcode == Opcodes.GETSTATIC || opcode == Opcodes.GETFIELD ) && name.indexOf('$') < 0 ) {
this.parent.getAnalyzer().instantiable(this.ref, Type.getType(desc));
}
super.visitFieldInsn(opcode, owner, name, desc);
}
@Override
public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) {
super.visitLookupSwitchInsn(dflt, keys, labels);
execute(Opcodes.LOOKUPSWITCH, 0, null);
this.locals = null;
this.stack = null;
}
protected TestClassVisitor(TestFrameworkDetector detector) {
super(Opcodes.ASM4);
if (detector == null) {
throw new IllegalArgumentException("detector == null!");
}
this.detector = detector;
}
public SimpleBlockCoverageVisitor(List<Block> blocks,
InstructionCounter counter, final int classId,
final MethodVisitor writer, final int access, final String name,
final String desc, final int probeOffset) {
super(Opcodes.ASM7, writer);
this.counter = counter;
this.methodVisitor = writer;
this.classId = classId;
this.blocks = blocks;
this.probeOffset = probeOffset;
}
/**
* Deprecated.
*
* @deprecated use {@link #visitMethodInsn(int, String, String, String, boolean)} instead.
*/
@Deprecated
@Override
public void visitMethodInsn(
final int opcode, final String owner, final String name, final String descriptor) {
if (api >= Opcodes.ASM5) {
super.visitMethodInsn(opcode, owner, name, descriptor);
return;
}
p.visitMethodInsn(opcode, owner, name, descriptor);
if (mv != null) {
mv.visitMethodInsn(opcode, owner, name, descriptor);
}
}
/**
* Deprecated.
*
* @param owner the internal name of the method's owner class.
* @param name the method's name.
* @param descriptor the method's descriptor (see {@link Type}).
* @deprecated use {@link #invokespecial(String, String, String, boolean)} instead.
*/
@Deprecated
public void invokespecial(final String owner, final String name, final String descriptor) {
if (api >= Opcodes.ASM5) {
invokespecial(owner, name, descriptor, false);
return;
}
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, owner, name, descriptor, false);
}
public static AbstractInsnNode getWrapperMethod(Type type) {
if (type.getSort() != Type.VOID && TYPE_TO_WRAPPER.containsKey(type)) {
return new MethodInsnNode(Opcodes.INVOKESTATIC, TYPE_TO_WRAPPER.get(type), "valueOf", "(" + type.toString() + ")L" + TYPE_TO_WRAPPER.get(type) + ";", false);
}
return new InsnNode(Opcodes.NOP);
}
@Test
public void testTypeVariableOutOfScopeIsErased() throws Exception {
TypeDescription typeDescription = new InstrumentedType.Default("foo",
Opcodes.ACC_PUBLIC,
TypeDescription.Generic.OfNonGenericType.ForLoadedType.of(AbstractOuter.ExtendedInner.class),
Collections.<TypeVariableToken>emptyList(),
Collections.<TypeDescription.Generic>emptyList(),
Collections.<FieldDescription.Token>emptyList(),
Collections.singletonList(new MethodDescription.Token("foo",
Opcodes.ACC_BRIDGE,
TypeDescription.Generic.VOID,
Collections.<TypeDescription.Generic>emptyList())),
Collections.<RecordComponentDescription.Token>emptyList(),
Collections.<AnnotationDescription>emptyList(),
TypeInitializer.None.INSTANCE,
LoadedTypeInitializer.NoOp.INSTANCE,
TypeDescription.UNDEFINED,
MethodDescription.UNDEFINED,
TypeDescription.UNDEFINED,
Collections.<TypeDescription>emptyList(),
false,
false,
false,
TargetType.DESCRIPTION,
Collections.<TypeDescription>emptyList());
MethodDescription methodDescription = typeDescription.getSuperClass().getSuperClass().getDeclaredMethods().filter(named(FOO)).getOnly();
assertThat(methodDescription.getReturnType(), is(TypeDescription.Generic.OBJECT));
}
private InsnList insertCancelMountHealthRendering(LabelNode label) {
InsnList list = new InsnList();
list.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "codes/biscuit/skyblockaddons/asm/hooks/GuiIngameCustomHook", "shouldRenderMountHealth", "()Z", false));
list.add(new JumpInsnNode(Opcodes.IFEQ, label)); // && shouldRenderMountHealth()
return list;
}
FieldScanner(FieldVisitor parent, int access, String name, String descriptor) {
super(Opcodes.ASM7, parent);
this.access = access;
this.name = name;
this.descriptor = descriptor;
}
MethodBuilder(SootMethod method, SootClassBuilder scb,
String desc, String[] ex) {
super(Opcodes.ASM5, null, method.getModifiers(),
method.getName(), desc, null, ex);
this.method = method;
this.scb = scb;
}
/**
* Deprecated.
*
* @deprecated use {@link #visitMethodInsn(int, String, String, String, boolean)} instead.
*/
@Deprecated
@Override
public void visitMethodInsn(
final int opcode, final String owner, final String name, final String descriptor) {
if (api >= Opcodes.ASM5) {
super.visitMethodInsn(opcode, owner, name, descriptor);
return;
}
doVisitMethodInsn(opcode, owner, name, descriptor, opcode == Opcodes.INVOKEINTERFACE);
}
private boolean processAccessor(ClassNode classNode, MixinInfo mixin) {
if (!MixinEnvironment.getCompatibilityLevel().supports(LanguageFeature.METHODS_IN_INTERFACES)) {
return false;
}
boolean transformed = false;
MixinClassNode mixinClassNode = mixin.getClassNode(0);
ClassInfo targetClass = mixin.getTargets().get(0);
for (MixinMethodNode methodNode : mixinClassNode.mixinMethods) {
if (!Bytecode.hasFlag(methodNode, Opcodes.ACC_STATIC)) {
continue;
}
AnnotationNode accessor = methodNode.getVisibleAnnotation(Accessor.class);
AnnotationNode invoker = methodNode.getVisibleAnnotation(Invoker.class);
if (accessor != null || invoker != null) {
Method method = this.getAccessorMethod(mixin, methodNode, targetClass);
MixinPostProcessor.createProxy(methodNode, targetClass, method);
Annotations.setVisible(methodNode, MixinProxy.class, "sessionId", this.sessionId);
classNode.methods.add(methodNode);
transformed = true;
}
}
if (!transformed) {
return false;
}
Bytecode.replace(mixinClassNode, classNode);
return true;
}
private InsnList insertDurabilityHook() {
InsnList list = new InsnList();
list.add(new TypeInsnNode(Opcodes.NEW, "codes/biscuit/skyblockaddons/asm/utils/ReturnValue"));
list.add(new InsnNode(Opcodes.DUP)); // ReturnValue returnValue = new ReturnValue();
list.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "codes/biscuit/skyblockaddons/asm/utils/ReturnValue", "<init>", "()V", false));
list.add(new VarInsnNode(Opcodes.ASTORE, 2));
list.add(new VarInsnNode(Opcodes.ALOAD, 1)); // stack
list.add(new VarInsnNode(Opcodes.ALOAD, 2)); // ItemHook.getDurabilityForDisplay(stack, returnValue);
list.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "codes/biscuit/skyblockaddons/asm/hooks/ItemHook", "getDurabilityForDisplay",
"("+TransformerClass.ItemStack.getName()+"Lcodes/biscuit/skyblockaddons/asm/utils/ReturnValue;)V", false));
list.add(new VarInsnNode(Opcodes.ALOAD, 2));
list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "codes/biscuit/skyblockaddons/asm/utils/ReturnValue", "isCancelled",
"()Z", false));
LabelNode notCancelled = new LabelNode(); // if (returnValue.isCancelled())
list.add(new JumpInsnNode(Opcodes.IFEQ, notCancelled));
list.add(new VarInsnNode(Opcodes.ALOAD, 2));
list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "codes/biscuit/skyblockaddons/asm/utils/ReturnValue", "getReturnValue",
"()Ljava/lang/Object;", false));
list.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Double"));
list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Double", "doubleValue",
"()D", false));
list.add(new InsnNode(Opcodes.DRETURN)); // return returnValue.getValue();
list.add(notCancelled);
return list;
}
/**
* Find the first <tt><init></tt> invocation after the specified
* <tt>NEW</tt> insn
*
* @param newNode NEW insn
* @return INVOKESPECIAL opcode of ctor, or null if not found
*/
public MethodInsnNode findInitNodeFor(TypeInsnNode newNode) {
int start = this.indexOf(newNode);
for (Iterator<AbstractInsnNode> iter = this.insns.iterator(start); iter.hasNext();) {
AbstractInsnNode insn = iter.next();
if (insn instanceof MethodInsnNode && insn.getOpcode() == Opcodes.INVOKESPECIAL) {
MethodInsnNode methodNode = (MethodInsnNode)insn;
if (Constants.CTOR.equals(methodNode.name) && methodNode.owner.equals(newNode.desc)) {
return methodNode;
}
}
}
return null;
}
@Override
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
super.visitFieldInsn(opcode, owner, name, desc);
final boolean isStatic = Opcodes.GETSTATIC == opcode || Opcodes.PUTSTATIC == opcode;
if (name.startsWith("this$")) {
return;
}
accessedFields.add(new AccessedField(owner, name, desc, isStatic));
}
@Override
public void visitUse(final String service) {
checkVisitEndNotCalled();
CheckMethodAdapter.checkInternalName(Opcodes.V9, service, "service");
usedServices.checkNameNotAlreadyDeclared(service);
super.visitUse(service);
}
@Test
public void testForMethod() throws Exception {
assertThat(ModifierContributor.Resolver.of(Visibility.PUBLIC, MethodManifestation.FINAL).resolve(),
is(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL));
assertThat(ModifierContributor.Resolver.of(Visibility.PUBLIC, MethodManifestation.ABSTRACT, MethodManifestation.FINAL).resolve(),
is(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL));
assertThat(ModifierContributor.Resolver.of(Visibility.PUBLIC, MethodManifestation.FINAL).resolve(1),
is(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | 1));
}
/**
* Generates the instruction to create and push on the stack an array of the given type.
*
* @param type an array Type.
*/
public void newarray(final Type type) {
int arrayType;
switch (type.getSort()) {
case Type.BOOLEAN:
arrayType = Opcodes.T_BOOLEAN;
break;
case Type.CHAR:
arrayType = Opcodes.T_CHAR;
break;
case Type.BYTE:
arrayType = Opcodes.T_BYTE;
break;
case Type.SHORT:
arrayType = Opcodes.T_SHORT;
break;
case Type.INT:
arrayType = Opcodes.T_INT;
break;
case Type.FLOAT:
arrayType = Opcodes.T_FLOAT;
break;
case Type.LONG:
arrayType = Opcodes.T_LONG;
break;
case Type.DOUBLE:
arrayType = Opcodes.T_DOUBLE;
break;
default:
mv.visitTypeInsn(Opcodes.ANEWARRAY, type.getInternalName());
return;
}
mv.visitIntInsn(Opcodes.NEWARRAY, arrayType);
}
private void doVisitMethodInsn(int opcode, final String owner, final String name, final String desc, final boolean itf) {
checkStartCode();
checkEndCode();
checkOpcode(opcode, 5);
if (opcode != Opcodes.INVOKESPECIAL || !"<init>".equals(name)) {
checkMethodIdentifier(version, name, "name");
}
checkInternalName(owner, "owner");
checkMethodDesc(desc);
if (opcode == Opcodes.INVOKEVIRTUAL && itf) {
throw new IllegalArgumentException("INVOKEVIRTUAL can't be used with interfaces");
}
if (opcode == Opcodes.INVOKEINTERFACE && !itf) {
throw new IllegalArgumentException("INVOKEINTERFACE can't be used with classes");
}
if (opcode == Opcodes.INVOKESPECIAL && itf && (version & 0xFFFF) < Opcodes.V1_8) {
throw new IllegalArgumentException("INVOKESPECIAL can't be used with interfaces prior to Java 8");
}
// 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.
if (mv != null) {
mv.visitMethodInsn(opcode, owner, name, desc, itf);
}
++insnCount;
}
@Override
public void visitMethodInsn(
final int opcode,
final String owner,
final String name,
final String descriptor,
final boolean isInterface) {
if (api < Opcodes.ASM5) {
super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
return;
}
doVisitMethodInsn(opcode, owner, name, descriptor, isInterface);
}
@Override
public void visitMethodInsn(
final int opcode,
final String owner,
final String name,
final String descriptor,
final boolean isInterface) {
if (api < Opcodes.ASM5) {
super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
return;
}
doVisitMethodInsn(opcode, owner, name, descriptor, isInterface);
}
@Override
public FieldVisitor visitField(
final int access,
final String name,
final String desc,
final String signature,
final Object value) {
// Get the class field information for step 4 of the algorithm. Also determine if the class
// already has a SVUID.
if (computeSVUID) {
if ("serialVersionUID".equals(name)) {
// Since the class already has SVUID, we won't be computing it.
computeSVUID = false;
hasSVUID = true;
}
// Collect the non private fields. Only the ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED,
// ACC_STATIC, ACC_FINAL, ACC_VOLATILE, and ACC_TRANSIENT flags are used when computing
// serialVersionUID values.
if ((access & Opcodes.ACC_PRIVATE) == 0
|| (access & (Opcodes.ACC_STATIC | Opcodes.ACC_TRANSIENT)) == 0) {
int mods =
access
& (Opcodes.ACC_PUBLIC
| Opcodes.ACC_PRIVATE
| Opcodes.ACC_PROTECTED
| Opcodes.ACC_STATIC
| Opcodes.ACC_FINAL
| Opcodes.ACC_VOLATILE
| Opcodes.ACC_TRANSIENT);
svuidFields.add(new Item(name, mods, desc));
}
}
return super.visitField(access, name, desc, signature, value);
}
/** Gets the class file version corresponding to the given source version constant. */
public static int sourceVersionToClassFileVersion(SourceVersion version) {
switch (version) {
case RELEASE_0:
return Opcodes.V1_1; // JVMS8 4.1: 1.0 and 1.1 both support version 45.3 (Opcodes.V1_1)
case RELEASE_1:
return Opcodes.V1_1;
case RELEASE_2:
return Opcodes.V1_2;
case RELEASE_3:
return Opcodes.V1_3;
case RELEASE_4:
return Opcodes.V1_4;
case RELEASE_5:
return Opcodes.V1_5;
case RELEASE_6:
return Opcodes.V1_6;
case RELEASE_7:
return Opcodes.V1_7;
case RELEASE_8:
return Opcodes.V1_8;
case RELEASE_9:
return Opcodes.V9;
case RELEASE_10:
return Opcodes.V10;
case RELEASE_11:
return Opcodes.V11;
default:
throw new IllegalArgumentException(String.format("Unexpected source version: %s", version));
}
}
@Override
public MethodKey visitInvokeInterface(MethodKey methodKey, MethodVisitor mv) {
final MethodKey methodBridge = methodKey.substituteOfInterfaceInstanceMethod();
mv.visitMethodInsn(
Opcodes.INVOKESTATIC,
methodBridge.ownerName(),
methodBridge.name(),
methodBridge.descriptor(),
/* isInterface= */ true);
return methodKey;
}
public void dup(TypeWidget typeWidget) {
switch (typeWidget.getJVMType().getSize()) {
case 0:
throw new UnsupportedOperationException();
case 1:
getMethodVisitor().visitInsn(Opcodes.DUP);
return;
case 2:
getMethodVisitor().visitInsn(Opcodes.DUP2);
return;
default:
throw new UnsupportedOperationException("Unexpected JVM type width: " + typeWidget.getJVMType());
}
}