Java Code Examples for org.objectweb.asm.Opcodes#GETFIELD

The following examples show how to use org.objectweb.asm.Opcodes#GETFIELD . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: JVMImpl.java    From serianalyzer with GNU General Public License v3.0 6 votes vote down vote up
/**
 * @param opcode
 * @param owner
 * @param name
 * @param desc
 * @param s
 */
static void handleFieldInsn ( int opcode, String owner, String name, String desc, JVMStackState s ) {
    switch ( opcode ) {
    case Opcodes.GETFIELD:
        Object tgt = s.pop();
        if ( log.isTraceEnabled() ) {
            log.trace("From " + tgt); //$NON-NLS-1$
        }
    case Opcodes.GETSTATIC:
        // this can be more specific
        if ( log.isTraceEnabled() ) {
            log.trace("Load field " + name + " (" + desc + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
        }
        s.push(new FieldReference(DotName.createSimple(owner.replace('/', '.')), name, Type.getType(desc), true));
        break;
    case Opcodes.PUTFIELD:
        s.pop();
        s.pop();
        break;
    case Opcodes.PUTSTATIC:
        s.pop();
        break;
    default:
        log.warn("Unsupported opcode " + opcode); //$NON-NLS-1$
    }
}
 
Example 2
Source File: FlowObfuscationTransformer.java    From deobfuscator with Apache License 2.0 6 votes vote down vote up
private List<AbstractInsnNode> getPossibleSwap(AbstractInsnNode ain, int mode)
{
	AbstractInsnNode next = ain;
	List<AbstractInsnNode> instrs = new ArrayList<>();
	while(next != null)
	{
		if(Utils.isInstruction(next) && next.getOpcode() != Opcodes.IINC)
			instrs.add(next);
		if(instrs.size() >= (mode == 0 ? 3 : 4))
			break;
		next = next.getNext();
	}
	if(mode == 0 && instrs.size() >= 3 && willPush(instrs.get(0)) && willPush(instrs.get(1))
		&& instrs.get(2).getOpcode() == Opcodes.SWAP)
		return instrs;
	else if(mode == 1 && instrs.size() >= 4 && willPush(instrs.get(0)) 
		&& (willPush(instrs.get(1)) || instrs.get(1).getOpcode() == Opcodes.DUP)
		&& instrs.get(2).getOpcode() == Opcodes.GETFIELD
		&& Type.getType(((FieldInsnNode)instrs.get(2)).desc).getSort() != Type.LONG
		&& Type.getType(((FieldInsnNode)instrs.get(2)).desc).getSort() != Type.DOUBLE
		&& instrs.get(3).getOpcode() == Opcodes.SWAP)
		return instrs;
	else
		return null;
}
 
Example 3
Source File: ClassMeteringReadOnlyTest.java    From AVM with MIT License 6 votes vote down vote up
/**
 * Parses a test class into extents.
 */
@Test
public void testMethodBlocks() throws Exception {
    List<BasicBlock> initBlocks = METHOD_BLOCKS.get("<init>(I)V");
    int[][] expectedInitBlocks = new int[][]{
            {Opcodes.ALOAD, Opcodes.INVOKESPECIAL, Opcodes.ALOAD, Opcodes.ILOAD, Opcodes.PUTFIELD, Opcodes.RETURN}
    };
    boolean didMatch = compareBlocks(expectedInitBlocks, initBlocks);
    Assert.assertTrue(didMatch);
    List<BasicBlock> hashCodeBlocks = METHOD_BLOCKS.get("hashCode()I");
    int[][] expectedHashCodeBlocks = new int[][]{
            {Opcodes.ALOAD, Opcodes.GETFIELD, Opcodes.IRETURN}
    };
    didMatch = compareBlocks(expectedHashCodeBlocks, hashCodeBlocks);
    Assert.assertTrue(didMatch);
}
 
Example 4
Source File: AbstractFurnaceBlockEntityMixin_RealTime.java    From Galaxy with GNU Affero General Public License v3.0 6 votes vote down vote up
@Redirect(
    method = "tick",
    at = @At(
        value = "FIELD",
        target = "Lnet/minecraft/block/entity/AbstractFurnaceBlockEntity;cookTime:I",
        opcode = Opcodes.PUTFIELD
    ),
    slice = @Slice(
        from = @At(
            value = "INVOKE",
            target = "Lnet/minecraft/block/entity/AbstractFurnaceBlockEntity;canAcceptRecipeOutput(Lnet/minecraft/recipe/Recipe;)Z",
            ordinal = 1
        ),
        to = @At(
            value = "FIELD",
            target = "Lnet/minecraft/block/entity/AbstractFurnaceBlockEntity;cookTimeTotal:I",
            opcode = Opcodes.GETFIELD,
            ordinal = 0
        )
    )
)
private void realTimeImpl$adjustForRealTimeCookTime(final AbstractFurnaceBlockEntity self, final int modifier) {
    final int ticks = (int) ((RealTimeTrackingBridge) this.getWorld()).realTimeBridge$getRealTimeTicks();
    this.cookTime = Math.min(this.cookTimeTotal, this.cookTime + ticks);
}
 
Example 5
Source File: EntityMixin_RealTime.java    From Galaxy with GNU Affero General Public License v3.0 6 votes vote down vote up
@Redirect(method = "baseTick",
    at = @At(
        value = "FIELD",
        target = "Lnet/minecraft/entity/Entity;ridingCooldown:I",
        opcode = Opcodes.PUTFIELD
    ),
    slice = @Slice(
        from = @At(
            value = "INVOKE",
            target = "Lnet/minecraft/entity/Entity;stopRiding()V"
        ),
        to = @At(
            value = "FIELD",
            target = "Lnet/minecraft/entity/Entity;horizontalSpeed:F",
            opcode = Opcodes.GETFIELD
        )
    )
)
private void realTimeImpl$adjustForRealTimeEntityCooldown(final Entity self, final int modifier) {
    final int ticks = (int) ((RealTimeTrackingBridge) this.world).realTimeBridge$getRealTimeTicks();
    this.ridingCooldown = Math.max(0, this.ridingCooldown - ticks);
}
 
Example 6
Source File: XFactory.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
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());
}
 
