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

The following examples show how to use org.objectweb.asm.Opcodes#ICONST_0 . 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: AsmUtil.java    From Bats with Apache License 2.0 6 votes vote down vote up
/**
 * Determine if the given opcode is a load of a constant (xCONST_y).
 *
 * @param opcode the opcode
 * @return true if the opcode is one of the constant loading ones, false otherwise
 */
public static boolean isXconst(final int opcode) {
  switch(opcode) {
  case Opcodes.ICONST_0:
  case Opcodes.ICONST_1:
  case Opcodes.ICONST_2:
  case Opcodes.ICONST_3:
  case Opcodes.ICONST_4:
  case Opcodes.ICONST_5:
  case Opcodes.ICONST_M1:
  case Opcodes.DCONST_0:
  case Opcodes.DCONST_1:
  case Opcodes.FCONST_0:
  case Opcodes.FCONST_1:
  case Opcodes.LCONST_0:
  case Opcodes.LCONST_1:
    return true;
  }

  return false;
}
 
Example 2
Source File: OpcodeFormatting.java    From Cafebabe with GNU General Public License v3.0 6 votes vote down vote up
/**
 * Given an integer, returns an InsnNode that will properly represent the int.
 * 
 * @param i
 * @return
 */
public static AbstractInsnNode toInt(int i) {
	switch (i) {
	case -1:
		return new InsnNode(Opcodes.ICONST_M1);
	case 0:
		return new InsnNode(Opcodes.ICONST_0);
	case 1:
		return new InsnNode(Opcodes.ICONST_1);
	case 2:
		return new InsnNode(Opcodes.ICONST_2);
	case 3:
		return new InsnNode(Opcodes.ICONST_3);
	case 4:
		return new InsnNode(Opcodes.ICONST_4);
	case 5:
		return new InsnNode(Opcodes.ICONST_5);
	}
	if (i > -129 && i < 128) {
		return new IntInsnNode(Opcodes.BIPUSH, i);
	}
	return new LdcInsnNode(i);
}
 
Example 3
Source File: CodeGenUtils.java    From Concurnas with MIT License 6 votes vote down vote up
static void intOpcode(MethodVisitor mv, int input)
{
	if(input ==-1){
		mv.visitInsn(Opcodes.ICONST_M1);
	} else if(input >= 0 && input <= 5) {
		int res = Opcodes.ICONST_5;
		switch(input)
		{
			case 0: res =  Opcodes.ICONST_0; break;
			case 1: res =  Opcodes.ICONST_1; break;
			case 2: res =  Opcodes.ICONST_2; break;
			case 3: res =  Opcodes.ICONST_3; break;
			case 4: res =  Opcodes.ICONST_4; break;
		}
		mv.visitInsn(res);
	} else if( -128 <= input && input <= 127){//8 bit
		mv.visitIntInsn(Opcodes.BIPUSH, input);
	} else if( -32768 <= input && input <= 32767){//16 bit
		mv.visitIntInsn(Opcodes.SIPUSH, input);
	} else{//32 bit - ldc
		mv.visitLdcInsn(new Integer(input));
	}
}
 
Example 4
Source File: TreeInstructions.java    From instrumentation with Apache License 2.0 6 votes vote down vote up
public static AbstractInsnNode getPushInstruction(int value) {

        if (value == -1) {
            return new InsnNode(Opcodes.ICONST_M1);
        } else if (value == 0) {
            return new InsnNode(Opcodes.ICONST_0);
        } else if (value == 1) {
            return new InsnNode(Opcodes.ICONST_1);
        } else if (value == 2) {
            return new InsnNode(Opcodes.ICONST_2);
        } else if (value == 3) {
            return new InsnNode(Opcodes.ICONST_3);
        } else if (value == 4) {
            return new InsnNode(Opcodes.ICONST_4);
        } else if (value == 5) {
            return new InsnNode(Opcodes.ICONST_5);
        } else if ((value >= -128) && (value <= 127)) {
            return new IntInsnNode(Opcodes.BIPUSH, value);
        } else if ((value >= -32768) && (value <= 32767)) {
            return new IntInsnNode(Opcodes.SIPUSH, value);
        } else {
            return new LdcInsnNode(value);
        }
    }
 
