private static <T> void appendGetDelayedCellSetterSwitch(
      DelayedCellSetterFactory<T, ?>[] delayedCellSetters,
      String classType,
      MethodVisitor mv,
      int switchStart,
      int switchEnd) {
    mv.visitVarInsn(ILOAD, 1);
    Label defaultLabel = new Label();
    Label[] labels = newLabels(switchEnd - switchStart);
    mv.visitTableSwitchInsn(switchStart, switchEnd - 1, defaultLabel, labels);

    for (int i = switchStart; i < switchEnd; i++) {
      mv.visitLabel(labels[i - switchStart]);
      mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
      if (delayedCellSetters != null) {
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(
            GETFIELD, classType, "delayedCellSetter" + i, "L" + DELAYED_CELL_SETTER_TYPE + ";");
      } else {
        mv.visitInsn(ACONST_NULL);
      }
      mv.visitInsn(ARETURN);
    }

    mv.visitLabel(defaultLabel);
    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
  }
  @Override
  public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {

    _touchBranch();

    super.visitTableSwitchInsn(min, max, dflt, labels);
  }
  protected void injectGetByIndex(
      ClassWriter classWriter, String targetClassName, List<Field> fields) {
    MethodVisitor methodVisitor =
        classWriter.visitMethod(
            ACC_PUBLIC,
            "get",
            "(Ljava/lang/Object;I)Ljava/lang/Object;",
            null,
            new String[] {getInternalName(ILLEGAL_ACCESS_EXCEPTION.getCanonicalName())});

    Boxer boxer = new Boxer(methodVisitor);

    methodVisitor.visitCode();
    methodVisitor.visitVarInsn(ILOAD, 2);

    int maxStack = 6;

    Label[] labels = new Label[fields.size()];
    Label errorLabel = new Label();

    for (int i = 0; i < fields.size(); i++) {
      labels[i] = new Label();
    }

    methodVisitor.visitTableSwitchInsn(0, labels.length - 1, errorLabel, labels);

    if (!fields.isEmpty()) {
      maxStack--;

      for (int i = 0; i < fields.size(); i++) {
        Field field = fields.get(i);
        Class<?> type = field.getType();
        String fieldDescriptor = Type.getDescriptor(type);

        methodVisitor.visitLabel(labels[i]);

        if (i == 0) methodVisitor.visitFrame(F_APPEND, 1, new Object[] {targetClassName}, 0, null);
        else methodVisitor.visitFrame(F_SAME, 0, null, 0, null);

        if (isPublic(field)) {
          methodVisitor.visitVarInsn(ALOAD, 1);
          methodVisitor.visitTypeInsn(CHECKCAST, targetClassName);
          methodVisitor.visitFieldInsn(GETFIELD, targetClassName, field.getName(), fieldDescriptor);

          boxer.box(Type.getType(type));
        } else {
          injectReflectiveGetter(methodVisitor);
        }

        methodVisitor.visitInsn(ARETURN);
      }

      methodVisitor.visitLabel(errorLabel);
      methodVisitor.visitFrame(F_SAME, 0, null, 0, null);
    }

    injectException(methodVisitor, IllegalAccessException.class);
    methodVisitor.visitMaxs(maxStack, 3);
    methodVisitor.visitEnd();
  }
 public void accept(final MethodVisitor mv) {
   Label[] labels = new Label[this.labels.size()];
   for (int i = 0; i < labels.length; ++i) {
     labels[i] = ((LabelNode) this.labels.get(i)).getLabel();
   }
   mv.visitTableSwitchInsn(min, max, dflt.getLabel(), labels);
 }
