下面列出了org.objectweb.asm.Opcodes# GETSTATIC 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
if (checkTargetInsn(opcode, owner, name, desc)) {
markPatchedSuccessfully();
super.visitFieldInsn(Opcodes.PUTSTATIC, TARGET_CLASS_NAME, SpecialArmorClassVisitor.CACHED_TOUGHNESS_FIELD_NAME, "F"); //store armorToughness
super.visitFieldInsn(Opcodes.PUTSTATIC, TARGET_CLASS_NAME, SpecialArmorClassVisitor.CACHED_TOTAL_ARMOR_FIELD_NAME, "F"); //store totalArmor
super.visitInsn(Opcodes.DUP); //duplicate damage
super.visitVarInsn(Opcodes.ALOAD, 0); //load entity
super.visitVarInsn(Opcodes.ALOAD, 1); //load inventory
super.visitVarInsn(Opcodes.ALOAD, 2); //load damageSource
super.visitMethodInsn(Opcodes.INVOKESTATIC, ARMOR_HOOKS_OWNER, ARMOR_HOOKS_METHOD_NAME, ARMOR_HOOKS_SIGNATURE, false); //call ArmorHooks
super.visitFieldInsn(Opcodes.GETSTATIC, TARGET_CLASS_NAME, SpecialArmorClassVisitor.CACHED_TOTAL_ARMOR_FIELD_NAME, "F"); //load totalArmor back
super.visitFieldInsn(Opcodes.GETSTATIC, TARGET_CLASS_NAME, SpecialArmorClassVisitor.CACHED_TOUGHNESS_FIELD_NAME, "F"); //load armorToughness back
}
super.visitMethodInsn(opcode, owner, name, desc, itf);
}
@Override
public void visitFieldInsn(
final int opcode, final String owner, final String name, final String descriptor) {
switch (opcode) {
case Opcodes.GETSTATIC:
getstatic(owner, name, descriptor);
break;
case Opcodes.PUTSTATIC:
putstatic(owner, name, descriptor);
break;
case Opcodes.GETFIELD:
getfield(owner, name, descriptor);
break;
case Opcodes.PUTFIELD:
putfield(owner, name, descriptor);
break;
default:
throw new IllegalArgumentException();
}
}
/**
* {@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);
}
private static MethodNode findEnumSwitchUsage(ClassNode classNode, String owner) {
String target = ENUM_SWITCH_PREFIX + owner.replace('/', '$');
@SuppressWarnings("rawtypes") // ASM API
List methodList = classNode.methods;
for (Object f : methodList) {
MethodNode method = (MethodNode) f;
InsnList nodes = method.instructions;
for (int i = 0, n = nodes.size(); i < n; i++) {
AbstractInsnNode instruction = nodes.get(i);
if (instruction.getOpcode() == Opcodes.GETSTATIC) {
FieldInsnNode field = (FieldInsnNode) instruction;
if (field.name.equals(target)) {
return method;
}
}
}
}
return null;
}
private void instrumentToTrackStaticFieldState(AccessedField accessedField, int lineNumber) {
logger.log(" - instrumentToTrackFieldState (static) at " + lineNumber + ": " + accessedField);
// Put field value to the stack
super.visitFieldInsn(Opcodes.GETSTATIC, accessedField.owner, accessedField.name, accessedField.desc);
// Put other params to the stack
super.visitLdcInsn(accessedField.name);
super.visitLdcInsn(lineNumber);
super.visitLdcInsn(methodName);
super.visitLdcInsn(Type.getType("L" + className + ";"));
super.visitLdcInsn(accessedField.isStatic);
super.visitLdcInsn(accessedField.owner);
// Call tracking code
super.visitMethodInsn(Opcodes.INVOKESTATIC, instrumentationActions.trackerClass, "trackFieldState", "(" + getFieldDescriptor(accessedField) + "Ljava/lang/String;ILjava/lang/String;Ljava/lang/Class;ZLjava/lang/String;)V", false);
}
@Override
public void visitFieldInsn(
final int opcode, final String owner, final String name, final String descriptor) {
switch (opcode) {
case Opcodes.GETSTATIC:
getstatic(owner, name, descriptor);
break;
case Opcodes.PUTSTATIC:
putstatic(owner, name, descriptor);
break;
case Opcodes.GETFIELD:
getfield(owner, name, descriptor);
break;
case Opcodes.PUTFIELD:
putfield(owner, name, descriptor);
break;
default:
throw new IllegalArgumentException();
}
}
public void visitFieldInsn(final int opcode, final String owner,
final String name, final String desc) {
String newDesc = translator.getClassMirrorTranslationDescriptor(desc);
if (opcode == Opcodes.GETSTATIC) {
final Mirror mirror = translator.getMirror(owner);
if (mirror.hasStaticField(name, newDesc)) {
super.visitFieldInsn(opcode,
translator.translate(owner), name, newDesc);
return;
}
}
super.visitFieldInsn(opcode,
translator.getClassMirrorTranslation(owner),
name, newDesc);
}
public void visitFieldInsn(final int opcode, final String owner, final String name, final String descriptor) {
if (opcode == Opcodes.GETSTATIC || opcode == Opcodes.PUTSTATIC) {
if(!owner.equals(me.myName)) {
getNode(owner).nodesDependingOnMyStaticFields.add(this.instx);
}else if(!localfields.contains(name + descriptor)){
//if owner is myname but field is not defined in class, find where it is defined
String origin = findLocationOfField(name, descriptor, superName, interfaces);
if(null != origin) {//include source of field and intermediate classes for inclusion.. TODO: remove, not used
Pair<ClassNode, Boolean> intermia = new Pair<ClassNode, Boolean>(this.instx.getA(), true);
getNode(origin).nodesDependingOnMyStaticFields.add(intermia);
}
}
}
}
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
//->
//INVOKESTATIC bytecodeSandbox$MYE$Globals$.getInstance? ()LbytecodeSandbox$MYE$Globals$;
//GETFIELD TestClass$MyEnum.ENUM$VALUES : TestClass$MyEnum[] -> GETSTATIC TestClass$MyEnum$Globals$.ENUM$VALUES : TestClass$MyEnum[]
if(opcode == Opcodes.GETSTATIC && name.equals("ENUM$VALUES")){
owner += "$Globals$";
mv.visitMethodInsn(INVOKESTATIC, owner, "getInstance?", "()L"+owner+";", false);
opcode = Opcodes.GETFIELD;
}
super.visitFieldInsn(opcode, owner, name, desc);
}
@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));
}
public static XField createReferencedXField(DismantleBytecode visitor) {
int seen = visitor.getOpcode();
if (seen != Opcodes.GETFIELD && seen != Opcodes.GETSTATIC && seen != Opcodes.PUTFIELD && seen != Opcodes.PUTSTATIC) {
throw new IllegalArgumentException("Not at a field reference");
}
return createXFieldUsingSlashedClassName(visitor.getClassConstantOperand(), visitor.getNameConstantOperand(),
visitor.getSigConstantOperand(), visitor.getRefFieldIsStatic());
}
private boolean willPush(AbstractInsnNode ain)
{
if(ain.getOpcode() == Opcodes.LDC && (((LdcInsnNode)ain).cst instanceof Long || ((LdcInsnNode)ain).cst instanceof Double))
return false;
return (Utils.willPushToStack(ain.getOpcode()) || ain.getOpcode() == Opcodes.NEW) && ain.getOpcode() != Opcodes.GETSTATIC
&& ain.getOpcode() != Opcodes.LLOAD && ain.getOpcode() != Opcodes.DLOAD;
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
if (opcode == Opcodes.INVOKESTATIC && "$jacocoInit".equals(name)) {
// Rewrite $jacocoInit() calls to just read the $jacocoData field
super.visitFieldInsn(Opcodes.GETSTATIC, owner, "$jacocoData", "[Z");
} else {
super.visitMethodInsn(opcode, owner, name, desc, itf);
}
}
private static boolean isSdkVersionLookup(@NonNull AbstractInsnNode instruction) {
if (instruction.getOpcode() == Opcodes.GETSTATIC) {
FieldInsnNode fieldNode = (FieldInsnNode) instruction;
return (SDK_INT.equals(fieldNode.name)
&& ANDROID_OS_BUILD_VERSION.equals(fieldNode.owner));
}
return false;
}
@Override
public MethodNode generate() {
MethodNode method = this.createMethod(this.targetType.getSize(), this.targetType.getSize());
if (!this.targetIsStatic) {
method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
}
int opcode = this.targetIsStatic ? Opcodes.GETSTATIC : Opcodes.GETFIELD;
method.instructions.add(new FieldInsnNode(opcode, this.info.getClassNode().name, this.targetField.name, this.targetField.desc));
method.instructions.add(new InsnNode(this.targetType.getOpcode(Opcodes.IRETURN)));
return method;
}
@Override
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
if (!"java/lang/invoke/LambdaMetafactory".equals(bsm.getOwner())) {
// Not an invokedynamic for a lambda expression
super.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
return;
}
try {
Lookup lookup = createLookup(internalName);
ArrayList<Object> args = new ArrayList<>(bsmArgs.length + 3);
args.add(lookup);
args.add(name);
args.add(MethodType.fromMethodDescriptorString(desc, targetLoader));
for (Object bsmArg : bsmArgs) {
args.add(toJvmMetatype(lookup, bsmArg));
}
// Both bootstrap methods in LambdaMetafactory expect a MethodHandle as their 5th argument
// so we can assume bsmArgs[1] (the 5th arg) to be a Handle.
MethodReferenceBridgeInfo bridgeInfo = queueUpBridgeMethodIfNeeded((Handle) bsmArgs[1]);
// Resolve the bootstrap method in "host configuration" (this tool's default classloader)
// since targetLoader may only contain stubs that we can't actually execute.
// generateLambdaClass() below will invoke the bootstrap method, so a stub isn't enough,
// and ultimately we don't care if the bootstrap method was even on the bootclasspath
// when this class was compiled (although it must've been since javac is unhappy otherwise).
MethodHandle bsmMethod = toMethodHandle(publicLookup(), bsm, /*target*/ false);
// Give generated classes to have more stable names (b/35643761). Use BSM's naming scheme
// but with separate counter for each surrounding class.
String lambdaClassName = internalName + "$$Lambda$" + (lambdaCount++);
Type[] capturedTypes = Type.getArgumentTypes(desc);
boolean needFactory =
capturedTypes.length != 0
&& !attemptAllocationBeforeArgumentLoads(lambdaClassName, capturedTypes);
lambdas.generateLambdaClass(
internalName,
LambdaInfo.create(
lambdaClassName,
desc,
needFactory,
bridgeInfo.methodReference(),
bridgeInfo.bridgeMethod()),
bsmMethod,
args);
if (desc.startsWith("()")) {
// For stateless lambda classes we'll generate a singleton instance that we can just load
checkState(capturedTypes.length == 0);
super.visitFieldInsn(
Opcodes.GETSTATIC,
lambdaClassName,
LambdaClassFixer.SINGLETON_FIELD_NAME,
desc.substring("()".length()));
} else if (needFactory) {
// If we were unable to inline the allocation of the generated lambda class then
// invoke factory method of generated lambda class with the arguments on the stack
super.visitMethodInsn(
Opcodes.INVOKESTATIC,
lambdaClassName,
LambdaClassFixer.FACTORY_METHOD_NAME,
desc,
/*itf*/ false);
} else {
// Otherwise we inserted a new/dup pair of instructions above and now just need to invoke
// the constructor of generated lambda class with the arguments on the stack
super.visitMethodInsn(
Opcodes.INVOKESPECIAL,
lambdaClassName,
"<init>",
Type.getMethodDescriptor(Type.VOID_TYPE, capturedTypes),
/*itf*/ false);
}
} catch (IOException | ReflectiveOperationException e) {
throw new IllegalStateException(
"Couldn't desugar invokedynamic for "
+ internalName
+ "."
+ name
+ " using "
+ bsm
+ " with arguments "
+ Arrays.toString(bsmArgs),
e);
}
}
static boolean isGetStatic(final int mod) {
return (mod & Opcodes.GETSTATIC) != 0;
}
@Override
public boolean assignTo(String varName, StringBuilder sb) {
if (opcode == Opcodes.GETSTATIC || (opcode == Opcodes.GETFIELD)) {
StringBuilder b = new StringBuilder();
if (varName != null) {
b.append(varName).append(" = ");
}
if (opcode == Opcodes.GETSTATIC) {
b.append("get_static_");
b.append(owner.replace('/', '_').replace('$', '_'));
b.append("_");
b.append(name.replace('/', '_').replace('$', '_'));
b.append("(threadStateData)");
} else {
b.append("get_field_");
b.append(owner.replace('/', '_').replace('$', '_'));
b.append("_");
b.append(name);
StringBuilder sb3 = new StringBuilder();
boolean targetProvided = (targetOp != null &&
targetOp instanceof AssignableExpression &&
((AssignableExpression)targetOp).assignTo(null, sb3));
if (targetProvided) {
b.append("(").append(sb3.toString().trim()).append(")");
//} else if (useThis) {
// b.append("(__cn1ThisObject)");
} else {
return false;
}
}
if (varName != null) {
b.append(";\n");
}
sb.append(b);
return true;
}
return false;
}
public FieldInsnNode() {
super(Opcodes.GETSTATIC);
owner = "";
desc = "";
name = "";
}
@Override
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
if (DEBUG) {
System.out.println(
"Visit field access : " + owner + ":" + name + ":" + desc + ":" + isStatic);
}
AccessRight accessRight;
if (!owner.equals(visitedClassName)) {
if (DEBUG) {
System.out.println(owner + ":" + name + " field access");
}
// we are accessing another object field, and at this point the visitor is not smart
// enough to know if has seen this class before or not so we must assume the field
// is *not* accessible from the $override class which lives in a different
// hierarchy and package.
// However, since we made all package-private and protected fields public, and it
// cannot be private since the visitedClassName is not the "owner", we can safely
// assume it's public.
accessRight = AccessRight.PUBLIC;
} else {
// check the field access bits.
FieldNode fieldNode = getFieldByName(name);
if (fieldNode == null) {
// If this is an inherited field, we might not have had access to the parent
// bytecode. In such a case, treat it as private.
accessRight = AccessRight.PACKAGE_PRIVATE;
} else {
accessRight = AccessRight.fromNodeAccess(fieldNode.access);
}
}
boolean handled = false;
switch (opcode) {
case Opcodes.PUTSTATIC:
case Opcodes.GETSTATIC:
handled = visitStaticFieldAccess(opcode, owner, name, desc, accessRight);
break;
case Opcodes.PUTFIELD:
case Opcodes.GETFIELD:
handled = visitFieldAccess(opcode, owner, name, desc, accessRight);
break;
default:
System.out.println("Unhandled field opcode " + opcode);
}
if (!handled) {
super.visitFieldInsn(opcode, owner, name, desc);
}
}