Example 5
Source File: BasicInstruction.java    From CodenameOne with GNU General Public License v2.0 6 votes vote down vote up
@Override
public boolean isConstant() {
    switch (opcode) {
        case Opcodes.ACONST_NULL:
        case Opcodes.ICONST_0:
        case Opcodes.ICONST_1:
        case Opcodes.ICONST_2:
        case Opcodes.ICONST_3:
        case Opcodes.ICONST_4:
        case Opcodes.ICONST_5:
        case Opcodes.ICONST_M1:
        case Opcodes.FCONST_0:
        case Opcodes.FCONST_1:
        case Opcodes.FCONST_2:
        case Opcodes.DCONST_0:
        case Opcodes.DCONST_1:
        case Opcodes.LCONST_0:
        case Opcodes.LCONST_1:
        case Opcodes.LDC:
            return true;
    }
    return super.isConstant();
}
 
Example 6
Source File: OpUtils.java    From zelixkiller with GNU General Public License v3.0 6 votes vote down vote up
/**
 * Given an integer, returns an InsnNode that will properly represent the
 * int.
 * 
 * @param i
 * @return
 */
public static AbstractInsnNode toInt(int i) {
	switch (i) {
	case -1:
		return new InsnNode(Opcodes.ICONST_M1);
	case 0:
		return new InsnNode(Opcodes.ICONST_0);
	case 1:
		return new InsnNode(Opcodes.ICONST_1);
	case 2:
		return new InsnNode(Opcodes.ICONST_2);
	case 3:
		return new InsnNode(Opcodes.ICONST_3);
	case 4:
		return new InsnNode(Opcodes.ICONST_4);
	case 5:
		return new InsnNode(Opcodes.ICONST_5);
	}
	if (i > -129 && i < 128) {
		return new IntInsnNode(Opcodes.BIPUSH, i);
	}
	return new LdcInsnNode(i);
}
 
Example 7
Source File: OpUtils.java    From JByteMod-Beta with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Gets the integer value of a given opcode.
 * 
 * @param opcode
 * @return
 */
public static int getIntValue(int opcode) {
  if (opcode == Opcodes.ICONST_0) {
    return 0;
  } else if (opcode == Opcodes.ICONST_1) {
    return 1;
  } else if (opcode == Opcodes.ICONST_2) {
    return 2;
  } else if (opcode == Opcodes.ICONST_3) {
    return 3;
  } else if (opcode == Opcodes.ICONST_4) {
    return 4;
  } else if (opcode == Opcodes.ICONST_5) {
    return 5;
  } else {
    return -1;
  }
}
 
Example 8
Source File: ReturnValuesMutator.java    From pitest with Apache License 2.0 6 votes vote down vote up
private void mutatePrimitiveIntegerReturn() {

      if (shouldMutate("primitive boolean/byte/short/integer",
          "(x == 1) ? 0 : x + 1")) {
        final Label label = new Label();

        super.visitInsn(Opcodes.DUP);
        super.visitInsn(Opcodes.ICONST_1);
        super.visitJumpInsn(Opcodes.IF_ICMPEQ, label);

        super.visitInsn(Opcodes.ICONST_1);
        super.visitInsn(Opcodes.IADD);
        super.visitInsn(Opcodes.IRETURN);

        super.visitLabel(label);
        super.visitInsn(Opcodes.ICONST_0);
        super.visitInsn(Opcodes.IRETURN);
      }
    }
 
Example 9
Source File: BytecodeGenUtils.java    From Concurnas with MIT License 5 votes vote down vote up
public static void intOpcode(MethodVisitor mv, int input)
{//TODO: nasty copy paste
	if(input ==-1)
	{
		mv.visitInsn(Opcodes.ICONST_M1);
	}
	else if(input > -1 && input <= 5)
	{
		int res = Opcodes.ICONST_5;
		switch(input)
		{
			case 0: res =  Opcodes.ICONST_0; break;
			case 1: res =  Opcodes.ICONST_1; break;
			case 2: res =  Opcodes.ICONST_2; break;
			case 3: res =  Opcodes.ICONST_3; break;
			case 4: res =  Opcodes.ICONST_4; break;
		}
		mv.visitInsn(res);
	}
	else if( -128 <= input && input <= 127)
	{//8 bit
		mv.visitIntInsn(Opcodes.BIPUSH, input);
	}
	else if( -32768 <= input && input <= 32767)
	{//16 bit
		mv.visitIntInsn(Opcodes.SIPUSH, input);
	}
	else
	{//32 bit - ldc
		mv.visitLdcInsn(new Integer(input));
	}
}
 