Example 7
Source File: RedirectInjector.java    From Mixin with MIT License 5 votes vote down vote up
RedirectedFieldData(Target target, FieldInsnNode node) {
    super(target);
    this.node = node;
    this.opcode = node.getOpcode();
    this.owner = Type.getObjectType(node.owner);
    this.type = Type.getType(node.desc);
    this.dimensions = (this.type.getSort() == Type.ARRAY) ? this.type.getDimensions() : 0;
    this.isStatic = this.opcode == Opcodes.GETSTATIC || this.opcode == Opcodes.PUTSTATIC;
    this.isGetter = this.opcode == Opcodes.GETSTATIC || this.opcode == Opcodes.GETFIELD;
    this.isSetter = this.opcode == Opcodes.PUTSTATIC || this.opcode == Opcodes.PUTFIELD;
    this.description = this.isGetter ? "field getter" : this.isSetter ? "field setter" : "handler";
}
 
Example 8
Source File: MixinTargetContext.java    From Mixin with MIT License 5 votes vote down vote up
/**
 * Handle "imaginary super" invocations, these are invocations in
 * non-derived mixins for accessing methods known to exist in a supermixin
 * which is not directly inherited by this mixix. The method can only call
 * its <b>own</b> super-implmentation and the methd must also be tagged with
 * {@link SoftOverride} to indicate that the method must exist in a super
 * class.
 * 
 * @param method Method being processed
 * @param fieldInsn the GETFIELD insn which access the pseudo-field which is
 *      used as a handle to the superclass
 */