Example #5
0
  private static void insertGetString(
      ClassWriter cw, String classNameInternal, ArrayList<Field> fields) {
    int maxStack = 6;
    MethodVisitor mv =
        cw.visitMethod(
            ACC_PUBLIC, "getString", "(Ljava/lang/Object;I)Ljava/lang/String;", null, null);
    mv.visitCode();
    mv.visitVarInsn(ILOAD, 2);

    if (!fields.isEmpty()) {
      maxStack--;
      Label[] labels = new Label[fields.size()];
      Label labelForInvalidTypes = new Label();
      boolean hasAnyBadTypeLabel = false;
      for (int i = 0, n = labels.length; i < n; i++) {
        if (fields.get(i).getType().equals(String.class)) labels[i] = new Label();
        else {
          labels[i] = labelForInvalidTypes;
          hasAnyBadTypeLabel = true;
        }
      }
      Label defaultLabel = new Label();
      mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels);

      for (int i = 0, n = labels.length; i < n; i++) {
        if (!labels[i].equals(labelForInvalidTypes)) {
          Field field = fields.get(i);
          mv.visitLabel(labels[i]);
          mv.visitFrame(F_SAME, 0, null, 0, null);
          if (!Modifier.isStatic(field.getModifiers())) {
            mv.visitVarInsn(ALOAD, 1);
            mv.visitTypeInsn(CHECKCAST, classNameInternal);
          }
          mv.visitFieldInsn(
              Modifier.isStatic(field.getModifiers()) ? GETSTATIC : GETFIELD,
              classNameInternal,
              field.getName(),
              "Ljava/lang/String;");
          mv.visitInsn(ARETURN);
        }
      }
      // Rest of fields: different type
      if (hasAnyBadTypeLabel) {
        mv.visitLabel(labelForInvalidTypes);
        mv.visitFrame(F_SAME, 0, null, 0, null);
        insertThrowExceptionForFieldType(mv, "String");
      }
      // Default: field not found
      mv.visitLabel(defaultLabel);
      mv.visitFrame(F_SAME, 0, null, 0, null);
    }
    insertThrowExceptionForFieldNotFound(mv);
    mv.visitMaxs(maxStack, 3);
    mv.visitEnd();
  }
Example #6
0
 @Override
 public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
   int[] keys = new int[labels.length];
   int counter = min;
   for (int iter = 0; iter < keys.length; iter++) {
     keys[iter] = counter;
     counter++;
   }
   mtd.addSwitch(dflt, keys, labels);
   super.visitTableSwitchInsn(min, max, dflt, labels);
 }
 @Override
 public void visitTableSwitchInsn(
     final int min, final int max, final Label dflt, final Label... labels) {
   checkStartCode();
   checkEndCode();
   if (max < min) {
     throw new IllegalArgumentException(
         "Max = " + max + " must be greater than or equal to min = " + min);
   }
   checkLabel(dflt, false, "default label");
   checkNonDebugLabel(dflt);
   if (labels == null || labels.length != max - min + 1) {
     throw new IllegalArgumentException("There must be max - min + 1 labels");
   }
   for (int i = 0; i < labels.length; ++i) {
     checkLabel(labels[i], false, "label at index " + i);
     checkNonDebugLabel(labels[i]);
   }
   super.visitTableSwitchInsn(min, max, dflt, labels);
   for (int i = 0; i < labels.length; ++i) {
     usedLabels.add(labels[i]);
   }
   ++insnCount;
 }
 public void visitTableSwitchInsn(int i, int i1, Label label, Label[] labels) {
   System.out.println(
       "visitTableSwitchInsn(" + i + ", " + i1 + ", " + label + ", " + labels + ")");
   methodVisitor.visitTableSwitchInsn(i, i1, label, labels);
 }
    @Override
    public void nodeDispatch(String suffix, int divide, int start, int end) {
      MethodVisitor mv;
      mv = cw.visitMethod(ACC_PRIVATE, name() + suffix, signature(), null, null);
      mv.visitCode();
      Label startLabel = new Label();
      mv.visitLabel(startLabel);
      final int powerOfTwo = Integer.numberOfTrailingZeros(divide);

      int sStart = start >> powerOfTwo;
      int sEnd = end >> powerOfTwo;

      int left = end - (sEnd << powerOfTwo);
      if (left > 0) {
        sEnd++;
      }

      Label[] labels = newLabels(sEnd - sStart);
      Label defaultLabel = new Label();

      mv.visitVarInsn(ILOAD, argIndex());

      int sub = leafStart();
      if (sub != 0) {
        AsmUtils.addIndex(mv, sub);
        mv.visitInsn(ISUB);
      }

      AsmUtils.addIndex(mv, powerOfTwo);
      mv.visitInsn(ISHR);

      mv.visitVarInsn(ISTORE, maxArgIndex() + 1);
      mv.visitVarInsn(ILOAD, maxArgIndex() + 1);
      mv.visitTableSwitchInsn(sStart, sEnd - 1, defaultLabel, labels);

      for (int i = sStart; i < sEnd; i++) {

        int estart = i << powerOfTwo;
        int eend = Math.min(end, (i + 1) << powerOfTwo);

        mv.visitLabel(labels[i - sStart]);
        if (i == start) {
          mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {Opcodes.INTEGER}, 0, null);
        } else {
          mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
        }

        loadArguments(mv);
        mv.visitMethodInsn(
            INVOKESPECIAL,
            classType,
            name() + (divide / maxMethodSize) + "n" + estart + "t" + eend,
            signature(),
            false);

        if (isVoid()) {
          if (i < (sEnd - 1)) {
            mv.visitJumpInsn(GOTO, defaultLabel);
          }
        } else {
          mv.visitInsn(ARETURN);
        }
      }

      mv.visitLabel(defaultLabel);
      mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);

      if (isVoid()) {
        mv.visitInsn(RETURN);
      } else {
        mv.visitInsn(ACONST_NULL);
        mv.visitInsn(ARETURN);
      }

      Label endLabel = new Label();
      mv.visitLabel(endLabel);
      appendDebugInfo(mv, startLabel, endLabel);
      mv.visitMaxs(6, 5);
      mv.visitEnd();
    }