Example 10
Source File: InlineConstantMutator.java    From pitest with Apache License 2.0 5 votes vote down vote up
private void translateToByteCode(final Integer constant) {
  switch (constant) {
  case -1:
    super.visitInsn(Opcodes.ICONST_M1);
    break;
  case 0:
    super.visitInsn(Opcodes.ICONST_0);
    break;
  case 1:
    super.visitInsn(Opcodes.ICONST_1);
    break;
  case 2:
    super.visitInsn(Opcodes.ICONST_2);
    break;
  case 3:
    super.visitInsn(Opcodes.ICONST_3);
    break;
  case 4:
    super.visitInsn(Opcodes.ICONST_4);
    break;
  case 5:
    super.visitInsn(Opcodes.ICONST_5);
    break;
  default:
    super.visitLdcInsn(constant);
    break;
  }
}
 
Example 11
Source File: BlockBuildingMethodVisitorTest.java    From AVM with MIT License 5 votes vote down vote up
@Test
public void test_checkTableSwitch() throws Exception {
    List<BasicBlock> hashCodeBlocks = METHOD_BLOCKS.get("checkTableSwitch(I)I");
    int[][] expectedHashCodeBlocks = new int[][]{
            {Opcodes.ICONST_5, Opcodes.ISTORE, Opcodes.ILOAD, Opcodes.TABLESWITCH},
            {Opcodes.ICONST_1, Opcodes.ISTORE, Opcodes.GOTO},
            {Opcodes.ICONST_2, Opcodes.ISTORE, Opcodes.GOTO},
            {Opcodes.ICONST_3, Opcodes.ISTORE, Opcodes.GOTO},
            {Opcodes.ICONST_0, Opcodes.ISTORE},
            {Opcodes.ILOAD, Opcodes.IRETURN},
    };
    int[][] expectedSwitchCounts = new int[][]{
        {4},
        {},
        {},
        {},
        {},
        {},
    };
    
    // Verify the shape of the blocks.
    boolean didMatch = compareBlocks(expectedHashCodeBlocks, hashCodeBlocks);
    Assert.assertTrue(didMatch);
    
    // Verify the switch option value.
    didMatch = compareSwitches(expectedSwitchCounts, hashCodeBlocks);
    Assert.assertTrue(didMatch);
}
 
Example 12
Source File: BlockBuildingMethodVisitorTest.java    From AVM with MIT License 5 votes vote down vote up
@Test
public void test_checkLookupSwitch() throws Exception {
    List<BasicBlock> hashCodeBlocks = METHOD_BLOCKS.get("checkLookupSwitch(I)I");
    int[][] expectedHashCodeBlocks = new int[][]{
            {Opcodes.ICONST_5, Opcodes.ISTORE, Opcodes.ILOAD, Opcodes.LOOKUPSWITCH},
            {Opcodes.ICONST_1, Opcodes.ISTORE, Opcodes.GOTO},
            {Opcodes.ICONST_2, Opcodes.ISTORE, Opcodes.GOTO},
            {Opcodes.ICONST_3, Opcodes.ISTORE, Opcodes.GOTO},
            {Opcodes.ICONST_0, Opcodes.ISTORE},
            {Opcodes.ILOAD, Opcodes.IRETURN},
    };
    int[][] expectedSwitchCounts = new int[][]{
        {4},
        {},
        {},
        {},
        {},
        {},
    };
    
    // Verify the shape of the blocks.
    boolean didMatch = compareBlocks(expectedHashCodeBlocks, hashCodeBlocks);
    Assert.assertTrue(didMatch);
    
    // Verify the switch option value.
    didMatch = compareSwitches(expectedSwitchCounts, hashCodeBlocks);
    Assert.assertTrue(didMatch);
}
 