private void processImaginarySuper(MethodNode method, FieldInsnNode fieldInsn) {
    if (fieldInsn.getOpcode() != Opcodes.GETFIELD) {
        if (Constants.CTOR.equals(method.name)) {
            throw new InvalidMixinException(this, "Illegal imaginary super declaration: field " + fieldInsn.name
                    + " must not specify an initialiser");
        }
        
        throw new InvalidMixinException(this, "Illegal imaginary super access: found " + Bytecode.getOpcodeName(fieldInsn.getOpcode())
                + " opcode in " + method.name + method.desc);
    }
    
    if ((method.access & Opcodes.ACC_PRIVATE) != 0 || (method.access & Opcodes.ACC_STATIC) != 0) {
        throw new InvalidMixinException(this, "Illegal imaginary super access: method " + method.name + method.desc
                + " is private or static");
    }
    
    if (Annotations.getInvisible(method, SoftOverride.class) == null) {
        throw new InvalidMixinException(this, "Illegal imaginary super access: method " + method.name + method.desc
                + " is not decorated with @SoftOverride");
    }
    
    for (Iterator<AbstractInsnNode> methodIter = method.instructions.iterator(method.instructions.indexOf(fieldInsn)); methodIter.hasNext();) {
        AbstractInsnNode insn = methodIter.next();
        if (insn instanceof MethodInsnNode) {
            MethodInsnNode methodNode = (MethodInsnNode)insn;
            if (methodNode.owner.equals(this.getClassRef()) && methodNode.name.equals(method.name) && methodNode.desc.equals(method.desc)) {
                methodNode.setOpcode(Opcodes.INVOKESPECIAL);
                this.updateStaticBinding(method, new MemberRef.Method(methodNode));
                return;
            }
        }
    }
    
    throw new InvalidMixinException(this, "Illegal imaginary super access: could not find INVOKE for " + method.name + method.desc);
}
 
Example 9
Source File: MixinTargetContext.java    From Mixin with MIT License 5 votes vote down vote up
private void checkFinal(MethodNode method, Iterator<AbstractInsnNode> iter, FieldInsnNode fieldNode) {
    if (!fieldNode.owner.equals(this.getTarget().getClassRef())) {
        return;
    }
    
    int opcode = fieldNode.getOpcode();
    if (opcode == Opcodes.GETFIELD || opcode == Opcodes.GETSTATIC) {
        return;
    }
    
    for (Entry<FieldNode, Field> shadow : this.shadowFields.entrySet()) {
        FieldNode shadowFieldNode = shadow.getKey();
        if (!shadowFieldNode.desc.equals(fieldNode.desc) || !shadowFieldNode.name.equals(fieldNode.name)) {
            continue;
        }
        Field shadowField = shadow.getValue();
        if (shadowField.isDecoratedFinal()) {
            if (shadowField.isDecoratedMutable()) {
                if (this.mixin.getParent().getEnvironment().getOption(Option.DEBUG_VERBOSE)) {
                    MixinTargetContext.logger.warn("Write access to @Mutable @Final field {} in {}::{}", shadowField, this.mixin, method.name);
                }                    
            } else {
                if (Constants.CTOR.equals(method.name) || Constants.CLINIT.equals(method.name)) {
                    MixinTargetContext.logger.warn("@Final field {} in {} should be final", shadowField, this.mixin);
                } else {
                    MixinTargetContext.logger.error("Write access detected to @Final field {} in {}::{}", shadowField, this.mixin, method.name);
                    if (this.mixin.getParent().getEnvironment().getOption(Option.DEBUG_VERIFY)) {
                        throw new InvalidMixinException(this.mixin, "Write access detected to @Final field " + shadowField + " in " + this.mixin
                                + "::" + method.name);
                    }
                }                    
            }
        }
        return;
    }
}
 
Example 10
Source File: Globalizer.java    From Concurnas with MIT License 5 votes vote down vote up
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);
}
 