Example #10
0
 public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
   visitor.visitTableSwitchInsn(min, max, dflt, labels);
 }
Example #11
0
  private static void insertGetPrimitive(
      ClassWriter cw, String classNameInternal, ArrayList<Field> fields, Type primitiveType) {
    int maxStack = 6;
    final String getterMethodName;
    final String typeNameInternal = primitiveType.getDescriptor();
    final int returnValueInstruction;
    switch (primitiveType.getSort()) {
      case Type.BOOLEAN:
        getterMethodName = "getBoolean";
        returnValueInstruction = IRETURN;
        break;
      case Type.BYTE:
        getterMethodName = "getByte";
        returnValueInstruction = IRETURN;
        break;
      case Type.CHAR:
        getterMethodName = "getChar";
        returnValueInstruction = IRETURN;
        break;
      case Type.SHORT:
        getterMethodName = "getShort";
        returnValueInstruction = IRETURN;
        break;
      case Type.INT:
        getterMethodName = "getInt";
        returnValueInstruction = IRETURN;
        break;
      case Type.FLOAT:
        getterMethodName = "getFloat";
        returnValueInstruction = FRETURN;
        break;
      case Type.LONG:
        getterMethodName = "getLong";
        returnValueInstruction = LRETURN;
        break;
      case Type.DOUBLE:
        getterMethodName = "getDouble";
        returnValueInstruction = DRETURN;
        break;
      default:
        getterMethodName = "get";
        returnValueInstruction = ARETURN;
        break;
    }
    MethodVisitor mv =
        cw.visitMethod(
            ACC_PUBLIC, getterMethodName, "(Ljava/lang/Object;I)" + typeNameInternal, null, null);
    mv.visitCode();
    mv.visitVarInsn(ILOAD, 2);

    if (!fields.isEmpty()) {
      maxStack--;
      Label[] labels = new Label[fields.size()];
      Label labelForInvalidTypes = new Label();
      boolean hasAnyBadTypeLabel = false;
      for (int i = 0, n = labels.length; i < n; i++) {
        if (Type.getType(fields.get(i).getType()).equals(primitiveType)) labels[i] = new Label();
        else {
          labels[i] = labelForInvalidTypes;
          hasAnyBadTypeLabel = true;
        }
      }
      Label defaultLabel = new Label();
      mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels);

      for (int i = 0, n = labels.length; i < n; i++) {
        Field field = fields.get(i);
        if (!labels[i].equals(labelForInvalidTypes)) {
          mv.visitLabel(labels[i]);
          mv.visitFrame(F_SAME, 0, null, 0, null);
          if (!Modifier.isStatic(field.getModifiers())) {
            mv.visitVarInsn(ALOAD, 1);
            mv.visitTypeInsn(CHECKCAST, classNameInternal);
          }
          mv.visitFieldInsn(
              Modifier.isStatic(field.getModifiers()) ? GETSTATIC : GETFIELD,
              classNameInternal,
              field.getName(),
              typeNameInternal);
          mv.visitInsn(returnValueInstruction);
        }
      }
      // Rest of fields: different type
      if (hasAnyBadTypeLabel) {
        mv.visitLabel(labelForInvalidTypes);
        mv.visitFrame(F_SAME, 0, null, 0, null);
        insertThrowExceptionForFieldType(mv, primitiveType.getClassName());
      }
      // Default: field not found
      mv.visitLabel(defaultLabel);
      mv.visitFrame(F_SAME, 0, null, 0, null);
    }
    mv = insertThrowExceptionForFieldNotFound(mv);
    mv.visitMaxs(maxStack, 3);
    mv.visitEnd();
  }