Example 13
Source File: AbstractCRCRVisitor.java    From pitest with Apache License 2.0 5 votes vote down vote up
void translateToByteCode(final Integer constant) {
    switch (constant) {
        case -1:
            super.visitInsn(Opcodes.ICONST_M1);
            break;
        case 0:
            super.visitInsn(Opcodes.ICONST_0);
            break;
        case 1:
            super.visitInsn(Opcodes.ICONST_1);
            break;
        case 2:
            super.visitInsn(Opcodes.ICONST_2);
            break;
        case 3:
            super.visitInsn(Opcodes.ICONST_3);
            break;
        case 4:
            super.visitInsn(Opcodes.ICONST_4);
            break;
        case 5:
            super.visitInsn(Opcodes.ICONST_5);
            break;
        default:
            super.visitLdcInsn(constant);
            break;
    }
}
 
Example 14
Source File: AbstractCRCRVisitor.java    From pitest with Apache License 2.0 5 votes vote down vote up
Number translateToNumber(final int opcode) {
    switch (opcode) {
        case Opcodes.ICONST_M1:
            return Integer.valueOf(-1);
        case Opcodes.ICONST_0:
            return Integer.valueOf(0);
        case Opcodes.ICONST_1:
            return Integer.valueOf(1);
        case Opcodes.ICONST_2:
            return Integer.valueOf(2);
        case Opcodes.ICONST_3:
            return Integer.valueOf(3);
        case Opcodes.ICONST_4:
            return Integer.valueOf(4);
        case Opcodes.ICONST_5:
            return Integer.valueOf(5);
        case Opcodes.LCONST_0:
            return Long.valueOf(0L);
        case Opcodes.LCONST_1:
            return Long.valueOf(1L);
        case Opcodes.FCONST_0:
            return Float.valueOf(0F);
        case Opcodes.FCONST_1:
            return Float.valueOf(1F);
        case Opcodes.FCONST_2:
            return Float.valueOf(2F);
        case Opcodes.DCONST_0:
            return Double.valueOf(0D);
        case Opcodes.DCONST_1:
            return Double.valueOf(1D);
        default:
            return null;
    }
}
 
Example 15
Source File: AllocationMethodAdapter.java    From allocation-instrumenter with Apache License 2.0 4 votes vote down vote up
private void pushProductOfIntArrayOnStack() {
  Label beginScopeLabel = new Label();
  Label endScopeLabel = new Label();

  int dimsArrayIndex = newLocal("[I", beginScopeLabel, endScopeLabel);
  int counterIndex = newLocal("I", beginScopeLabel, endScopeLabel);
  int productIndex = newLocal("I", beginScopeLabel, endScopeLabel);
  Label loopLabel = new Label();
  Label endLabel = new Label();

  super.visitLabel(beginScopeLabel);

  // stack: ... intArray
  super.visitVarInsn(Opcodes.ASTORE, dimsArrayIndex);
  // -> stack: ...

  // counter = 0
  super.visitInsn(Opcodes.ICONST_0);
  super.visitVarInsn(Opcodes.ISTORE, counterIndex);
  // product = 1
  super.visitInsn(Opcodes.ICONST_1);
  super.visitVarInsn(Opcodes.ISTORE, productIndex);
  // loop:
  super.visitLabel(loopLabel);
  // if index >= arraylength goto end:
  super.visitVarInsn(Opcodes.ILOAD, counterIndex);
  super.visitVarInsn(Opcodes.ALOAD, dimsArrayIndex);
  super.visitInsn(Opcodes.ARRAYLENGTH);
  super.visitJumpInsn(Opcodes.IF_ICMPGE, endLabel);
  // product = product * max(array[counter],1)
  super.visitVarInsn(Opcodes.ALOAD, dimsArrayIndex);
  super.visitVarInsn(Opcodes.ILOAD, counterIndex);
  super.visitInsn(Opcodes.IALOAD);
  super.visitInsn(Opcodes.DUP);
  Label nonZeroDimension = new Label();
  super.visitJumpInsn(Opcodes.IFNE, nonZeroDimension);
  super.visitInsn(Opcodes.POP);
  super.visitInsn(Opcodes.ICONST_1);
  super.visitLabel(nonZeroDimension);
  super.visitVarInsn(Opcodes.ILOAD, productIndex);
  super.visitInsn(Opcodes.IMUL); // if overflow happens it happens.
  super.visitVarInsn(Opcodes.ISTORE, productIndex);
  // iinc counter 1
  super.visitIincInsn(counterIndex, 1);
  // goto loop
  super.visitJumpInsn(Opcodes.GOTO, loopLabel);
  // end:
  super.visitLabel(endLabel);
  // re-push dimensions array
  super.visitVarInsn(Opcodes.ALOAD, dimsArrayIndex);
  // push product
  super.visitVarInsn(Opcodes.ILOAD, productIndex);

  super.visitLabel(endScopeLabel);
}
 