Example 11
Source File: JClassPatcher.java    From rscplus with GNU General Public License v3.0 5 votes vote down vote up
/**
 * TODO: Complete JavaDoc
 *
 * @param methodNode
 * @param owner The class of the variable to be hooked
 * @param var The variable to be hooked
 * @param desc
 * @param newClass The class the hooked variable will be stored in
 * @param newVar The variable name the hooked variable will be stored in
 * @param newDesc
 * @param canRead Specifies if the hooked variable should be readable
 * @param canWrite Specifies if the hooked variable should be writable
 */
private void hookClassVariable(
    MethodNode methodNode,
    String owner,
    String var,
    String desc,
    String newClass,
    String newVar,
    String newDesc,
    boolean canRead,
    boolean canWrite) {
  Iterator<AbstractInsnNode> insnNodeList = methodNode.instructions.iterator();
  while (insnNodeList.hasNext()) {
    AbstractInsnNode insnNode = insnNodeList.next();

    int opcode = insnNode.getOpcode();
    if (opcode == Opcodes.GETFIELD || opcode == Opcodes.PUTFIELD) {
      FieldInsnNode field = (FieldInsnNode) insnNode;
      if (field.owner.equals(owner) && field.name.equals(var) && field.desc.equals(desc)) {
        if (opcode == Opcodes.GETFIELD && canWrite) {
          methodNode.instructions.insert(
              insnNode, new FieldInsnNode(Opcodes.GETSTATIC, newClass, newVar, newDesc));
          methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.POP));
        } else if (opcode == Opcodes.PUTFIELD && canRead) {
          methodNode.instructions.insertBefore(insnNode, new InsnNode(Opcodes.DUP_X1));
          methodNode.instructions.insert(
              insnNode, new FieldInsnNode(Opcodes.PUTSTATIC, newClass, newVar, newDesc));
        }
      }
    }
  }
}
 
Example 12
Source File: ManagedStrategyTransformer.java    From lin-check with GNU Lesser General Public License v3.0 5 votes vote down vote up
@Override
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
    switch (opcode) {
    case Opcodes.GETSTATIC:
    case Opcodes.GETFIELD:
        invokeBeforeSharedVariableRead();
        break;
    case Opcodes.PUTSTATIC:
    case Opcodes.PUTFIELD:
        invokeBeforeSharedVariableWrite();
        break;
    }
    super.visitFieldInsn(opcode, owner, name, desc);
}
 
Example 13
Source File: LazyLoadingMethodVisitor.java    From AVM with MIT License 4 votes vote down vote up
/**
 * NOTE:  All calls to instruction visitation routines are made against super, directly, since we do frame offset accounting within our overrides
 * and that offset only applies to incoming bytecodes, not outgoing ones.
 * 
 * @param opcode The opcode.
 * @param descriptor The type descriptor of the field to which the opcode is applied.
 */
