org.objectweb.asm.Opcodes# SWAP 源码实例Demo

下面列出了org.objectweb.asm.Opcodes# SWAP 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。


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;
}
 

private void buildRecorderFromObject(
    int opcode, String owner, String name, String signature, boolean itf) {
  super.visitMethodInsn(opcode, owner, name, signature, itf);
  // -> stack: ... newobj
  super.visitInsn(Opcodes.DUP);
  // -> stack: ... newobj newobj
  super.visitInsn(Opcodes.DUP);
  // -> stack: ... newobj newobj newobj
  // We could be instantiating this class or a subclass, so we
  // have to get the class the hard way.
  super.visitMethodInsn(
      Opcodes.INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
  // -> stack: ... newobj newobj Class
  super.visitInsn(Opcodes.SWAP);
  // -> stack: ... newobj Class newobj
  super.visitMethodInsn(
      Opcodes.INVOKESTATIC, recorderClass, recorderMethod, CLASS_RECORDER_SIG, false);
  // -> stack: ... newobj
}
 

private void invokeRecordAllocation(String typeName) {
  Matcher matcher = namePattern.matcher(typeName);
  if (matcher.find()) {
    typeName = matcher.group(1);
  }
  // stack: ... count newobj
  super.visitInsn(Opcodes.DUP_X1);
  // -> stack: ... newobj count newobj
  super.visitLdcInsn(typeName);
  // -> stack: ... newobj count newobj typename
  super.visitInsn(Opcodes.SWAP);
  // -> stack: ... newobj count typename newobj
  super.visitMethodInsn(
      Opcodes.INVOKESTATIC, recorderClass, recorderMethod, RECORDER_SIGNATURE, false);
  // -> stack: ... newobj
}
 
源代码4 项目: Concurnas   文件: Globalizer.java

private void genericSswap(String desc) {
	//caters for double, int on stack - to swap
	if(desc.equals("J") || desc.equals("D")){//long and double take up two slots insteead of 1
		super.visitInsn(Opcodes.DUP_X2);
		super.visitInsn(Opcodes.POP);
	}
	else{//1 slot each
		super.visitInsn(Opcodes.SWAP);
	}
}
 
源代码5 项目: deobfuscator   文件: SwapFrame.java

public SwapFrame(Frame top, Frame bottom) {
    super (Opcodes.SWAP);
    this.top = top;
    this.bottom = bottom;
    this.top.children.add(this);
    this.bottom.children.add(this);
}
 
源代码6 项目: dacapobench   文件: AllocateInstrument.java

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);
}
 

void calculateArrayLengthAndDispatch(String typeName, int dimCount) {
  // Since the dimensions of the array are not known at instrumentation
  // time, we take the created multi-dimensional array and peel off nesting
  // levels from the left.  For each nesting layer we probe the array length
  // and accumulate a partial product which we can then feed the recording
  // function.

  // below we note the partial product of dimensions 1 to X-1 as productToX
  // (so productTo1 == 1 == no dimensions yet).  We denote by aref0 the
  // array reference at the current nesting level (the containing aref's [0]
  // element).  If we hit a level whose arraylength is 0 or whose
  // reference is null, there's no point continuing, so we shortcut
  // out.

  // This approach works pretty well when you create a new array with the
  // newarray bytecodes.  You can also create a new array by cloning an
  // existing array; an existing multidimensional array might have had some
  // of its [0] elements nulled out.  We currently deal with this by bailing
  // out, but arguably we should do something more principled (like calculate
  // the size of the multidimensional array from scratch if you are using
  // clone()).
  // TODO(java-platform-team): Do something about modified multidimensional
  // arrays and clone().
  Label zeroDimension = new Label();
  super.visitInsn(Opcodes.DUP); // -> stack: ... origaref aref0
  super.visitLdcInsn(1); // -> stack: ... origaref aref0 productTo1
  for (int i = 0; i < dimCount; ++i) {
    // pre: stack: ... origaref aref0 productToI
    super.visitInsn(Opcodes.SWAP); // -> stack: ... origaref productToI aref
    super.visitInsn(Opcodes.DUP);

    Label nonNullDimension = new Label();
    // -> stack: ... origaref productToI aref aref
    super.visitJumpInsn(Opcodes.IFNONNULL, nonNullDimension);
    // -> stack: ... origaref productToI aref
    super.visitInsn(Opcodes.SWAP);
    // -> stack: ... origaref aref productToI
    super.visitJumpInsn(Opcodes.GOTO, zeroDimension);
    super.visitLabel(nonNullDimension);

    // -> stack: ... origaref productToI aref
    super.visitInsn(Opcodes.DUP_X1);
    // -> stack: ... origaref aref0 productToI aref
    super.visitInsn(Opcodes.ARRAYLENGTH);
    // -> stack: ... origaref aref0 productToI dimI

    Label nonZeroDimension = new Label();
    super.visitInsn(Opcodes.DUP);
    // -> stack: ... origaref aref0 productToI dimI dimI
    super.visitJumpInsn(Opcodes.IFNE, nonZeroDimension);
    // -> stack: ... origaref aref0 productToI dimI
    super.visitInsn(Opcodes.POP);
    // -> stack: ... origaref aref0 productToI
    super.visitJumpInsn(Opcodes.GOTO, zeroDimension);
    super.visitLabel(nonZeroDimension);
    // -> stack: ... origaref aref0 productToI max(dimI,1)

    super.visitInsn(Opcodes.IMUL);
    // -> stack: ... origaref aref0 productTo{I+1}
    if (i < dimCount - 1) {
      super.visitInsn(Opcodes.SWAP);
      // -> stack: ... origaref productTo{I+1} aref0
      super.visitInsn(Opcodes.ICONST_0);
      // -> stack: ... origaref productTo{I+1} aref0 0
      super.visitInsn(Opcodes.AALOAD);
      // -> stack: ... origaref productTo{I+1} aref0'
      super.visitInsn(Opcodes.SWAP);
    }
    // post: stack: ... origaref aref0 productTo{I+1}
  }
  super.visitLabel(zeroDimension);

  super.visitInsn(Opcodes.SWAP); // -> stack: ... origaref product aref0
  super.visitInsn(Opcodes.POP); // -> stack: ... origaref product
  super.visitInsn(Opcodes.SWAP); // -> stack: ... product origaref
  invokeRecordAllocation(typeName);
}
 