Example 16
Source File: LambdaDesugaring.java    From bazel with Apache License 2.0 4 votes vote down vote up
/**
 * Returns whether a given instruction can be used to push argument of {@code type} on stack.
 */
private /* static */ boolean isPushForType(AbstractInsnNode insn, Type type) {
  int opcode = insn.getOpcode();
  if (opcode == type.getOpcode(Opcodes.ILOAD)) {
    return true;
  }
  // b/62060793: AsyncAwait rewrites bytecode to convert java methods into state machine with
  // support of lambdas. Constant zero values are pushed on stack for all yet uninitialized
  // local variables. And SIPUSH instruction is used to advance an internal state of a state
  // machine.
  switch (type.getSort()) {
    case Type.BOOLEAN:
      return opcode == Opcodes.ICONST_0 || opcode == Opcodes.ICONST_1;

    case Type.BYTE:
    case Type.CHAR:
    case Type.SHORT:
    case Type.INT:
      return opcode == Opcodes.SIPUSH
          || opcode == Opcodes.ICONST_0
          || opcode == Opcodes.ICONST_1
          || opcode == Opcodes.ICONST_2
          || opcode == Opcodes.ICONST_3
          || opcode == Opcodes.ICONST_4
          || opcode == Opcodes.ICONST_5
          || opcode == Opcodes.ICONST_M1;

    case Type.LONG:
      return opcode == Opcodes.LCONST_0 || opcode == Opcodes.LCONST_1;

    case Type.FLOAT:
      return opcode == Opcodes.FCONST_0
          || opcode == Opcodes.FCONST_1
          || opcode == Opcodes.FCONST_2;

    case Type.DOUBLE:
      return opcode == Opcodes.DCONST_0 || opcode == Opcodes.DCONST_1;

    case Type.OBJECT:
    case Type.ARRAY:
      return opcode == Opcodes.ACONST_NULL;

    default:
      // Support for BIPUSH and LDC* opcodes is not implemented as there is no known use case.
      return false;
  }
}
 
Example 17
Source File: UselessArithmeticTransformer.java    From deobfuscator with Apache License 2.0 4 votes vote down vote up
private List<AbstractInsnNode> getPossibleInsns(AbstractInsnNode ain)
{
	List<AbstractInsnNode> instrs = new ArrayList<>();
	while(ain != null)
	{
		if(ain instanceof LineNumberNode || ain instanceof FrameNode)
		{
			ain = ain.getNext();
			continue;
		}
		instrs.add(ain);
		if(instrs.size() >= 23)
			break;
		ain = ain.getNext();
	}
	if(instrs.size() == 23 && instrs.get(0).getOpcode() == Opcodes.ILOAD
		&& instrs.get(1).getOpcode() == Opcodes.ICONST_1
		&& instrs.get(2).getOpcode() == Opcodes.ISUB
		&& instrs.get(3).getOpcode() == Opcodes.ISTORE)
	{
		int var1 = ((VarInsnNode)instrs.get(0)).var;
		int var2 = ((VarInsnNode)instrs.get(3)).var;
		if(instrs.get(4).getOpcode() == Opcodes.ILOAD
			&& ((VarInsnNode)instrs.get(4)).var == var1
			&& instrs.get(5).getOpcode() == Opcodes.ILOAD
			&& ((VarInsnNode)instrs.get(5)).var == var2
			&& instrs.get(6).getOpcode() == Opcodes.IMUL
			&& instrs.get(7).getOpcode() == Opcodes.ISTORE
			&& ((VarInsnNode)instrs.get(7)).var == var2
			&& instrs.get(8).getOpcode() == Opcodes.ILOAD
			&& ((VarInsnNode)instrs.get(8)).var == var2
			&& instrs.get(9).getOpcode() == Opcodes.ICONST_2
			&& instrs.get(10).getOpcode() == Opcodes.IREM
			&& instrs.get(11).getOpcode() == Opcodes.ISTORE
			&& ((VarInsnNode)instrs.get(11)).var == var2
			&& instrs.get(12).getOpcode() == Opcodes.ILOAD
			&& ((VarInsnNode)instrs.get(12)).var == var2
			&& instrs.get(13).getOpcode() == Opcodes.I2L
			&& instrs.get(14).getOpcode() == Opcodes.ICONST_0
			&& instrs.get(15).getOpcode() == Opcodes.I2L
			&& instrs.get(16).getOpcode() == Opcodes.LCMP
			&& instrs.get(17).getOpcode() == Opcodes.ICONST_1
			&& instrs.get(18).getOpcode() == Opcodes.IXOR
			&& instrs.get(19).getOpcode() == Opcodes.ICONST_1
			&& instrs.get(20).getOpcode() == Opcodes.IAND
			&& instrs.get(21).getOpcode() == Opcodes.IFEQ
			&& instrs.get(22).getOpcode() == Opcodes.IINC)
			return instrs;
	}
	return null;
}
 
