List of usage examples for org.objectweb.asm Opcodes DUP2
int DUP2
To view the source code for org.objectweb.asm Opcodes DUP2.
Click Source Link
From source file:org.jboss.byteman.agent.adapter.RuleTriggerMethodAdapter.java
License:Open Source License
private int doReturnOrThrowSave() { // allocate a slot for the return or throwable on top of the stack // stash the value into the slot and return the slot idx int saveValueSlot = newLocal(saveValueType); if (saveValueType.getSize() == 2) { visitInsn(Opcodes.DUP2); } else {/* ww w . j ava2s . c o m*/ visitInsn(Opcodes.DUP); } storeLocal(saveValueSlot); return saveValueSlot; }
From source file:org.jboss.byteman.rule.expression.ArrayExpression.java
License:Open Source License
@Override public void compileAssign(MethodVisitor mv, CompileContext compileContext) throws CompileException { // make sure we are at the right source line compileContext.notifySourceLine(line); Type valueType = arrayRef.getType().getBaseType(); int currentStack = compileContext.getStackCount(); boolean isTwoWords = (valueType.getNBytes() > 4); int toPop = 0; int size = (isTwoWords ? 2 : 1); // value to be assigned is TOS and will already be coerced to the correct value type // copy it so we can install the copy and leave the original as a a return value on the stack if (isTwoWords) { // [... val1 val2 ==> ... val1 val2 val1 val2] mv.visitInsn(Opcodes.DUP2); } else {//w w w . j av a 2 s.c o m // [... val ==> ... val val] mv.visitInsn(Opcodes.DUP); } compileContext.addStackCount(size); // compile load of array reference -- adds 1 to stack height arrayRef.compile(mv, compileContext); // for each index expression compile the expression and the do an array load Iterator<Expression> iterator = idxList.iterator(); while (iterator.hasNext()) { Expression idxExpr = iterator.next(); if (iterator.hasNext()) { // dereference the array to get an embedded array // compile expression index -- adds 1 to height idxExpr.compile(mv, compileContext); // make sure the index is an integer compileTypeConversion(idxExpr.getType(), Type.I, mv, compileContext); // fetch embedded array pop 2 and add 1 mv.visitInsn(Opcodes.AALOAD); compileContext.addStackCount(-1); valueType = valueType.getBaseType(); } else { if (isTwoWords) { // stack is [..., val1, val2, val1, val2, aref ] and we want [..., val1, val2, aref, val1, val2 ] mv.visitInsn(Opcodes.DUP_X2); // ==> [..., val1, val2, aref. val1, val2, aref ] compileContext.addStackCount(1); mv.visitInsn(Opcodes.POP); // ==> [..., val1, val2, aref. val1, val2 ] compileContext.addStackCount(-1); } else { // stack is [..., val, val, aref ] and we want [..., val, aref, val ] mv.visitInsn(Opcodes.SWAP); } // compile expression index -- adds 1 to height idxExpr.compile(mv, compileContext); // make sure the index is an integer compileTypeConversion(idxExpr.getType(), Type.I, mv, compileContext); if (isTwoWords) { // stack is [..., val1, val2, aref, val1, val2, idx] and we want [..., val1, val2, aref, idx, val1, val2 ] mv.visitInsn(Opcodes.DUP_X2); // ==> [..., val1, val2, aref, idx, val1, val2, idx] compileContext.addStackCount(1); mv.visitInsn(Opcodes.POP); // ==> [..., val1, val2, aref, idx, val1, val2 ] compileContext.addStackCount(-1); } else { // stack is [..., val, aref, val, idx] and we want [..., val, aref, idx, val ] mv.visitInsn(Opcodes.SWAP); } // now we can do the array store if (valueType.isObject() || valueType.isArray()) { // compile load object - pops 3 mv.visitInsn(Opcodes.AASTORE); toPop = -3; } else if (valueType == Type.Z || valueType == Type.B) { // compile load byte - pops 3 mv.visitInsn(Opcodes.BASTORE); toPop = -3; } else if (valueType == Type.S) { // compile load short - pops 3 mv.visitInsn(Opcodes.SASTORE); toPop = -3; } else if (valueType == Type.C) { // compile load char - pops 3 mv.visitInsn(Opcodes.CASTORE); toPop = -3; } else if (valueType == Type.I) { // compile load int - pops 3 mv.visitInsn(Opcodes.IASTORE); toPop = -3; } else if (valueType == Type.J) { // compile load long - pops 4 mv.visitInsn(Opcodes.LASTORE); toPop = -4; } else if (valueType == Type.F) { // compile load float - pops 3 mv.visitInsn(Opcodes.FASTORE); toPop = -3; } else if (valueType == Type.D) { // compile load double - pops 4 mv.visitInsn(Opcodes.DASTORE); toPop = -4; } compileContext.addStackCount(toPop); if (iterator.hasNext()) { assert valueType.isArray(); valueType = valueType.getBaseType(); } } } // check stack height if (compileContext.getStackCount() != currentStack) { throw new CompileException("ArrayExpression.compile : invalid stack height " + compileContext.getStackCount() + " expecting " + currentStack); } // we needed room for an aray and an index or for a one or two word result // but the recursive evaluations will have made sure the max stack is big enough // so there is no need to update the maximum stack height }
From source file:org.jboss.byteman.rule.expression.ComparisonExpression.java
License:Open Source License
public void compile(MethodVisitor mv, CompileContext compileContext) throws CompileException { // make sure we are at the right source line compileContext.notifySourceLine(line); Expression oper0 = getOperand(0); Expression oper1 = getOperand(1); int removed = 0; // evaluate the operands and ensure the reuslt is of the correct type for comparison adds 2 oper0.compile(mv, compileContext);//from w ww. j a v a 2s .c o m compileTypeConversion(oper0.getType(), comparisonType, mv, compileContext); oper1.compile(mv, compileContext); compileTypeConversion(oper1.getType(), comparisonType, mv, compileContext); // now do the appropriate type of comparison if (comparisonType == type.B || comparisonType == type.S || comparisonType == type.S || comparisonType == type.I) { Label elsetarget = new Label(); Label endtarget = new Label(); // we remove 2 words from the stack and then add 1 back removed = 2; switch (oper) { case LT: mv.visitJumpInsn(Opcodes.IF_ICMPGE, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; case LE: mv.visitJumpInsn(Opcodes.IF_ICMPGT, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; case GT: mv.visitJumpInsn(Opcodes.IF_ICMPLE, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; case GE: mv.visitJumpInsn(Opcodes.IF_ICMPLT, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; case EQ: mv.visitJumpInsn(Opcodes.IF_ICMPNE, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; case NE: mv.visitJumpInsn(Opcodes.IF_ICMPEQ, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; } } else if (comparisonType == type.J || comparisonType == type.F || comparisonType == type.D) { if (comparisonType == type.J) { mv.visitInsn(Opcodes.LCMP); // we remove four words from the stack and add 1 back removed = 4; } else if (comparisonType == type.F) { // we remove two words from the stack and add 1 back removed = 2; mv.visitInsn(Opcodes.FCMPG); } else if (comparisonType == type.D) { // we remove four words from the stack and add 1 back removed = 4; mv.visitInsn(Opcodes.DCMPG); } Label elsetarget = new Label(); Label endtarget = new Label(); switch (oper) { case LT: mv.visitJumpInsn(Opcodes.IFGE, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; case LE: mv.visitJumpInsn(Opcodes.IFGT, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; case GT: mv.visitJumpInsn(Opcodes.IFLE, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; case GE: mv.visitJumpInsn(Opcodes.IFLT, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; case EQ: mv.visitJumpInsn(Opcodes.IFNE, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; case NE: mv.visitJumpInsn(Opcodes.IFEQ, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; } } else if (comparable) { // we add a further two words setting up the relevant test then remove them // and also remove the original two words replacing them with a single word removed = 4; compileContext.addStackCount(2); // we need to deal with null values correctly // if op1 == null || op2 == null // then // EQ: // push value1 == value2 // NE: // push value1 != value2 // ow: // push false // else // execute compareTo or equals and test for the desired outcome // end if Label splittarget = new Label(); // else Label jointarget = new Label(); // end if mv.visitInsn(Opcodes.DUP2); // [... op1, op2 ] ==> [... op1, op2, op1, op2] mv.visitInsn(Opcodes.POP); // [... op1, op2, op1, op2 ] ==> [... op1, op2, op1] // if op1 == null mv.visitJumpInsn(Opcodes.IFNULL, splittarget); // [... op1, op2, op1] ==> [... op1, op2] mv.visitInsn(Opcodes.DUP); // [... op1, op2 ] ==> [... op1, op2, op2] // || op2 == null mv.visitJumpInsn(Opcodes.IFNULL, splittarget); // [... op1, op2, op2] ==> [... op1, op2] // so, it is ok to call compareTo leaving an int or equals leaving a boolean if (oper != EQ && oper != NE) { mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/lang/Comparable", "compareTo", "(Ljava/lang/Object;)I"); } else { mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z"); } // now if we did a compareTo we need to generate the required boolean Label elsetarget = new Label(); Label endtarget = new Label(); // if needed the convert the compareTo result to the required boolean outcome switch (oper) { case LT: mv.visitJumpInsn(Opcodes.IFGE, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; case LE: mv.visitJumpInsn(Opcodes.IFGT, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; case GT: mv.visitJumpInsn(Opcodes.IFLE, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; case GE: mv.visitJumpInsn(Opcodes.IFLT, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); break; case NE: mv.visitJumpInsn(Opcodes.IFEQ, elsetarget); mv.visitLdcInsn(false); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(true); mv.visitLabel(endtarget); break; } // skip to the join point mv.visitJumpInsn(Opcodes.GOTO, jointarget); // label the split point mv.visitLabel(splittarget); if (oper == EQ) { elsetarget = new Label(); endtarget = new Label(); mv.visitJumpInsn(Opcodes.IF_ACMPEQ, elsetarget); mv.visitLdcInsn(false); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(true); mv.visitLabel(endtarget); } else if (oper == NE) { elsetarget = new Label(); endtarget = new Label(); mv.visitJumpInsn(Opcodes.IF_ACMPNE, elsetarget); mv.visitLdcInsn(false); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(true); mv.visitLabel(endtarget); } else { // pop the operands and stack false mv.visitInsn(Opcodes.POP2); mv.visitLdcInsn(false); } // label the join point mv.visitLabel(jointarget); } else if (comparisonType == Type.Z) { // unboxed booleans need special treatment // we remove two words replacing them with a single word removed = 2; Label elsetarget = new Label(); Label endtarget = new Label(); mv.visitJumpInsn(Opcodes.IFEQ, elsetarget); // on this branch for EQ the stacked value is what we need and for NE // the stacked value needs flipping if (oper == NE) { Label elsetarget2 = new Label(); mv.visitJumpInsn(Opcodes.IFEQ, elsetarget2); mv.visitLdcInsn(false); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget2); mv.visitLdcInsn(true); } mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); // on this branch for NE the stacked value is what we need and for EQ // the stacked value needs flipping if (oper == EQ) { Label elsetarget2 = new Label(); mv.visitJumpInsn(Opcodes.IFEQ, elsetarget2); mv.visitLdcInsn(false); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget2); mv.visitLdcInsn(true); } mv.visitLabel(endtarget); } else if (comparisonType == Type.BOOLEAN) { // boxed booleans need special treatment // we remove two words replacing them with a single word removed = 2; Label elsetarget = new Label(); Label endtarget = new Label(); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java.lang.Boolean", "equals", "(Ljava/lang/Boolean;)Z"); if (oper == NE) { mv.visitJumpInsn(Opcodes.IFEQ, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); } } else { // we remove two words replacing them with a single word removed = 2; Label elsetarget = new Label(); Label endtarget = new Label(); if (oper == EQ) { mv.visitJumpInsn(Opcodes.IF_ACMPNE, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); } else { mv.visitJumpInsn(Opcodes.IF_ACMPEQ, elsetarget); mv.visitLdcInsn(true); mv.visitJumpInsn(Opcodes.GOTO, endtarget); mv.visitLabel(elsetarget); mv.visitLdcInsn(false); mv.visitLabel(endtarget); } } compileContext.addStackCount(1 - removed); }
From source file:org.jboss.byteman.rule.expression.DollarExpression.java
License:Open Source License
@Override public void compileAssign(MethodVisitor mv, CompileContext compileContext) throws CompileException { // make sure we are at the right source line compileContext.notifySourceLine(line); String targetName = binding.getName(); int currentStack = compileContext.getStackCount(); int size = ((type.getNBytes() > 4) ? 2 : 1); if (index == HELPER_IDX) { // not allowed to reassign the helper binding throw new CompileException("DollarExpression.compileAssign : invalid assignment to helper binding $$"); } else {//from w ww . java 2s.co m // value to be assigned is TOS and will already be coerced to the correct value type // copy it so we leave it as a a return value on the stack if (size == 2) { mv.visitInsn(Opcodes.DUP2); } else { mv.visitInsn(Opcodes.DUP); } // stack the current helper then insert it below the value mv.visitVarInsn(Opcodes.ALOAD, 0); if (size == 2) { // use a DUP_X2 to push a copy below the value then pop the redundant value mv.visitInsn(Opcodes.DUP_X2); mv.visitInsn(Opcodes.POP); } else { // we can just swap the two values mv.visitInsn(Opcodes.SWAP); } // stack the name for the variable and swap below the value mv.visitLdcInsn(targetName); if (size == 2) { // use a DUP_X2 to push a copy below the value then pop the redundant value mv.visitInsn(Opcodes.DUP_X2); // this is the high water mark // at this point the stack has gone from [ .. val1 val2] to [.. val1 val2 helper name val1 val2 name] compileContext.addStackCount(5); mv.visitInsn(Opcodes.POP); compileContext.addStackCount(-1); } else { // this is the high water mark // at this point the stack has gone from [ .. val] to [.. val helper val name] compileContext.addStackCount(3); // we can just swap the two values mv.visitInsn(Opcodes.SWAP); } // ensure we have an object compileObjectConversion(type, Type.OBJECT, mv, compileContext); // call the setBinding method mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.internalName(HelperAdapter.class), "setBinding", "(Ljava/lang/String;Ljava/lang/Object;)V"); // the call will remove 3 from the stack height compileContext.addStackCount(-3); // ok, the stack height should be as it was if (compileContext.getStackCount() != currentStack) { throw new CompileException("variable.compileAssignment : invalid stack height " + compileContext.getStackCount() + " expecting " + currentStack); } } }
From source file:org.jboss.byteman.rule.expression.FieldExpression.java
License:Open Source License
@Override public void compileAssign(MethodVisitor mv, CompileContext compileContext) throws CompileException { if (indirectStatic != null) { // this is just wrapping a static field expression so compile it indirectStatic.compileAssign(mv, compileContext); } else {/*from w w w. java 2s .co m*/ // make sure we are at the right source line compileContext.notifySourceLine(line); int currentStack = compileContext.getStackCount(); int size = (type.getNBytes() > 4 ? 2 : 1); // copy the value so we leave it as a result if (size == 1) { // this means at the maximum we add 1 to the current stack // [.. val] ==> [.. val val] mv.visitInsn(Opcodes.DUP); } else { // [.. val1 val2] ==> [.. val1 val2 val1 val2] mv.visitInsn(Opcodes.DUP2); } compileContext.addStackCount(size); // compile the owner expression and swap with the value owner.compile(mv, compileContext); if (size == 1) { // [.. val val owner] ==> [.. val owner val] mv.visitInsn(Opcodes.SWAP); } else { // we have to use a DUP_X2 and a POP to insert the owner below the two word value // i.e. [.. val1 val2 val1 val2] ==> [.. val1 val2 val1 val2 owner] ==> // [.. val1 val2 owner val1 val2 owner] ==> [.. val1 val2 owner val1 val2] mv.visitInsn(Opcodes.DUP_X2); compileContext.addStackCount(1); mv.visitInsn(Opcodes.POP); compileContext.addStackCount(-1); } if (isPublicField) { // now compile a field update String ownerType = Type.internalName(field.getDeclaringClass()); String fieldName = field.getName(); String fieldType = Type.internalName(field.getType(), true); mv.visitFieldInsn(Opcodes.PUTFIELD, ownerType, fieldName, fieldType); // we removed the owner and the value compileContext.addStackCount(-(1 + size)); } else { // since this is a private field we need to do the update using reflection // box the value to an object if necessary if (type.isPrimitive()) { compileBox(Type.boxType(type), mv, compileContext); } // stack the helper and then dupx2 it so it goes under the owner and value // [.. val(s) owner valObj ==> val(s) owner valObj helper ] mv.visitVarInsn(Opcodes.ALOAD, 0); // [.. val(s) owner valObj helper ==> val(s) helper owner valObj helper ] mv.visitInsn(Opcodes.DUP_X2); // stack now has 2 more words so count them compileContext.addStackCount(2); // now pop the redundant top word and stack the field index instead // [.. val(s) helper owner valObj helper ==> val(s) helper owner valObj index ] mv.visitInsn(Opcodes.POP); mv.visitLdcInsn(fieldIndex); // use the HelperAdapter method setAccessibleField to set the field value mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.internalName(HelperAdapter.class), "setAccessibleField", "(Ljava/lang/Object;Ljava/lang/Object;I)V"); // we popped four args compileContext.addStackCount(-4); } // check the stack height is ok if (compileContext.getStackCount() != currentStack) { throw new CompileException("FieldExpression.compileAssign : invalid stack height " + compileContext.getStackCount() + " expecting " + (currentStack)); } } }
From source file:org.jboss.byteman.rule.expression.StaticExpression.java
License:Open Source License
@Override public void compileAssign(MethodVisitor mv, CompileContext compileContext) throws CompileException { // make sure we are at the right source line compileContext.notifySourceLine(line); int currentStack = compileContext.getStackCount(); int size = (type.getNBytes() > 4 ? 2 : 1); // copy the value so we leave a result // increases stack height by size words if (size == 1) { mv.visitInsn(Opcodes.DUP);//w w w . j ava2 s . c o m } else { mv.visitInsn(Opcodes.DUP2); } compileContext.addStackCount(size); // compile a static field update if (isPublicField) { String ownerType = Type.internalName(field.getDeclaringClass()); String fieldName = field.getName(); String fieldType = Type.internalName(field.getType(), true); compileContext.addStackCount(-size); mv.visitFieldInsn(Opcodes.PUTSTATIC, ownerType, fieldName, fieldType); } else { // since this is a private field we need to do the update using reflection // box the value to an object if necessary // [.. val(s) val(s) ==> val(s) valObj] if (type.isPrimitive()) { compileBox(Type.boxType(type), mv, compileContext); } // stack the helper and then swap it so it goes under the value // [.. val(s) valObj ==> val(s) valObj helper ==> val(s) helper valObj] mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitInsn(Opcodes.SWAP); // stack a null owner then swap it so it goes under the value // [val(s) helper valObj ==> val(s) helper valObj null ==> val(s) helper null valObj] mv.visitInsn(Opcodes.ACONST_NULL); mv.visitInsn(Opcodes.SWAP); // now stack the field index // [.. val(s) helper null valObj ==> val(s) helper null valObj index ] mv.visitLdcInsn(fieldIndex); // we added three more words compileContext.addStackCount(3); // use the HelperAdapter method setAccessibleField to set the field value mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.internalName(HelperAdapter.class), "setAccessibleField", "(Ljava/lang/Object;Ljava/lang/Object;I)V"); // we popped four args compileContext.addStackCount(-4); } if (compileContext.getStackCount() != currentStack) { throw new CompileException("StaticExpression.compileAssign : invalid stack height " + compileContext.getStackCount() + " expecting " + currentStack); } }
From source file:org.jboss.byteman.rule.expression.Variable.java
License:Open Source License
@Override public void compileAssign(MethodVisitor mv, CompileContext compileContext) throws CompileException { // make sure we are at the right source line compileContext.notifySourceLine(line); int currentStack = compileContext.getStackCount(); int size = ((type.getNBytes() > 4) ? 2 : 1); int max;/*from ww w . j a va2 s. c o m*/ // value to be assigned is TOS and will already be coerced to the correct value type // copy it so we leave it as a a return value on the stack if (size == 2) { // [... val1 val2 ==> ... val1 val2 val1 val2] mv.visitInsn(Opcodes.DUP2); } else { // [... val ==> ... val val] mv.visitInsn(Opcodes.DUP); } // stack the current helper then insert it below the value mv.visitVarInsn(Opcodes.ALOAD, 0); if (size == 2) { // use a DUP_X2 to push a copy below the value then pop the redundant value // [... val1 val2 val1 val2 helper ==> ... val1 val2 helper val1 val2 helper] mv.visitInsn(Opcodes.DUP_X2); // [... val1 val2 helper val1 val2 helper ==> ... val1 val2 helper val1 val2] mv.visitInsn(Opcodes.POP); } else { // we can just swap the two values // [... val val helper ==> ... val helper val] mv.visitInsn(Opcodes.SWAP); } // stack the name for the variable and swap below the value mv.visitLdcInsn(name); if (size == 2) { // use a DUP_X2 to push a copy below the value then pop the redundant value // [... val1 val2 helper val1 val2 name ==> [... val1 val2 helper name val1 val2 name] mv.visitInsn(Opcodes.DUP_X2); // this is the high water mark compileContext.addStackCount(5); // [... val1 val2 helper name val1 val2 name ==> [... val1 val2 helper name val1 val2] mv.visitInsn(Opcodes.POP); compileContext.addStackCount(-1); // and now we have the desired arrangement for the call[.. val1 val2 helper name val1 val2] } else { // this is the high water mark // at this point the stack has gone from [ .. val] to [.. val helper val name] compileContext.addStackCount(3); // we can just swap the two values // [... val helper val name ==> ... val helper name val] mv.visitInsn(Opcodes.SWAP); // and now we have the desired arrangement for the call[.. val helper name val] } // ensure we have an object compileObjectConversion(type, Type.OBJECT, mv, compileContext); // call the setBinding method mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.internalName(HelperAdapter.class), "setBinding", "(Ljava/lang/String;Ljava/lang/Object;)V"); // the call will remove 3 from the stack height compileContext.addStackCount(-3); // ok, the stack height should be as it was if (compileContext.getStackCount() != currentStack) { throw new CompileException("variable.compileAssignment : invalid stack height " + compileContext.getStackCount() + " expecting " + currentStack); } }
From source file:org.mbte.groovypp.compiler.bytecode.BytecodeExpr.java
License:Apache License
public static void dup(ClassNode type, MethodVisitor mv) { if (type == double_TYPE || type == long_TYPE) mv.visitInsn(Opcodes.DUP2); else/* w w w .ja v a 2s. c o m*/ mv.visitInsn(Opcodes.DUP); }
From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java
License:Open Source License
/** * @param type//w ww .j a v a2 s .com * @return the DUP or DUP2 instruction, depending on type. */ private static int getDupOpCode(JavaTypeName type) { switch (type.getTag()) { case JavaTypeName.BOOLEAN_TAG: case JavaTypeName.BYTE_TAG: case JavaTypeName.SHORT_TAG: case JavaTypeName.CHAR_TAG: case JavaTypeName.INT_TAG: case JavaTypeName.FLOAT_TAG: case JavaTypeName.ARRAY_TAG: case JavaTypeName.OBJECT_TAG: return Opcodes.DUP; case JavaTypeName.LONG_TAG: case JavaTypeName.DOUBLE_TAG: return Opcodes.DUP2; case JavaTypeName.VOID_TAG: default: { throw new IllegalArgumentException("invalid type: " + type); } } }
From source file:org.pitest.mutationtest.engine.gregor.mutators.experimental.extended.UOIMutator1.java
License:Apache License
@Override public void visitVarInsn(int opcode, int var) { mv.visitVarInsn(opcode, var); switch (opcode) { case Opcodes.ILOAD: if (this.shouldMutate("Incremented (a++) integer local variable number " + var)) { mv.visitIincInsn(var, 1); }//from w w w.jav a2 s . c o m break; case Opcodes.FLOAD: if (this.shouldMutate("Incremented (a++) float local variable number " + var)) { mv.visitInsn(Opcodes.DUP); mv.visitInsn(Opcodes.FCONST_1); mv.visitInsn(Opcodes.FADD); mv.visitVarInsn(Opcodes.FSTORE, var); } break; case Opcodes.LLOAD: if (this.shouldMutate("Incremented (a++) long local variable number " + var)) { mv.visitInsn(Opcodes.DUP2); mv.visitInsn(Opcodes.LCONST_1); mv.visitInsn(Opcodes.LADD); mv.visitVarInsn(Opcodes.LSTORE, var); } break; case Opcodes.DLOAD: if (this.shouldMutate("Incremented (a++) double local variable number " + var)) { mv.visitInsn(Opcodes.DUP2); mv.visitInsn(Opcodes.DCONST_1); mv.visitInsn(Opcodes.DADD); mv.visitVarInsn(Opcodes.DSTORE, var); } break; default: break; } }