private void checkInjectLazyLoad(int opcode, String descriptor) {
    // If this is a PUTFIELD or GETFIELD, we want to call "lazyLoad()":
    // -PUTIFELD:  DUP2, POP, INVOKEVIRTUAL
    // -GETIFELD:  DUP, INVOKEVIRTUAL
    if ((Opcodes.PUTFIELD == opcode) && ((null == this.tracker) || !this.tracker.isThisTargetOfPut(this.frameOffset))) {
        // We need to see how big this type is since double and long need a far more complex dance.
        if ((1 == descriptor.length()) && ((DescriptorParser.LONG == descriptor.charAt(0)) || (DescriptorParser.DOUBLE == descriptor.charAt(0)))) {
            // Here, the stack looks like: ... OBJECT, VAR1, VAR2 (top)
            // Where we need:  ... OBJECT, VAR1, VAR2, OBJECT (top)
            // This is multiple stages:
            // DUP2_X1: ... VAR1, VAR2, OBJECT, VAR1, VAR2 (top)
            super.visitInsn(Opcodes.DUP2_X1);
            // POP2: ... VAR1, VAR2, OBJECT (top)
            super.visitInsn(Opcodes.POP2);
            // DUP: ... VAR1, VAR2, OBJECT, OBJECT (top)
            super.visitInsn(Opcodes.DUP);
            // INOKE: ... VAR1, VAR2, OBJECT (top)
            super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, SHADOW_OBJECT_NAME, LAZY_LOAD_NAME, LAZY_LOAD_DESCRIPTOR, false);
            // DUP_X2: ... OBJECT, VAR1, VAR2, OBJECT (top)
            super.visitInsn(Opcodes.DUP_X2);
            // POP: ... OBJECT, VAR1, VAR2 (top)
            super.visitInsn(Opcodes.POP);
        } else {
            // Here, the stack looks like: ... OBJECT, VAR, (top)
            // Where we need:  ... OBJECT, VAR, OBJECT (top)
            // Stages:
            // DUP2: ... OBJECT, VAR, OBJECT, VAR (top)
            super.visitInsn(Opcodes.DUP2);
            // POP: ... OBJECT, VAR, OBJECT (top)
            super.visitInsn(Opcodes.POP);
            // INOKE: ... OBJECT, VAR (top)
            super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, SHADOW_OBJECT_NAME, LAZY_LOAD_NAME, LAZY_LOAD_DESCRIPTOR, false);
        }
    } else if ((Opcodes.GETFIELD == opcode) && ((null == this.tracker) || !this.tracker.isThisTargetOfGet(this.frameOffset))) {
        // Here, the stack looks like: ... OBJECT, (top)
        // Where we need:  ... OBJECT, OBJECT (top)
        super.visitInsn(Opcodes.DUP);
        super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, SHADOW_OBJECT_NAME, LAZY_LOAD_NAME, LAZY_LOAD_DESCRIPTOR, false);
    }
}
 
Example 14
Source File: IncrementalChangeVisitor.java    From AnoleFix with MIT License 4 votes vote down vote up
@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);
    }
}
 
Example 15
Source File: AllocateInstrument.java    From dacapobench with Apache License 2.0 4 votes vote down vote up
public void visitFieldInsn(int opcode, String owner, String fieldName,
		String desc) {
	if (firstInstruction)
		addInc();
	if (logPointerChange && opcode == Opcodes.PUTFIELD
			&& desc.charAt(0) == 'L') {
		if (constructor && !doneSuperConstructor && name.equals(owner)
				&& finalFields.contains(fieldName))
			delayedFieldPointer.put(fieldName, desc);
		else {
			// instrument reference changes from
			// putfield ...,obj,v' => ...
			// to
			// dup2 ...,obj,v' => ...,obj,v',obj,v'
			// swap ...,obj,v',obj,v' => ...,obj,v',v',obj
			// dup ...,obj,v',v',obj => ...,obj,v',v',obj,obj
			// getfield ...,obj,v',v',obj,obj => ...,obj,v',v',obj,v
			// invokespecial
			// pointerchangelog(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V
			// ...,obj,v',v',obj,v => ...,obj,v'
			// putfield ...,obj,v' =>
			super.visitInsn(Opcodes.DUP2);
			super.visitInsn(Opcodes.SWAP);
			super.visitInsn(Opcodes.DUP);
			super.visitFieldInsn(Opcodes.GETFIELD, owner, fieldName,
					desc);
			super.visitMethodInsn(Opcodes.INVOKESTATIC, name,
					LOG_INTERNAL_POINTER_CHANGE,
					POINTER_CHANGE_SIGNATURE);
		}
	} else if (logPointerChange && opcode == Opcodes.PUTSTATIC
			&& desc.charAt(0) == 'L') {
		// if (finalFields.contains(fieldName)) {
		// // assume field is initially null
		// super.visitInsn(Opcodes.DUP);
		// } else {
		// instrument reference changes from
		// putstatic ...,v' => ...
		// to
		// dup ...,v' => ...,v',v'
		// ldc owner.class ...,v',v' => ...,v',v',k
		// getstatic ...,v',v',k => ...,v',v',k,v
		// invokespecial
		// staticpointerchangelog(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Object;)V
		// ...,v',v',k,v => ...,v'
		super.visitInsn(Opcodes.DUP);
		super.visitLdcInsn(Type.getObjectType(owner));
		super.visitFieldInsn(Opcodes.GETSTATIC, owner, fieldName, desc);
		super.visitMethodInsn(Opcodes.INVOKESTATIC, name,
				LOG_INTERNAL_STATIC_POINTER_CHANGE,
				STATIC_POINTER_CHANGE_SIGNATURE);
		// }
	}
	super.visitFieldInsn(opcode, owner, fieldName, desc);
}
 
