Exemple #1
0
  private void finalizeToString(MethodVisitor mv) {
    // The StringBuilder is on the top of the stack from the last append() -
    // duplicate it for call to replace()
    mv.visitVarInsn(ALOAD, 1);
    mv.visitInsn(DUP);

    // The replace starts at 2 characters before the end, to remove the
    // extra command and space added
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "length", "()I", false);
    mv.visitLdcInsn(2);
    mv.visitInsn(ISUB);

    mv.visitVarInsn(ALOAD, 1);
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "length", "()I", false);

    mv.visitLdcInsn("}");

    mv.visitMethodInsn(
        INVOKEVIRTUAL,
        "java/lang/StringBuilder",
        "replace",
        "(IILjava/lang/String;)Ljava/lang/StringBuilder;",
        false);
    mv.visitMethodInsn(
        INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);

    mv.visitInsn(ARETURN);
    mv.visitMaxs(0, 0);
    mv.visitEnd();
  }
Exemple #2
0
  private void contributeToString(
      String internalName, Property<Class<?>, Method> property, MethodVisitor toStringMv) {
    if (property.isLeastSpecificType()) {
      Type returnType = Type.getReturnType(property.getAccessor());

      toStringMv.visitVarInsn(ALOAD, 0);

      toStringMv.visitVarInsn(ALOAD, 1);
      toStringMv.visitLdcInsn(property.getName());
      toStringMv.visitMethodInsn(
          INVOKEVIRTUAL,
          "java/lang/StringBuilder",
          "append",
          "(Ljava/lang/Object;)Ljava/lang/StringBuilder;",
          false);

      toStringMv.visitLdcInsn("=");
      toStringMv.visitMethodInsn(
          INVOKEVIRTUAL,
          "java/lang/StringBuilder",
          "append",
          "(Ljava/lang/Object;)Ljava/lang/StringBuilder;",
          false);

      toStringMv.visitVarInsn(ALOAD, 0);
      toStringMv.visitMethodInsn(
          INVOKESPECIAL,
          internalName,
          property.getAccessor().getName(),
          Type.getMethodDescriptor(property.getAccessor()),
          false);

      String desc =
          property.getType().isPrimitive()
              ? Type.getDescriptor(property.getType())
              : "Ljava/lang/Object;";

      toStringMv.visitMethodInsn(
          INVOKEVIRTUAL,
          "java/lang/StringBuilder",
          "append",
          "(" + desc + ")Ljava/lang/StringBuilder;",
          false);

      toStringMv.visitLdcInsn(", ");
      toStringMv.visitMethodInsn(
          INVOKEVIRTUAL,
          "java/lang/StringBuilder",
          "append",
          "(Ljava/lang/Object;)Ljava/lang/StringBuilder;",
          false);
    }
  }