Example 18
Source File: TransformX.java    From SocialSdkLibrary with Apache License 2.0 4 votes vote down vote up
public static int toAsmBool(boolean value) {
    return value ? Opcodes.ICONST_1 : Opcodes.ICONST_0;
}
 
Example 19
Source File: StackHelper.java    From zelixkiller with GNU General Public License v3.0 4 votes vote down vote up
public InsnValue createConstant(AbstractInsnNode insn) throws AnalyzerException {
	switch (insn.getOpcode()) {
	case Opcodes.ACONST_NULL:
		return InsnValue.NULL_REFERENCE_VALUE;
	case Opcodes.ICONST_M1:
	case Opcodes.ICONST_0:
	case Opcodes.ICONST_1:
	case Opcodes.ICONST_2:
	case Opcodes.ICONST_3:
	case Opcodes.ICONST_4:
	case Opcodes.ICONST_5:
	case Opcodes.BIPUSH:
	case Opcodes.SIPUSH:
		return InsnValue.intValue(insn);
	case Opcodes.LCONST_0:
	case Opcodes.LCONST_1:
		return InsnValue.longValue(insn.getOpcode());
	case Opcodes.FCONST_0:
	case Opcodes.FCONST_1:
	case Opcodes.FCONST_2:
		return InsnValue.floatValue(insn.getOpcode());
	case Opcodes.DCONST_0:
	case Opcodes.DCONST_1:
		return InsnValue.doubleValue(insn.getOpcode());
	case Opcodes.LDC:
		Object obj = ((LdcInsnNode) insn).cst;
		if (obj instanceof Type) {
			return new InsnValue((Type) obj);
		} else {
			Type t = Type.getType(obj.getClass());
			int sort = t.getSort();
			// Non-included types:
			// Type.ARRAY
			// Type.VOID
			// Type.METHOD
			switch (sort) {
			case Type.BOOLEAN:
				return InsnValue.intValue((int) obj);
			case Type.CHAR:
				return InsnValue.charValue((char) obj);
			case Type.BYTE:
				return InsnValue.byteValue((byte) obj);
			case Type.SHORT:
				return InsnValue.shortValue((short) obj);
			case Type.INT:
				return InsnValue.intValue((int) obj);
			case Type.FLOAT:
				return InsnValue.floatValue((float) obj);
			case Type.LONG:
				return InsnValue.longValue((long) obj);
			case Type.DOUBLE:
				return InsnValue.doubleValue((double) obj);
			case Type.OBJECT:
				return new InsnValue(t, obj);
			}
			return new InsnValue(t);
		}
	case Opcodes.NEW:
		return new InsnValue(Type.getType(((TypeInsnNode) insn).desc));
	case Opcodes.JSR:
		// TODO: IDK if this is right.
		return InsnValue.REFERENCE_VALUE;
	}

	return null;
}
 
Example 20
Source File: AllocationMethodAdapter.java    From allocation-instrumenter with Apache License 2.0 4 votes vote down vote up
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);
}