Example #12
0
  private static void insertGetObject(
      ClassWriter cw, String classNameInternal, ArrayList<Field> fields) {
    int maxStack = 6;
    MethodVisitor mv =
        cw.visitMethod(ACC_PUBLIC, "get", "(Ljava/lang/Object;I)Ljava/lang/Object;", null, null);
    mv.visitCode();
    mv.visitVarInsn(ILOAD, 2);

    if (!fields.isEmpty()) {
      maxStack--;
      Label[] labels = new Label[fields.size()];
      for (int i = 0, n = labels.length; i < n; i++) labels[i] = new Label();
      Label defaultLabel = new Label();
      mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels);

      for (int i = 0, n = labels.length; i < n; i++) {
        Field field = fields.get(i);

        mv.visitLabel(labels[i]);
        mv.visitFrame(F_SAME, 0, null, 0, null);
        if (!Modifier.isStatic(field.getModifiers())) {
          mv.visitVarInsn(ALOAD, 1);
          mv.visitTypeInsn(CHECKCAST, classNameInternal);
        }
        mv.visitFieldInsn(
            Modifier.isStatic(field.getModifiers()) ? GETSTATIC : GETFIELD,
            classNameInternal,
            field.getName(),
            Type.getDescriptor(field.getType()));

        Type fieldType = Type.getType(field.getType());
        switch (fieldType.getSort()) {
          case Type.BOOLEAN:
            mv.visitMethodInsn(
                INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;");
            break;
          case Type.BYTE:
            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;");
            break;
          case Type.CHAR:
            mv.visitMethodInsn(
                INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;");
            break;
          case Type.SHORT:
            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;");
            break;
          case Type.INT:
            mv.visitMethodInsn(
                INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;");
            break;
          case Type.FLOAT:
            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;");
            break;
          case Type.LONG:
            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;");
            break;
          case Type.DOUBLE:
            mv.visitMethodInsn(
                INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;");
            break;
        }

        mv.visitInsn(ARETURN);
      }

      mv.visitLabel(defaultLabel);
      mv.visitFrame(F_SAME, 0, null, 0, null);
    }
    insertThrowExceptionForFieldNotFound(mv);
    mv.visitMaxs(maxStack, 3);
    mv.visitEnd();
  }
Example #13
0
  private static void insertSetObject(
      ClassWriter cw, String classNameInternal, ArrayList<Field> fields) {
    int maxStack = 6;
    MethodVisitor mv =
        cw.visitMethod(ACC_PUBLIC, "set", "(Ljava/lang/Object;ILjava/lang/Object;)V", null, null);
    mv.visitCode();
    mv.visitVarInsn(ILOAD, 2);

    if (!fields.isEmpty()) {
      maxStack--;
      Label[] labels = new Label[fields.size()];
      for (int i = 0, n = labels.length; i < n; i++) labels[i] = new Label();
      Label defaultLabel = new Label();
      mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels);

      for (int i = 0, n = labels.length; i < n; i++) {
        Field field = fields.get(i);
        Type fieldType = Type.getType(field.getType());

        mv.visitLabel(labels[i]);
        mv.visitFrame(F_SAME, 0, null, 0, null);
        if (!Modifier.isStatic(field.getModifiers())) {
          mv.visitVarInsn(ALOAD, 1);
          mv.visitTypeInsn(CHECKCAST, classNameInternal);
        }
        mv.visitVarInsn(ALOAD, 3);

        switch (fieldType.getSort()) {
          case Type.BOOLEAN:
            mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z");
            break;
          case Type.BYTE:
            mv.visitTypeInsn(CHECKCAST, "java/lang/Byte");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B");
            break;
          case Type.CHAR:
            mv.visitTypeInsn(CHECKCAST, "java/lang/Character");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C");
            break;
          case Type.SHORT:
            mv.visitTypeInsn(CHECKCAST, "java/lang/Short");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S");
            break;
          case Type.INT:
            mv.visitTypeInsn(CHECKCAST, "java/lang/Integer");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I");
            break;
          case Type.FLOAT:
            mv.visitTypeInsn(CHECKCAST, "java/lang/Float");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F");
            break;
          case Type.LONG:
            mv.visitTypeInsn(CHECKCAST, "java/lang/Long");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J");
            break;
          case Type.DOUBLE:
            mv.visitTypeInsn(CHECKCAST, "java/lang/Double");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D");
            break;
          case Type.ARRAY:
            mv.visitTypeInsn(CHECKCAST, fieldType.getDescriptor());
            break;
          case Type.OBJECT:
            mv.visitTypeInsn(CHECKCAST, fieldType.getInternalName());
            break;
        }

        mv.visitFieldInsn(
            Modifier.isStatic(field.getModifiers()) ? PUTSTATIC : PUTFIELD,
            classNameInternal,
            field.getName(),
            fieldType.getDescriptor());
        mv.visitInsn(RETURN);
      }

      mv.visitLabel(defaultLabel);
      mv.visitFrame(F_SAME, 0, null, 0, null);
    }
    mv = insertThrowExceptionForFieldNotFound(mv);
    mv.visitMaxs(maxStack, 4);
    mv.visitEnd();
  }
Example #14
0
 public void TABLESWITCH(int min, int max, Label dflt, Label[] labels) {
   itsVisitor.visitTableSwitchInsn(min, max, dflt, labels);
 }