Example 16
Source File: Field.java    From CodenameOne with GNU General Public License v2.0 4 votes vote down vote up
@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;
}
 
Example 17
Source File: FieldGetterDetector.java    From javaide with GNU General Public License v3.0 4 votes vote down vote up
private static Map<String, String> checkMethods(ClassNode classNode, Set<String> names) {
    Map<String, String> validGetters = Maps.newHashMap();
    @SuppressWarnings("rawtypes")
    List methods = classNode.methods;
    String fieldName = null;
    checkMethod:
    for (Object methodObject : methods) {
        MethodNode method = (MethodNode) methodObject;
        if (names.contains(method.name)
                && method.desc.startsWith("()")) { //$NON-NLS-1$ // (): No arguments
            InsnList instructions = method.instructions;
            int mState = 1;
            for (AbstractInsnNode curr = instructions.getFirst();
                    curr != null;
                    curr = curr.getNext()) {
                switch (curr.getOpcode()) {
                    case -1:
                        // Skip label and line number nodes
                        continue;
                    case Opcodes.ALOAD:
                        if (mState == 1) {
                            fieldName = null;
                            mState = 2;
                        } else {
                            continue checkMethod;
                        }
                        break;
                    case Opcodes.GETFIELD:
                        if (mState == 2) {
                            FieldInsnNode field = (FieldInsnNode) curr;
                            fieldName = field.name;
                            mState = 3;
                        } else {
                            continue checkMethod;
                        }
                        break;
                    case Opcodes.ARETURN:
                    case Opcodes.FRETURN:
                    case Opcodes.IRETURN:
                    case Opcodes.DRETURN:
                    case Opcodes.LRETURN:
                    case Opcodes.RETURN:
                        if (mState == 3) {
                            validGetters.put(method.name, fieldName);
                        }
                        continue checkMethod;
                    default:
                        continue checkMethod;
                }
            }
        }
    }

    return validGetters;
}
 