Exemple #3
0
 void compile(MethodVisitor mv) {
   // compiles e1, e2, and adds the instructions to compare the two values
   e1.compile(mv);
   e2.compile(mv);
   Label iftrue = new Label();
   Label end = new Label();
   mv.visitJumpInsn(IF_ICMPGT, iftrue);
   // case where e1 <= e2 : pushes false and jump to "end"
   mv.visitLdcInsn(new Integer(0));
   mv.visitJumpInsn(GOTO, end);
   // case where e1 > e2 : pushes true
   mv.visitLabel(iftrue);
   mv.visitLdcInsn(new Integer(1));
   mv.visitLabel(end);
 }
 public static void pushConstant(MethodVisitor mv, int value) {
   switch (value) {
     case 0:
       mv.visitInsn(ICONST_0);
       break;
     case 1:
       mv.visitInsn(ICONST_1);
       break;
     case 2:
       mv.visitInsn(ICONST_2);
       break;
     case 3:
       mv.visitInsn(ICONST_3);
       break;
     case 4:
       mv.visitInsn(ICONST_4);
       break;
     case 5:
       mv.visitInsn(ICONST_5);
       break;
     default:
       if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
         mv.visitIntInsn(BIPUSH, value);
       } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
         mv.visitIntInsn(SIPUSH, value);
       } else {
         mv.visitLdcInsn(Integer.valueOf(value));
       }
   }
 }
  private void writeMapDotProperty(
      final Expression receiver,
      final String methodName,
      final MethodVisitor mv,
      final boolean safe) {
    receiver.visit(controller.getAcg()); // load receiver

    Label exit = new Label();
    if (safe) {
      Label doGet = new Label();
      mv.visitJumpInsn(IFNONNULL, doGet);
      controller.getOperandStack().remove(1);
      mv.visitInsn(ACONST_NULL);
      mv.visitJumpInsn(GOTO, exit);
      mv.visitLabel(doGet);
      receiver.visit(controller.getAcg());
    }

    mv.visitLdcInsn(methodName); // load property name
    mv.visitMethodInsn(
        INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;", true);
    if (safe) {
      mv.visitLabel(exit);
    }
    controller.getOperandStack().replace(OBJECT_TYPE);
  }
Exemple #6
0
  private void createAddMessage(ClassNode cn) {
    Pattern p =
        new PatternBuilder()
            .add(
                new InstructionElement(ALOAD),
                new LdcElement(new LdcInsnNode("")),
                new InstructionElement(ALOAD),
                new InstructionElement(INVOKEVIRTUAL))
            .build();

    MethodInsnNode ebola1 = null;

    for (MethodNode mn : cn.methods) {
      if (!p.contains(mn.instructions)) continue;

      int offset = p.getOffset(mn.instructions);

      ebola1 = (MethodInsnNode) mn.instructions.get(offset + 3);
    }

    {
      MethodVisitor mv =
          cn.visitMethod(ACC_PUBLIC, "addChatMessage", "(Ljava/lang/String;)V", null, null);
      mv.visitVarInsn(ALOAD, 0);
      mv.visitLdcInsn("");
      mv.visitVarInsn(ALOAD, 1);
      mv.visitMethodInsn(INVOKEVIRTUAL, ebola1.owner, ebola1.name, ebola1.desc, ebola1.itf);
      mv.visitInsn(RETURN);
      mv.visitEnd();
    }
  }
 /**
  * Initializes a static mixin field.
  *
  * @param mv
  * @param fieldInfo
  */
 private void initializeStaticMixinField(final MethodVisitor mv, final MixinFieldInfo fieldInfo) {
   mv.visitLdcInsn(fieldInfo.mixinClassInfo.getName().replace('/', '.'));
   if (fieldInfo.isPerJVM) {
     mv.visitFieldInsn(
         GETSTATIC, m_declaringTypeName, TARGET_CLASS_FIELD_NAME, CLASS_CLASS_SIGNATURE);
     mv.visitMethodInsn(
         INVOKEVIRTUAL,
         CLASS_CLASS,
         GETCLASSLOADER_METHOD_NAME,
         CLASS_CLASS_GETCLASSLOADER_METHOD_SIGNATURE);
     mv.visitMethodInsn(
         INVOKESTATIC, MIXINS_CLASS_NAME, MIXIN_OF_METHOD_NAME, MIXIN_OF_METHOD_PER_JVM_SIGNATURE);
   } else {
     mv.visitFieldInsn(
         GETSTATIC, m_declaringTypeName, TARGET_CLASS_FIELD_NAME, CLASS_CLASS_SIGNATURE);
     mv.visitMethodInsn(
         INVOKESTATIC,
         MIXINS_CLASS_NAME,
         MIXIN_OF_METHOD_NAME,
         MIXIN_OF_METHOD_PER_CLASS_SIGNATURE);
   }
   mv.visitTypeInsn(CHECKCAST, fieldInfo.mixinClassInfo.getName().replace('.', '/'));
   mv.visitFieldInsn(
       PUTSTATIC,
       m_declaringTypeName,
       fieldInfo.fieldName,
       fieldInfo.mixinClassInfo.getSignature());
 }
 @Test
 public void testInstrumentationLegacyClassOtherType() throws Exception {
   ClassVisitor classVisitor =
       TypeConstantAdjustment.INSTANCE.wrap(
           mock(TypeDescription.class),
           this.classVisitor,
           mock(Implementation.Context.class),
           mock(TypePool.class),
           new FieldList.Empty<FieldDescription.InDefinedShape>(),
           new MethodList.Empty<MethodDescription>(),
           IGNORED,
           IGNORED);
   classVisitor.visit(
       ClassFileVersion.JAVA_V4.getMinorMajorVersion(), FOOBAR, FOO, BAR, QUX, new String[] {BAZ});
   MethodVisitor methodVisitor =
       classVisitor.visitMethod(FOOBAR, FOO, BAR, QUX, new String[] {BAZ});
   assertThat(methodVisitor, not(this.methodVisitor));
   methodVisitor.visitLdcInsn(FOO);
   verify(this.classVisitor)
       .visit(
           ClassFileVersion.JAVA_V4.getMinorMajorVersion(),
           FOOBAR,
           FOO,
           BAR,
           QUX,
           new String[] {BAZ});
   verify(this.classVisitor).visitMethod(FOOBAR, FOO, BAR, QUX, new String[] {BAZ});
   verifyNoMoreInteractions(this.classVisitor);
   verify(this.methodVisitor).visitLdcInsn(FOO);
   verifyNoMoreInteractions(this.methodVisitor);
 }
 @Override
 public void visitLdcInsn(final Object cst) {
   checkStartCode();
   checkEndCode();
   checkLDCConstant(cst);
   super.visitLdcInsn(cst);
   ++insnCount;
 }
Exemple #10
0
  public static byte[] dump1() {
    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    FieldVisitor fv;
    MethodVisitor mv;

    cw.visit(V1_4, ACC_SUPER, "pkg/Outer$1", null, "pkg/Outer", null);

    cw.visitOuterClass("pkg/Outer", "m", "()V");
    cw.visitInnerClass("pkg/Outer$1", null, null, 0);

    fv = cw.visitField(ACC_FINAL + ACC_SYNTHETIC, "this$0", "Lpkg/Outer;", null, null);
    fv.visitEnd();

    mv = cw.visitMethod(0, "<init>", "(Lpkg/Outer;)V", null, null);
    mv.visitCode();
    mv.visitVarInsn(ALOAD, 0);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitFieldInsn(PUTFIELD, "pkg/Outer$1", "this$0", "Lpkg/Outer;");
    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKESPECIAL, "pkg/Outer", "<init>", "()V");
    mv.visitInsn(RETURN);
    mv.visitMaxs(0, 0);
    mv.visitEnd();

    mv = cw.visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null);
    mv.visitCode();
    mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
    mv.visitInsn(DUP);
    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V");
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, "pkg/Outer$1", "this$0", "Lpkg/Outer;");
    mv.visitMethodInsn(
        INVOKEVIRTUAL,
        "java/lang/StringBuilder",
        "append",
        "(Ljava/lang/Object;)Ljava/lang/StringBuilder;");
    mv.visitLdcInsn(" ");
    mv.visitMethodInsn(
        INVOKEVIRTUAL,
        "java/lang/StringBuilder",
        "append",
        "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, "pkg/Outer$1", "this$0", "Lpkg/Outer;");
    mv.visitMethodInsn(INVOKESTATIC, "pkg/Outer", "access$000", "(Lpkg/Outer;)I");
    mv.visitMethodInsn(
        INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;");
    mv.visitMethodInsn(
        INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;");
    mv.visitInsn(ARETURN);
    mv.visitMaxs(0, 0);
    mv.visitEnd();

    cw.visitEnd();

    return cw.toByteArray();
  }
 private void loadInitValue(ClassNode type) {
   MethodVisitor mv = controller.getMethodVisitor();
   if (ClassHelper.isPrimitiveType(type)) {
     mv.visitLdcInsn(0);
   } else {
     mv.visitInsn(ACONST_NULL);
   }
   controller.getOperandStack().push(type);
 }
 @Override
 protected void insertCauseCall(MethodVisitor mv, Parameter param, Class<?> targetType) {
   mv.visitLdcInsn(Type.getType(this.anno.value()));
   mv.visitMethodInsn(
       INVOKEVIRTUAL,
       Type.getInternalName(Cause.class),
       "after",
       "(Ljava/lang/Class;)Ljava/util/Optional;",
       false);
 }
 private void setCanCallSettersField(
     MethodVisitor methodVisitor, Type generatedType, boolean canCallSetters) {
   putThisOnStack(methodVisitor);
   methodVisitor.visitLdcInsn(canCallSetters);
   methodVisitor.visitFieldInsn(
       PUTFIELD,
       generatedType.getInternalName(),
       CAN_CALL_SETTERS_FIELD_NAME,
       Type.BOOLEAN_TYPE.getDescriptor());
 }
 protected static void injectGetTargetClass(ClassWriter classWriter, Class<?> targetClass) {
   MethodVisitor methodVisitor =
       classWriter.visitMethod(
           ACC_PUBLIC, "getTargetClass", "()Ljava/lang/Class;", "()Ljava/lang/Class<*>;", null);
   methodVisitor.visitCode();
   methodVisitor.visitLdcInsn(Type.getType(targetClass));
   methodVisitor.visitInsn(ARETURN);
   methodVisitor.visitMaxs(1, 1);
   methodVisitor.visitEnd();
 }
Exemple #15
0
  /**
   * Creates bytecode for evaluating the argument values as integers. The bytecode is generated
   * using the specified method visitor.
   *
   * @param visitor the method visitor
   */
  private void compileInt(MethodVisitor visitor) {
    Label labelFalse = new Label();
    Label labelEnd = new Label();

    value1.compile(visitor, Type.INT);
    value2.compile(visitor, Type.INT);

    visitor.visitJumpInsn(Opcodes.IF_ICMPLE, labelFalse);

    // True
    visitor.visitLdcInsn(true);
    visitor.visitJumpInsn(Opcodes.GOTO, labelEnd);

    // False
    visitor.visitLabel(labelFalse);
    visitor.visitLdcInsn(false);

    visitor.visitLabel(labelEnd);
  }
Exemple #16
0
  /**
   * Creates bytecode for evaluating the argument values as doubles. The bytecode is generated using
   * the specified method visitor.
   *
   * @param visitor the method visitor
   */
  private void compileDouble(MethodVisitor visitor) {
    Label labelFalse = new Label();
    Label labelEnd = new Label();

    value1.compile(visitor, Type.DOUBLE);
    value2.compile(visitor, Type.DOUBLE);

    visitor.visitInsn(Opcodes.DCMPL);
    visitor.visitJumpInsn(Opcodes.IFLE, labelFalse);

    // True
    visitor.visitLdcInsn(true);
    visitor.visitJumpInsn(Opcodes.GOTO, labelEnd);

    // False
    visitor.visitLabel(labelFalse);
    visitor.visitLdcInsn(false);

    visitor.visitLabel(labelEnd);
  }
Exemple #17
0
  /** Generates the bytecode that pushes the given value onto the stack */
  public void pushDouble(double aValue) {
    if (aValue == 0) {
      itsVisitor.visitInsn(Opcodes.DCONST_0);
      return;
    } else if (aValue == 1) {
      itsVisitor.visitInsn(Opcodes.DCONST_1);
      return;
    }

    itsVisitor.visitLdcInsn(new Double(aValue));
  }
Exemple #18
0
  /** Generates the bytecode that pushes the given value onto the stack */
  public void pushLong(long aValue) {
    if (aValue == 0) {
      itsVisitor.visitInsn(Opcodes.LCONST_0);
      return;
    } else if (aValue == 1) {
      itsVisitor.visitInsn(Opcodes.LCONST_1);
      return;
    }

    itsVisitor.visitLdcInsn(new Long(aValue));
  }
 private void writeManagedTypeStaticField(
     Type generatedType, Class<?> managedTypeClass, MethodVisitor constructorVisitor) {
   constructorVisitor.visitLdcInsn(Type.getType(managedTypeClass));
   constructorVisitor.visitMethodInsn(
       INVOKESTATIC, MODELTYPE_INTERNAL_NAME, "of", MODELTYPE_OF_METHOD_DESCRIPTOR, false);
   constructorVisitor.visitFieldInsn(
       PUTSTATIC,
       generatedType.getInternalName(),
       MANAGED_TYPE_FIELD_NAME,
       Type.getDescriptor(ModelType.class));
 }
 /**
  * Visits a class literal. If the type of the classnode is a primitive type, the generated
  * bytecode will be a GETSTATIC Integer.TYPE. If the classnode is not a primitive type, we will
  * generate a LDC instruction.
  */
 public static void visitClassLiteral(MethodVisitor mv, ClassNode classNode) {
   if (ClassHelper.isPrimitiveType(classNode)) {
     mv.visitFieldInsn(
         GETSTATIC,
         getClassInternalName(ClassHelper.getWrapper(classNode)),
         "TYPE",
         "Ljava/lang/Class;");
   } else {
     mv.visitLdcInsn(org.objectweb.asm.Type.getType(getTypeDescription(classNode)));
   }
 }
  public MethodVisitor visitMethod(
      final int access,
      final String methodName,
      final String desc,
      final String signature,
      final String[] exceptions) {
    if ("display2".equals(methodName)) {
      return null; // 我们屏蔽了这个方法
    }
    if ("display1".equals(methodName)) {
      MethodVisitor methodVisitor = cv.visitMethod(access, methodName, desc, signature, exceptions);
      methodVisitor.visitCode();
      // 增加的语句等价于增加代码:name = "我是name"
      methodVisitor.visitVarInsn(
          Opcodes.ALOAD, 0); // aload_0 is supposed to push 'this' on to the stack
      methodVisitor.visitLdcInsn("我是name");
      methodVisitor.visitFieldInsn(
          Opcodes.PUTFIELD, "chapter03/asm/ForASMTestClass", "name", "Ljava/lang/String;");

      // 这条语句等价于增加代码:value = "我是value";
      methodVisitor.visitVarInsn(
          Opcodes.ALOAD, 0); // aload_0 is supposed to push 'this' on to the stack
      methodVisitor.visitLdcInsn("我是value");
      methodVisitor.visitFieldInsn(
          Opcodes.PUTFIELD, "chapter03/asm/ForASMTestClass", "value", "Ljava/lang/String;");

      // 再将一个属性获取出来打印出来
      methodVisitor.visitFieldInsn(
          Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
      methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
      methodVisitor.visitFieldInsn(
          Opcodes.GETFIELD, "chapter03/asm/ForASMTestClass", "name", "Ljava/lang/String;");
      methodVisitor.visitMethodInsn(
          Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");

      methodVisitor.visitEnd();
      return methodVisitor; // 返回visitor
    } else {
      return cv.visitMethod(access, methodName, desc, signature, exceptions);
    }
  }
  /** load the constant on the operand stack. */
  public void pushConstant(ConstantExpression expression) {
    MethodVisitor mv = controller.getMethodVisitor();
    Object value = expression.getValue();
    ClassNode origType = expression.getType().redirect();
    ClassNode type = ClassHelper.getUnwrapper(origType);
    boolean boxing = origType != type;
    boolean asPrimitive = boxing || ClassHelper.isPrimitiveType(type);

    if (value == null) {
      mv.visitInsn(ACONST_NULL);
    } else if (boxing && value instanceof Boolean) {
      // special path for boxed boolean
      Boolean bool = (Boolean) value;
      String text = bool ? "TRUE" : "FALSE";
      mv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", text, "Ljava/lang/Boolean;");
      boxing = false;
      type = origType;
    } else if (asPrimitive) {
      pushPrimitiveConstant(mv, value, type);
    } else if (value instanceof BigDecimal) {
      String className = BytecodeHelper.getClassInternalName(value.getClass().getName());
      mv.visitTypeInsn(NEW, className);
      mv.visitInsn(DUP);
      mv.visitLdcInsn(value.toString());
      mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", "(Ljava/lang/String;)V", false);
    } else if (value instanceof BigInteger) {
      String className = BytecodeHelper.getClassInternalName(value.getClass().getName());
      mv.visitTypeInsn(NEW, className);
      mv.visitInsn(DUP);
      mv.visitLdcInsn(value.toString());
      mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", "(Ljava/lang/String;)V", false);
    } else if (value instanceof String) {
      mv.visitLdcInsn(value);
    } else {
      throw new ClassGeneratorException(
          "Cannot generate bytecode for constant: " + value + " of type: " + type.getName());
    }

    push(type);
    if (boxing) box();
  }
 @Override
 public Object visitIntLitExpression(IntLitExpression intLitExpression, Object arg)
     throws Exception {
   MethodVisitor mv = ((InheritedAttributes) arg).mv; // this should be the
   // first statement
   // of all visit
   // methods that
   // generate
   // instructions
   mv.visitLdcInsn(intLitExpression.value);
   return intType;
 }
  /** Generate a call to the delegate object. */
  protected MethodVisitor makeDelegateCall(
      final String name,
      final String desc,
      final String signature,
      final String[] exceptions,
      final int accessFlags) {
    MethodVisitor mv = super.visitMethod(accessFlags, name, desc, signature, exceptions);
    mv.visitVarInsn(ALOAD, 0); // load this
    mv.visitFieldInsn(
        GETFIELD,
        proxyName,
        DELEGATE_OBJECT_FIELD,
        BytecodeHelper.getTypeDescription(delegateClass)); // load delegate
    // using InvokerHelper to allow potential intercepted calls
    int size;
    mv.visitLdcInsn(name); // method name
    Type[] args = Type.getArgumentTypes(desc);
    BytecodeHelper.pushConstant(mv, args.length);
    mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
    size = 3;
    int idx = 1;
    for (int i = 0; i < args.length; i++) {
      Type arg = args[i];
      mv.visitInsn(DUP);
      BytecodeHelper.pushConstant(mv, i);
      // primitive types must be boxed
      if (isPrimitive(arg)) {
        mv.visitIntInsn(getLoadInsn(arg), idx);
        String wrappedType = getWrappedClassDescriptor(arg);
        mv.visitMethodInsn(
            INVOKESTATIC,
            wrappedType,
            "valueOf",
            "(" + arg.getDescriptor() + ")L" + wrappedType + ";");
      } else {
        mv.visitVarInsn(ALOAD, idx); // load argument i
      }
      size = Math.max(6, 5 + registerLen(arg));
      idx += registerLen(arg);
      mv.visitInsn(AASTORE); // store value into array
    }
    mv.visitMethodInsn(
        INVOKESTATIC,
        "org/codehaus/groovy/runtime/InvokerHelper",
        "invokeMethod",
        "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;");
    unwrapResult(mv, desc);
    mv.visitMaxs(size, registerLen(args) + 1);

    return EMPTY_VISITOR;
  }
  // the overload of type Object for Groovy coercions:  public void setFoo(Object foo)
  private void createTypeConvertingSetter(
      ClassVisitor visitor, Type generatedType, ModelProperty<?> property) {
    if (!property.isWritable() || !(property.getSchema() instanceof ScalarValueSchema)) {
      return;
    }

    Class<?> propertyClass = property.getType().getConcreteClass();
    Type propertyType = Type.getType(propertyClass);
    Class<?> boxedClass =
        propertyClass.isPrimitive() ? BOXED_TYPES.get(propertyClass) : propertyClass;
    Type boxedType = Type.getType(boxedClass);

    Method setter = property.getSetter().getMethod();
    MethodVisitor methodVisitor =
        declareMethod(
            visitor,
            setter.getName(),
            SET_OBJECT_PROPERTY_DESCRIPTOR,
            SET_OBJECT_PROPERTY_DESCRIPTOR);

    putThisOnStack(methodVisitor);
    putTypeConverterFieldValueOnStack(methodVisitor, generatedType);

    // Object converted = $typeConverter.convert(foo, Float.class, false);
    methodVisitor.visitVarInsn(ALOAD, 1); // put var #1 ('foo') on the stack
    methodVisitor.visitLdcInsn(boxedType); // push the constant Class onto the stack
    methodVisitor.visitInsn(
        propertyClass.isPrimitive()
            ? ICONST_1
            : ICONST_0); // push int 1 or 0 (interpreted as true or false) onto the stack
    methodVisitor.visitMethodInsn(
        INVOKEINTERFACE,
        TYPE_CONVERTER_TYPE.getInternalName(),
        "convert",
        COERCE_TO_SCALAR_DESCRIPTOR,
        true);
    methodVisitor.visitTypeInsn(CHECKCAST, boxedType.getInternalName());

    if (propertyClass.isPrimitive()) {
      unboxType(methodVisitor, propertyClass);
    }

    // invoke the typed setter, popping 'this' and 'converted' from the stack
    methodVisitor.visitMethodInsn(
        INVOKEVIRTUAL,
        generatedType.getInternalName(),
        setter.getName(),
        Type.getMethodDescriptor(Type.VOID_TYPE, propertyType),
        false);
    finishVisitingMethod(methodVisitor);
  }
  @Override
  public Object visitStringLitExpression(StringLitExpression stringLitExpression, Object arg)
      throws Exception {
    // throw new UnsupportedOperationException("code generation not yet implemented");

    MethodVisitor mv = ((InheritedAttributes) arg).mv; // this should be the
    // first statement
    // of all visit
    // methods that
    // generate
    // instructions
    mv.visitLdcInsn(stringLitExpression.value);
    return stringType;
  }
Exemple #27
0
  /** Generates the bytecode that pushes the given value onto the stack */
  public void pushFloat(float aValue) {
    if (aValue == 0) {
      itsVisitor.visitInsn(Opcodes.FCONST_0);
      return;
    } else if (aValue == 1) {
      itsVisitor.visitInsn(Opcodes.FCONST_1);
      return;
    } else if (aValue == 2) {
      itsVisitor.visitInsn(Opcodes.FCONST_2);
      return;
    }

    itsVisitor.visitLdcInsn(new Float(aValue));
  }
  public void visitConstructor(ConstructorNode node) {

    visitParameters(node, node.getParameters());

    String methodType =
        BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, node.getParameters());
    mv = cv.visitMethod(node.getModifiers(), "<init>", methodType, null, null);
    mv.visitTypeInsn(NEW, "java/lang/RuntimeException");
    mv.visitInsn(DUP);
    mv.visitLdcInsn("not intended for execution");
    mv.visitMethodInsn(
        INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/String;)V", false);
    mv.visitInsn(ATHROW);
    mv.visitMaxs(0, 0);
  }
 /**
  * Initializes a member mixin field.
  *
  * @param mv
  * @param fieldInfo
  */
 private void initializeMemberMixinField(final MethodVisitor mv, final MixinFieldInfo fieldInfo) {
   mv.visitVarInsn(ALOAD, 0);
   mv.visitLdcInsn(fieldInfo.mixinClassInfo.getName().replace('/', '.'));
   mv.visitVarInsn(ALOAD, 0);
   mv.visitMethodInsn(
       INVOKESTATIC,
       MIXINS_CLASS_NAME,
       MIXIN_OF_METHOD_NAME,
       MIXIN_OF_METHOD_PER_INSTANCE_SIGNATURE);
   mv.visitTypeInsn(CHECKCAST, fieldInfo.mixinClassInfo.getName().replace('.', '/'));
   mv.visitFieldInsn(
       PUTFIELD,
       m_declaringTypeName,
       fieldInfo.fieldName,
       fieldInfo.mixinClassInfo.getSignature());
 }
 private static MethodVisitor insertThrowExceptionForFieldNotFound(MethodVisitor mv) {
   mv.visitTypeInsn(NEW, "java/lang/IllegalArgumentException");
   mv.visitInsn(DUP);
   mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
   mv.visitInsn(DUP);
   mv.visitLdcInsn("Field not found: ");
   mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V");
   mv.visitVarInsn(ILOAD, 2);
   mv.visitMethodInsn(
       INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;");
   mv.visitMethodInsn(
       INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;");
   mv.visitMethodInsn(
       INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>", "(Ljava/lang/String;)V");
   mv.visitInsn(ATHROW);
   return mv;
 }