public void visitMethodInsn(final int opcode, final String owner,
		final String name, final String desc) {

	// Special case method invocations for name translation.
	// Specifically to deal with methods mirrors.
	String newOwner = owner;
	int newOpcode = opcode;
	String newDesc = translator.translateMethodDescriptor(desc);
	
	String lookupOwner = owner;
	while (lookupOwner.startsWith("[")) {
		lookupOwner = lookupOwner.substring(1);
	}
	final Mirror mirror = translator.getMirror(lookupOwner);

	if (mirror.isClassMirror()) {
		newOwner = translator.translate(owner);
	} else if ("<init>".equals(name)&&(opcode == Opcodes.INVOKESPECIAL)) {
		/* Look for an equivalent constructor. For instance,
		 * INVOKESPECIAL, "java/math/BigDecimal", "<init>", "(I)V")
		 * will be transformed as
		 * INVOKESTATIC, "../BigDecimal_", "BigDecimal", "(I)Ljava/math/BigDecimal;"
		 * 
		 * the previously constructed object was on top of the stack and the mirror
		 * function has put its result on top, so a SWAP and POP are issued to
		 * discard the previously constructed object and store the new one instead.
		 */
		String constructorDesc = newDesc.substring(0, newDesc.length()-1) + 'L' + owner + ';';
		String constructorName;
		int i = owner.lastIndexOf('/');
		if (i == -1) {
			constructorName = owner;
		} else {
			constructorName = owner.substring(i+1);
		}
		if (mirror.hasMethod(owner, constructorName, constructorDesc, Opcodes.INVOKESPECIAL)) {
			newOwner = translator.translate(owner);

			super.visitMethodInsn(Opcodes.INVOKESTATIC, newOwner, constructorName,
					constructorDesc);

			super.visitInsn(Opcodes.SWAP);
			super.visitInsn(Opcodes.POP);
			super.visitInsn(Opcodes.SWAP);
			super.visitInsn(Opcodes.POP);
			return;
		}
	} else if (mirror.hasMethod(owner, name, newDesc, opcode)) {
		newOwner = translator.translate(owner);
		newOpcode = Opcodes.INVOKESTATIC;

		// We have to insert the owner into the arguments of the
		// descriptor
		if (opcode == Opcodes.INVOKEVIRTUAL || opcode == Opcodes.INVOKEINTERFACE) {
			final Type[] argTypes = Type.getArgumentTypes(newDesc);
			final Type[] newArgTypes = new Type[argTypes.length + 1];
			newArgTypes[0] = Type.getType("L" + owner + ";");
			System.arraycopy(argTypes, 0, newArgTypes, 1, argTypes.length);
			newDesc = Type.getMethodDescriptor(
					Type.getReturnType(newDesc), newArgTypes);
			newDesc = translator.translateMethodDescriptor(newDesc);
		}
	}

	super.visitMethodInsn(newOpcode, newOwner, name, newDesc);
}
 
 方法所在类
 同类方法