Example 18
Source File: MemberSubstitution.java    From byte-buddy with Apache License 2.0 4 votes vote down vote up
@Override
public void visitFieldInsn(int opcode, String owner, String internalName, String descriptor) {
    TypePool.Resolution resolution = typePool.describe(owner.replace('/', '.'));
    if (resolution.isResolved()) {
        FieldList<FieldDescription.InDefinedShape> candidates = resolution.resolve().getDeclaredFields().filter(strict
                ? ElementMatchers.<FieldDescription>named(internalName).and(hasDescriptor(descriptor))
                : ElementMatchers.<FieldDescription>failSafe(named(internalName).and(hasDescriptor(descriptor))));
        if (!candidates.isEmpty()) {
            Replacement.Binding binding = replacement.bind(instrumentedType,
                    instrumentedMethod,
                    candidates.getOnly(),
                    opcode == Opcodes.PUTFIELD || opcode == Opcodes.PUTSTATIC);
            if (binding.isBound()) {
                TypeList.Generic parameters;
                TypeDescription.Generic result;
                switch (opcode) {
                    case Opcodes.PUTFIELD:
                        parameters = new TypeList.Generic.Explicit(candidates.getOnly().getDeclaringType(), candidates.getOnly().getType());
                        result = TypeDescription.Generic.VOID;
                        break;
                    case Opcodes.PUTSTATIC:
                        parameters = new TypeList.Generic.Explicit(candidates.getOnly().getType());
                        result = TypeDescription.Generic.VOID;
                        break;
                    case Opcodes.GETFIELD:
                        parameters = new TypeList.Generic.Explicit(candidates.getOnly().getDeclaringType());
                        result = candidates.getOnly().getType();
                        break;
                    case Opcodes.GETSTATIC:
                        parameters = new TypeList.Generic.Empty();
                        result = candidates.getOnly().getType();
                        break;
                    default:
                        throw new IllegalStateException("Unexpected opcode: " + opcode);
                }
                stackSizeBuffer = Math.max(stackSizeBuffer, binding.make(parameters, result, getFreeOffset())
                        .apply(new LocalVariableTracingMethodVisitor(mv), implementationContext)
                        .getMaximalSize() - result.getStackSize().getSize());
                return;
            }
        } else if (strict) {
            throw new IllegalStateException("Could not resolve " + owner.replace('/', '.')
                    + "." + internalName + descriptor + " using " + typePool);
        }
    } else if (strict) {
        throw new IllegalStateException("Could not resolve " + owner.replace('/', '.') + " using " + typePool);
    }
    super.visitFieldInsn(opcode, owner, internalName, descriptor);
}
 
Example 19
Source File: ABSMutator.java    From pitest with Apache License 2.0 4 votes vote down vote up
@Override
public void visitFieldInsn(int opcode, String owner, String name, String desc) {

    mv.visitFieldInsn(opcode, owner, name, desc);

    // non static
    if (opcode == Opcodes.GETFIELD) {
        if (desc.equals("I")) {
            if (this.shouldMutate("Negated integer field " + name)) {
                mv.visitInsn(Opcodes.INEG);
                return;
            }
        }
        if (desc.equals("F")) {
            if (this.shouldMutate("Negated float field " + name)) {
                mv.visitInsn(Opcodes.FNEG);
                return;
            }
        }
        if (desc.equals("J")) {
            if (this.shouldMutate("Negated long field " + name)) {
                mv.visitInsn(Opcodes.LNEG);
                return;
            }
        }
        if (desc.equals("D")) {
            if (this.shouldMutate("Negated double field " + name)) {
                mv.visitInsn(Opcodes.DNEG);
                return;
            }
        }
        if (desc.equals("B")) {
            if (this.shouldMutate("Negated byte field " + name)) {
                mv.visitInsn(Opcodes.INEG);
                mv.visitInsn(Opcodes.I2B);
                return;
            }
        }
        if (desc.equals("S")) {
            if (this.shouldMutate("Negated short field " + name)) {
                mv.visitInsn(Opcodes.INEG);
                mv.visitInsn(Opcodes.I2S);
                return;
            }
        }
    }

    // static
    if (opcode == Opcodes.GETSTATIC) {
        if (desc.equals("I")) {
            if (this.shouldMutate("Negated integer static field " + name)) {
                mv.visitInsn(Opcodes.INEG);
                return;
            }
        }
        if (desc.equals("F")) {
            if (this.shouldMutate("Negated float static field " + name)) {
                mv.visitInsn(Opcodes.FNEG);
                return;
            }
        }
        if (desc.equals("J")) {
            if (this.shouldMutate("Negated long static field " + name)) {
                mv.visitInsn(Opcodes.LNEG);
                return;
            }
        }
        if (desc.equals("D")) {
            if (this.shouldMutate("Negated double static field " + name)) {
                mv.visitInsn(Opcodes.DNEG);
                return;
            }
        }
        if (desc.equals("B")) {
            if (this.shouldMutate("Negated byte static field " + name)) {
                mv.visitInsn(Opcodes.INEG);
                mv.visitInsn(Opcodes.I2B);
                return;
            }
        }
        if (desc.equals("S")) {
            if (this.shouldMutate("Negated short static field " + name)) {
                mv.visitInsn(Opcodes.INEG);
                mv.visitInsn(Opcodes.I2S);
                return;
            }
        }
    }
}
 
Example 20
Source File: IncrementalChangeVisitor.java    From AnoleFix with MIT License 4 votes vote down vote up
/**
 * Visits an instance field access. The field could be of the visited class or it could be
 * an accessible field from the class being visited (unless it's private).
 * <p/>
 * For private instance fields, the access instruction is rewritten to calls to reflection
 * to access the fields value:
 * <p/>
 * Pseudo code for Get:
 * <code>
 * value = $instance.fieldName;
 * </code>
 * becomes:
 * <code>
 * value = (unbox)$package/AndroidInstantRuntime.getPrivateField($instance, $fieldName);
 * </code>
 * <p/>
 * Pseudo code for Set:
 * <code>
 * $instance.fieldName = value;
 * </code>
 * becomes:
 * <code>
 * $package/AndroidInstantRuntime.setPrivateField($instance, value, $fieldName);
 * </code>
 *
 * @param opcode      the field access opcode, can only be {@link Opcodes#PUTFIELD} or
 *                    {@link Opcodes#GETFIELD}
 * @param owner       the field declaring class
 * @param name        the field name
 * @param desc        the field type
 * @param accessRight the {@link AccessRight} for the field.
 * @return true if the field access was handled or false otherwise.
 */
private boolean visitFieldAccess(
        int opcode, String owner, String name, String desc, AccessRight accessRight) {

    // if the accessed field is anything but public, we must go through reflection.
    boolean useReflection = accessRight != AccessRight.PUBLIC;

    // if the accessed field is accessed from within a constructor, it might be a public
    // final field that cannot be set by anything but the original constructor unless
    // we use reflection.
    if (!useReflection) {
        useReflection = isConstructor && (owner.equals(visitedClassName));
    }

    if (useReflection) {
        // we should make this more efficient, have a per field access type method
        // for getting and setting field values.
        switch (opcode) {
            case Opcodes.GETFIELD:
                if (DEBUG) {
                    System.out.println("Get field");
                }
                // push declaring class
                visitLdcInsn(Type.getType("L" + owner + ";"));

                // the instance of the owner class we are getting the field value from
                // is on top of the stack. It could be "this"
                push(name);

                // Stack :  <receiver>
                //          <field_declaring_class>
                //          <field_name>
                invokeStatic(RUNTIME_TYPE,
                        Method.getMethod("Object getPrivateField(Object, Class, String)"));
                // Stack : <field_value>
                ByteCodeUtils.unbox(this, Type.getType(desc));
                break;
            case Opcodes.PUTFIELD:
                if (DEBUG) {
                    System.out.println("Set field");
                }
                // the instance of the owner class we are getting the field value from
                // is second on the stack. It could be "this"
                // top of the stack is the new value we are trying to set, box it.
                box(Type.getType(desc));

                // push declaring class
                visitLdcInsn(Type.getType("L" + owner + ";"));
                // push the field name.
                push(name);
                // Stack :  <receiver>
                //          <boxed_field_value>
                //          <field_declaring_class>
                //          <field_name>
                invokeStatic(RUNTIME_TYPE,
                        Method.getMethod(
                                "void setPrivateField(Object, Object, Class, String)"));
                break;
            default:
                throw new RuntimeException(
                        "VisitFieldAccess called with wrong opcode " + opcode);
        }
        return true;
    }
    // if this is a public field, no need to change anything we can access it from the
    // $override class.
    return false;
}